diff --git a/vendor/github.com/BurntSushi/toml/.gitignore b/vendor/github.com/BurntSushi/toml/.gitignore new file mode 100644 index 0000000..fe79e3a --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/.gitignore @@ -0,0 +1,2 @@ +/toml.test +/toml-test diff --git a/vendor/github.com/BurntSushi/toml/COPYING b/vendor/github.com/BurntSushi/toml/COPYING new file mode 100644 index 0000000..01b5743 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/COPYING @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 TOML authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/BurntSushi/toml/README.md b/vendor/github.com/BurntSushi/toml/README.md new file mode 100644 index 0000000..639e6c3 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/README.md @@ -0,0 +1,120 @@ +TOML stands for Tom's Obvious, Minimal Language. This Go package provides a +reflection interface similar to Go's standard library `json` and `xml` packages. + +Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0). + +Documentation: https://godocs.io/github.com/BurntSushi/toml + +See the [releases page](https://github.com/BurntSushi/toml/releases) for a +changelog; this information is also in the git tag annotations (e.g. `git show +v0.4.0`). + +This library requires Go 1.18 or newer; add it to your go.mod with: + + % go get github.com/BurntSushi/toml@latest + +It also comes with a TOML validator CLI tool: + + % go install github.com/BurntSushi/toml/cmd/tomlv@latest + % tomlv some-toml-file.toml + +### Examples +For the simplest example, consider some TOML file as just a list of keys and +values: + +```toml +Age = 25 +Cats = [ "Cauchy", "Plato" ] +Pi = 3.14 +Perfection = [ 6, 28, 496, 8128 ] +DOB = 1987-07-05T05:45:00Z +``` + +Which can be decoded with: + +```go +type Config struct { + Age int + Cats []string + Pi float64 + Perfection []int + DOB time.Time +} + +var conf Config +_, err := toml.Decode(tomlData, &conf) +``` + +You can also use struct tags if your struct field name doesn't map to a TOML key +value directly: + +```toml +some_key_NAME = "wat" +``` + +```go +type TOML struct { + ObscureKey string `toml:"some_key_NAME"` +} +``` + +Beware that like other decoders **only exported fields** are considered when +encoding and decoding; private fields are silently ignored. + +### Using the `Marshaler` and `encoding.TextUnmarshaler` interfaces +Here's an example that automatically parses values in a `mail.Address`: + +```toml +contacts = [ + "Donald Duck ", + "Scrooge McDuck ", +] +``` + +Can be decoded with: + +```go +// Create address type which satisfies the encoding.TextUnmarshaler interface. +type address struct { + *mail.Address +} + +func (a *address) UnmarshalText(text []byte) error { + var err error + a.Address, err = mail.ParseAddress(string(text)) + return err +} + +// Decode it. +func decode() { + blob := ` + contacts = [ + "Donald Duck ", + "Scrooge McDuck ", + ] + ` + + var contacts struct { + Contacts []address + } + + _, err := toml.Decode(blob, &contacts) + if err != nil { + log.Fatal(err) + } + + for _, c := range contacts.Contacts { + fmt.Printf("%#v\n", c.Address) + } + + // Output: + // &mail.Address{Name:"Donald Duck", Address:"donald@duckburg.com"} + // &mail.Address{Name:"Scrooge McDuck", Address:"scrooge@duckburg.com"} +} +``` + +To target TOML specifically you can implement `UnmarshalTOML` TOML interface in +a similar way. + +### More complex usage +See the [`_example/`](/_example) directory for a more complex example. diff --git a/vendor/github.com/BurntSushi/toml/decode.go b/vendor/github.com/BurntSushi/toml/decode.go new file mode 100644 index 0000000..c05a0b7 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/decode.go @@ -0,0 +1,615 @@ +package toml + +import ( + "bytes" + "encoding" + "encoding/json" + "fmt" + "io" + "io/fs" + "math" + "os" + "reflect" + "strconv" + "strings" + "time" +) + +// Unmarshaler is the interface implemented by objects that can unmarshal a +// TOML description of themselves. +type Unmarshaler interface { + UnmarshalTOML(any) error +} + +// Unmarshal decodes the contents of data in TOML format into a pointer v. +// +// See [Decoder] for a description of the decoding process. +func Unmarshal(data []byte, v any) error { + _, err := NewDecoder(bytes.NewReader(data)).Decode(v) + return err +} + +// Decode the TOML data in to the pointer v. +// +// See [Decoder] for a description of the decoding process. +func Decode(data string, v any) (MetaData, error) { + return NewDecoder(strings.NewReader(data)).Decode(v) +} + +// DecodeFile reads the contents of a file and decodes it with [Decode]. +func DecodeFile(path string, v any) (MetaData, error) { + fp, err := os.Open(path) + if err != nil { + return MetaData{}, err + } + defer fp.Close() + return NewDecoder(fp).Decode(v) +} + +// DecodeFS reads the contents of a file from [fs.FS] and decodes it with +// [Decode]. +func DecodeFS(fsys fs.FS, path string, v any) (MetaData, error) { + fp, err := fsys.Open(path) + if err != nil { + return MetaData{}, err + } + defer fp.Close() + return NewDecoder(fp).Decode(v) +} + +// Primitive is a TOML value that hasn't been decoded into a Go value. +// +// This type can be used for any value, which will cause decoding to be delayed. +// You can use [PrimitiveDecode] to "manually" decode these values. +// +// NOTE: The underlying representation of a `Primitive` value is subject to +// change. Do not rely on it. +// +// NOTE: Primitive values are still parsed, so using them will only avoid the +// overhead of reflection. They can be useful when you don't know the exact type +// of TOML data until runtime. +type Primitive struct { + undecoded any + context Key +} + +// The significand precision for float32 and float64 is 24 and 53 bits; this is +// the range a natural number can be stored in a float without loss of data. +const ( + maxSafeFloat32Int = 16777215 // 2^24-1 + maxSafeFloat64Int = int64(9007199254740991) // 2^53-1 +) + +// Decoder decodes TOML data. +// +// TOML tables correspond to Go structs or maps; they can be used +// interchangeably, but structs offer better type safety. +// +// TOML table arrays correspond to either a slice of structs or a slice of maps. +// +// TOML datetimes correspond to [time.Time]. Local datetimes are parsed in the +// local timezone. +// +// [time.Duration] types are treated as nanoseconds if the TOML value is an +// integer, or they're parsed with time.ParseDuration() if they're strings. +// +// All other TOML types (float, string, int, bool and array) correspond to the +// obvious Go types. +// +// An exception to the above rules is if a type implements the TextUnmarshaler +// interface, in which case any primitive TOML value (floats, strings, integers, +// booleans, datetimes) will be converted to a []byte and given to the value's +// UnmarshalText method. See the Unmarshaler example for a demonstration with +// email addresses. +// +// # Key mapping +// +// TOML keys can map to either keys in a Go map or field names in a Go struct. +// The special `toml` struct tag can be used to map TOML keys to struct fields +// that don't match the key name exactly (see the example). A case insensitive +// match to struct names will be tried if an exact match can't be found. +// +// The mapping between TOML values and Go values is loose. That is, there may +// exist TOML values that cannot be placed into your representation, and there +// may be parts of your representation that do not correspond to TOML values. +// This loose mapping can be made stricter by using the IsDefined and/or +// Undecoded methods on the MetaData returned. +// +// This decoder does not handle cyclic types. Decode will not terminate if a +// cyclic type is passed. +type Decoder struct { + r io.Reader +} + +// NewDecoder creates a new Decoder. +func NewDecoder(r io.Reader) *Decoder { + return &Decoder{r: r} +} + +var ( + unmarshalToml = reflect.TypeOf((*Unmarshaler)(nil)).Elem() + unmarshalText = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() + primitiveType = reflect.TypeOf((*Primitive)(nil)).Elem() +) + +// Decode TOML data in to the pointer `v`. +func (dec *Decoder) Decode(v any) (MetaData, error) { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr { + s := "%q" + if reflect.TypeOf(v) == nil { + s = "%v" + } + + return MetaData{}, fmt.Errorf("toml: cannot decode to non-pointer "+s, reflect.TypeOf(v)) + } + if rv.IsNil() { + return MetaData{}, fmt.Errorf("toml: cannot decode to nil value of %q", reflect.TypeOf(v)) + } + + // Check if this is a supported type: struct, map, any, or something that + // implements UnmarshalTOML or UnmarshalText. + rv = indirect(rv) + rt := rv.Type() + if rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map && + !(rv.Kind() == reflect.Interface && rv.NumMethod() == 0) && + !rt.Implements(unmarshalToml) && !rt.Implements(unmarshalText) { + return MetaData{}, fmt.Errorf("toml: cannot decode to type %s", rt) + } + + // TODO: parser should read from io.Reader? Or at the very least, make it + // read from []byte rather than string + data, err := io.ReadAll(dec.r) + if err != nil { + return MetaData{}, err + } + + p, err := parse(string(data)) + if err != nil { + return MetaData{}, err + } + + md := MetaData{ + mapping: p.mapping, + keyInfo: p.keyInfo, + keys: p.ordered, + decoded: make(map[string]struct{}, len(p.ordered)), + context: nil, + data: data, + } + return md, md.unify(p.mapping, rv) +} + +// PrimitiveDecode is just like the other Decode* functions, except it decodes a +// TOML value that has already been parsed. Valid primitive values can *only* be +// obtained from values filled by the decoder functions, including this method. +// (i.e., v may contain more [Primitive] values.) +// +// Meta data for primitive values is included in the meta data returned by the +// Decode* functions with one exception: keys returned by the Undecoded method +// will only reflect keys that were decoded. Namely, any keys hidden behind a +// Primitive will be considered undecoded. Executing this method will update the +// undecoded keys in the meta data. (See the example.) +func (md *MetaData) PrimitiveDecode(primValue Primitive, v any) error { + md.context = primValue.context + defer func() { md.context = nil }() + return md.unify(primValue.undecoded, rvalue(v)) +} + +// unify performs a sort of type unification based on the structure of `rv`, +// which is the client representation. +// +// Any type mismatch produces an error. Finding a type that we don't know +// how to handle produces an unsupported type error. +func (md *MetaData) unify(data any, rv reflect.Value) error { + // Special case. Look for a `Primitive` value. + // TODO: #76 would make this superfluous after implemented. + if rv.Type() == primitiveType { + // Save the undecoded data and the key context into the primitive + // value. + context := make(Key, len(md.context)) + copy(context, md.context) + rv.Set(reflect.ValueOf(Primitive{ + undecoded: data, + context: context, + })) + return nil + } + + rvi := rv.Interface() + if v, ok := rvi.(Unmarshaler); ok { + err := v.UnmarshalTOML(data) + if err != nil { + return md.parseErr(err) + } + return nil + } + if v, ok := rvi.(encoding.TextUnmarshaler); ok { + return md.unifyText(data, v) + } + + // TODO: + // The behavior here is incorrect whenever a Go type satisfies the + // encoding.TextUnmarshaler interface but also corresponds to a TOML hash or + // array. In particular, the unmarshaler should only be applied to primitive + // TOML values. But at this point, it will be applied to all kinds of values + // and produce an incorrect error whenever those values are hashes or arrays + // (including arrays of tables). + + k := rv.Kind() + + if k >= reflect.Int && k <= reflect.Uint64 { + return md.unifyInt(data, rv) + } + switch k { + case reflect.Struct: + return md.unifyStruct(data, rv) + case reflect.Map: + return md.unifyMap(data, rv) + case reflect.Array: + return md.unifyArray(data, rv) + case reflect.Slice: + return md.unifySlice(data, rv) + case reflect.String: + return md.unifyString(data, rv) + case reflect.Bool: + return md.unifyBool(data, rv) + case reflect.Interface: + if rv.NumMethod() > 0 { /// Only empty interfaces are supported. + return md.e("unsupported type %s", rv.Type()) + } + return md.unifyAnything(data, rv) + case reflect.Float32, reflect.Float64: + return md.unifyFloat64(data, rv) + } + return md.e("unsupported type %s", rv.Kind()) +} + +func (md *MetaData) unifyStruct(mapping any, rv reflect.Value) error { + tmap, ok := mapping.(map[string]any) + if !ok { + if mapping == nil { + return nil + } + return md.e("type mismatch for %s: expected table but found %s", rv.Type().String(), fmtType(mapping)) + } + + for key, datum := range tmap { + var f *field + fields := cachedTypeFields(rv.Type()) + for i := range fields { + ff := &fields[i] + if ff.name == key { + f = ff + break + } + if f == nil && strings.EqualFold(ff.name, key) { + f = ff + } + } + if f != nil { + subv := rv + for _, i := range f.index { + subv = indirect(subv.Field(i)) + } + + if isUnifiable(subv) { + md.decoded[md.context.add(key).String()] = struct{}{} + md.context = append(md.context, key) + + err := md.unify(datum, subv) + if err != nil { + return err + } + md.context = md.context[0 : len(md.context)-1] + } else if f.name != "" { + return md.e("cannot write unexported field %s.%s", rv.Type().String(), f.name) + } + } + } + return nil +} + +func (md *MetaData) unifyMap(mapping any, rv reflect.Value) error { + keyType := rv.Type().Key().Kind() + if keyType != reflect.String && keyType != reflect.Interface { + return fmt.Errorf("toml: cannot decode to a map with non-string key type (%s in %q)", + keyType, rv.Type()) + } + + tmap, ok := mapping.(map[string]any) + if !ok { + if tmap == nil { + return nil + } + return md.badtype("map", mapping) + } + if rv.IsNil() { + rv.Set(reflect.MakeMap(rv.Type())) + } + for k, v := range tmap { + md.decoded[md.context.add(k).String()] = struct{}{} + md.context = append(md.context, k) + + rvval := reflect.Indirect(reflect.New(rv.Type().Elem())) + + err := md.unify(v, indirect(rvval)) + if err != nil { + return err + } + md.context = md.context[0 : len(md.context)-1] + + rvkey := indirect(reflect.New(rv.Type().Key())) + + switch keyType { + case reflect.Interface: + rvkey.Set(reflect.ValueOf(k)) + case reflect.String: + rvkey.SetString(k) + } + + rv.SetMapIndex(rvkey, rvval) + } + return nil +} + +func (md *MetaData) unifyArray(data any, rv reflect.Value) error { + datav := reflect.ValueOf(data) + if datav.Kind() != reflect.Slice { + if !datav.IsValid() { + return nil + } + return md.badtype("slice", data) + } + if l := datav.Len(); l != rv.Len() { + return md.e("expected array length %d; got TOML array of length %d", rv.Len(), l) + } + return md.unifySliceArray(datav, rv) +} + +func (md *MetaData) unifySlice(data any, rv reflect.Value) error { + datav := reflect.ValueOf(data) + if datav.Kind() != reflect.Slice { + if !datav.IsValid() { + return nil + } + return md.badtype("slice", data) + } + n := datav.Len() + if rv.IsNil() || rv.Cap() < n { + rv.Set(reflect.MakeSlice(rv.Type(), n, n)) + } + rv.SetLen(n) + return md.unifySliceArray(datav, rv) +} + +func (md *MetaData) unifySliceArray(data, rv reflect.Value) error { + l := data.Len() + for i := 0; i < l; i++ { + err := md.unify(data.Index(i).Interface(), indirect(rv.Index(i))) + if err != nil { + return err + } + } + return nil +} + +func (md *MetaData) unifyString(data any, rv reflect.Value) error { + _, ok := rv.Interface().(json.Number) + if ok { + if i, ok := data.(int64); ok { + rv.SetString(strconv.FormatInt(i, 10)) + } else if f, ok := data.(float64); ok { + rv.SetString(strconv.FormatFloat(f, 'f', -1, 64)) + } else { + return md.badtype("string", data) + } + return nil + } + + if s, ok := data.(string); ok { + rv.SetString(s) + return nil + } + return md.badtype("string", data) +} + +func (md *MetaData) unifyFloat64(data any, rv reflect.Value) error { + rvk := rv.Kind() + + if num, ok := data.(float64); ok { + switch rvk { + case reflect.Float32: + if num < -math.MaxFloat32 || num > math.MaxFloat32 { + return md.parseErr(errParseRange{i: num, size: rvk.String()}) + } + fallthrough + case reflect.Float64: + rv.SetFloat(num) + default: + panic("bug") + } + return nil + } + + if num, ok := data.(int64); ok { + if (rvk == reflect.Float32 && (num < -maxSafeFloat32Int || num > maxSafeFloat32Int)) || + (rvk == reflect.Float64 && (num < -maxSafeFloat64Int || num > maxSafeFloat64Int)) { + return md.parseErr(errUnsafeFloat{i: num, size: rvk.String()}) + } + rv.SetFloat(float64(num)) + return nil + } + + return md.badtype("float", data) +} + +func (md *MetaData) unifyInt(data any, rv reflect.Value) error { + _, ok := rv.Interface().(time.Duration) + if ok { + // Parse as string duration, and fall back to regular integer parsing + // (as nanosecond) if this is not a string. + if s, ok := data.(string); ok { + dur, err := time.ParseDuration(s) + if err != nil { + return md.parseErr(errParseDuration{s}) + } + rv.SetInt(int64(dur)) + return nil + } + } + + num, ok := data.(int64) + if !ok { + return md.badtype("integer", data) + } + + rvk := rv.Kind() + switch { + case rvk >= reflect.Int && rvk <= reflect.Int64: + if (rvk == reflect.Int8 && (num < math.MinInt8 || num > math.MaxInt8)) || + (rvk == reflect.Int16 && (num < math.MinInt16 || num > math.MaxInt16)) || + (rvk == reflect.Int32 && (num < math.MinInt32 || num > math.MaxInt32)) { + return md.parseErr(errParseRange{i: num, size: rvk.String()}) + } + rv.SetInt(num) + case rvk >= reflect.Uint && rvk <= reflect.Uint64: + unum := uint64(num) + if rvk == reflect.Uint8 && (num < 0 || unum > math.MaxUint8) || + rvk == reflect.Uint16 && (num < 0 || unum > math.MaxUint16) || + rvk == reflect.Uint32 && (num < 0 || unum > math.MaxUint32) { + return md.parseErr(errParseRange{i: num, size: rvk.String()}) + } + rv.SetUint(unum) + default: + panic("unreachable") + } + return nil +} + +func (md *MetaData) unifyBool(data any, rv reflect.Value) error { + if b, ok := data.(bool); ok { + rv.SetBool(b) + return nil + } + return md.badtype("boolean", data) +} + +func (md *MetaData) unifyAnything(data any, rv reflect.Value) error { + rv.Set(reflect.ValueOf(data)) + return nil +} + +func (md *MetaData) unifyText(data any, v encoding.TextUnmarshaler) error { + var s string + switch sdata := data.(type) { + case Marshaler: + text, err := sdata.MarshalTOML() + if err != nil { + return err + } + s = string(text) + case encoding.TextMarshaler: + text, err := sdata.MarshalText() + if err != nil { + return err + } + s = string(text) + case fmt.Stringer: + s = sdata.String() + case string: + s = sdata + case bool: + s = fmt.Sprintf("%v", sdata) + case int64: + s = fmt.Sprintf("%d", sdata) + case float64: + s = fmt.Sprintf("%f", sdata) + default: + return md.badtype("primitive (string-like)", data) + } + if err := v.UnmarshalText([]byte(s)); err != nil { + return md.parseErr(err) + } + return nil +} + +func (md *MetaData) badtype(dst string, data any) error { + return md.e("incompatible types: TOML value has type %s; destination has type %s", fmtType(data), dst) +} + +func (md *MetaData) parseErr(err error) error { + k := md.context.String() + d := string(md.data) + return ParseError{ + Message: err.Error(), + err: err, + LastKey: k, + Position: md.keyInfo[k].pos.withCol(d), + Line: md.keyInfo[k].pos.Line, + input: d, + } +} + +func (md *MetaData) e(format string, args ...any) error { + f := "toml: " + if len(md.context) > 0 { + f = fmt.Sprintf("toml: (last key %q): ", md.context) + p := md.keyInfo[md.context.String()].pos + if p.Line > 0 { + f = fmt.Sprintf("toml: line %d (last key %q): ", p.Line, md.context) + } + } + return fmt.Errorf(f+format, args...) +} + +// rvalue returns a reflect.Value of `v`. All pointers are resolved. +func rvalue(v any) reflect.Value { + return indirect(reflect.ValueOf(v)) +} + +// indirect returns the value pointed to by a pointer. +// +// Pointers are followed until the value is not a pointer. New values are +// allocated for each nil pointer. +// +// An exception to this rule is if the value satisfies an interface of interest +// to us (like encoding.TextUnmarshaler). +func indirect(v reflect.Value) reflect.Value { + if v.Kind() != reflect.Ptr { + if v.CanSet() { + pv := v.Addr() + pvi := pv.Interface() + if _, ok := pvi.(encoding.TextUnmarshaler); ok { + return pv + } + if _, ok := pvi.(Unmarshaler); ok { + return pv + } + } + return v + } + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + return indirect(reflect.Indirect(v)) +} + +func isUnifiable(rv reflect.Value) bool { + if rv.CanSet() { + return true + } + rvi := rv.Interface() + if _, ok := rvi.(encoding.TextUnmarshaler); ok { + return true + } + if _, ok := rvi.(Unmarshaler); ok { + return true + } + return false +} + +// fmt %T with "interface {}" replaced with "any", which is far more readable. +func fmtType(t any) string { + return strings.ReplaceAll(fmt.Sprintf("%T", t), "interface {}", "any") +} diff --git a/vendor/github.com/BurntSushi/toml/deprecated.go b/vendor/github.com/BurntSushi/toml/deprecated.go new file mode 100644 index 0000000..155709a --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/deprecated.go @@ -0,0 +1,29 @@ +package toml + +import ( + "encoding" + "io" +) + +// TextMarshaler is an alias for encoding.TextMarshaler. +// +// Deprecated: use encoding.TextMarshaler +type TextMarshaler encoding.TextMarshaler + +// TextUnmarshaler is an alias for encoding.TextUnmarshaler. +// +// Deprecated: use encoding.TextUnmarshaler +type TextUnmarshaler encoding.TextUnmarshaler + +// DecodeReader is an alias for NewDecoder(r).Decode(v). +// +// Deprecated: use NewDecoder(reader).Decode(&value). +func DecodeReader(r io.Reader, v any) (MetaData, error) { return NewDecoder(r).Decode(v) } + +// PrimitiveDecode is an alias for MetaData.PrimitiveDecode(). +// +// Deprecated: use MetaData.PrimitiveDecode. +func PrimitiveDecode(primValue Primitive, v any) error { + md := MetaData{decoded: make(map[string]struct{})} + return md.unify(primValue.undecoded, rvalue(v)) +} diff --git a/vendor/github.com/BurntSushi/toml/doc.go b/vendor/github.com/BurntSushi/toml/doc.go new file mode 100644 index 0000000..82c90a9 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/doc.go @@ -0,0 +1,8 @@ +// Package toml implements decoding and encoding of TOML files. +// +// This package supports TOML v1.0.0, as specified at https://toml.io +// +// The github.com/BurntSushi/toml/cmd/tomlv package implements a TOML validator, +// and can be used to verify if TOML document is valid. It can also be used to +// print the type of each key. +package toml diff --git a/vendor/github.com/BurntSushi/toml/encode.go b/vendor/github.com/BurntSushi/toml/encode.go new file mode 100644 index 0000000..73366c0 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/encode.go @@ -0,0 +1,778 @@ +package toml + +import ( + "bufio" + "bytes" + "encoding" + "encoding/json" + "errors" + "fmt" + "io" + "math" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/BurntSushi/toml/internal" +) + +type tomlEncodeError struct{ error } + +var ( + errArrayNilElement = errors.New("toml: cannot encode array with nil element") + errNonString = errors.New("toml: cannot encode a map with non-string key type") + errNoKey = errors.New("toml: top-level values must be Go maps or structs") + errAnything = errors.New("") // used in testing +) + +var dblQuotedReplacer = strings.NewReplacer( + "\"", "\\\"", + "\\", "\\\\", + "\x00", `\u0000`, + "\x01", `\u0001`, + "\x02", `\u0002`, + "\x03", `\u0003`, + "\x04", `\u0004`, + "\x05", `\u0005`, + "\x06", `\u0006`, + "\x07", `\u0007`, + "\b", `\b`, + "\t", `\t`, + "\n", `\n`, + "\x0b", `\u000b`, + "\f", `\f`, + "\r", `\r`, + "\x0e", `\u000e`, + "\x0f", `\u000f`, + "\x10", `\u0010`, + "\x11", `\u0011`, + "\x12", `\u0012`, + "\x13", `\u0013`, + "\x14", `\u0014`, + "\x15", `\u0015`, + "\x16", `\u0016`, + "\x17", `\u0017`, + "\x18", `\u0018`, + "\x19", `\u0019`, + "\x1a", `\u001a`, + "\x1b", `\u001b`, + "\x1c", `\u001c`, + "\x1d", `\u001d`, + "\x1e", `\u001e`, + "\x1f", `\u001f`, + "\x7f", `\u007f`, +) + +var ( + marshalToml = reflect.TypeOf((*Marshaler)(nil)).Elem() + marshalText = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + timeType = reflect.TypeOf((*time.Time)(nil)).Elem() +) + +// Marshaler is the interface implemented by types that can marshal themselves +// into valid TOML. +type Marshaler interface { + MarshalTOML() ([]byte, error) +} + +// Marshal returns a TOML representation of the Go value. +// +// See [Encoder] for a description of the encoding process. +func Marshal(v any) ([]byte, error) { + buff := new(bytes.Buffer) + if err := NewEncoder(buff).Encode(v); err != nil { + return nil, err + } + return buff.Bytes(), nil +} + +// Encoder encodes a Go to a TOML document. +// +// The mapping between Go values and TOML values should be precisely the same as +// for [Decode]. +// +// time.Time is encoded as a RFC 3339 string, and time.Duration as its string +// representation. +// +// The [Marshaler] and [encoding.TextMarshaler] interfaces are supported to +// encoding the value as custom TOML. +// +// If you want to write arbitrary binary data then you will need to use +// something like base64 since TOML does not have any binary types. +// +// When encoding TOML hashes (Go maps or structs), keys without any sub-hashes +// are encoded first. +// +// Go maps will be sorted alphabetically by key for deterministic output. +// +// The toml struct tag can be used to provide the key name; if omitted the +// struct field name will be used. If the "omitempty" option is present the +// following value will be skipped: +// +// - arrays, slices, maps, and string with len of 0 +// - struct with all zero values +// - bool false +// +// If omitzero is given all int and float types with a value of 0 will be +// skipped. +// +// Encoding Go values without a corresponding TOML representation will return an +// error. Examples of this includes maps with non-string keys, slices with nil +// elements, embedded non-struct types, and nested slices containing maps or +// structs. (e.g. [][]map[string]string is not allowed but []map[string]string +// is okay, as is []map[string][]string). +// +// NOTE: only exported keys are encoded due to the use of reflection. Unexported +// keys are silently discarded. +type Encoder struct { + Indent string // string for a single indentation level; default is two spaces. + hasWritten bool // written any output to w yet? + w *bufio.Writer +} + +// NewEncoder create a new Encoder. +func NewEncoder(w io.Writer) *Encoder { + return &Encoder{w: bufio.NewWriter(w), Indent: " "} +} + +// Encode writes a TOML representation of the Go value to the [Encoder]'s writer. +// +// An error is returned if the value given cannot be encoded to a valid TOML +// document. +func (enc *Encoder) Encode(v any) error { + rv := eindirect(reflect.ValueOf(v)) + err := enc.safeEncode(Key([]string{}), rv) + if err != nil { + return err + } + return enc.w.Flush() +} + +func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) { + defer func() { + if r := recover(); r != nil { + if terr, ok := r.(tomlEncodeError); ok { + err = terr.error + return + } + panic(r) + } + }() + enc.encode(key, rv) + return nil +} + +func (enc *Encoder) encode(key Key, rv reflect.Value) { + // If we can marshal the type to text, then we use that. This prevents the + // encoder for handling these types as generic structs (or whatever the + // underlying type of a TextMarshaler is). + switch { + case isMarshaler(rv): + enc.writeKeyValue(key, rv, false) + return + case rv.Type() == primitiveType: // TODO: #76 would make this superfluous after implemented. + enc.encode(key, reflect.ValueOf(rv.Interface().(Primitive).undecoded)) + return + } + + k := rv.Kind() + switch k { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, + reflect.Uint64, + reflect.Float32, reflect.Float64, reflect.String, reflect.Bool: + enc.writeKeyValue(key, rv, false) + case reflect.Array, reflect.Slice: + if typeEqual(tomlArrayHash, tomlTypeOfGo(rv)) { + enc.eArrayOfTables(key, rv) + } else { + enc.writeKeyValue(key, rv, false) + } + case reflect.Interface: + if rv.IsNil() { + return + } + enc.encode(key, rv.Elem()) + case reflect.Map: + if rv.IsNil() { + return + } + enc.eTable(key, rv) + case reflect.Ptr: + if rv.IsNil() { + return + } + enc.encode(key, rv.Elem()) + case reflect.Struct: + enc.eTable(key, rv) + default: + encPanic(fmt.Errorf("unsupported type for key '%s': %s", key, k)) + } +} + +// eElement encodes any value that can be an array element. +func (enc *Encoder) eElement(rv reflect.Value) { + switch v := rv.Interface().(type) { + case time.Time: // Using TextMarshaler adds extra quotes, which we don't want. + format := time.RFC3339Nano + switch v.Location() { + case internal.LocalDatetime: + format = "2006-01-02T15:04:05.999999999" + case internal.LocalDate: + format = "2006-01-02" + case internal.LocalTime: + format = "15:04:05.999999999" + } + switch v.Location() { + default: + enc.wf(v.Format(format)) + case internal.LocalDatetime, internal.LocalDate, internal.LocalTime: + enc.wf(v.In(time.UTC).Format(format)) + } + return + case Marshaler: + s, err := v.MarshalTOML() + if err != nil { + encPanic(err) + } + if s == nil { + encPanic(errors.New("MarshalTOML returned nil and no error")) + } + enc.w.Write(s) + return + case encoding.TextMarshaler: + s, err := v.MarshalText() + if err != nil { + encPanic(err) + } + if s == nil { + encPanic(errors.New("MarshalText returned nil and no error")) + } + enc.writeQuoted(string(s)) + return + case time.Duration: + enc.writeQuoted(v.String()) + return + case json.Number: + n, _ := rv.Interface().(json.Number) + + if n == "" { /// Useful zero value. + enc.w.WriteByte('0') + return + } else if v, err := n.Int64(); err == nil { + enc.eElement(reflect.ValueOf(v)) + return + } else if v, err := n.Float64(); err == nil { + enc.eElement(reflect.ValueOf(v)) + return + } + encPanic(fmt.Errorf("unable to convert %q to int64 or float64", n)) + } + + switch rv.Kind() { + case reflect.Ptr: + enc.eElement(rv.Elem()) + return + case reflect.String: + enc.writeQuoted(rv.String()) + case reflect.Bool: + enc.wf(strconv.FormatBool(rv.Bool())) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + enc.wf(strconv.FormatInt(rv.Int(), 10)) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + enc.wf(strconv.FormatUint(rv.Uint(), 10)) + case reflect.Float32: + f := rv.Float() + if math.IsNaN(f) { + if math.Signbit(f) { + enc.wf("-") + } + enc.wf("nan") + } else if math.IsInf(f, 0) { + if math.Signbit(f) { + enc.wf("-") + } + enc.wf("inf") + } else { + enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 32))) + } + case reflect.Float64: + f := rv.Float() + if math.IsNaN(f) { + if math.Signbit(f) { + enc.wf("-") + } + enc.wf("nan") + } else if math.IsInf(f, 0) { + if math.Signbit(f) { + enc.wf("-") + } + enc.wf("inf") + } else { + enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 64))) + } + case reflect.Array, reflect.Slice: + enc.eArrayOrSliceElement(rv) + case reflect.Struct: + enc.eStruct(nil, rv, true) + case reflect.Map: + enc.eMap(nil, rv, true) + case reflect.Interface: + enc.eElement(rv.Elem()) + default: + encPanic(fmt.Errorf("unexpected type: %s", fmtType(rv.Interface()))) + } +} + +// By the TOML spec, all floats must have a decimal with at least one number on +// either side. +func floatAddDecimal(fstr string) string { + if !strings.Contains(fstr, ".") { + return fstr + ".0" + } + return fstr +} + +func (enc *Encoder) writeQuoted(s string) { + enc.wf("\"%s\"", dblQuotedReplacer.Replace(s)) +} + +func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) { + length := rv.Len() + enc.wf("[") + for i := 0; i < length; i++ { + elem := eindirect(rv.Index(i)) + enc.eElement(elem) + if i != length-1 { + enc.wf(", ") + } + } + enc.wf("]") +} + +func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) { + if len(key) == 0 { + encPanic(errNoKey) + } + for i := 0; i < rv.Len(); i++ { + trv := eindirect(rv.Index(i)) + if isNil(trv) { + continue + } + enc.newline() + enc.wf("%s[[%s]]", enc.indentStr(key), key) + enc.newline() + enc.eMapOrStruct(key, trv, false) + } +} + +func (enc *Encoder) eTable(key Key, rv reflect.Value) { + if len(key) == 1 { + // Output an extra newline between top-level tables. + // (The newline isn't written if nothing else has been written though.) + enc.newline() + } + if len(key) > 0 { + enc.wf("%s[%s]", enc.indentStr(key), key) + enc.newline() + } + enc.eMapOrStruct(key, rv, false) +} + +func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value, inline bool) { + switch rv.Kind() { + case reflect.Map: + enc.eMap(key, rv, inline) + case reflect.Struct: + enc.eStruct(key, rv, inline) + default: + // Should never happen? + panic("eTable: unhandled reflect.Value Kind: " + rv.Kind().String()) + } +} + +func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) { + rt := rv.Type() + if rt.Key().Kind() != reflect.String { + encPanic(errNonString) + } + + // Sort keys so that we have deterministic output. And write keys directly + // underneath this key first, before writing sub-structs or sub-maps. + var mapKeysDirect, mapKeysSub []string + for _, mapKey := range rv.MapKeys() { + k := mapKey.String() + if typeIsTable(tomlTypeOfGo(eindirect(rv.MapIndex(mapKey)))) { + mapKeysSub = append(mapKeysSub, k) + } else { + mapKeysDirect = append(mapKeysDirect, k) + } + } + + var writeMapKeys = func(mapKeys []string, trailC bool) { + sort.Strings(mapKeys) + for i, mapKey := range mapKeys { + val := eindirect(rv.MapIndex(reflect.ValueOf(mapKey))) + if isNil(val) { + continue + } + + if inline { + enc.writeKeyValue(Key{mapKey}, val, true) + if trailC || i != len(mapKeys)-1 { + enc.wf(", ") + } + } else { + enc.encode(key.add(mapKey), val) + } + } + } + + if inline { + enc.wf("{") + } + writeMapKeys(mapKeysDirect, len(mapKeysSub) > 0) + writeMapKeys(mapKeysSub, false) + if inline { + enc.wf("}") + } +} + +const is32Bit = (32 << (^uint(0) >> 63)) == 32 + +func pointerTo(t reflect.Type) reflect.Type { + if t.Kind() == reflect.Ptr { + return pointerTo(t.Elem()) + } + return t +} + +func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) { + // Write keys for fields directly under this key first, because if we write + // a field that creates a new table then all keys under it will be in that + // table (not the one we're writing here). + // + // Fields is a [][]int: for fieldsDirect this always has one entry (the + // struct index). For fieldsSub it contains two entries: the parent field + // index from tv, and the field indexes for the fields of the sub. + var ( + rt = rv.Type() + fieldsDirect, fieldsSub [][]int + addFields func(rt reflect.Type, rv reflect.Value, start []int) + ) + addFields = func(rt reflect.Type, rv reflect.Value, start []int) { + for i := 0; i < rt.NumField(); i++ { + f := rt.Field(i) + isEmbed := f.Anonymous && pointerTo(f.Type).Kind() == reflect.Struct + if f.PkgPath != "" && !isEmbed { /// Skip unexported fields. + continue + } + opts := getOptions(f.Tag) + if opts.skip { + continue + } + + frv := eindirect(rv.Field(i)) + + if is32Bit { + // Copy so it works correct on 32bit archs; not clear why this + // is needed. See #314, and https://www.reddit.com/r/golang/comments/pnx8v4 + // This also works fine on 64bit, but 32bit archs are somewhat + // rare and this is a wee bit faster. + copyStart := make([]int, len(start)) + copy(copyStart, start) + start = copyStart + } + + // Treat anonymous struct fields with tag names as though they are + // not anonymous, like encoding/json does. + // + // Non-struct anonymous fields use the normal encoding logic. + if isEmbed { + if getOptions(f.Tag).name == "" && frv.Kind() == reflect.Struct { + addFields(frv.Type(), frv, append(start, f.Index...)) + continue + } + } + + if typeIsTable(tomlTypeOfGo(frv)) { + fieldsSub = append(fieldsSub, append(start, f.Index...)) + } else { + fieldsDirect = append(fieldsDirect, append(start, f.Index...)) + } + } + } + addFields(rt, rv, nil) + + writeFields := func(fields [][]int) { + for _, fieldIndex := range fields { + fieldType := rt.FieldByIndex(fieldIndex) + fieldVal := rv.FieldByIndex(fieldIndex) + + opts := getOptions(fieldType.Tag) + if opts.skip { + continue + } + if opts.omitempty && isEmpty(fieldVal) { + continue + } + + fieldVal = eindirect(fieldVal) + + if isNil(fieldVal) { /// Don't write anything for nil fields. + continue + } + + keyName := fieldType.Name + if opts.name != "" { + keyName = opts.name + } + + if opts.omitzero && isZero(fieldVal) { + continue + } + + if inline { + enc.writeKeyValue(Key{keyName}, fieldVal, true) + if fieldIndex[0] != len(fields)-1 { + enc.wf(", ") + } + } else { + enc.encode(key.add(keyName), fieldVal) + } + } + } + + if inline { + enc.wf("{") + } + writeFields(fieldsDirect) + writeFields(fieldsSub) + if inline { + enc.wf("}") + } +} + +// tomlTypeOfGo returns the TOML type name of the Go value's type. +// +// It is used to determine whether the types of array elements are mixed (which +// is forbidden). If the Go value is nil, then it is illegal for it to be an +// array element, and valueIsNil is returned as true. +// +// The type may be `nil`, which means no concrete TOML type could be found. +func tomlTypeOfGo(rv reflect.Value) tomlType { + if isNil(rv) || !rv.IsValid() { + return nil + } + + if rv.Kind() == reflect.Struct { + if rv.Type() == timeType { + return tomlDatetime + } + if isMarshaler(rv) { + return tomlString + } + return tomlHash + } + + if isMarshaler(rv) { + return tomlString + } + + switch rv.Kind() { + case reflect.Bool: + return tomlBool + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, + reflect.Uint64: + return tomlInteger + case reflect.Float32, reflect.Float64: + return tomlFloat + case reflect.Array, reflect.Slice: + if isTableArray(rv) { + return tomlArrayHash + } + return tomlArray + case reflect.Ptr, reflect.Interface: + return tomlTypeOfGo(rv.Elem()) + case reflect.String: + return tomlString + case reflect.Map: + return tomlHash + default: + encPanic(errors.New("unsupported type: " + rv.Kind().String())) + panic("unreachable") + } +} + +func isMarshaler(rv reflect.Value) bool { + return rv.Type().Implements(marshalText) || rv.Type().Implements(marshalToml) +} + +// isTableArray reports if all entries in the array or slice are a table. +func isTableArray(arr reflect.Value) bool { + if isNil(arr) || !arr.IsValid() || arr.Len() == 0 { + return false + } + + ret := true + for i := 0; i < arr.Len(); i++ { + tt := tomlTypeOfGo(eindirect(arr.Index(i))) + // Don't allow nil. + if tt == nil { + encPanic(errArrayNilElement) + } + + if ret && !typeEqual(tomlHash, tt) { + ret = false + } + } + return ret +} + +type tagOptions struct { + skip bool // "-" + name string + omitempty bool + omitzero bool +} + +func getOptions(tag reflect.StructTag) tagOptions { + t := tag.Get("toml") + if t == "-" { + return tagOptions{skip: true} + } + var opts tagOptions + parts := strings.Split(t, ",") + opts.name = parts[0] + for _, s := range parts[1:] { + switch s { + case "omitempty": + opts.omitempty = true + case "omitzero": + opts.omitzero = true + } + } + return opts +} + +func isZero(rv reflect.Value) bool { + switch rv.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return rv.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return rv.Uint() == 0 + case reflect.Float32, reflect.Float64: + return rv.Float() == 0.0 + } + return false +} + +func isEmpty(rv reflect.Value) bool { + switch rv.Kind() { + case reflect.Array, reflect.Slice, reflect.Map, reflect.String: + return rv.Len() == 0 + case reflect.Struct: + if rv.Type().Comparable() { + return reflect.Zero(rv.Type()).Interface() == rv.Interface() + } + // Need to also check if all the fields are empty, otherwise something + // like this with uncomparable types will always return true: + // + // type a struct{ field b } + // type b struct{ s []string } + // s := a{field: b{s: []string{"AAA"}}} + for i := 0; i < rv.NumField(); i++ { + if !isEmpty(rv.Field(i)) { + return false + } + } + return true + case reflect.Bool: + return !rv.Bool() + case reflect.Ptr: + return rv.IsNil() + } + return false +} + +func (enc *Encoder) newline() { + if enc.hasWritten { + enc.wf("\n") + } +} + +// Write a key/value pair: +// +// key = +// +// This is also used for "k = v" in inline tables; so something like this will +// be written in three calls: +// +// ┌───────────────────┐ +// │ ┌───┐ ┌────┐│ +// v v v v vv +// key = {k = 1, k2 = 2} +func (enc *Encoder) writeKeyValue(key Key, val reflect.Value, inline bool) { + /// Marshaler used on top-level document; call eElement() to just call + /// Marshal{TOML,Text}. + if len(key) == 0 { + enc.eElement(val) + return + } + enc.wf("%s%s = ", enc.indentStr(key), key.maybeQuoted(len(key)-1)) + enc.eElement(val) + if !inline { + enc.newline() + } +} + +func (enc *Encoder) wf(format string, v ...any) { + _, err := fmt.Fprintf(enc.w, format, v...) + if err != nil { + encPanic(err) + } + enc.hasWritten = true +} + +func (enc *Encoder) indentStr(key Key) string { + return strings.Repeat(enc.Indent, len(key)-1) +} + +func encPanic(err error) { + panic(tomlEncodeError{err}) +} + +// Resolve any level of pointers to the actual value (e.g. **string → string). +func eindirect(v reflect.Value) reflect.Value { + if v.Kind() != reflect.Ptr && v.Kind() != reflect.Interface { + if isMarshaler(v) { + return v + } + if v.CanAddr() { /// Special case for marshalers; see #358. + if pv := v.Addr(); isMarshaler(pv) { + return pv + } + } + return v + } + + if v.IsNil() { + return v + } + + return eindirect(v.Elem()) +} + +func isNil(rv reflect.Value) bool { + switch rv.Kind() { + case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return rv.IsNil() + default: + return false + } +} diff --git a/vendor/github.com/BurntSushi/toml/error.go b/vendor/github.com/BurntSushi/toml/error.go new file mode 100644 index 0000000..1dd5232 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/error.go @@ -0,0 +1,347 @@ +package toml + +import ( + "fmt" + "strings" +) + +// ParseError is returned when there is an error parsing the TOML syntax such as +// invalid syntax, duplicate keys, etc. +// +// In addition to the error message itself, you can also print detailed location +// information with context by using [ErrorWithPosition]: +// +// toml: error: Key 'fruit' was already created and cannot be used as an array. +// +// At line 4, column 2-7: +// +// 2 | fruit = [] +// 3 | +// 4 | [[fruit]] # Not allowed +// ^^^^^ +// +// [ErrorWithUsage] can be used to print the above with some more detailed usage +// guidance: +// +// toml: error: newlines not allowed within inline tables +// +// At line 1, column 18: +// +// 1 | x = [{ key = 42 # +// ^ +// +// Error help: +// +// Inline tables must always be on a single line: +// +// table = {key = 42, second = 43} +// +// It is invalid to split them over multiple lines like so: +// +// # INVALID +// table = { +// key = 42, +// second = 43 +// } +// +// Use regular for this: +// +// [table] +// key = 42 +// second = 43 +type ParseError struct { + Message string // Short technical message. + Usage string // Longer message with usage guidance; may be blank. + Position Position // Position of the error + LastKey string // Last parsed key, may be blank. + + // Line the error occurred. + // + // Deprecated: use [Position]. + Line int + + err error + input string +} + +// Position of an error. +type Position struct { + Line int // Line number, starting at 1. + Col int // Error column, starting at 1. + Start int // Start of error, as byte offset starting at 0. + Len int // Lenght of the error in bytes. +} + +func (p Position) withCol(tomlFile string) Position { + var ( + pos int + lines = strings.Split(tomlFile, "\n") + ) + for i := range lines { + ll := len(lines[i]) + 1 // +1 for the removed newline + if pos+ll >= p.Start { + p.Col = p.Start - pos + 1 + if p.Col < 1 { // Should never happen, but just in case. + p.Col = 1 + } + break + } + pos += ll + } + return p +} + +func (pe ParseError) Error() string { + if pe.LastKey == "" { + return fmt.Sprintf("toml: line %d: %s", pe.Position.Line, pe.Message) + } + return fmt.Sprintf("toml: line %d (last key %q): %s", + pe.Position.Line, pe.LastKey, pe.Message) +} + +// ErrorWithPosition returns the error with detailed location context. +// +// See the documentation on [ParseError]. +func (pe ParseError) ErrorWithPosition() string { + if pe.input == "" { // Should never happen, but just in case. + return pe.Error() + } + + // TODO: don't show control characters as literals? This may not show up + // well everywhere. + + var ( + lines = strings.Split(pe.input, "\n") + b = new(strings.Builder) + ) + if pe.Position.Len == 1 { + fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d:\n\n", + pe.Message, pe.Position.Line, pe.Position.Col) + } else { + fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d-%d:\n\n", + pe.Message, pe.Position.Line, pe.Position.Col, pe.Position.Col+pe.Position.Len-1) + } + if pe.Position.Line > 2 { + fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-2, expandTab(lines[pe.Position.Line-3])) + } + if pe.Position.Line > 1 { + fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-1, expandTab(lines[pe.Position.Line-2])) + } + + /// Expand tabs, so that the ^^^s are at the correct position, but leave + /// "column 10-13" intact. Adjusting this to the visual column would be + /// better, but we don't know the tabsize of the user in their editor, which + /// can be 8, 4, 2, or something else. We can't know. So leaving it as the + /// character index is probably the "most correct". + expanded := expandTab(lines[pe.Position.Line-1]) + diff := len(expanded) - len(lines[pe.Position.Line-1]) + + fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line, expanded) + fmt.Fprintf(b, "% 10s%s%s\n", "", strings.Repeat(" ", pe.Position.Col-1+diff), strings.Repeat("^", pe.Position.Len)) + return b.String() +} + +// ErrorWithUsage returns the error with detailed location context and usage +// guidance. +// +// See the documentation on [ParseError]. +func (pe ParseError) ErrorWithUsage() string { + m := pe.ErrorWithPosition() + if u, ok := pe.err.(interface{ Usage() string }); ok && u.Usage() != "" { + lines := strings.Split(strings.TrimSpace(u.Usage()), "\n") + for i := range lines { + if lines[i] != "" { + lines[i] = " " + lines[i] + } + } + return m + "Error help:\n\n" + strings.Join(lines, "\n") + "\n" + } + return m +} + +func expandTab(s string) string { + var ( + b strings.Builder + l int + fill = func(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = ' ' + } + return string(b) + } + ) + b.Grow(len(s)) + for _, r := range s { + switch r { + case '\t': + tw := 8 - l%8 + b.WriteString(fill(tw)) + l += tw + default: + b.WriteRune(r) + l += 1 + } + } + return b.String() +} + +type ( + errLexControl struct{ r rune } + errLexEscape struct{ r rune } + errLexUTF8 struct{ b byte } + errParseDate struct{ v string } + errLexInlineTableNL struct{} + errLexStringNL struct{} + errParseRange struct { + i any // int or float + size string // "int64", "uint16", etc. + } + errUnsafeFloat struct { + i interface{} // float32 or float64 + size string // "float32" or "float64" + } + errParseDuration struct{ d string } +) + +func (e errLexControl) Error() string { + return fmt.Sprintf("TOML files cannot contain control characters: '0x%02x'", e.r) +} +func (e errLexControl) Usage() string { return "" } + +func (e errLexEscape) Error() string { return fmt.Sprintf(`invalid escape in string '\%c'`, e.r) } +func (e errLexEscape) Usage() string { return usageEscape } +func (e errLexUTF8) Error() string { return fmt.Sprintf("invalid UTF-8 byte: 0x%02x", e.b) } +func (e errLexUTF8) Usage() string { return "" } +func (e errParseDate) Error() string { return fmt.Sprintf("invalid datetime: %q", e.v) } +func (e errParseDate) Usage() string { return usageDate } +func (e errLexInlineTableNL) Error() string { return "newlines not allowed within inline tables" } +func (e errLexInlineTableNL) Usage() string { return usageInlineNewline } +func (e errLexStringNL) Error() string { return "strings cannot contain newlines" } +func (e errLexStringNL) Usage() string { return usageStringNewline } +func (e errParseRange) Error() string { return fmt.Sprintf("%v is out of range for %s", e.i, e.size) } +func (e errParseRange) Usage() string { return usageIntOverflow } +func (e errUnsafeFloat) Error() string { + return fmt.Sprintf("%v is out of the safe %s range", e.i, e.size) +} +func (e errUnsafeFloat) Usage() string { return usageUnsafeFloat } +func (e errParseDuration) Error() string { return fmt.Sprintf("invalid duration: %q", e.d) } +func (e errParseDuration) Usage() string { return usageDuration } + +const usageEscape = ` +A '\' inside a "-delimited string is interpreted as an escape character. + +The following escape sequences are supported: +\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX + +To prevent a '\' from being recognized as an escape character, use either: + +- a ' or '''-delimited string; escape characters aren't processed in them; or +- write two backslashes to get a single backslash: '\\'. + +If you're trying to add a Windows path (e.g. "C:\Users\martin") then using '/' +instead of '\' will usually also work: "C:/Users/martin". +` + +const usageInlineNewline = ` +Inline tables must always be on a single line: + + table = {key = 42, second = 43} + +It is invalid to split them over multiple lines like so: + + # INVALID + table = { + key = 42, + second = 43 + } + +Use regular for this: + + [table] + key = 42 + second = 43 +` + +const usageStringNewline = ` +Strings must always be on a single line, and cannot span more than one line: + + # INVALID + string = "Hello, + world!" + +Instead use """ or ''' to split strings over multiple lines: + + string = """Hello, + world!""" +` + +const usageIntOverflow = ` +This number is too large; this may be an error in the TOML, but it can also be a +bug in the program that uses too small of an integer. + +The maximum and minimum values are: + + size │ lowest │ highest + ───────┼────────────────┼────────────── + int8 │ -128 │ 127 + int16 │ -32,768 │ 32,767 + int32 │ -2,147,483,648 │ 2,147,483,647 + int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷ + uint8 │ 0 │ 255 + uint16 │ 0 │ 65,535 + uint32 │ 0 │ 4,294,967,295 + uint64 │ 0 │ 1.8 × 10¹⁸ + +int refers to int32 on 32-bit systems and int64 on 64-bit systems. +` + +const usageUnsafeFloat = ` +This number is outside of the "safe" range for floating point numbers; whole +(non-fractional) numbers outside the below range can not always be represented +accurately in a float, leading to some loss of accuracy. + +Explicitly mark a number as a fractional unit by adding ".0", which will incur +some loss of accuracy; for example: + + f = 2_000_000_000.0 + +Accuracy ranges: + + float32 = 16,777,215 + float64 = 9,007,199,254,740,991 +` + +const usageDuration = ` +A duration must be as "number", without any spaces. Valid units are: + + ns nanoseconds (billionth of a second) + us, µs microseconds (millionth of a second) + ms milliseconds (thousands of a second) + s seconds + m minutes + h hours + +You can combine multiple units; for example "5m10s" for 5 minutes and 10 +seconds. +` + +const usageDate = ` +A TOML datetime must be in one of the following formats: + + 2006-01-02T15:04:05Z07:00 Date and time, with timezone. + 2006-01-02T15:04:05 Date and time, but without timezone. + 2006-01-02 Date without a time or timezone. + 15:04:05 Just a time, without any timezone. + +Seconds may optionally have a fraction, up to nanosecond precision: + + 15:04:05.123 + 15:04:05.856018510 +` + +// TOML 1.1: +// The seconds part in times is optional, and may be omitted: +// 2006-01-02T15:04Z07:00 +// 2006-01-02T15:04 +// 15:04 diff --git a/vendor/github.com/BurntSushi/toml/internal/tz.go b/vendor/github.com/BurntSushi/toml/internal/tz.go new file mode 100644 index 0000000..022f15b --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/internal/tz.go @@ -0,0 +1,36 @@ +package internal + +import "time" + +// Timezones used for local datetime, date, and time TOML types. +// +// The exact way times and dates without a timezone should be interpreted is not +// well-defined in the TOML specification and left to the implementation. These +// defaults to current local timezone offset of the computer, but this can be +// changed by changing these variables before decoding. +// +// TODO: +// Ideally we'd like to offer people the ability to configure the used timezone +// by setting Decoder.Timezone and Encoder.Timezone; however, this is a bit +// tricky: the reason we use three different variables for this is to support +// round-tripping – without these specific TZ names we wouldn't know which +// format to use. +// +// There isn't a good way to encode this right now though, and passing this sort +// of information also ties in to various related issues such as string format +// encoding, encoding of comments, etc. +// +// So, for the time being, just put this in internal until we can write a good +// comprehensive API for doing all of this. +// +// The reason they're exported is because they're referred from in e.g. +// internal/tag. +// +// Note that this behaviour is valid according to the TOML spec as the exact +// behaviour is left up to implementations. +var ( + localOffset = func() int { _, o := time.Now().Zone(); return o }() + LocalDatetime = time.FixedZone("datetime-local", localOffset) + LocalDate = time.FixedZone("date-local", localOffset) + LocalTime = time.FixedZone("time-local", localOffset) +) diff --git a/vendor/github.com/BurntSushi/toml/lex.go b/vendor/github.com/BurntSushi/toml/lex.go new file mode 100644 index 0000000..6878d9d --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/lex.go @@ -0,0 +1,1287 @@ +package toml + +import ( + "fmt" + "reflect" + "runtime" + "strings" + "unicode" + "unicode/utf8" +) + +type itemType int + +const ( + itemError itemType = iota + itemNIL // used in the parser to indicate no type + itemEOF + itemText + itemString + itemStringEsc + itemRawString + itemMultilineString + itemRawMultilineString + itemBool + itemInteger + itemFloat + itemDatetime + itemArray // the start of an array + itemArrayEnd + itemTableStart + itemTableEnd + itemArrayTableStart + itemArrayTableEnd + itemKeyStart + itemKeyEnd + itemCommentStart + itemInlineTableStart + itemInlineTableEnd +) + +const eof = 0 + +type stateFn func(lx *lexer) stateFn + +func (p Position) String() string { + return fmt.Sprintf("at line %d; start %d; length %d", p.Line, p.Start, p.Len) +} + +type lexer struct { + input string + start int + pos int + line int + state stateFn + items chan item + tomlNext bool + esc bool + + // Allow for backing up up to 4 runes. This is necessary because TOML + // contains 3-rune tokens (""" and '''). + prevWidths [4]int + nprev int // how many of prevWidths are in use + atEOF bool // If we emit an eof, we can still back up, but it is not OK to call next again. + + // A stack of state functions used to maintain context. + // + // The idea is to reuse parts of the state machine in various places. For + // example, values can appear at the top level or within arbitrarily nested + // arrays. The last state on the stack is used after a value has been lexed. + // Similarly for comments. + stack []stateFn +} + +type item struct { + typ itemType + val string + err error + pos Position +} + +func (lx *lexer) nextItem() item { + for { + select { + case item := <-lx.items: + return item + default: + lx.state = lx.state(lx) + //fmt.Printf(" STATE %-24s current: %-10s stack: %s\n", lx.state, lx.current(), lx.stack) + } + } +} + +func lex(input string, tomlNext bool) *lexer { + lx := &lexer{ + input: input, + state: lexTop, + items: make(chan item, 10), + stack: make([]stateFn, 0, 10), + line: 1, + tomlNext: tomlNext, + } + return lx +} + +func (lx *lexer) push(state stateFn) { + lx.stack = append(lx.stack, state) +} + +func (lx *lexer) pop() stateFn { + if len(lx.stack) == 0 { + return lx.errorf("BUG in lexer: no states to pop") + } + last := lx.stack[len(lx.stack)-1] + lx.stack = lx.stack[0 : len(lx.stack)-1] + return last +} + +func (lx *lexer) current() string { + return lx.input[lx.start:lx.pos] +} + +func (lx lexer) getPos() Position { + p := Position{ + Line: lx.line, + Start: lx.start, + Len: lx.pos - lx.start, + } + if p.Len <= 0 { + p.Len = 1 + } + return p +} + +func (lx *lexer) emit(typ itemType) { + // Needed for multiline strings ending with an incomplete UTF-8 sequence. + if lx.start > lx.pos { + lx.error(errLexUTF8{lx.input[lx.pos]}) + return + } + lx.items <- item{typ: typ, pos: lx.getPos(), val: lx.current()} + lx.start = lx.pos +} + +func (lx *lexer) emitTrim(typ itemType) { + lx.items <- item{typ: typ, pos: lx.getPos(), val: strings.TrimSpace(lx.current())} + lx.start = lx.pos +} + +func (lx *lexer) next() (r rune) { + if lx.atEOF { + panic("BUG in lexer: next called after EOF") + } + if lx.pos >= len(lx.input) { + lx.atEOF = true + return eof + } + + if lx.input[lx.pos] == '\n' { + lx.line++ + } + lx.prevWidths[3] = lx.prevWidths[2] + lx.prevWidths[2] = lx.prevWidths[1] + lx.prevWidths[1] = lx.prevWidths[0] + if lx.nprev < 4 { + lx.nprev++ + } + + r, w := utf8.DecodeRuneInString(lx.input[lx.pos:]) + if r == utf8.RuneError && w == 1 { + lx.error(errLexUTF8{lx.input[lx.pos]}) + return utf8.RuneError + } + + // Note: don't use peek() here, as this calls next(). + if isControl(r) || (r == '\r' && (len(lx.input)-1 == lx.pos || lx.input[lx.pos+1] != '\n')) { + lx.errorControlChar(r) + return utf8.RuneError + } + + lx.prevWidths[0] = w + lx.pos += w + return r +} + +// ignore skips over the pending input before this point. +func (lx *lexer) ignore() { + lx.start = lx.pos +} + +// backup steps back one rune. Can be called 4 times between calls to next. +func (lx *lexer) backup() { + if lx.atEOF { + lx.atEOF = false + return + } + if lx.nprev < 1 { + panic("BUG in lexer: backed up too far") + } + w := lx.prevWidths[0] + lx.prevWidths[0] = lx.prevWidths[1] + lx.prevWidths[1] = lx.prevWidths[2] + lx.prevWidths[2] = lx.prevWidths[3] + lx.nprev-- + + lx.pos -= w + if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' { + lx.line-- + } +} + +// accept consumes the next rune if it's equal to `valid`. +func (lx *lexer) accept(valid rune) bool { + if lx.next() == valid { + return true + } + lx.backup() + return false +} + +// peek returns but does not consume the next rune in the input. +func (lx *lexer) peek() rune { + r := lx.next() + lx.backup() + return r +} + +// skip ignores all input that matches the given predicate. +func (lx *lexer) skip(pred func(rune) bool) { + for { + r := lx.next() + if pred(r) { + continue + } + lx.backup() + lx.ignore() + return + } +} + +// error stops all lexing by emitting an error and returning `nil`. +// +// Note that any value that is a character is escaped if it's a special +// character (newlines, tabs, etc.). +func (lx *lexer) error(err error) stateFn { + if lx.atEOF { + return lx.errorPrevLine(err) + } + lx.items <- item{typ: itemError, pos: lx.getPos(), err: err} + return nil +} + +// errorfPrevline is like error(), but sets the position to the last column of +// the previous line. +// +// This is so that unexpected EOF or NL errors don't show on a new blank line. +func (lx *lexer) errorPrevLine(err error) stateFn { + pos := lx.getPos() + pos.Line-- + pos.Len = 1 + pos.Start = lx.pos - 1 + lx.items <- item{typ: itemError, pos: pos, err: err} + return nil +} + +// errorPos is like error(), but allows explicitly setting the position. +func (lx *lexer) errorPos(start, length int, err error) stateFn { + pos := lx.getPos() + pos.Start = start + pos.Len = length + lx.items <- item{typ: itemError, pos: pos, err: err} + return nil +} + +// errorf is like error, and creates a new error. +func (lx *lexer) errorf(format string, values ...any) stateFn { + if lx.atEOF { + pos := lx.getPos() + pos.Line-- + pos.Len = 1 + pos.Start = lx.pos - 1 + lx.items <- item{typ: itemError, pos: pos, err: fmt.Errorf(format, values...)} + return nil + } + lx.items <- item{typ: itemError, pos: lx.getPos(), err: fmt.Errorf(format, values...)} + return nil +} + +func (lx *lexer) errorControlChar(cc rune) stateFn { + return lx.errorPos(lx.pos-1, 1, errLexControl{cc}) +} + +// lexTop consumes elements at the top level of TOML data. +func lexTop(lx *lexer) stateFn { + r := lx.next() + if isWhitespace(r) || isNL(r) { + return lexSkip(lx, lexTop) + } + switch r { + case '#': + lx.push(lexTop) + return lexCommentStart + case '[': + return lexTableStart + case eof: + if lx.pos > lx.start { + return lx.errorf("unexpected EOF") + } + lx.emit(itemEOF) + return nil + } + + // At this point, the only valid item can be a key, so we back up + // and let the key lexer do the rest. + lx.backup() + lx.push(lexTopEnd) + return lexKeyStart +} + +// lexTopEnd is entered whenever a top-level item has been consumed. (A value +// or a table.) It must see only whitespace, and will turn back to lexTop +// upon a newline. If it sees EOF, it will quit the lexer successfully. +func lexTopEnd(lx *lexer) stateFn { + r := lx.next() + switch { + case r == '#': + // a comment will read to a newline for us. + lx.push(lexTop) + return lexCommentStart + case isWhitespace(r): + return lexTopEnd + case isNL(r): + lx.ignore() + return lexTop + case r == eof: + lx.emit(itemEOF) + return nil + } + return lx.errorf("expected a top-level item to end with a newline, comment, or EOF, but got %q instead", r) +} + +// lexTable lexes the beginning of a table. Namely, it makes sure that +// it starts with a character other than '.' and ']'. +// It assumes that '[' has already been consumed. +// It also handles the case that this is an item in an array of tables. +// e.g., '[[name]]'. +func lexTableStart(lx *lexer) stateFn { + if lx.peek() == '[' { + lx.next() + lx.emit(itemArrayTableStart) + lx.push(lexArrayTableEnd) + } else { + lx.emit(itemTableStart) + lx.push(lexTableEnd) + } + return lexTableNameStart +} + +func lexTableEnd(lx *lexer) stateFn { + lx.emit(itemTableEnd) + return lexTopEnd +} + +func lexArrayTableEnd(lx *lexer) stateFn { + if r := lx.next(); r != ']' { + return lx.errorf("expected end of table array name delimiter ']', but got %q instead", r) + } + lx.emit(itemArrayTableEnd) + return lexTopEnd +} + +func lexTableNameStart(lx *lexer) stateFn { + lx.skip(isWhitespace) + switch r := lx.peek(); { + case r == ']' || r == eof: + return lx.errorf("unexpected end of table name (table names cannot be empty)") + case r == '.': + return lx.errorf("unexpected table separator (table names cannot be empty)") + case r == '"' || r == '\'': + lx.ignore() + lx.push(lexTableNameEnd) + return lexQuotedName + default: + lx.push(lexTableNameEnd) + return lexBareName + } +} + +// lexTableNameEnd reads the end of a piece of a table name, optionally +// consuming whitespace. +func lexTableNameEnd(lx *lexer) stateFn { + lx.skip(isWhitespace) + switch r := lx.next(); { + case isWhitespace(r): + return lexTableNameEnd + case r == '.': + lx.ignore() + return lexTableNameStart + case r == ']': + return lx.pop() + default: + return lx.errorf("expected '.' or ']' to end table name, but got %q instead", r) + } +} + +// lexBareName lexes one part of a key or table. +// +// It assumes that at least one valid character for the table has already been +// read. +// +// Lexes only one part, e.g. only 'a' inside 'a.b'. +func lexBareName(lx *lexer) stateFn { + r := lx.next() + if isBareKeyChar(r, lx.tomlNext) { + return lexBareName + } + lx.backup() + lx.emit(itemText) + return lx.pop() +} + +// lexBareName lexes one part of a key or table. +// +// It assumes that at least one valid character for the table has already been +// read. +// +// Lexes only one part, e.g. only '"a"' inside '"a".b'. +func lexQuotedName(lx *lexer) stateFn { + r := lx.next() + switch { + case isWhitespace(r): + return lexSkip(lx, lexValue) + case r == '"': + lx.ignore() // ignore the '"' + return lexString + case r == '\'': + lx.ignore() // ignore the "'" + return lexRawString + case r == eof: + return lx.errorf("unexpected EOF; expected value") + default: + return lx.errorf("expected value but found %q instead", r) + } +} + +// lexKeyStart consumes all key parts until a '='. +func lexKeyStart(lx *lexer) stateFn { + lx.skip(isWhitespace) + switch r := lx.peek(); { + case r == '=' || r == eof: + return lx.errorf("unexpected '=': key name appears blank") + case r == '.': + return lx.errorf("unexpected '.': keys cannot start with a '.'") + case r == '"' || r == '\'': + lx.ignore() + fallthrough + default: // Bare key + lx.emit(itemKeyStart) + return lexKeyNameStart + } +} + +func lexKeyNameStart(lx *lexer) stateFn { + lx.skip(isWhitespace) + switch r := lx.peek(); { + case r == '=' || r == eof: + return lx.errorf("unexpected '='") + case r == '.': + return lx.errorf("unexpected '.'") + case r == '"' || r == '\'': + lx.ignore() + lx.push(lexKeyEnd) + return lexQuotedName + default: + lx.push(lexKeyEnd) + return lexBareName + } +} + +// lexKeyEnd consumes the end of a key and trims whitespace (up to the key +// separator). +func lexKeyEnd(lx *lexer) stateFn { + lx.skip(isWhitespace) + switch r := lx.next(); { + case isWhitespace(r): + return lexSkip(lx, lexKeyEnd) + case r == eof: + return lx.errorf("unexpected EOF; expected key separator '='") + case r == '.': + lx.ignore() + return lexKeyNameStart + case r == '=': + lx.emit(itemKeyEnd) + return lexSkip(lx, lexValue) + default: + if r == '\n' { + return lx.errorPrevLine(fmt.Errorf("expected '.' or '=', but got %q instead", r)) + } + return lx.errorf("expected '.' or '=', but got %q instead", r) + } +} + +// lexValue starts the consumption of a value anywhere a value is expected. +// lexValue will ignore whitespace. +// After a value is lexed, the last state on the next is popped and returned. +func lexValue(lx *lexer) stateFn { + // We allow whitespace to precede a value, but NOT newlines. + // In array syntax, the array states are responsible for ignoring newlines. + r := lx.next() + switch { + case isWhitespace(r): + return lexSkip(lx, lexValue) + case isDigit(r): + lx.backup() // avoid an extra state and use the same as above + return lexNumberOrDateStart + } + switch r { + case '[': + lx.ignore() + lx.emit(itemArray) + return lexArrayValue + case '{': + lx.ignore() + lx.emit(itemInlineTableStart) + return lexInlineTableValue + case '"': + if lx.accept('"') { + if lx.accept('"') { + lx.ignore() // Ignore """ + return lexMultilineString + } + lx.backup() + } + lx.ignore() // ignore the '"' + return lexString + case '\'': + if lx.accept('\'') { + if lx.accept('\'') { + lx.ignore() // Ignore """ + return lexMultilineRawString + } + lx.backup() + } + lx.ignore() // ignore the "'" + return lexRawString + case '.': // special error case, be kind to users + return lx.errorf("floats must start with a digit, not '.'") + case 'i', 'n': + if (lx.accept('n') && lx.accept('f')) || (lx.accept('a') && lx.accept('n')) { + lx.emit(itemFloat) + return lx.pop() + } + case '-', '+': + return lexDecimalNumberStart + } + if unicode.IsLetter(r) { + // Be permissive here; lexBool will give a nice error if the + // user wrote something like + // x = foo + // (i.e. not 'true' or 'false' but is something else word-like.) + lx.backup() + return lexBool + } + if r == eof { + return lx.errorf("unexpected EOF; expected value") + } + if r == '\n' { + return lx.errorPrevLine(fmt.Errorf("expected value but found %q instead", r)) + } + return lx.errorf("expected value but found %q instead", r) +} + +// lexArrayValue consumes one value in an array. It assumes that '[' or ',' +// have already been consumed. All whitespace and newlines are ignored. +func lexArrayValue(lx *lexer) stateFn { + r := lx.next() + switch { + case isWhitespace(r) || isNL(r): + return lexSkip(lx, lexArrayValue) + case r == '#': + lx.push(lexArrayValue) + return lexCommentStart + case r == ',': + return lx.errorf("unexpected comma") + case r == ']': + return lexArrayEnd + } + + lx.backup() + lx.push(lexArrayValueEnd) + return lexValue +} + +// lexArrayValueEnd consumes everything between the end of an array value and +// the next value (or the end of the array): it ignores whitespace and newlines +// and expects either a ',' or a ']'. +func lexArrayValueEnd(lx *lexer) stateFn { + switch r := lx.next(); { + case isWhitespace(r) || isNL(r): + return lexSkip(lx, lexArrayValueEnd) + case r == '#': + lx.push(lexArrayValueEnd) + return lexCommentStart + case r == ',': + lx.ignore() + return lexArrayValue // move on to the next value + case r == ']': + return lexArrayEnd + default: + return lx.errorf("expected a comma (',') or array terminator (']'), but got %s", runeOrEOF(r)) + } +} + +// lexArrayEnd finishes the lexing of an array. +// It assumes that a ']' has just been consumed. +func lexArrayEnd(lx *lexer) stateFn { + lx.ignore() + lx.emit(itemArrayEnd) + return lx.pop() +} + +// lexInlineTableValue consumes one key/value pair in an inline table. +// It assumes that '{' or ',' have already been consumed. Whitespace is ignored. +func lexInlineTableValue(lx *lexer) stateFn { + r := lx.next() + switch { + case isWhitespace(r): + return lexSkip(lx, lexInlineTableValue) + case isNL(r): + if lx.tomlNext { + return lexSkip(lx, lexInlineTableValue) + } + return lx.errorPrevLine(errLexInlineTableNL{}) + case r == '#': + lx.push(lexInlineTableValue) + return lexCommentStart + case r == ',': + return lx.errorf("unexpected comma") + case r == '}': + return lexInlineTableEnd + } + lx.backup() + lx.push(lexInlineTableValueEnd) + return lexKeyStart +} + +// lexInlineTableValueEnd consumes everything between the end of an inline table +// key/value pair and the next pair (or the end of the table): +// it ignores whitespace and expects either a ',' or a '}'. +func lexInlineTableValueEnd(lx *lexer) stateFn { + switch r := lx.next(); { + case isWhitespace(r): + return lexSkip(lx, lexInlineTableValueEnd) + case isNL(r): + if lx.tomlNext { + return lexSkip(lx, lexInlineTableValueEnd) + } + return lx.errorPrevLine(errLexInlineTableNL{}) + case r == '#': + lx.push(lexInlineTableValueEnd) + return lexCommentStart + case r == ',': + lx.ignore() + lx.skip(isWhitespace) + if lx.peek() == '}' { + if lx.tomlNext { + return lexInlineTableValueEnd + } + return lx.errorf("trailing comma not allowed in inline tables") + } + return lexInlineTableValue + case r == '}': + return lexInlineTableEnd + default: + return lx.errorf("expected a comma or an inline table terminator '}', but got %s instead", runeOrEOF(r)) + } +} + +func runeOrEOF(r rune) string { + if r == eof { + return "end of file" + } + return "'" + string(r) + "'" +} + +// lexInlineTableEnd finishes the lexing of an inline table. +// It assumes that a '}' has just been consumed. +func lexInlineTableEnd(lx *lexer) stateFn { + lx.ignore() + lx.emit(itemInlineTableEnd) + return lx.pop() +} + +// lexString consumes the inner contents of a string. It assumes that the +// beginning '"' has already been consumed and ignored. +func lexString(lx *lexer) stateFn { + r := lx.next() + switch { + case r == eof: + return lx.errorf(`unexpected EOF; expected '"'`) + case isNL(r): + return lx.errorPrevLine(errLexStringNL{}) + case r == '\\': + lx.push(lexString) + return lexStringEscape + case r == '"': + lx.backup() + if lx.esc { + lx.esc = false + lx.emit(itemStringEsc) + } else { + lx.emit(itemString) + } + lx.next() + lx.ignore() + return lx.pop() + } + return lexString +} + +// lexMultilineString consumes the inner contents of a string. It assumes that +// the beginning '"""' has already been consumed and ignored. +func lexMultilineString(lx *lexer) stateFn { + r := lx.next() + switch r { + default: + return lexMultilineString + case eof: + return lx.errorf(`unexpected EOF; expected '"""'`) + case '\\': + return lexMultilineStringEscape + case '"': + /// Found " → try to read two more "". + if lx.accept('"') { + if lx.accept('"') { + /// Peek ahead: the string can contain " and "", including at the + /// end: """str""""" + /// 6 or more at the end, however, is an error. + if lx.peek() == '"' { + /// Check if we already lexed 5 's; if so we have 6 now, and + /// that's just too many man! + /// + /// Second check is for the edge case: + /// + /// two quotes allowed. + /// vv + /// """lol \"""""" + /// ^^ ^^^---- closing three + /// escaped + /// + /// But ugly, but it works + if strings.HasSuffix(lx.current(), `"""""`) && !strings.HasSuffix(lx.current(), `\"""""`) { + return lx.errorf(`unexpected '""""""'`) + } + lx.backup() + lx.backup() + return lexMultilineString + } + + lx.backup() /// backup: don't include the """ in the item. + lx.backup() + lx.backup() + lx.esc = false + lx.emit(itemMultilineString) + lx.next() /// Read over ''' again and discard it. + lx.next() + lx.next() + lx.ignore() + return lx.pop() + } + lx.backup() + } + return lexMultilineString + } +} + +// lexRawString consumes a raw string. Nothing can be escaped in such a string. +// It assumes that the beginning "'" has already been consumed and ignored. +func lexRawString(lx *lexer) stateFn { + r := lx.next() + switch { + default: + return lexRawString + case r == eof: + return lx.errorf(`unexpected EOF; expected "'"`) + case isNL(r): + return lx.errorPrevLine(errLexStringNL{}) + case r == '\'': + lx.backup() + lx.emit(itemRawString) + lx.next() + lx.ignore() + return lx.pop() + } +} + +// lexMultilineRawString consumes a raw string. Nothing can be escaped in such a +// string. It assumes that the beginning triple-' has already been consumed and +// ignored. +func lexMultilineRawString(lx *lexer) stateFn { + r := lx.next() + switch r { + default: + return lexMultilineRawString + case eof: + return lx.errorf(`unexpected EOF; expected "'''"`) + case '\'': + /// Found ' → try to read two more ''. + if lx.accept('\'') { + if lx.accept('\'') { + /// Peek ahead: the string can contain ' and '', including at the + /// end: '''str''''' + /// 6 or more at the end, however, is an error. + if lx.peek() == '\'' { + /// Check if we already lexed 5 's; if so we have 6 now, and + /// that's just too many man! + if strings.HasSuffix(lx.current(), "'''''") { + return lx.errorf(`unexpected "''''''"`) + } + lx.backup() + lx.backup() + return lexMultilineRawString + } + + lx.backup() /// backup: don't include the ''' in the item. + lx.backup() + lx.backup() + lx.emit(itemRawMultilineString) + lx.next() /// Read over ''' again and discard it. + lx.next() + lx.next() + lx.ignore() + return lx.pop() + } + lx.backup() + } + return lexMultilineRawString + } +} + +// lexMultilineStringEscape consumes an escaped character. It assumes that the +// preceding '\\' has already been consumed. +func lexMultilineStringEscape(lx *lexer) stateFn { + if isNL(lx.next()) { /// \ escaping newline. + return lexMultilineString + } + lx.backup() + lx.push(lexMultilineString) + return lexStringEscape(lx) +} + +func lexStringEscape(lx *lexer) stateFn { + lx.esc = true + r := lx.next() + switch r { + case 'e': + if !lx.tomlNext { + return lx.error(errLexEscape{r}) + } + fallthrough + case 'b': + fallthrough + case 't': + fallthrough + case 'n': + fallthrough + case 'f': + fallthrough + case 'r': + fallthrough + case '"': + fallthrough + case ' ', '\t': + // Inside """ .. """ strings you can use \ to escape newlines, and any + // amount of whitespace can be between the \ and \n. + fallthrough + case '\\': + return lx.pop() + case 'x': + if !lx.tomlNext { + return lx.error(errLexEscape{r}) + } + return lexHexEscape + case 'u': + return lexShortUnicodeEscape + case 'U': + return lexLongUnicodeEscape + } + return lx.error(errLexEscape{r}) +} + +func lexHexEscape(lx *lexer) stateFn { + var r rune + for i := 0; i < 2; i++ { + r = lx.next() + if !isHex(r) { + return lx.errorf(`expected two hexadecimal digits after '\x', but got %q instead`, lx.current()) + } + } + return lx.pop() +} + +func lexShortUnicodeEscape(lx *lexer) stateFn { + var r rune + for i := 0; i < 4; i++ { + r = lx.next() + if !isHex(r) { + return lx.errorf(`expected four hexadecimal digits after '\u', but got %q instead`, lx.current()) + } + } + return lx.pop() +} + +func lexLongUnicodeEscape(lx *lexer) stateFn { + var r rune + for i := 0; i < 8; i++ { + r = lx.next() + if !isHex(r) { + return lx.errorf(`expected eight hexadecimal digits after '\U', but got %q instead`, lx.current()) + } + } + return lx.pop() +} + +// lexNumberOrDateStart processes the first character of a value which begins +// with a digit. It exists to catch values starting with '0', so that +// lexBaseNumberOrDate can differentiate base prefixed integers from other +// types. +func lexNumberOrDateStart(lx *lexer) stateFn { + r := lx.next() + switch r { + case '0': + return lexBaseNumberOrDate + } + + if !isDigit(r) { + // The only way to reach this state is if the value starts + // with a digit, so specifically treat anything else as an + // error. + return lx.errorf("expected a digit but got %q", r) + } + + return lexNumberOrDate +} + +// lexNumberOrDate consumes either an integer, float or datetime. +func lexNumberOrDate(lx *lexer) stateFn { + r := lx.next() + if isDigit(r) { + return lexNumberOrDate + } + switch r { + case '-', ':': + return lexDatetime + case '_': + return lexDecimalNumber + case '.', 'e', 'E': + return lexFloat + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexDatetime consumes a Datetime, to a first approximation. +// The parser validates that it matches one of the accepted formats. +func lexDatetime(lx *lexer) stateFn { + r := lx.next() + if isDigit(r) { + return lexDatetime + } + switch r { + case '-', ':', 'T', 't', ' ', '.', 'Z', 'z', '+': + return lexDatetime + } + + lx.backup() + lx.emitTrim(itemDatetime) + return lx.pop() +} + +// lexHexInteger consumes a hexadecimal integer after seeing the '0x' prefix. +func lexHexInteger(lx *lexer) stateFn { + r := lx.next() + if isHex(r) { + return lexHexInteger + } + switch r { + case '_': + return lexHexInteger + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexOctalInteger consumes an octal integer after seeing the '0o' prefix. +func lexOctalInteger(lx *lexer) stateFn { + r := lx.next() + if isOctal(r) { + return lexOctalInteger + } + switch r { + case '_': + return lexOctalInteger + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexBinaryInteger consumes a binary integer after seeing the '0b' prefix. +func lexBinaryInteger(lx *lexer) stateFn { + r := lx.next() + if isBinary(r) { + return lexBinaryInteger + } + switch r { + case '_': + return lexBinaryInteger + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexDecimalNumber consumes a decimal float or integer. +func lexDecimalNumber(lx *lexer) stateFn { + r := lx.next() + if isDigit(r) { + return lexDecimalNumber + } + switch r { + case '.', 'e', 'E': + return lexFloat + case '_': + return lexDecimalNumber + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexDecimalNumber consumes the first digit of a number beginning with a sign. +// It assumes the sign has already been consumed. Values which start with a sign +// are only allowed to be decimal integers or floats. +// +// The special "nan" and "inf" values are also recognized. +func lexDecimalNumberStart(lx *lexer) stateFn { + r := lx.next() + + // Special error cases to give users better error messages + switch r { + case 'i': + if !lx.accept('n') || !lx.accept('f') { + return lx.errorf("invalid float: '%s'", lx.current()) + } + lx.emit(itemFloat) + return lx.pop() + case 'n': + if !lx.accept('a') || !lx.accept('n') { + return lx.errorf("invalid float: '%s'", lx.current()) + } + lx.emit(itemFloat) + return lx.pop() + case '0': + p := lx.peek() + switch p { + case 'b', 'o', 'x': + return lx.errorf("cannot use sign with non-decimal numbers: '%s%c'", lx.current(), p) + } + case '.': + return lx.errorf("floats must start with a digit, not '.'") + } + + if isDigit(r) { + return lexDecimalNumber + } + + return lx.errorf("expected a digit but got %q", r) +} + +// lexBaseNumberOrDate differentiates between the possible values which +// start with '0'. It assumes that before reaching this state, the initial '0' +// has been consumed. +func lexBaseNumberOrDate(lx *lexer) stateFn { + r := lx.next() + // Note: All datetimes start with at least two digits, so we don't + // handle date characters (':', '-', etc.) here. + if isDigit(r) { + return lexNumberOrDate + } + switch r { + case '_': + // Can only be decimal, because there can't be an underscore + // between the '0' and the base designator, and dates can't + // contain underscores. + return lexDecimalNumber + case '.', 'e', 'E': + return lexFloat + case 'b': + r = lx.peek() + if !isBinary(r) { + lx.errorf("not a binary number: '%s%c'", lx.current(), r) + } + return lexBinaryInteger + case 'o': + r = lx.peek() + if !isOctal(r) { + lx.errorf("not an octal number: '%s%c'", lx.current(), r) + } + return lexOctalInteger + case 'x': + r = lx.peek() + if !isHex(r) { + lx.errorf("not a hexidecimal number: '%s%c'", lx.current(), r) + } + return lexHexInteger + } + + lx.backup() + lx.emit(itemInteger) + return lx.pop() +} + +// lexFloat consumes the elements of a float. It allows any sequence of +// float-like characters, so floats emitted by the lexer are only a first +// approximation and must be validated by the parser. +func lexFloat(lx *lexer) stateFn { + r := lx.next() + if isDigit(r) { + return lexFloat + } + switch r { + case '_', '.', '-', '+', 'e', 'E': + return lexFloat + } + + lx.backup() + lx.emit(itemFloat) + return lx.pop() +} + +// lexBool consumes a bool string: 'true' or 'false. +func lexBool(lx *lexer) stateFn { + var rs []rune + for { + r := lx.next() + if !unicode.IsLetter(r) { + lx.backup() + break + } + rs = append(rs, r) + } + s := string(rs) + switch s { + case "true", "false": + lx.emit(itemBool) + return lx.pop() + } + return lx.errorf("expected value but found %q instead", s) +} + +// lexCommentStart begins the lexing of a comment. It will emit +// itemCommentStart and consume no characters, passing control to lexComment. +func lexCommentStart(lx *lexer) stateFn { + lx.ignore() + lx.emit(itemCommentStart) + return lexComment +} + +// lexComment lexes an entire comment. It assumes that '#' has been consumed. +// It will consume *up to* the first newline character, and pass control +// back to the last state on the stack. +func lexComment(lx *lexer) stateFn { + switch r := lx.next(); { + case isNL(r) || r == eof: + lx.backup() + lx.emit(itemText) + return lx.pop() + default: + return lexComment + } +} + +// lexSkip ignores all slurped input and moves on to the next state. +func lexSkip(lx *lexer, nextState stateFn) stateFn { + lx.ignore() + return nextState +} + +func (s stateFn) String() string { + name := runtime.FuncForPC(reflect.ValueOf(s).Pointer()).Name() + if i := strings.LastIndexByte(name, '.'); i > -1 { + name = name[i+1:] + } + if s == nil { + name = "" + } + return name + "()" +} + +func (itype itemType) String() string { + switch itype { + case itemError: + return "Error" + case itemNIL: + return "NIL" + case itemEOF: + return "EOF" + case itemText: + return "Text" + case itemString, itemStringEsc, itemRawString, itemMultilineString, itemRawMultilineString: + return "String" + case itemBool: + return "Bool" + case itemInteger: + return "Integer" + case itemFloat: + return "Float" + case itemDatetime: + return "DateTime" + case itemTableStart: + return "TableStart" + case itemTableEnd: + return "TableEnd" + case itemKeyStart: + return "KeyStart" + case itemKeyEnd: + return "KeyEnd" + case itemArray: + return "Array" + case itemArrayEnd: + return "ArrayEnd" + case itemCommentStart: + return "CommentStart" + case itemInlineTableStart: + return "InlineTableStart" + case itemInlineTableEnd: + return "InlineTableEnd" + } + panic(fmt.Sprintf("BUG: Unknown type '%d'.", int(itype))) +} + +func (item item) String() string { + return fmt.Sprintf("(%s, %s)", item.typ, item.val) +} + +func isWhitespace(r rune) bool { return r == '\t' || r == ' ' } +func isNL(r rune) bool { return r == '\n' || r == '\r' } +func isControl(r rune) bool { // Control characters except \t, \r, \n + switch r { + case '\t', '\r', '\n': + return false + default: + return (r >= 0x00 && r <= 0x1f) || r == 0x7f + } +} +func isDigit(r rune) bool { return r >= '0' && r <= '9' } +func isBinary(r rune) bool { return r == '0' || r == '1' } +func isOctal(r rune) bool { return r >= '0' && r <= '7' } +func isHex(r rune) bool { return (r >= '0' && r <= '9') || (r|0x20 >= 'a' && r|0x20 <= 'f') } +func isBareKeyChar(r rune, tomlNext bool) bool { + if tomlNext { + return (r >= 'A' && r <= 'Z') || + (r >= 'a' && r <= 'z') || + (r >= '0' && r <= '9') || + r == '_' || r == '-' || + r == 0xb2 || r == 0xb3 || r == 0xb9 || (r >= 0xbc && r <= 0xbe) || + (r >= 0xc0 && r <= 0xd6) || (r >= 0xd8 && r <= 0xf6) || (r >= 0xf8 && r <= 0x037d) || + (r >= 0x037f && r <= 0x1fff) || + (r >= 0x200c && r <= 0x200d) || (r >= 0x203f && r <= 0x2040) || + (r >= 0x2070 && r <= 0x218f) || (r >= 0x2460 && r <= 0x24ff) || + (r >= 0x2c00 && r <= 0x2fef) || (r >= 0x3001 && r <= 0xd7ff) || + (r >= 0xf900 && r <= 0xfdcf) || (r >= 0xfdf0 && r <= 0xfffd) || + (r >= 0x10000 && r <= 0xeffff) + } + + return (r >= 'A' && r <= 'Z') || + (r >= 'a' && r <= 'z') || + (r >= '0' && r <= '9') || + r == '_' || r == '-' +} diff --git a/vendor/github.com/BurntSushi/toml/meta.go b/vendor/github.com/BurntSushi/toml/meta.go new file mode 100644 index 0000000..e614537 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/meta.go @@ -0,0 +1,148 @@ +package toml + +import ( + "strings" +) + +// MetaData allows access to meta information about TOML data that's not +// accessible otherwise. +// +// It allows checking if a key is defined in the TOML data, whether any keys +// were undecoded, and the TOML type of a key. +type MetaData struct { + context Key // Used only during decoding. + + keyInfo map[string]keyInfo + mapping map[string]any + keys []Key + decoded map[string]struct{} + data []byte // Input file; for errors. +} + +// IsDefined reports if the key exists in the TOML data. +// +// The key should be specified hierarchically, for example to access the TOML +// key "a.b.c" you would use IsDefined("a", "b", "c"). Keys are case sensitive. +// +// Returns false for an empty key. +func (md *MetaData) IsDefined(key ...string) bool { + if len(key) == 0 { + return false + } + + var ( + hash map[string]any + ok bool + hashOrVal any = md.mapping + ) + for _, k := range key { + if hash, ok = hashOrVal.(map[string]any); !ok { + return false + } + if hashOrVal, ok = hash[k]; !ok { + return false + } + } + return true +} + +// Type returns a string representation of the type of the key specified. +// +// Type will return the empty string if given an empty key or a key that does +// not exist. Keys are case sensitive. +func (md *MetaData) Type(key ...string) string { + if ki, ok := md.keyInfo[Key(key).String()]; ok { + return ki.tomlType.typeString() + } + return "" +} + +// Keys returns a slice of every key in the TOML data, including key groups. +// +// Each key is itself a slice, where the first element is the top of the +// hierarchy and the last is the most specific. The list will have the same +// order as the keys appeared in the TOML data. +// +// All keys returned are non-empty. +func (md *MetaData) Keys() []Key { + return md.keys +} + +// Undecoded returns all keys that have not been decoded in the order in which +// they appear in the original TOML document. +// +// This includes keys that haven't been decoded because of a [Primitive] value. +// Once the Primitive value is decoded, the keys will be considered decoded. +// +// Also note that decoding into an empty interface will result in no decoding, +// and so no keys will be considered decoded. +// +// In this sense, the Undecoded keys correspond to keys in the TOML document +// that do not have a concrete type in your representation. +func (md *MetaData) Undecoded() []Key { + undecoded := make([]Key, 0, len(md.keys)) + for _, key := range md.keys { + if _, ok := md.decoded[key.String()]; !ok { + undecoded = append(undecoded, key) + } + } + return undecoded +} + +// Key represents any TOML key, including key groups. Use [MetaData.Keys] to get +// values of this type. +type Key []string + +func (k Key) String() string { + // This is called quite often, so it's a bit funky to make it faster. + var b strings.Builder + b.Grow(len(k) * 25) +outer: + for i, kk := range k { + if i > 0 { + b.WriteByte('.') + } + if kk == "" { + b.WriteString(`""`) + } else { + for _, r := range kk { + // "Inline" isBareKeyChar + if !((r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '_' || r == '-') { + b.WriteByte('"') + b.WriteString(dblQuotedReplacer.Replace(kk)) + b.WriteByte('"') + continue outer + } + } + b.WriteString(kk) + } + } + return b.String() +} + +func (k Key) maybeQuoted(i int) string { + if k[i] == "" { + return `""` + } + for _, r := range k[i] { + if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '_' || r == '-' { + continue + } + return `"` + dblQuotedReplacer.Replace(k[i]) + `"` + } + return k[i] +} + +// Like append(), but only increase the cap by 1. +func (k Key) add(piece string) Key { + if cap(k) > len(k) { + return append(k, piece) + } + newKey := make(Key, len(k)+1) + copy(newKey, k) + newKey[len(k)] = piece + return newKey +} + +func (k Key) parent() Key { return k[:len(k)-1] } // all except the last piece. +func (k Key) last() string { return k[len(k)-1] } // last piece of this key. diff --git a/vendor/github.com/BurntSushi/toml/parse.go b/vendor/github.com/BurntSushi/toml/parse.go new file mode 100644 index 0000000..3f2c090 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/parse.go @@ -0,0 +1,846 @@ +package toml + +import ( + "fmt" + "math" + "os" + "strconv" + "strings" + "time" + "unicode/utf8" + + "github.com/BurntSushi/toml/internal" +) + +type parser struct { + lx *lexer + context Key // Full key for the current hash in scope. + currentKey string // Base key name for everything except hashes. + pos Position // Current position in the TOML file. + tomlNext bool + + ordered []Key // List of keys in the order that they appear in the TOML data. + + keyInfo map[string]keyInfo // Map keyname → info about the TOML key. + mapping map[string]any // Map keyname → key value. + implicits map[string]struct{} // Record implicit keys (e.g. "key.group.names"). +} + +type keyInfo struct { + pos Position + tomlType tomlType +} + +func parse(data string) (p *parser, err error) { + _, tomlNext := os.LookupEnv("BURNTSUSHI_TOML_110") + + defer func() { + if r := recover(); r != nil { + if pErr, ok := r.(ParseError); ok { + pErr.input = data + err = pErr + return + } + panic(r) + } + }() + + // Read over BOM; do this here as the lexer calls utf8.DecodeRuneInString() + // which mangles stuff. UTF-16 BOM isn't strictly valid, but some tools add + // it anyway. + if strings.HasPrefix(data, "\xff\xfe") || strings.HasPrefix(data, "\xfe\xff") { // UTF-16 + data = data[2:] + //lint:ignore S1017 https://github.com/dominikh/go-tools/issues/1447 + } else if strings.HasPrefix(data, "\xef\xbb\xbf") { // UTF-8 + data = data[3:] + } + + // Examine first few bytes for NULL bytes; this probably means it's a UTF-16 + // file (second byte in surrogate pair being NULL). Again, do this here to + // avoid having to deal with UTF-8/16 stuff in the lexer. + ex := 6 + if len(data) < 6 { + ex = len(data) + } + if i := strings.IndexRune(data[:ex], 0); i > -1 { + return nil, ParseError{ + Message: "files cannot contain NULL bytes; probably using UTF-16; TOML files must be UTF-8", + Position: Position{Line: 1, Col: 1, Start: i, Len: 1}, + Line: 1, + input: data, + } + } + + p = &parser{ + keyInfo: make(map[string]keyInfo), + mapping: make(map[string]any), + lx: lex(data, tomlNext), + ordered: make([]Key, 0), + implicits: make(map[string]struct{}), + tomlNext: tomlNext, + } + for { + item := p.next() + if item.typ == itemEOF { + break + } + p.topLevel(item) + } + + return p, nil +} + +func (p *parser) panicErr(it item, err error) { + panic(ParseError{ + Message: err.Error(), + err: err, + Position: it.pos.withCol(p.lx.input), + Line: it.pos.Len, + LastKey: p.current(), + }) +} + +func (p *parser) panicItemf(it item, format string, v ...any) { + panic(ParseError{ + Message: fmt.Sprintf(format, v...), + Position: it.pos.withCol(p.lx.input), + Line: it.pos.Len, + LastKey: p.current(), + }) +} + +func (p *parser) panicf(format string, v ...any) { + panic(ParseError{ + Message: fmt.Sprintf(format, v...), + Position: p.pos.withCol(p.lx.input), + Line: p.pos.Line, + LastKey: p.current(), + }) +} + +func (p *parser) next() item { + it := p.lx.nextItem() + //fmt.Printf("ITEM %-18s line %-3d │ %q\n", it.typ, it.pos.Line, it.val) + if it.typ == itemError { + if it.err != nil { + panic(ParseError{ + Message: it.err.Error(), + err: it.err, + Position: it.pos.withCol(p.lx.input), + Line: it.pos.Line, + LastKey: p.current(), + }) + } + + p.panicItemf(it, "%s", it.val) + } + return it +} + +func (p *parser) nextPos() item { + it := p.next() + p.pos = it.pos + return it +} + +func (p *parser) bug(format string, v ...any) { + panic(fmt.Sprintf("BUG: "+format+"\n\n", v...)) +} + +func (p *parser) expect(typ itemType) item { + it := p.next() + p.assertEqual(typ, it.typ) + return it +} + +func (p *parser) assertEqual(expected, got itemType) { + if expected != got { + p.bug("Expected '%s' but got '%s'.", expected, got) + } +} + +func (p *parser) topLevel(item item) { + switch item.typ { + case itemCommentStart: // # .. + p.expect(itemText) + case itemTableStart: // [ .. ] + name := p.nextPos() + + var key Key + for ; name.typ != itemTableEnd && name.typ != itemEOF; name = p.next() { + key = append(key, p.keyString(name)) + } + p.assertEqual(itemTableEnd, name.typ) + + p.addContext(key, false) + p.setType("", tomlHash, item.pos) + p.ordered = append(p.ordered, key) + case itemArrayTableStart: // [[ .. ]] + name := p.nextPos() + + var key Key + for ; name.typ != itemArrayTableEnd && name.typ != itemEOF; name = p.next() { + key = append(key, p.keyString(name)) + } + p.assertEqual(itemArrayTableEnd, name.typ) + + p.addContext(key, true) + p.setType("", tomlArrayHash, item.pos) + p.ordered = append(p.ordered, key) + case itemKeyStart: // key = .. + outerContext := p.context + /// Read all the key parts (e.g. 'a' and 'b' in 'a.b') + k := p.nextPos() + var key Key + for ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() { + key = append(key, p.keyString(k)) + } + p.assertEqual(itemKeyEnd, k.typ) + + /// The current key is the last part. + p.currentKey = key.last() + + /// All the other parts (if any) are the context; need to set each part + /// as implicit. + context := key.parent() + for i := range context { + p.addImplicitContext(append(p.context, context[i:i+1]...)) + } + p.ordered = append(p.ordered, p.context.add(p.currentKey)) + + /// Set value. + vItem := p.next() + val, typ := p.value(vItem, false) + p.setValue(p.currentKey, val) + p.setType(p.currentKey, typ, vItem.pos) + + /// Remove the context we added (preserving any context from [tbl] lines). + p.context = outerContext + p.currentKey = "" + default: + p.bug("Unexpected type at top level: %s", item.typ) + } +} + +// Gets a string for a key (or part of a key in a table name). +func (p *parser) keyString(it item) string { + switch it.typ { + case itemText: + return it.val + case itemString, itemStringEsc, itemMultilineString, + itemRawString, itemRawMultilineString: + s, _ := p.value(it, false) + return s.(string) + default: + p.bug("Unexpected key type: %s", it.typ) + } + panic("unreachable") +} + +var datetimeRepl = strings.NewReplacer( + "z", "Z", + "t", "T", + " ", "T") + +// value translates an expected value from the lexer into a Go value wrapped +// as an empty interface. +func (p *parser) value(it item, parentIsArray bool) (any, tomlType) { + switch it.typ { + case itemString: + return it.val, p.typeOfPrimitive(it) + case itemStringEsc: + return p.replaceEscapes(it, it.val), p.typeOfPrimitive(it) + case itemMultilineString: + return p.replaceEscapes(it, p.stripEscapedNewlines(stripFirstNewline(it.val))), p.typeOfPrimitive(it) + case itemRawString: + return it.val, p.typeOfPrimitive(it) + case itemRawMultilineString: + return stripFirstNewline(it.val), p.typeOfPrimitive(it) + case itemInteger: + return p.valueInteger(it) + case itemFloat: + return p.valueFloat(it) + case itemBool: + switch it.val { + case "true": + return true, p.typeOfPrimitive(it) + case "false": + return false, p.typeOfPrimitive(it) + default: + p.bug("Expected boolean value, but got '%s'.", it.val) + } + case itemDatetime: + return p.valueDatetime(it) + case itemArray: + return p.valueArray(it) + case itemInlineTableStart: + return p.valueInlineTable(it, parentIsArray) + default: + p.bug("Unexpected value type: %s", it.typ) + } + panic("unreachable") +} + +func (p *parser) valueInteger(it item) (any, tomlType) { + if !numUnderscoresOK(it.val) { + p.panicItemf(it, "Invalid integer %q: underscores must be surrounded by digits", it.val) + } + if numHasLeadingZero(it.val) { + p.panicItemf(it, "Invalid integer %q: cannot have leading zeroes", it.val) + } + + num, err := strconv.ParseInt(it.val, 0, 64) + if err != nil { + // Distinguish integer values. Normally, it'd be a bug if the lexer + // provides an invalid integer, but it's possible that the number is + // out of range of valid values (which the lexer cannot determine). + // So mark the former as a bug but the latter as a legitimate user + // error. + if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange { + p.panicErr(it, errParseRange{i: it.val, size: "int64"}) + } else { + p.bug("Expected integer value, but got '%s'.", it.val) + } + } + return num, p.typeOfPrimitive(it) +} + +func (p *parser) valueFloat(it item) (any, tomlType) { + parts := strings.FieldsFunc(it.val, func(r rune) bool { + switch r { + case '.', 'e', 'E': + return true + } + return false + }) + for _, part := range parts { + if !numUnderscoresOK(part) { + p.panicItemf(it, "Invalid float %q: underscores must be surrounded by digits", it.val) + } + } + if len(parts) > 0 && numHasLeadingZero(parts[0]) { + p.panicItemf(it, "Invalid float %q: cannot have leading zeroes", it.val) + } + if !numPeriodsOK(it.val) { + // As a special case, numbers like '123.' or '1.e2', + // which are valid as far as Go/strconv are concerned, + // must be rejected because TOML says that a fractional + // part consists of '.' followed by 1+ digits. + p.panicItemf(it, "Invalid float %q: '.' must be followed by one or more digits", it.val) + } + val := strings.Replace(it.val, "_", "", -1) + signbit := false + if val == "+nan" || val == "-nan" { + signbit = val == "-nan" + val = "nan" + } + num, err := strconv.ParseFloat(val, 64) + if err != nil { + if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange { + p.panicErr(it, errParseRange{i: it.val, size: "float64"}) + } else { + p.panicItemf(it, "Invalid float value: %q", it.val) + } + } + if signbit { + num = math.Copysign(num, -1) + } + return num, p.typeOfPrimitive(it) +} + +var dtTypes = []struct { + fmt string + zone *time.Location + next bool +}{ + {time.RFC3339Nano, time.Local, false}, + {"2006-01-02T15:04:05.999999999", internal.LocalDatetime, false}, + {"2006-01-02", internal.LocalDate, false}, + {"15:04:05.999999999", internal.LocalTime, false}, + + // tomlNext + {"2006-01-02T15:04Z07:00", time.Local, true}, + {"2006-01-02T15:04", internal.LocalDatetime, true}, + {"15:04", internal.LocalTime, true}, +} + +func (p *parser) valueDatetime(it item) (any, tomlType) { + it.val = datetimeRepl.Replace(it.val) + var ( + t time.Time + ok bool + err error + ) + for _, dt := range dtTypes { + if dt.next && !p.tomlNext { + continue + } + t, err = time.ParseInLocation(dt.fmt, it.val, dt.zone) + if err == nil { + if missingLeadingZero(it.val, dt.fmt) { + p.panicErr(it, errParseDate{it.val}) + } + ok = true + break + } + } + if !ok { + p.panicErr(it, errParseDate{it.val}) + } + return t, p.typeOfPrimitive(it) +} + +// Go's time.Parse() will accept numbers without a leading zero; there isn't any +// way to require it. https://github.com/golang/go/issues/29911 +// +// Depend on the fact that the separators (- and :) should always be at the same +// location. +func missingLeadingZero(d, l string) bool { + for i, c := range []byte(l) { + if c == '.' || c == 'Z' { + return false + } + if (c < '0' || c > '9') && d[i] != c { + return true + } + } + return false +} + +func (p *parser) valueArray(it item) (any, tomlType) { + p.setType(p.currentKey, tomlArray, it.pos) + + var ( + // Initialize to a non-nil slice to make it consistent with how S = [] + // decodes into a non-nil slice inside something like struct { S + // []string }. See #338 + array = make([]any, 0, 2) + ) + for it = p.next(); it.typ != itemArrayEnd; it = p.next() { + if it.typ == itemCommentStart { + p.expect(itemText) + continue + } + + val, typ := p.value(it, true) + array = append(array, val) + + // XXX: type isn't used here, we need it to record the accurate type + // information. + // + // Not entirely sure how to best store this; could use "key[0]", + // "key[1]" notation, or maybe store it on the Array type? + _ = typ + } + return array, tomlArray +} + +func (p *parser) valueInlineTable(it item, parentIsArray bool) (any, tomlType) { + var ( + topHash = make(map[string]any) + outerContext = p.context + outerKey = p.currentKey + ) + + p.context = append(p.context, p.currentKey) + prevContext := p.context + p.currentKey = "" + + p.addImplicit(p.context) + p.addContext(p.context, parentIsArray) + + /// Loop over all table key/value pairs. + for it := p.next(); it.typ != itemInlineTableEnd; it = p.next() { + if it.typ == itemCommentStart { + p.expect(itemText) + continue + } + + /// Read all key parts. + k := p.nextPos() + var key Key + for ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() { + key = append(key, p.keyString(k)) + } + p.assertEqual(itemKeyEnd, k.typ) + + /// The current key is the last part. + p.currentKey = key.last() + + /// All the other parts (if any) are the context; need to set each part + /// as implicit. + context := key.parent() + for i := range context { + p.addImplicitContext(append(p.context, context[i:i+1]...)) + } + p.ordered = append(p.ordered, p.context.add(p.currentKey)) + + /// Set the value. + val, typ := p.value(p.next(), false) + p.setValue(p.currentKey, val) + p.setType(p.currentKey, typ, it.pos) + + hash := topHash + for _, c := range context { + h, ok := hash[c] + if !ok { + h = make(map[string]any) + hash[c] = h + } + hash, ok = h.(map[string]any) + if !ok { + p.panicf("%q is not a table", p.context) + } + } + hash[p.currentKey] = val + + /// Restore context. + p.context = prevContext + } + p.context = outerContext + p.currentKey = outerKey + return topHash, tomlHash +} + +// numHasLeadingZero checks if this number has leading zeroes, allowing for '0', +// +/- signs, and base prefixes. +func numHasLeadingZero(s string) bool { + if len(s) > 1 && s[0] == '0' && !(s[1] == 'b' || s[1] == 'o' || s[1] == 'x') { // Allow 0b, 0o, 0x + return true + } + if len(s) > 2 && (s[0] == '-' || s[0] == '+') && s[1] == '0' { + return true + } + return false +} + +// numUnderscoresOK checks whether each underscore in s is surrounded by +// characters that are not underscores. +func numUnderscoresOK(s string) bool { + switch s { + case "nan", "+nan", "-nan", "inf", "-inf", "+inf": + return true + } + accept := false + for _, r := range s { + if r == '_' { + if !accept { + return false + } + } + + // isHexis a superset of all the permissable characters surrounding an + // underscore. + accept = isHex(r) + } + return accept +} + +// numPeriodsOK checks whether every period in s is followed by a digit. +func numPeriodsOK(s string) bool { + period := false + for _, r := range s { + if period && !isDigit(r) { + return false + } + period = r == '.' + } + return !period +} + +// Set the current context of the parser, where the context is either a hash or +// an array of hashes, depending on the value of the `array` parameter. +// +// Establishing the context also makes sure that the key isn't a duplicate, and +// will create implicit hashes automatically. +func (p *parser) addContext(key Key, array bool) { + /// Always start at the top level and drill down for our context. + hashContext := p.mapping + keyContext := make(Key, 0, len(key)-1) + + /// We only need implicit hashes for the parents. + for _, k := range key.parent() { + _, ok := hashContext[k] + keyContext = append(keyContext, k) + + // No key? Make an implicit hash and move on. + if !ok { + p.addImplicit(keyContext) + hashContext[k] = make(map[string]any) + } + + // If the hash context is actually an array of tables, then set + // the hash context to the last element in that array. + // + // Otherwise, it better be a table, since this MUST be a key group (by + // virtue of it not being the last element in a key). + switch t := hashContext[k].(type) { + case []map[string]any: + hashContext = t[len(t)-1] + case map[string]any: + hashContext = t + default: + p.panicf("Key '%s' was already created as a hash.", keyContext) + } + } + + p.context = keyContext + if array { + // If this is the first element for this array, then allocate a new + // list of tables for it. + k := key.last() + if _, ok := hashContext[k]; !ok { + hashContext[k] = make([]map[string]any, 0, 4) + } + + // Add a new table. But make sure the key hasn't already been used + // for something else. + if hash, ok := hashContext[k].([]map[string]any); ok { + hashContext[k] = append(hash, make(map[string]any)) + } else { + p.panicf("Key '%s' was already created and cannot be used as an array.", key) + } + } else { + p.setValue(key.last(), make(map[string]any)) + } + p.context = append(p.context, key.last()) +} + +// setValue sets the given key to the given value in the current context. +// It will make sure that the key hasn't already been defined, account for +// implicit key groups. +func (p *parser) setValue(key string, value any) { + var ( + tmpHash any + ok bool + hash = p.mapping + keyContext = make(Key, 0, len(p.context)+1) + ) + for _, k := range p.context { + keyContext = append(keyContext, k) + if tmpHash, ok = hash[k]; !ok { + p.bug("Context for key '%s' has not been established.", keyContext) + } + switch t := tmpHash.(type) { + case []map[string]any: + // The context is a table of hashes. Pick the most recent table + // defined as the current hash. + hash = t[len(t)-1] + case map[string]any: + hash = t + default: + p.panicf("Key '%s' has already been defined.", keyContext) + } + } + keyContext = append(keyContext, key) + + if _, ok := hash[key]; ok { + // Normally redefining keys isn't allowed, but the key could have been + // defined implicitly and it's allowed to be redefined concretely. (See + // the `valid/implicit-and-explicit-after.toml` in toml-test) + // + // But we have to make sure to stop marking it as an implicit. (So that + // another redefinition provokes an error.) + // + // Note that since it has already been defined (as a hash), we don't + // want to overwrite it. So our business is done. + if p.isArray(keyContext) { + p.removeImplicit(keyContext) + hash[key] = value + return + } + if p.isImplicit(keyContext) { + p.removeImplicit(keyContext) + return + } + // Otherwise, we have a concrete key trying to override a previous key, + // which is *always* wrong. + p.panicf("Key '%s' has already been defined.", keyContext) + } + + hash[key] = value +} + +// setType sets the type of a particular value at a given key. It should be +// called immediately AFTER setValue. +// +// Note that if `key` is empty, then the type given will be applied to the +// current context (which is either a table or an array of tables). +func (p *parser) setType(key string, typ tomlType, pos Position) { + keyContext := make(Key, 0, len(p.context)+1) + keyContext = append(keyContext, p.context...) + if len(key) > 0 { // allow type setting for hashes + keyContext = append(keyContext, key) + } + // Special case to make empty keys ("" = 1) work. + // Without it it will set "" rather than `""`. + // TODO: why is this needed? And why is this only needed here? + if len(keyContext) == 0 { + keyContext = Key{""} + } + p.keyInfo[keyContext.String()] = keyInfo{tomlType: typ, pos: pos} +} + +// Implicit keys need to be created when tables are implied in "a.b.c.d = 1" and +// "[a.b.c]" (the "a", "b", and "c" hashes are never created explicitly). +func (p *parser) addImplicit(key Key) { p.implicits[key.String()] = struct{}{} } +func (p *parser) removeImplicit(key Key) { delete(p.implicits, key.String()) } +func (p *parser) isImplicit(key Key) bool { _, ok := p.implicits[key.String()]; return ok } +func (p *parser) isArray(key Key) bool { return p.keyInfo[key.String()].tomlType == tomlArray } +func (p *parser) addImplicitContext(key Key) { p.addImplicit(key); p.addContext(key, false) } + +// current returns the full key name of the current context. +func (p *parser) current() string { + if len(p.currentKey) == 0 { + return p.context.String() + } + if len(p.context) == 0 { + return p.currentKey + } + return fmt.Sprintf("%s.%s", p.context, p.currentKey) +} + +func stripFirstNewline(s string) string { + if len(s) > 0 && s[0] == '\n' { + return s[1:] + } + if len(s) > 1 && s[0] == '\r' && s[1] == '\n' { + return s[2:] + } + return s +} + +// stripEscapedNewlines removes whitespace after line-ending backslashes in +// multiline strings. +// +// A line-ending backslash is an unescaped \ followed only by whitespace until +// the next newline. After a line-ending backslash, all whitespace is removed +// until the next non-whitespace character. +func (p *parser) stripEscapedNewlines(s string) string { + var ( + b strings.Builder + i int + ) + b.Grow(len(s)) + for { + ix := strings.Index(s[i:], `\`) + if ix < 0 { + b.WriteString(s) + return b.String() + } + i += ix + + if len(s) > i+1 && s[i+1] == '\\' { + // Escaped backslash. + i += 2 + continue + } + // Scan until the next non-whitespace. + j := i + 1 + whitespaceLoop: + for ; j < len(s); j++ { + switch s[j] { + case ' ', '\t', '\r', '\n': + default: + break whitespaceLoop + } + } + if j == i+1 { + // Not a whitespace escape. + i++ + continue + } + if !strings.Contains(s[i:j], "\n") { + // This is not a line-ending backslash. (It's a bad escape sequence, + // but we can let replaceEscapes catch it.) + i++ + continue + } + b.WriteString(s[:i]) + s = s[j:] + i = 0 + } +} + +func (p *parser) replaceEscapes(it item, str string) string { + var ( + b strings.Builder + skip = 0 + ) + b.Grow(len(str)) + for i, c := range str { + if skip > 0 { + skip-- + continue + } + if c != '\\' { + b.WriteRune(c) + continue + } + + if i >= len(str) { + p.bug("Escape sequence at end of string.") + return "" + } + switch str[i+1] { + default: + p.bug("Expected valid escape code after \\, but got %q.", str[i+1]) + case ' ', '\t': + p.panicItemf(it, "invalid escape: '\\%c'", str[i+1]) + case 'b': + b.WriteByte(0x08) + skip = 1 + case 't': + b.WriteByte(0x09) + skip = 1 + case 'n': + b.WriteByte(0x0a) + skip = 1 + case 'f': + b.WriteByte(0x0c) + skip = 1 + case 'r': + b.WriteByte(0x0d) + skip = 1 + case 'e': + if p.tomlNext { + b.WriteByte(0x1b) + skip = 1 + } + case '"': + b.WriteByte(0x22) + skip = 1 + case '\\': + b.WriteByte(0x5c) + skip = 1 + // The lexer guarantees the correct number of characters are present; + // don't need to check here. + case 'x': + if p.tomlNext { + escaped := p.asciiEscapeToUnicode(it, str[i+2:i+4]) + b.WriteRune(escaped) + skip = 3 + } + case 'u': + escaped := p.asciiEscapeToUnicode(it, str[i+2:i+6]) + b.WriteRune(escaped) + skip = 5 + case 'U': + escaped := p.asciiEscapeToUnicode(it, str[i+2:i+10]) + b.WriteRune(escaped) + skip = 9 + } + } + return b.String() +} + +func (p *parser) asciiEscapeToUnicode(it item, s string) rune { + hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32) + if err != nil { + p.bug("Could not parse '%s' as a hexadecimal number, but the lexer claims it's OK: %s", s, err) + } + if !utf8.ValidRune(rune(hex)) { + p.panicItemf(it, "Escaped character '\\u%s' is not valid UTF-8.", s) + } + return rune(hex) +} diff --git a/vendor/github.com/BurntSushi/toml/type_fields.go b/vendor/github.com/BurntSushi/toml/type_fields.go new file mode 100644 index 0000000..10c51f7 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/type_fields.go @@ -0,0 +1,238 @@ +package toml + +// Struct field handling is adapted from code in encoding/json: +// +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the Go distribution. + +import ( + "reflect" + "sort" + "sync" +) + +// A field represents a single field found in a struct. +type field struct { + name string // the name of the field (`toml` tag included) + tag bool // whether field has a `toml` tag + index []int // represents the depth of an anonymous field + typ reflect.Type // the type of the field +} + +// byName sorts field by name, breaking ties with depth, +// then breaking ties with "name came from toml tag", then +// breaking ties with index sequence. +type byName []field + +func (x byName) Len() int { return len(x) } +func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x byName) Less(i, j int) bool { + if x[i].name != x[j].name { + return x[i].name < x[j].name + } + if len(x[i].index) != len(x[j].index) { + return len(x[i].index) < len(x[j].index) + } + if x[i].tag != x[j].tag { + return x[i].tag + } + return byIndex(x).Less(i, j) +} + +// byIndex sorts field by index sequence. +type byIndex []field + +func (x byIndex) Len() int { return len(x) } +func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x byIndex) Less(i, j int) bool { + for k, xik := range x[i].index { + if k >= len(x[j].index) { + return false + } + if xik != x[j].index[k] { + return xik < x[j].index[k] + } + } + return len(x[i].index) < len(x[j].index) +} + +// typeFields returns a list of fields that TOML should recognize for the given +// type. The algorithm is breadth-first search over the set of structs to +// include - the top struct and then any reachable anonymous structs. +func typeFields(t reflect.Type) []field { + // Anonymous fields to explore at the current level and the next. + current := []field{} + next := []field{{typ: t}} + + // Count of queued names for current level and the next. + var count map[reflect.Type]int + var nextCount map[reflect.Type]int + + // Types already visited at an earlier level. + visited := map[reflect.Type]bool{} + + // Fields found. + var fields []field + + for len(next) > 0 { + current, next = next, current[:0] + count, nextCount = nextCount, map[reflect.Type]int{} + + for _, f := range current { + if visited[f.typ] { + continue + } + visited[f.typ] = true + + // Scan f.typ for fields to include. + for i := 0; i < f.typ.NumField(); i++ { + sf := f.typ.Field(i) + if sf.PkgPath != "" && !sf.Anonymous { // unexported + continue + } + opts := getOptions(sf.Tag) + if opts.skip { + continue + } + index := make([]int, len(f.index)+1) + copy(index, f.index) + index[len(f.index)] = i + + ft := sf.Type + if ft.Name() == "" && ft.Kind() == reflect.Ptr { + // Follow pointer. + ft = ft.Elem() + } + + // Record found field and index sequence. + if opts.name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { + tagged := opts.name != "" + name := opts.name + if name == "" { + name = sf.Name + } + fields = append(fields, field{name, tagged, index, ft}) + if count[f.typ] > 1 { + // If there were multiple instances, add a second, + // so that the annihilation code will see a duplicate. + // It only cares about the distinction between 1 or 2, + // so don't bother generating any more copies. + fields = append(fields, fields[len(fields)-1]) + } + continue + } + + // Record new anonymous struct to explore in next round. + nextCount[ft]++ + if nextCount[ft] == 1 { + f := field{name: ft.Name(), index: index, typ: ft} + next = append(next, f) + } + } + } + } + + sort.Sort(byName(fields)) + + // Delete all fields that are hidden by the Go rules for embedded fields, + // except that fields with TOML tags are promoted. + + // The fields are sorted in primary order of name, secondary order + // of field index length. Loop over names; for each name, delete + // hidden fields by choosing the one dominant field that survives. + out := fields[:0] + for advance, i := 0, 0; i < len(fields); i += advance { + // One iteration per name. + // Find the sequence of fields with the name of this first field. + fi := fields[i] + name := fi.name + for advance = 1; i+advance < len(fields); advance++ { + fj := fields[i+advance] + if fj.name != name { + break + } + } + if advance == 1 { // Only one field with this name + out = append(out, fi) + continue + } + dominant, ok := dominantField(fields[i : i+advance]) + if ok { + out = append(out, dominant) + } + } + + fields = out + sort.Sort(byIndex(fields)) + + return fields +} + +// dominantField looks through the fields, all of which are known to +// have the same name, to find the single field that dominates the +// others using Go's embedding rules, modified by the presence of +// TOML tags. If there are multiple top-level fields, the boolean +// will be false: This condition is an error in Go and we skip all +// the fields. +func dominantField(fields []field) (field, bool) { + // The fields are sorted in increasing index-length order. The winner + // must therefore be one with the shortest index length. Drop all + // longer entries, which is easy: just truncate the slice. + length := len(fields[0].index) + tagged := -1 // Index of first tagged field. + for i, f := range fields { + if len(f.index) > length { + fields = fields[:i] + break + } + if f.tag { + if tagged >= 0 { + // Multiple tagged fields at the same level: conflict. + // Return no field. + return field{}, false + } + tagged = i + } + } + if tagged >= 0 { + return fields[tagged], true + } + // All remaining fields have the same length. If there's more than one, + // we have a conflict (two fields named "X" at the same level) and we + // return no field. + if len(fields) > 1 { + return field{}, false + } + return fields[0], true +} + +var fieldCache struct { + sync.RWMutex + m map[reflect.Type][]field +} + +// cachedTypeFields is like typeFields but uses a cache to avoid repeated work. +func cachedTypeFields(t reflect.Type) []field { + fieldCache.RLock() + f := fieldCache.m[t] + fieldCache.RUnlock() + if f != nil { + return f + } + + // Compute fields without lock. + // Might duplicate effort but won't hold other computations back. + f = typeFields(t) + if f == nil { + f = []field{} + } + + fieldCache.Lock() + if fieldCache.m == nil { + fieldCache.m = map[reflect.Type][]field{} + } + fieldCache.m[t] = f + fieldCache.Unlock() + return f +} diff --git a/vendor/github.com/BurntSushi/toml/type_toml.go b/vendor/github.com/BurntSushi/toml/type_toml.go new file mode 100644 index 0000000..1c090d3 --- /dev/null +++ b/vendor/github.com/BurntSushi/toml/type_toml.go @@ -0,0 +1,65 @@ +package toml + +// tomlType represents any Go type that corresponds to a TOML type. +// While the first draft of the TOML spec has a simplistic type system that +// probably doesn't need this level of sophistication, we seem to be militating +// toward adding real composite types. +type tomlType interface { + typeString() string +} + +// typeEqual accepts any two types and returns true if they are equal. +func typeEqual(t1, t2 tomlType) bool { + if t1 == nil || t2 == nil { + return false + } + return t1.typeString() == t2.typeString() +} + +func typeIsTable(t tomlType) bool { + return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash) +} + +type tomlBaseType string + +func (btype tomlBaseType) typeString() string { return string(btype) } +func (btype tomlBaseType) String() string { return btype.typeString() } + +var ( + tomlInteger tomlBaseType = "Integer" + tomlFloat tomlBaseType = "Float" + tomlDatetime tomlBaseType = "Datetime" + tomlString tomlBaseType = "String" + tomlBool tomlBaseType = "Bool" + tomlArray tomlBaseType = "Array" + tomlHash tomlBaseType = "Hash" + tomlArrayHash tomlBaseType = "ArrayHash" +) + +// typeOfPrimitive returns a tomlType of any primitive value in TOML. +// Primitive values are: Integer, Float, Datetime, String and Bool. +// +// Passing a lexer item other than the following will cause a BUG message +// to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime. +func (p *parser) typeOfPrimitive(lexItem item) tomlType { + switch lexItem.typ { + case itemInteger: + return tomlInteger + case itemFloat: + return tomlFloat + case itemDatetime: + return tomlDatetime + case itemString, itemStringEsc: + return tomlString + case itemMultilineString: + return tomlString + case itemRawString: + return tomlString + case itemRawMultilineString: + return tomlString + case itemBool: + return tomlBool + } + p.bug("Cannot infer primitive type of lex item '%s'.", lexItem) + panic("unreachable") +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/.travis.yml b/vendor/github.com/nathan-osman/go-sunrise/.travis.yml new file mode 100644 index 0000000..a976c17 --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/.travis.yml @@ -0,0 +1,10 @@ +language: go + +go: + - stable + +before_install: + - go install github.com/mattn/goveralls@latest + +script: + - $GOPATH/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/nathan-osman/go-sunrise/LICENSE.txt b/vendor/github.com/nathan-osman/go-sunrise/LICENSE.txt new file mode 100644 index 0000000..5e4eaa7 --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/LICENSE.txt @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (c) 2017 Nathan Osman + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/nathan-osman/go-sunrise/README.md b/vendor/github.com/nathan-osman/go-sunrise/README.md new file mode 100644 index 0000000..bbb7bed --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/README.md @@ -0,0 +1,29 @@ +## go-sunrise + +[![Build Status](https://app.travis-ci.com/nathan-osman/go-sunrise.svg?branch=master)](https://app.travis-ci.com/nathan-osman/go-sunrise) +[![Coverage Status](https://coveralls.io/repos/github/nathan-osman/go-sunrise/badge.svg?branch=master)](https://coveralls.io/github/nathan-osman/go-sunrise?branch=master) +[![Go Report Card](https://goreportcard.com/badge/github.com/nathan-osman/go-sunrise)](https://goreportcard.com/report/github.com/nathan-osman/go-sunrise) +[![GoDoc](https://godoc.org/github.com/nathan-osman/go-sunrise?status.svg)](https://godoc.org/github.com/nathan-osman/go-sunrise) +[![MIT License](http://img.shields.io/badge/license-MIT-9370d8.svg?style=flat)](http://opensource.org/licenses/MIT) + +Go package for calculating the sunrise and sunset times for a given location based on [this method](https://en.wikipedia.org/wiki/Sunrise_equation#Complete_calculation_on_Earth). + +### Usage + +To calculate sunrise and sunset times, you will need the following information: + +- the date for which you wish to calculate the times +- the latitude and longitudinal coordinates of the location + +Begin by importing the package: + + import "github.com/nathan-osman/go-sunrise" + +Next, feed the information into the SunriseSunset() method: + + rise, set := sunrise.SunriseSunset( + 43.65, -79.38, // Toronto, CA + 2000, time.January, 1, // 2000-01-01 + ) + +The two return values will be the sunrise and sunset times for the location on the given day as time.Time values. If sun does not rise or set, both return values will be time.Time{}. diff --git a/vendor/github.com/nathan-osman/go-sunrise/anomaly.go b/vendor/github.com/nathan-osman/go-sunrise/anomaly.go new file mode 100644 index 0000000..901b998 --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/anomaly.go @@ -0,0 +1,15 @@ +package sunrise + +import ( + "math" +) + +// SolarMeanAnomaly calculates the angle of the sun relative to the earth for +// the specified Julian day. +func SolarMeanAnomaly(d float64) float64 { + v := math.Remainder(357.5291+0.98560028*(d-J2000), 360) + if v < 0 { + v += 360 + } + return v +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/center.go b/vendor/github.com/nathan-osman/go-sunrise/center.go new file mode 100644 index 0000000..404a572 --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/center.go @@ -0,0 +1,18 @@ +package sunrise + +import ( + "math" +) + +// EquationOfCenter calculates the angular difference between the position of +// the earth in its elliptical orbit and the position it would occupy in a +// circular orbit for the given mean anomaly. +func EquationOfCenter(solarAnomaly float64) float64 { + var ( + anomalyInRad = solarAnomaly * (math.Pi / 180) + anomalySin = math.Sin(anomalyInRad) + anomaly2Sin = math.Sin(2 * anomalyInRad) + anomaly3Sin = math.Sin(3 * anomalyInRad) + ) + return 1.9148*anomalySin + 0.0200*anomaly2Sin + 0.0003*anomaly3Sin +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/const.go b/vendor/github.com/nathan-osman/go-sunrise/const.go new file mode 100644 index 0000000..381d0b6 --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/const.go @@ -0,0 +1,14 @@ +package sunrise + +import ( + "math" +) + +const ( + // Degree provides a precise fraction for converting between degrees and + // radians. + Degree = math.Pi / 180 + + // J2000 is the Julian date for January 1, 2000, 12:00:00 TT. + J2000 = 2451545 +) diff --git a/vendor/github.com/nathan-osman/go-sunrise/declination.go b/vendor/github.com/nathan-osman/go-sunrise/declination.go new file mode 100644 index 0000000..4c8780b --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/declination.go @@ -0,0 +1,12 @@ +package sunrise + +import ( + "math" +) + +// Declination calculates one of the two angles required to locate a point on +// the celestial sphere in the equatorial coordinate system. The ecliptic +// longitude parameter must be in degrees. +func Declination(eclipticLongitude float64) float64 { + return math.Asin(math.Sin(eclipticLongitude*Degree)*0.39779) / Degree +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/elevation.go b/vendor/github.com/nathan-osman/go-sunrise/elevation.go new file mode 100644 index 0000000..32a956c --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/elevation.go @@ -0,0 +1,54 @@ +package sunrise + +import ( + "math" + "time" +) + +// TimeOfElevation calculates the times of day when the sun is at a given elevation +// above the horizon on a given day at the specified location. +// Returns time.Time{} if there sun does not reach the elevation +func TimeOfElevation(latitude, longitude, elevation float64, year int, month time.Month, day int) (time.Time, time.Time) { + var ( + d = MeanSolarNoon(longitude, year, month, day) + solarAnomaly = SolarMeanAnomaly(d) + equationOfCenter = EquationOfCenter(solarAnomaly) + eclipticLongitude = EclipticLongitude(solarAnomaly, equationOfCenter, d) + solarTransit = SolarTransit(d, solarAnomaly, eclipticLongitude) + declination = Declination(eclipticLongitude) + // https://solarsena.com/solar-elevation-angle-altitude/ + numerator = math.Sin(elevation*Degree) - (math.Sin(latitude*Degree) * math.Sin(declination*Degree)) + denominator = math.Cos(latitude*Degree) * math.Cos(declination*Degree) + hourAngle = math.Acos(numerator / denominator) + frac = hourAngle / (2 * math.Pi) + morning = solarTransit - frac + evening = solarTransit + frac + ) + + // Check for cases where the sun never reaches the given elevation. + if math.IsNaN(hourAngle) { + return time.Time{}, time.Time{} + } + + return JulianDayToTime(morning), JulianDayToTime(evening) +} + +// Elevation calculates the angle of the sun above the horizon at a given moment +// at the specified location. +func Elevation(latitude, longitude float64, when time.Time) float64 { + var ( + d = MeanSolarNoon(longitude, when.Year(), when.Month(), when.Day()) + solarAnomaly = SolarMeanAnomaly(d) + equationOfCenter = EquationOfCenter(solarAnomaly) + eclipticLongitude = EclipticLongitude(solarAnomaly, equationOfCenter, d) + solarTransit = SolarTransit(d, solarAnomaly, eclipticLongitude) + declination = Declination(eclipticLongitude) + frac = solarTransit - TimeToJulianDay(when) + hourAngle = 2 * math.Pi * frac + // https://solarsena.com/solar-elevation-angle-altitude/ + firstPart = math.Sin(latitude*Degree) * math.Sin(declination*Degree) + secondPart = math.Cos(latitude*Degree) * math.Cos(declination*Degree) * math.Cos(hourAngle) + ) + + return math.Asin(firstPart+secondPart) / Degree +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/hourangle.go b/vendor/github.com/nathan-osman/go-sunrise/hourangle.go new file mode 100644 index 0000000..2e371e9 --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/hourangle.go @@ -0,0 +1,29 @@ +package sunrise + +import ( + "math" +) + +// HourAngle calculates the second of the two angles required to locate a point +// on the celestial sphere in the equatorial coordinate system. +func HourAngle(latitude, declination float64) float64 { + var ( + latitudeRad = latitude * Degree + declinationRad = declination * Degree + numerator = -0.01449 - math.Sin(latitudeRad)*math.Sin(declinationRad) + denominator = math.Cos(latitudeRad) * math.Cos(declinationRad) + ) + + // Check for no sunrise/sunset + if numerator/denominator > 1 { + // Sun never rises + return math.MaxFloat64 + } + + if numerator/denominator < -1 { + // Sun never sets + return -1 * math.MaxFloat64 + } + + return math.Acos(numerator/denominator) / Degree +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/julian.go b/vendor/github.com/nathan-osman/go-sunrise/julian.go new file mode 100644 index 0000000..2ef41e8 --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/julian.go @@ -0,0 +1,20 @@ +package sunrise + +import ( + "time" +) + +const ( + secondsInADay = 86400 + unixEpochJulianDay = 2440587.5 +) + +// TimeToJulianDay converts a time.Time into a Julian day. +func TimeToJulianDay(t time.Time) float64 { + return float64(t.Unix())/secondsInADay + unixEpochJulianDay +} + +// JulianDayToTime converts a Julian day into a time.Time. +func JulianDayToTime(d float64) time.Time { + return time.Unix(int64((d-unixEpochJulianDay)*secondsInADay), 0).UTC() +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/longitude.go b/vendor/github.com/nathan-osman/go-sunrise/longitude.go new file mode 100644 index 0000000..5e158c8 --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/longitude.go @@ -0,0 +1,11 @@ +package sunrise + +import ( + "math" +) + +// EclipticLongitude calculates the angular distance of the earth along the +// ecliptic. +func EclipticLongitude(solarAnomaly, equationOfCenter, d float64) float64 { + return math.Mod(solarAnomaly+equationOfCenter+180+ArgumentOfPerihelion(d), 360) +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/noon.go b/vendor/github.com/nathan-osman/go-sunrise/noon.go new file mode 100644 index 0000000..36c1814 --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/noon.go @@ -0,0 +1,12 @@ +package sunrise + +import ( + "time" +) + +// MeanSolarNoon calculates the time at which the sun is at its highest +// altitude. The returned time is in Julian days. +func MeanSolarNoon(longitude float64, year int, month time.Month, day int) float64 { + t := time.Date(year, month, day, 12, 0, 0, 0, time.UTC) + return TimeToJulianDay(t) - longitude/360 +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/perihelion.go b/vendor/github.com/nathan-osman/go-sunrise/perihelion.go new file mode 100644 index 0000000..ca92875 --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/perihelion.go @@ -0,0 +1,7 @@ +package sunrise + +// ArgumentOfPerihelion calculates the argument of periapsis for the earth on +// the given Julian day. +func ArgumentOfPerihelion(d float64) float64 { + return 102.93005 + 0.3179526*(d-2451545)/36525 +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/round.go b/vendor/github.com/nathan-osman/go-sunrise/round.go new file mode 100644 index 0000000..928809e --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/round.go @@ -0,0 +1,14 @@ +package sunrise + +import "math" + +// DefaultPlaces specifies the default precision for rounding. +const DefaultPlaces = 5 + +// Round takes the provided float and rounds it to the specified number of +// decimal places. This function is adapted from user korya on GitHub +// (https://gist.github.com/DavidVaini/10308388#gistcomment-1391788). +func Round(f float64, places int) float64 { + shift := math.Pow(10, float64(places)) + return math.Floor(f*shift+.5) / shift +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/sunrise.go b/vendor/github.com/nathan-osman/go-sunrise/sunrise.go new file mode 100644 index 0000000..ec7655b --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/sunrise.go @@ -0,0 +1,31 @@ +package sunrise + +import ( + "math" + "time" +) + +// SunriseSunset calculates when the sun will rise and when it will set on the +// given day at the specified location. +// Returns time.Time{} if there sun does not rise or set +func SunriseSunset(latitude, longitude float64, year int, month time.Month, day int) (time.Time, time.Time) { + var ( + d = MeanSolarNoon(longitude, year, month, day) + solarAnomaly = SolarMeanAnomaly(d) + equationOfCenter = EquationOfCenter(solarAnomaly) + eclipticLongitude = EclipticLongitude(solarAnomaly, equationOfCenter, d) + solarTransit = SolarTransit(d, solarAnomaly, eclipticLongitude) + declination = Declination(eclipticLongitude) + hourAngle = HourAngle(latitude, declination) + frac = hourAngle / 360 + sunrise = solarTransit - frac + sunset = solarTransit + frac + ) + + // Check for no sunrise, no sunset + if hourAngle == math.MaxFloat64 || hourAngle == -1*math.MaxFloat64 { + return time.Time{}, time.Time{} + } + + return JulianDayToTime(sunrise), JulianDayToTime(sunset) +} diff --git a/vendor/github.com/nathan-osman/go-sunrise/transit.go b/vendor/github.com/nathan-osman/go-sunrise/transit.go new file mode 100644 index 0000000..8e2c845 --- /dev/null +++ b/vendor/github.com/nathan-osman/go-sunrise/transit.go @@ -0,0 +1,12 @@ +package sunrise + +import ( + "math" +) + +// SolarTransit calculates the Julian data for the local true solar transit. +func SolarTransit(d, solarAnomaly, eclipticLongitude float64) float64 { + equationOfTime := 0.0053*math.Sin(solarAnomaly*Degree) - + 0.0069*math.Sin(2*eclipticLongitude*Degree) + return d + equationOfTime +} diff --git a/vendor/golang.org/x/exp/typeparams/LICENSE b/vendor/golang.org/x/exp/typeparams/LICENSE new file mode 100644 index 0000000..6a66aea --- /dev/null +++ b/vendor/golang.org/x/exp/typeparams/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/exp/typeparams/common.go b/vendor/golang.org/x/exp/typeparams/common.go new file mode 100644 index 0000000..7f867cf --- /dev/null +++ b/vendor/golang.org/x/exp/typeparams/common.go @@ -0,0 +1,182 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package typeparams contains common utilities for writing tools that interact +// with generic Go code, as introduced with Go 1.18. +// +// Many of the types and functions in this package are proxies for the new APIs +// introduced in the standard library with Go 1.18. For example, the +// typeparams.Union type is an alias for go/types.Union, and the ForTypeSpec +// function returns the value of the go/ast.TypeSpec.TypeParams field. At Go +// versions older than 1.18 these helpers are implemented as stubs, allowing +// users of this package to write code that handles generic constructs inline, +// even if the Go version being used to compile does not support generics. +// +// Additionally, this package contains common utilities for working with the +// new generic constructs, to supplement the standard library APIs. Notably, +// the NormalTerms API computes a minimal representation of the structural +// restrictions on a type parameter. In the future, these supplemental APIs may +// be available in the standard library.. +package typeparams + +import ( + "go/ast" + "go/token" + "go/types" +) + +// Enabled reports whether type parameters are enabled in the current build +// environment. +func Enabled() bool { + return enabled +} + +// UnpackIndexExpr extracts data from AST nodes that represent index +// expressions. +// +// For an ast.IndexExpr, the resulting indices slice will contain exactly one +// index expression. For an ast.IndexListExpr (go1.18+), it may have a variable +// number of index expressions. +// +// For nodes that don't represent index expressions, the first return value of +// UnpackIndexExpr will be nil. +func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) { + switch e := n.(type) { + case *ast.IndexExpr: + return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack + case *IndexListExpr: + return e.X, e.Lbrack, e.Indices, e.Rbrack + } + return nil, token.NoPos, nil, token.NoPos +} + +// PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on +// the cardinality of indices. Calling PackIndexExpr with len(indices) == 0 +// will panic. +func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr { + switch len(indices) { + case 0: + panic("empty indices") + case 1: + return &ast.IndexExpr{ + X: x, + Lbrack: lbrack, + Index: indices[0], + Rbrack: rbrack, + } + default: + return &IndexListExpr{ + X: x, + Lbrack: lbrack, + Indices: indices, + Rbrack: rbrack, + } + } +} + +// IsTypeParam reports whether t is a type parameter. +func IsTypeParam(t types.Type) bool { + _, ok := t.(*TypeParam) + return ok +} + +// OriginMethod returns the origin method associated with the method fn. For +// methods on a non-generic receiver base type, this is just fn. However, for +// methods with a generic receiver, OriginMethod returns the corresponding +// method in the method set of the origin type. +// +// As a special case, if fn is not a method (has no receiver), OriginMethod +// returns fn. +func OriginMethod(fn *types.Func) *types.Func { + recv := fn.Type().(*types.Signature).Recv() + if recv == nil { + return fn + } + base := recv.Type() + p, isPtr := base.(*types.Pointer) + if isPtr { + base = p.Elem() + } + named, isNamed := base.(*types.Named) + if !isNamed { + // Receiver is a *types.Interface. + return fn + } + if ForNamed(named).Len() == 0 { + // Receiver base has no type parameters, so we can avoid the lookup below. + return fn + } + orig := NamedTypeOrigin(named) + gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name()) + return gfn.(*types.Func) +} + +// GenericAssignableTo is a generalization of types.AssignableTo that +// implements the following rule for uninstantiated generic types: +// +// If V and T are generic named types, then V is considered assignable to T if, +// for every possible instantation of V[A_1, ..., A_N], the instantiation +// T[A_1, ..., A_N] is valid and V[A_1, ..., A_N] implements T[A_1, ..., A_N]. +// +// If T has structural constraints, they must be satisfied by V. +// +// For example, consider the following type declarations: +// +// type Interface[T any] interface { +// Accept(T) +// } +// +// type Container[T any] struct { +// Element T +// } +// +// func (c Container[T]) Accept(t T) { c.Element = t } +// +// In this case, GenericAssignableTo reports that instantiations of Container +// are assignable to the corresponding instantiation of Interface. +func GenericAssignableTo(ctxt *Context, V, T types.Type) bool { + // If V and T are not both named, or do not have matching non-empty type + // parameter lists, fall back on types.AssignableTo. + + VN, Vnamed := V.(*types.Named) + TN, Tnamed := T.(*types.Named) + if !Vnamed || !Tnamed { + return types.AssignableTo(V, T) + } + + vtparams := ForNamed(VN) + ttparams := ForNamed(TN) + if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || NamedTypeArgs(VN).Len() != 0 || NamedTypeArgs(TN).Len() != 0 { + return types.AssignableTo(V, T) + } + + // V and T have the same (non-zero) number of type params. Instantiate both + // with the type parameters of V. This must always succeed for V, and will + // succeed for T if and only if the type set of each type parameter of V is a + // subset of the type set of the corresponding type parameter of T, meaning + // that every instantiation of V corresponds to a valid instantiation of T. + + // Minor optimization: ensure we share a context across the two + // instantiations below. + if ctxt == nil { + ctxt = NewContext() + } + + var targs []types.Type + for i := 0; i < vtparams.Len(); i++ { + targs = append(targs, vtparams.At(i)) + } + + vinst, err := Instantiate(ctxt, V, targs, true) + if err != nil { + panic("type parameters should satisfy their own constraints") + } + + tinst, err := Instantiate(ctxt, T, targs, true) + if err != nil { + return false + } + + return types.AssignableTo(vinst, tinst) +} diff --git a/vendor/golang.org/x/exp/typeparams/normalize.go b/vendor/golang.org/x/exp/typeparams/normalize.go new file mode 100644 index 0000000..6cf71f0 --- /dev/null +++ b/vendor/golang.org/x/exp/typeparams/normalize.go @@ -0,0 +1,200 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typeparams + +import ( + "errors" + "fmt" + "go/types" + "os" + "strings" +) + +const debug = false + +// ErrEmptyTypeSet is returned if a type set computation results in a type set +// with no types. +var ErrEmptyTypeSet = errors.New("empty type set") + +// NormalTerms returns a slice of terms representing the normalized structural +// type restrictions of a type, if any. +// +// For all types whose underlying type is not *types.TypeParam, +// *types.Interface, or *types.Union, this is just a single term with Tilde() +// == false and Type() == typ. For types whose underlying type is +// *types.TypeParam, *types.Interface, and *types.Union, see below. +// +// Structural type restrictions of a type parameter are created via +// non-interface types embedded in its constraint interface (directly, or via a +// chain of interface embeddings). For example, in the declaration type T[P +// interface{~int; m()}] int is the structural restriction of the type +// parameter P is ~int. +// +// With interface embedding and unions, the specification of structural type +// restrictions may be arbitrarily complex. For example, consider the +// following: +// +// type A interface{ ~string|~[]byte } +// +// type B interface{ int|string } +// +// type C interface { ~string|~int } +// +// type T[P interface{ A|B; C }] int +// +// In this example, the structural type restriction of P is ~string|int: A|B +// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, +// which when intersected with C (~string|~int) yields ~string|int. +// +// NormalTerms computes these expansions and reductions, producing a +// "normalized" form of the embeddings. A structural restriction is normalized +// if it is a single union containing no interface terms, and is minimal in the +// sense that removing any term changes the set of types satisfying the +// constraint. It is left as a proof for the reader that, modulo sorting, there +// is exactly one such normalized form. +// +// Because the minimal representation always takes this form, NormalTerms +// returns a slice of tilde terms corresponding to the terms of the union in +// the normalized structural restriction. An error is returned if the type is +// invalid, exceeds complexity bounds, or has an empty type set. In the latter +// case, NormalTerms returns ErrEmptyTypeSet. +// +// NormalTerms makes no guarantees about the order of terms, except that it +// is deterministic. +func NormalTerms(typ types.Type) ([]*Term, error) { + if tparam, ok := typ.(*TypeParam); ok { + constraint := tparam.Constraint() + if constraint == nil { + return nil, fmt.Errorf("%s has nil constraint", tparam) + } + iface, _ := constraint.Underlying().(*types.Interface) + if iface == nil { + return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying()) + } + typ = iface + } + tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0) + if err != nil { + return nil, err + } + if tset.terms.isEmpty() { + return nil, ErrEmptyTypeSet + } + if tset.terms.isAll() { + return nil, nil + } + var terms []*Term + for _, term := range tset.terms { + terms = append(terms, NewTerm(term.tilde, term.typ)) + } + return terms, nil +} + +// A termSet holds the normalized set of terms for a given type. +// +// The name termSet is intentionally distinct from 'type set': a type set is +// all types that implement a type (and includes method restrictions), whereas +// a term set just represents the structural restrictions on a type. +type termSet struct { + complete bool + terms termlist +} + +func indentf(depth int, format string, args ...interface{}) { + fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...) +} + +func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { + if t == nil { + panic("nil type") + } + + if debug { + indentf(depth, "%s", t.String()) + defer func() { + if err != nil { + indentf(depth, "=> %s", err) + } else { + indentf(depth, "=> %s", res.terms.String()) + } + }() + } + + const maxTermCount = 100 + if tset, ok := seen[t]; ok { + if !tset.complete { + return nil, fmt.Errorf("cycle detected in the declaration of %s", t) + } + return tset, nil + } + + // Mark the current type as seen to avoid infinite recursion. + tset := new(termSet) + defer func() { + tset.complete = true + }() + seen[t] = tset + + switch u := t.Underlying().(type) { + case *types.Interface: + // The term set of an interface is the intersection of the term sets of its + // embedded types. + tset.terms = allTermlist + for i := 0; i < u.NumEmbeddeds(); i++ { + embedded := u.EmbeddedType(i) + if _, ok := embedded.Underlying().(*TypeParam); ok { + return nil, fmt.Errorf("invalid embedded type %T", embedded) + } + tset2, err := computeTermSetInternal(embedded, seen, depth+1) + if err != nil { + return nil, err + } + tset.terms = tset.terms.intersect(tset2.terms) + } + case *Union: + // The term set of a union is the union of term sets of its terms. + tset.terms = nil + for i := 0; i < u.Len(); i++ { + t := u.Term(i) + var terms termlist + switch t.Type().Underlying().(type) { + case *types.Interface: + tset2, err := computeTermSetInternal(t.Type(), seen, depth+1) + if err != nil { + return nil, err + } + terms = tset2.terms + case *TypeParam, *Union: + // A stand-alone type parameter or union is not permitted as union + // term. + return nil, fmt.Errorf("invalid union term %T", t) + default: + if t.Type() == types.Typ[types.Invalid] { + continue + } + terms = termlist{{t.Tilde(), t.Type()}} + } + tset.terms = tset.terms.union(terms) + if len(tset.terms) > maxTermCount { + return nil, fmt.Errorf("exceeded max term count %d", maxTermCount) + } + } + case *TypeParam: + panic("unreachable") + default: + // For all other types, the term set is just a single non-tilde term + // holding the type itself. + if u != types.Typ[types.Invalid] { + tset.terms = termlist{{false, t}} + } + } + return tset, nil +} + +// under is a facade for the go/types internal function of the same name. It is +// used by typeterm.go. +func under(t types.Type) types.Type { + return t.Underlying() +} diff --git a/vendor/golang.org/x/exp/typeparams/termlist.go b/vendor/golang.org/x/exp/typeparams/termlist.go new file mode 100644 index 0000000..6f88bfa --- /dev/null +++ b/vendor/golang.org/x/exp/typeparams/termlist.go @@ -0,0 +1,172 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by copytermlist.go DO NOT EDIT. + +package typeparams + +import ( + "bytes" + "go/types" +) + +// A termlist represents the type set represented by the union +// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn. +// A termlist is in normal form if all terms are disjoint. +// termlist operations don't require the operands to be in +// normal form. +type termlist []*term + +// allTermlist represents the set of all types. +// It is in normal form. +var allTermlist = termlist{new(term)} + +// String prints the termlist exactly (without normalization). +func (xl termlist) String() string { + if len(xl) == 0 { + return "∅" + } + var buf bytes.Buffer + for i, x := range xl { + if i > 0 { + buf.WriteString(" ∪ ") + } + buf.WriteString(x.String()) + } + return buf.String() +} + +// isEmpty reports whether the termlist xl represents the empty set of types. +func (xl termlist) isEmpty() bool { + // If there's a non-nil term, the entire list is not empty. + // If the termlist is in normal form, this requires at most + // one iteration. + for _, x := range xl { + if x != nil { + return false + } + } + return true +} + +// isAll reports whether the termlist xl represents the set of all types. +func (xl termlist) isAll() bool { + // If there's a 𝓤 term, the entire list is 𝓤. + // If the termlist is in normal form, this requires at most + // one iteration. + for _, x := range xl { + if x != nil && x.typ == nil { + return true + } + } + return false +} + +// norm returns the normal form of xl. +func (xl termlist) norm() termlist { + // Quadratic algorithm, but good enough for now. + // TODO(gri) fix asymptotic performance + used := make([]bool, len(xl)) + var rl termlist + for i, xi := range xl { + if xi == nil || used[i] { + continue + } + for j := i + 1; j < len(xl); j++ { + xj := xl[j] + if xj == nil || used[j] { + continue + } + if u1, u2 := xi.union(xj); u2 == nil { + // If we encounter a 𝓤 term, the entire list is 𝓤. + // Exit early. + // (Note that this is not just an optimization; + // if we continue, we may end up with a 𝓤 term + // and other terms and the result would not be + // in normal form.) + if u1.typ == nil { + return allTermlist + } + xi = u1 + used[j] = true // xj is now unioned into xi - ignore it in future iterations + } + } + rl = append(rl, xi) + } + return rl +} + +// If the type set represented by xl is specified by a single (non-𝓤) term, +// singleType returns that type. Otherwise it returns nil. +func (xl termlist) singleType() types.Type { + if nl := xl.norm(); len(nl) == 1 { + return nl[0].typ // if nl.isAll() then typ is nil, which is ok + } + return nil +} + +// union returns the union xl ∪ yl. +func (xl termlist) union(yl termlist) termlist { + return append(xl, yl...).norm() +} + +// intersect returns the intersection xl ∩ yl. +func (xl termlist) intersect(yl termlist) termlist { + if xl.isEmpty() || yl.isEmpty() { + return nil + } + + // Quadratic algorithm, but good enough for now. + // TODO(gri) fix asymptotic performance + var rl termlist + for _, x := range xl { + for _, y := range yl { + if r := x.intersect(y); r != nil { + rl = append(rl, r) + } + } + } + return rl.norm() +} + +// equal reports whether xl and yl represent the same type set. +func (xl termlist) equal(yl termlist) bool { + // TODO(gri) this should be more efficient + return xl.subsetOf(yl) && yl.subsetOf(xl) +} + +// includes reports whether t ∈ xl. +func (xl termlist) includes(t types.Type) bool { + for _, x := range xl { + if x.includes(t) { + return true + } + } + return false +} + +// supersetOf reports whether y ⊆ xl. +func (xl termlist) supersetOf(y *term) bool { + for _, x := range xl { + if y.subsetOf(x) { + return true + } + } + return false +} + +// subsetOf reports whether xl ⊆ yl. +func (xl termlist) subsetOf(yl termlist) bool { + if yl.isEmpty() { + return xl.isEmpty() + } + + // each term x of xl must be a subset of yl + for _, x := range xl { + if !yl.supersetOf(x) { + return false // x is not a subset yl + } + } + return true +} diff --git a/vendor/golang.org/x/exp/typeparams/typeparams_go117.go b/vendor/golang.org/x/exp/typeparams/typeparams_go117.go new file mode 100644 index 0000000..c1da793 --- /dev/null +++ b/vendor/golang.org/x/exp/typeparams/typeparams_go117.go @@ -0,0 +1,201 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.18 + +package typeparams + +import ( + "go/ast" + "go/token" + "go/types" +) + +const enabled = false + +func unsupported() { + panic("type parameters are unsupported at this go version") +} + +// IndexListExpr is a placeholder type, as type parameters are not supported at +// this Go version. Its methods panic on use. +type IndexListExpr struct { + ast.Expr + X ast.Expr // expression + Lbrack token.Pos // position of "[" + Indices []ast.Expr // index expressions + Rbrack token.Pos // position of "]" +} + +func (*IndexListExpr) Pos() token.Pos { unsupported(); return token.NoPos } +func (*IndexListExpr) End() token.Pos { unsupported(); return token.NoPos } + +// ForTypeSpec returns an empty field list, as type parameters on not supported +// at this Go version. +func ForTypeSpec(*ast.TypeSpec) *ast.FieldList { + return nil +} + +// ForFuncType returns an empty field list, as type parameters are not +// supported at this Go version. +func ForFuncType(*ast.FuncType) *ast.FieldList { + return nil +} + +// TypeParam is a placeholder type, as type parameters are not supported at +// this Go version. Its methods panic on use. +type TypeParam struct{ types.Type } + +func (*TypeParam) String() string { unsupported(); return "" } +func (*TypeParam) Underlying() types.Type { unsupported(); return nil } +func (*TypeParam) Index() int { unsupported(); return 0 } +func (*TypeParam) Constraint() types.Type { unsupported(); return nil } +func (*TypeParam) SetConstraint(types.Type) { unsupported() } +func (*TypeParam) Obj() *types.TypeName { unsupported(); return nil } + +// TypeParamList is a placeholder for an empty type parameter list. +type TypeParamList struct{} + +func (*TypeParamList) Len() int { return 0 } +func (*TypeParamList) At(int) *TypeParam { unsupported(); return nil } + +// TypeList is a placeholder for an empty type list. +type TypeList struct{} + +func (*TypeList) Len() int { return 0 } +func (*TypeList) At(int) types.Type { unsupported(); return nil } + +// NewTypeParam is unsupported at this Go version, and panics. +func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam { + unsupported() + return nil +} + +// NewSignatureType calls types.NewSignature, panicking if recvTypeParams or +// typeParams is non-empty. +func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature { + if len(recvTypeParams) != 0 || len(typeParams) != 0 { + unsupported() + } + return types.NewSignature(recv, params, results, variadic) +} + +// ForSignature returns an empty slice. +func ForSignature(*types.Signature) *TypeParamList { + return nil +} + +// RecvTypeParams returns a nil slice. +func RecvTypeParams(sig *types.Signature) *TypeParamList { + return nil +} + +// IsComparable returns false, as no interfaces are type-restricted at this Go +// version. +func IsComparable(*types.Interface) bool { + return false +} + +// IsMethodSet returns true, as no interfaces are type-restricted at this Go +// version. +func IsMethodSet(*types.Interface) bool { + return true +} + +// IsImplicit returns false, as no interfaces are implicit at this Go version. +func IsImplicit(*types.Interface) bool { + return false +} + +// MarkImplicit does nothing, because this Go version does not have implicit +// interfaces. +func MarkImplicit(*types.Interface) {} + +// ForNamed returns an empty type parameter list, as type parameters are not +// supported at this Go version. +func ForNamed(*types.Named) *TypeParamList { + return nil +} + +// SetForNamed panics if tparams is non-empty. +func SetForNamed(_ *types.Named, tparams []*TypeParam) { + if len(tparams) > 0 { + unsupported() + } +} + +// NamedTypeArgs returns nil. +func NamedTypeArgs(*types.Named) *TypeList { + return nil +} + +// NamedTypeOrigin is the identity method at this Go version. +func NamedTypeOrigin(named *types.Named) types.Type { + return named +} + +// Term holds information about a structural type restriction. +type Term struct { + tilde bool + typ types.Type +} + +func (m *Term) Tilde() bool { return m.tilde } +func (m *Term) Type() types.Type { return m.typ } +func (m *Term) String() string { + pre := "" + if m.tilde { + pre = "~" + } + return pre + m.typ.String() +} + +// NewTerm creates a new placeholder term type. +func NewTerm(tilde bool, typ types.Type) *Term { + return &Term{tilde, typ} +} + +// Union is a placeholder type, as type parameters are not supported at this Go +// version. Its methods panic on use. +type Union struct{ types.Type } + +func (*Union) String() string { unsupported(); return "" } +func (*Union) Underlying() types.Type { unsupported(); return nil } +func (*Union) Len() int { return 0 } +func (*Union) Term(i int) *Term { unsupported(); return nil } + +// NewUnion is unsupported at this Go version, and panics. +func NewUnion(terms []*Term) *Union { + unsupported() + return nil +} + +// InitInstances is a noop at this Go version. +func InitInstances(*types.Info) {} + +// Instance is a placeholder type, as type parameters are not supported at this +// Go version. +type Instance struct { + TypeArgs *TypeList + Type types.Type +} + +// GetInstances returns a nil map, as type parameters are not supported at this +// Go version. +func GetInstances(info *types.Info) map[*ast.Ident]Instance { return nil } + +// Context is a placeholder type, as type parameters are not supported at +// this Go version. +type Context struct{} + +// NewContext returns a placeholder Context instance. +func NewContext() *Context { + return &Context{} +} + +// Instantiate is unsupported on this Go version, and panics. +func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) { + unsupported() + return nil, nil +} diff --git a/vendor/golang.org/x/exp/typeparams/typeparams_go118.go b/vendor/golang.org/x/exp/typeparams/typeparams_go118.go new file mode 100644 index 0000000..0b35449 --- /dev/null +++ b/vendor/golang.org/x/exp/typeparams/typeparams_go118.go @@ -0,0 +1,147 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.18 + +package typeparams + +import ( + "go/ast" + "go/types" +) + +const enabled = true + +// IndexListExpr is an alias for ast.IndexListExpr. +type IndexListExpr = ast.IndexListExpr + +// ForTypeSpec returns n.TypeParams. +func ForTypeSpec(n *ast.TypeSpec) *ast.FieldList { + if n == nil { + return nil + } + return n.TypeParams +} + +// ForFuncType returns n.TypeParams. +func ForFuncType(n *ast.FuncType) *ast.FieldList { + if n == nil { + return nil + } + return n.TypeParams +} + +// TypeParam is an alias for types.TypeParam +type TypeParam = types.TypeParam + +// TypeParamList is an alias for types.TypeParamList +type TypeParamList = types.TypeParamList + +// TypeList is an alias for types.TypeList +type TypeList = types.TypeList + +// NewTypeParam calls types.NewTypeParam. +func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam { + return types.NewTypeParam(name, constraint) +} + +// NewSignatureType calls types.NewSignatureType. +func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature { + return types.NewSignatureType(recv, recvTypeParams, typeParams, params, results, variadic) +} + +// ForSignature returns sig.TypeParams() +func ForSignature(sig *types.Signature) *TypeParamList { + return sig.TypeParams() +} + +// RecvTypeParams returns sig.RecvTypeParams(). +func RecvTypeParams(sig *types.Signature) *TypeParamList { + return sig.RecvTypeParams() +} + +// IsComparable calls iface.IsComparable(). +func IsComparable(iface *types.Interface) bool { + return iface.IsComparable() +} + +// IsMethodSet calls iface.IsMethodSet(). +func IsMethodSet(iface *types.Interface) bool { + return iface.IsMethodSet() +} + +// IsImplicit calls iface.IsImplicit(). +func IsImplicit(iface *types.Interface) bool { + return iface.IsImplicit() +} + +// MarkImplicit calls iface.MarkImplicit(). +func MarkImplicit(iface *types.Interface) { + iface.MarkImplicit() +} + +// ForNamed extracts the (possibly empty) type parameter object list from +// named. +func ForNamed(named *types.Named) *TypeParamList { + return named.TypeParams() +} + +// SetForNamed sets the type params tparams on n. Each tparam must be of +// dynamic type *types.TypeParam. +func SetForNamed(n *types.Named, tparams []*TypeParam) { + n.SetTypeParams(tparams) +} + +// NamedTypeArgs returns named.TypeArgs(). +func NamedTypeArgs(named *types.Named) *TypeList { + return named.TypeArgs() +} + +// NamedTypeOrigin returns named.Orig(). +func NamedTypeOrigin(named *types.Named) types.Type { + return named.Origin() +} + +// Term is an alias for types.Term. +type Term = types.Term + +// NewTerm calls types.NewTerm. +func NewTerm(tilde bool, typ types.Type) *Term { + return types.NewTerm(tilde, typ) +} + +// Union is an alias for types.Union +type Union = types.Union + +// NewUnion calls types.NewUnion. +func NewUnion(terms []*Term) *Union { + return types.NewUnion(terms) +} + +// InitInstances initializes info to record information about type and function +// instances. +func InitInstances(info *types.Info) { + info.Instances = make(map[*ast.Ident]types.Instance) +} + +// Instance is an alias for types.Instance. +type Instance = types.Instance + +// GetInstances returns info.Instances. +func GetInstances(info *types.Info) map[*ast.Ident]Instance { + return info.Instances +} + +// Context is an alias for types.Context. +type Context = types.Context + +// NewContext calls types.NewContext. +func NewContext() *Context { + return types.NewContext() +} + +// Instantiate calls types.Instantiate. +func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) { + return types.Instantiate(ctxt, typ, targs, validate) +} diff --git a/vendor/golang.org/x/exp/typeparams/typeterm.go b/vendor/golang.org/x/exp/typeparams/typeterm.go new file mode 100644 index 0000000..7350bb7 --- /dev/null +++ b/vendor/golang.org/x/exp/typeparams/typeterm.go @@ -0,0 +1,169 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by copytermlist.go DO NOT EDIT. + +package typeparams + +import "go/types" + +// A term describes elementary type sets: +// +// ∅: (*term)(nil) == ∅ // set of no types (empty set) +// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse) +// T: &term{false, T} == {T} // set of type T +// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t +type term struct { + tilde bool // valid if typ != nil + typ types.Type +} + +func (x *term) String() string { + switch { + case x == nil: + return "∅" + case x.typ == nil: + return "𝓤" + case x.tilde: + return "~" + x.typ.String() + default: + return x.typ.String() + } +} + +// equal reports whether x and y represent the same type set. +func (x *term) equal(y *term) bool { + // easy cases + switch { + case x == nil || y == nil: + return x == y + case x.typ == nil || y.typ == nil: + return x.typ == y.typ + } + // ∅ ⊂ x, y ⊂ 𝓤 + + return x.tilde == y.tilde && types.Identical(x.typ, y.typ) +} + +// union returns the union x ∪ y: zero, one, or two non-nil terms. +func (x *term) union(y *term) (_, _ *term) { + // easy cases + switch { + case x == nil && y == nil: + return nil, nil // ∅ ∪ ∅ == ∅ + case x == nil: + return y, nil // ∅ ∪ y == y + case y == nil: + return x, nil // x ∪ ∅ == x + case x.typ == nil: + return x, nil // 𝓤 ∪ y == 𝓤 + case y.typ == nil: + return y, nil // x ∪ 𝓤 == 𝓤 + } + // ∅ ⊂ x, y ⊂ 𝓤 + + if x.disjoint(y) { + return x, y // x ∪ y == (x, y) if x ∩ y == ∅ + } + // x.typ == y.typ + + // ~t ∪ ~t == ~t + // ~t ∪ T == ~t + // T ∪ ~t == ~t + // T ∪ T == T + if x.tilde || !y.tilde { + return x, nil + } + return y, nil +} + +// intersect returns the intersection x ∩ y. +func (x *term) intersect(y *term) *term { + // easy cases + switch { + case x == nil || y == nil: + return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅ + case x.typ == nil: + return y // 𝓤 ∩ y == y + case y.typ == nil: + return x // x ∩ 𝓤 == x + } + // ∅ ⊂ x, y ⊂ 𝓤 + + if x.disjoint(y) { + return nil // x ∩ y == ∅ if x ∩ y == ∅ + } + // x.typ == y.typ + + // ~t ∩ ~t == ~t + // ~t ∩ T == T + // T ∩ ~t == T + // T ∩ T == T + if !x.tilde || y.tilde { + return x + } + return y +} + +// includes reports whether t ∈ x. +func (x *term) includes(t types.Type) bool { + // easy cases + switch { + case x == nil: + return false // t ∈ ∅ == false + case x.typ == nil: + return true // t ∈ 𝓤 == true + } + // ∅ ⊂ x ⊂ 𝓤 + + u := t + if x.tilde { + u = under(u) + } + return types.Identical(x.typ, u) +} + +// subsetOf reports whether x ⊆ y. +func (x *term) subsetOf(y *term) bool { + // easy cases + switch { + case x == nil: + return true // ∅ ⊆ y == true + case y == nil: + return false // x ⊆ ∅ == false since x != ∅ + case y.typ == nil: + return true // x ⊆ 𝓤 == true + case x.typ == nil: + return false // 𝓤 ⊆ y == false since y != 𝓤 + } + // ∅ ⊂ x, y ⊂ 𝓤 + + if x.disjoint(y) { + return false // x ⊆ y == false if x ∩ y == ∅ + } + // x.typ == y.typ + + // ~t ⊆ ~t == true + // ~t ⊆ T == false + // T ⊆ ~t == true + // T ⊆ T == true + return !x.tilde || y.tilde +} + +// disjoint reports whether x ∩ y == ∅. +// x.typ and y.typ must not be nil. +func (x *term) disjoint(y *term) bool { + if debug && (x.typ == nil || y.typ == nil) { + panic("invalid argument(s)") + } + ux := x.typ + if y.tilde { + ux = under(ux) + } + uy := y.typ + if x.tilde { + uy = under(uy) + } + return !types.Identical(ux, uy) +} diff --git a/vendor/golang.org/x/mod/LICENSE b/vendor/golang.org/x/mod/LICENSE new file mode 100644 index 0000000..2a7cf70 --- /dev/null +++ b/vendor/golang.org/x/mod/LICENSE @@ -0,0 +1,27 @@ +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/mod/PATENTS b/vendor/golang.org/x/mod/PATENTS new file mode 100644 index 0000000..7330990 --- /dev/null +++ b/vendor/golang.org/x/mod/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go b/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go new file mode 100644 index 0000000..150f887 --- /dev/null +++ b/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go @@ -0,0 +1,78 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package lazyregexp is a thin wrapper over regexp, allowing the use of global +// regexp variables without forcing them to be compiled at init. +package lazyregexp + +import ( + "os" + "regexp" + "strings" + "sync" +) + +// Regexp is a wrapper around [regexp.Regexp], where the underlying regexp will be +// compiled the first time it is needed. +type Regexp struct { + str string + once sync.Once + rx *regexp.Regexp +} + +func (r *Regexp) re() *regexp.Regexp { + r.once.Do(r.build) + return r.rx +} + +func (r *Regexp) build() { + r.rx = regexp.MustCompile(r.str) + r.str = "" +} + +func (r *Regexp) FindSubmatch(s []byte) [][]byte { + return r.re().FindSubmatch(s) +} + +func (r *Regexp) FindStringSubmatch(s string) []string { + return r.re().FindStringSubmatch(s) +} + +func (r *Regexp) FindStringSubmatchIndex(s string) []int { + return r.re().FindStringSubmatchIndex(s) +} + +func (r *Regexp) ReplaceAllString(src, repl string) string { + return r.re().ReplaceAllString(src, repl) +} + +func (r *Regexp) FindString(s string) string { + return r.re().FindString(s) +} + +func (r *Regexp) FindAllString(s string, n int) []string { + return r.re().FindAllString(s, n) +} + +func (r *Regexp) MatchString(s string) bool { + return r.re().MatchString(s) +} + +func (r *Regexp) SubexpNames() []string { + return r.re().SubexpNames() +} + +var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test") + +// New creates a new lazy regexp, delaying the compiling work until it is first +// needed. If the code is being run as part of tests, the regexp compiling will +// happen immediately. +func New(str string) *Regexp { + lr := &Regexp{str: str} + if inTest { + // In tests, always compile the regexps early. + lr.re() + } + return lr +} diff --git a/vendor/golang.org/x/mod/module/module.go b/vendor/golang.org/x/mod/module/module.go new file mode 100644 index 0000000..739c13f --- /dev/null +++ b/vendor/golang.org/x/mod/module/module.go @@ -0,0 +1,840 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package module defines the module.Version type along with support code. +// +// The [module.Version] type is a simple Path, Version pair: +// +// type Version struct { +// Path string +// Version string +// } +// +// There are no restrictions imposed directly by use of this structure, +// but additional checking functions, most notably [Check], verify that +// a particular path, version pair is valid. +// +// # Escaped Paths +// +// Module paths appear as substrings of file system paths +// (in the download cache) and of web server URLs in the proxy protocol. +// In general we cannot rely on file systems to be case-sensitive, +// nor can we rely on web servers, since they read from file systems. +// That is, we cannot rely on the file system to keep rsc.io/QUOTE +// and rsc.io/quote separate. Windows and macOS don't. +// Instead, we must never require two different casings of a file path. +// Because we want the download cache to match the proxy protocol, +// and because we want the proxy protocol to be possible to serve +// from a tree of static files (which might be stored on a case-insensitive +// file system), the proxy protocol must never require two different casings +// of a URL path either. +// +// One possibility would be to make the escaped form be the lowercase +// hexadecimal encoding of the actual path bytes. This would avoid ever +// needing different casings of a file path, but it would be fairly illegible +// to most programmers when those paths appeared in the file system +// (including in file paths in compiler errors and stack traces) +// in web server logs, and so on. Instead, we want a safe escaped form that +// leaves most paths unaltered. +// +// The safe escaped form is to replace every uppercase letter +// with an exclamation mark followed by the letter's lowercase equivalent. +// +// For example, +// +// github.com/Azure/azure-sdk-for-go -> github.com/!azure/azure-sdk-for-go. +// github.com/GoogleCloudPlatform/cloudsql-proxy -> github.com/!google!cloud!platform/cloudsql-proxy +// github.com/Sirupsen/logrus -> github.com/!sirupsen/logrus. +// +// Import paths that avoid upper-case letters are left unchanged. +// Note that because import paths are ASCII-only and avoid various +// problematic punctuation (like : < and >), the escaped form is also ASCII-only +// and avoids the same problematic punctuation. +// +// Import paths have never allowed exclamation marks, so there is no +// need to define how to escape a literal !. +// +// # Unicode Restrictions +// +// Today, paths are disallowed from using Unicode. +// +// Although paths are currently disallowed from using Unicode, +// we would like at some point to allow Unicode letters as well, to assume that +// file systems and URLs are Unicode-safe (storing UTF-8), and apply +// the !-for-uppercase convention for escaping them in the file system. +// But there are at least two subtle considerations. +// +// First, note that not all case-fold equivalent distinct runes +// form an upper/lower pair. +// For example, U+004B ('K'), U+006B ('k'), and U+212A ('K' for Kelvin) +// are three distinct runes that case-fold to each other. +// When we do add Unicode letters, we must not assume that upper/lower +// are the only case-equivalent pairs. +// Perhaps the Kelvin symbol would be disallowed entirely, for example. +// Or perhaps it would escape as "!!k", or perhaps as "(212A)". +// +// Second, it would be nice to allow Unicode marks as well as letters, +// but marks include combining marks, and then we must deal not +// only with case folding but also normalization: both U+00E9 ('é') +// and U+0065 U+0301 ('e' followed by combining acute accent) +// look the same on the page and are treated by some file systems +// as the same path. If we do allow Unicode marks in paths, there +// must be some kind of normalization to allow only one canonical +// encoding of any character used in an import path. +package module + +// IMPORTANT NOTE +// +// This file essentially defines the set of valid import paths for the go command. +// There are many subtle considerations, including Unicode ambiguity, +// security, network, and file system representations. +// +// This file also defines the set of valid module path and version combinations, +// another topic with many subtle considerations. +// +// Changes to the semantics in this file require approval from rsc. + +import ( + "cmp" + "errors" + "fmt" + "path" + "slices" + "strings" + "unicode" + "unicode/utf8" + + "golang.org/x/mod/semver" +) + +// A Version (for clients, a module.Version) is defined by a module path and version pair. +// These are stored in their plain (unescaped) form. +type Version struct { + // Path is a module path, like "golang.org/x/text" or "rsc.io/quote/v2". + Path string + + // Version is usually a semantic version in canonical form. + // There are three exceptions to this general rule. + // First, the top-level target of a build has no specific version + // and uses Version = "". + // Second, during MVS calculations the version "none" is used + // to represent the decision to take no version of a given module. + // Third, filesystem paths found in "replace" directives are + // represented by a path with an empty version. + Version string `json:",omitempty"` +} + +// String returns a representation of the Version suitable for logging +// (Path@Version, or just Path if Version is empty). +func (m Version) String() string { + if m.Version == "" { + return m.Path + } + return m.Path + "@" + m.Version +} + +// A ModuleError indicates an error specific to a module. +type ModuleError struct { + Path string + Version string + Err error +} + +// VersionError returns a [ModuleError] derived from a [Version] and error, +// or err itself if it is already such an error. +func VersionError(v Version, err error) error { + var mErr *ModuleError + if errors.As(err, &mErr) && mErr.Path == v.Path && mErr.Version == v.Version { + return err + } + return &ModuleError{ + Path: v.Path, + Version: v.Version, + Err: err, + } +} + +func (e *ModuleError) Error() string { + if v, ok := e.Err.(*InvalidVersionError); ok { + return fmt.Sprintf("%s@%s: invalid %s: %v", e.Path, v.Version, v.noun(), v.Err) + } + if e.Version != "" { + return fmt.Sprintf("%s@%s: %v", e.Path, e.Version, e.Err) + } + return fmt.Sprintf("module %s: %v", e.Path, e.Err) +} + +func (e *ModuleError) Unwrap() error { return e.Err } + +// An InvalidVersionError indicates an error specific to a version, with the +// module path unknown or specified externally. +// +// A [ModuleError] may wrap an InvalidVersionError, but an InvalidVersionError +// must not wrap a ModuleError. +type InvalidVersionError struct { + Version string + Pseudo bool + Err error +} + +// noun returns either "version" or "pseudo-version", depending on whether +// e.Version is a pseudo-version. +func (e *InvalidVersionError) noun() string { + if e.Pseudo { + return "pseudo-version" + } + return "version" +} + +func (e *InvalidVersionError) Error() string { + return fmt.Sprintf("%s %q invalid: %s", e.noun(), e.Version, e.Err) +} + +func (e *InvalidVersionError) Unwrap() error { return e.Err } + +// An InvalidPathError indicates a module, import, or file path doesn't +// satisfy all naming constraints. See [CheckPath], [CheckImportPath], +// and [CheckFilePath] for specific restrictions. +type InvalidPathError struct { + Kind string // "module", "import", or "file" + Path string + Err error +} + +func (e *InvalidPathError) Error() string { + return fmt.Sprintf("malformed %s path %q: %v", e.Kind, e.Path, e.Err) +} + +func (e *InvalidPathError) Unwrap() error { return e.Err } + +// Check checks that a given module path, version pair is valid. +// In addition to the path being a valid module path +// and the version being a valid semantic version, +// the two must correspond. +// For example, the path "yaml/v2" only corresponds to +// semantic versions beginning with "v2.". +func Check(path, version string) error { + if err := CheckPath(path); err != nil { + return err + } + if !semver.IsValid(version) { + return &ModuleError{ + Path: path, + Err: &InvalidVersionError{Version: version, Err: errors.New("not a semantic version")}, + } + } + _, pathMajor, _ := SplitPathVersion(path) + if err := CheckPathMajor(version, pathMajor); err != nil { + return &ModuleError{Path: path, Err: err} + } + return nil +} + +// firstPathOK reports whether r can appear in the first element of a module path. +// The first element of the path must be an LDH domain name, at least for now. +// To avoid case ambiguity, the domain name must be entirely lower case. +func firstPathOK(r rune) bool { + return r == '-' || r == '.' || + '0' <= r && r <= '9' || + 'a' <= r && r <= 'z' +} + +// modPathOK reports whether r can appear in a module path element. +// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~. +// +// This matches what "go get" has historically recognized in import paths, +// and avoids confusing sequences like '%20' or '+' that would change meaning +// if used in a URL. +// +// TODO(rsc): We would like to allow Unicode letters, but that requires additional +// care in the safe encoding (see "escaped paths" above). +func modPathOK(r rune) bool { + if r < utf8.RuneSelf { + return r == '-' || r == '.' || r == '_' || r == '~' || + '0' <= r && r <= '9' || + 'A' <= r && r <= 'Z' || + 'a' <= r && r <= 'z' + } + return false +} + +// importPathOK reports whether r can appear in a package import path element. +// +// Import paths are intermediate between module paths and file paths: we +// disallow characters that would be confusing or ambiguous as arguments to +// 'go get' (such as '@' and ' ' ), but allow certain characters that are +// otherwise-unambiguous on the command line and historically used for some +// binary names (such as '++' as a suffix for compiler binaries and wrappers). +func importPathOK(r rune) bool { + return modPathOK(r) || r == '+' +} + +// fileNameOK reports whether r can appear in a file name. +// For now we allow all Unicode letters but otherwise limit to pathOK plus a few more punctuation characters. +// If we expand the set of allowed characters here, we have to +// work harder at detecting potential case-folding and normalization collisions. +// See note about "escaped paths" above. +func fileNameOK(r rune) bool { + if r < utf8.RuneSelf { + // Entire set of ASCII punctuation, from which we remove characters: + // ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ + // We disallow some shell special characters: " ' * < > ? ` | + // (Note that some of those are disallowed by the Windows file system as well.) + // We also disallow path separators / : and \ (fileNameOK is only called on path element characters). + // We allow spaces (U+0020) in file names. + const allowed = "!#$%&()+,-.=@[]^_{}~ " + if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' { + return true + } + return strings.ContainsRune(allowed, r) + } + // It may be OK to add more ASCII punctuation here, but only carefully. + // For example Windows disallows < > \, and macOS disallows :, so we must not allow those. + return unicode.IsLetter(r) +} + +// CheckPath checks that a module path is valid. +// A valid module path is a valid import path, as checked by [CheckImportPath], +// with three additional constraints. +// First, the leading path element (up to the first slash, if any), +// by convention a domain name, must contain only lower-case ASCII letters, +// ASCII digits, dots (U+002E), and dashes (U+002D); +// it must contain at least one dot and cannot start with a dash. +// Second, for a final path element of the form /vN, where N looks numeric +// (ASCII digits and dots) must not begin with a leading zero, must not be /v1, +// and must not contain any dots. For paths beginning with "gopkg.in/", +// this second requirement is replaced by a requirement that the path +// follow the gopkg.in server's conventions. +// Third, no path element may begin with a dot. +func CheckPath(path string) (err error) { + defer func() { + if err != nil { + err = &InvalidPathError{Kind: "module", Path: path, Err: err} + } + }() + + if err := checkPath(path, modulePath); err != nil { + return err + } + i := strings.Index(path, "/") + if i < 0 { + i = len(path) + } + if i == 0 { + return fmt.Errorf("leading slash") + } + if !strings.Contains(path[:i], ".") { + return fmt.Errorf("missing dot in first path element") + } + if path[0] == '-' { + return fmt.Errorf("leading dash in first path element") + } + for _, r := range path[:i] { + if !firstPathOK(r) { + return fmt.Errorf("invalid char %q in first path element", r) + } + } + if _, _, ok := SplitPathVersion(path); !ok { + return fmt.Errorf("invalid version") + } + return nil +} + +// CheckImportPath checks that an import path is valid. +// +// A valid import path consists of one or more valid path elements +// separated by slashes (U+002F). (It must not begin with nor end in a slash.) +// +// A valid path element is a non-empty string made up of +// ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~. +// It must not end with a dot (U+002E), nor contain two dots in a row. +// +// The element prefix up to the first dot must not be a reserved file name +// on Windows, regardless of case (CON, com1, NuL, and so on). The element +// must not have a suffix of a tilde followed by one or more ASCII digits +// (to exclude paths elements that look like Windows short-names). +// +// CheckImportPath may be less restrictive in the future, but see the +// top-level package documentation for additional information about +// subtleties of Unicode. +func CheckImportPath(path string) error { + if err := checkPath(path, importPath); err != nil { + return &InvalidPathError{Kind: "import", Path: path, Err: err} + } + return nil +} + +// pathKind indicates what kind of path we're checking. Module paths, +// import paths, and file paths have different restrictions. +type pathKind int + +const ( + modulePath pathKind = iota + importPath + filePath +) + +// checkPath checks that a general path is valid. kind indicates what +// specific constraints should be applied. +// +// checkPath returns an error describing why the path is not valid. +// Because these checks apply to module, import, and file paths, +// and because other checks may be applied, the caller is expected to wrap +// this error with [InvalidPathError]. +func checkPath(path string, kind pathKind) error { + if !utf8.ValidString(path) { + return fmt.Errorf("invalid UTF-8") + } + if path == "" { + return fmt.Errorf("empty string") + } + if path[0] == '-' && kind != filePath { + return fmt.Errorf("leading dash") + } + if strings.Contains(path, "//") { + return fmt.Errorf("double slash") + } + if path[len(path)-1] == '/' { + return fmt.Errorf("trailing slash") + } + elemStart := 0 + for i, r := range path { + if r == '/' { + if err := checkElem(path[elemStart:i], kind); err != nil { + return err + } + elemStart = i + 1 + } + } + if err := checkElem(path[elemStart:], kind); err != nil { + return err + } + return nil +} + +// checkElem checks whether an individual path element is valid. +func checkElem(elem string, kind pathKind) error { + if elem == "" { + return fmt.Errorf("empty path element") + } + if strings.Count(elem, ".") == len(elem) { + return fmt.Errorf("invalid path element %q", elem) + } + if elem[0] == '.' && kind == modulePath { + return fmt.Errorf("leading dot in path element") + } + if elem[len(elem)-1] == '.' { + return fmt.Errorf("trailing dot in path element") + } + for _, r := range elem { + ok := false + switch kind { + case modulePath: + ok = modPathOK(r) + case importPath: + ok = importPathOK(r) + case filePath: + ok = fileNameOK(r) + default: + panic(fmt.Sprintf("internal error: invalid kind %v", kind)) + } + if !ok { + return fmt.Errorf("invalid char %q", r) + } + } + + // Windows disallows a bunch of path elements, sadly. + // See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file + short := elem + if i := strings.Index(short, "."); i >= 0 { + short = short[:i] + } + for _, bad := range badWindowsNames { + if strings.EqualFold(bad, short) { + return fmt.Errorf("%q disallowed as path element component on Windows", short) + } + } + + if kind == filePath { + // don't check for Windows short-names in file names. They're + // only an issue for import paths. + return nil + } + + // Reject path components that look like Windows short-names. + // Those usually end in a tilde followed by one or more ASCII digits. + if tilde := strings.LastIndexByte(short, '~'); tilde >= 0 && tilde < len(short)-1 { + suffix := short[tilde+1:] + suffixIsDigits := true + for _, r := range suffix { + if r < '0' || r > '9' { + suffixIsDigits = false + break + } + } + if suffixIsDigits { + return fmt.Errorf("trailing tilde and digits in path element") + } + } + + return nil +} + +// CheckFilePath checks that a slash-separated file path is valid. +// The definition of a valid file path is the same as the definition +// of a valid import path except that the set of allowed characters is larger: +// all Unicode letters, ASCII digits, the ASCII space character (U+0020), +// and the ASCII punctuation characters +// “!#$%&()+,-.=@[]^_{}~”. +// (The excluded punctuation characters, " * < > ? ` ' | / \ and :, +// have special meanings in certain shells or operating systems.) +// +// CheckFilePath may be less restrictive in the future, but see the +// top-level package documentation for additional information about +// subtleties of Unicode. +func CheckFilePath(path string) error { + if err := checkPath(path, filePath); err != nil { + return &InvalidPathError{Kind: "file", Path: path, Err: err} + } + return nil +} + +// badWindowsNames are the reserved file path elements on Windows. +// See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file +var badWindowsNames = []string{ + "CON", + "PRN", + "AUX", + "NUL", + "COM1", + "COM2", + "COM3", + "COM4", + "COM5", + "COM6", + "COM7", + "COM8", + "COM9", + "LPT1", + "LPT2", + "LPT3", + "LPT4", + "LPT5", + "LPT6", + "LPT7", + "LPT8", + "LPT9", +} + +// SplitPathVersion returns prefix and major version such that prefix+pathMajor == path +// and version is either empty or "/vN" for N >= 2. +// As a special case, gopkg.in paths are recognized directly; +// they require ".vN" instead of "/vN", and for all N, not just N >= 2. +// SplitPathVersion returns with ok = false when presented with +// a path whose last path element does not satisfy the constraints +// applied by [CheckPath], such as "example.com/pkg/v1" or "example.com/pkg/v1.2". +func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) { + if strings.HasPrefix(path, "gopkg.in/") { + return splitGopkgIn(path) + } + + i := len(path) + dot := false + for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9' || path[i-1] == '.') { + if path[i-1] == '.' { + dot = true + } + i-- + } + if i <= 1 || i == len(path) || path[i-1] != 'v' || path[i-2] != '/' { + return path, "", true + } + prefix, pathMajor = path[:i-2], path[i-2:] + if dot || len(pathMajor) <= 2 || pathMajor[2] == '0' || pathMajor == "/v1" { + return path, "", false + } + return prefix, pathMajor, true +} + +// splitGopkgIn is like SplitPathVersion but only for gopkg.in paths. +func splitGopkgIn(path string) (prefix, pathMajor string, ok bool) { + if !strings.HasPrefix(path, "gopkg.in/") { + return path, "", false + } + i := len(path) + if strings.HasSuffix(path, "-unstable") { + i -= len("-unstable") + } + for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9') { + i-- + } + if i <= 1 || path[i-1] != 'v' || path[i-2] != '.' { + // All gopkg.in paths must end in vN for some N. + return path, "", false + } + prefix, pathMajor = path[:i-2], path[i-2:] + if len(pathMajor) <= 2 || pathMajor[2] == '0' && pathMajor != ".v0" { + return path, "", false + } + return prefix, pathMajor, true +} + +// MatchPathMajor reports whether the semantic version v +// matches the path major version pathMajor. +// +// MatchPathMajor returns true if and only if [CheckPathMajor] returns nil. +func MatchPathMajor(v, pathMajor string) bool { + return CheckPathMajor(v, pathMajor) == nil +} + +// CheckPathMajor returns a non-nil error if the semantic version v +// does not match the path major version pathMajor. +func CheckPathMajor(v, pathMajor string) error { + // TODO(jayconrod): return errors or panic for invalid inputs. This function + // (and others) was covered by integration tests for cmd/go, and surrounding + // code protected against invalid inputs like non-canonical versions. + if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") { + pathMajor = strings.TrimSuffix(pathMajor, "-unstable") + } + if strings.HasPrefix(v, "v0.0.0-") && pathMajor == ".v1" { + // Allow old bug in pseudo-versions that generated v0.0.0- pseudoversion for gopkg .v1. + // For example, gopkg.in/yaml.v2@v2.2.1's go.mod requires gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405. + return nil + } + m := semver.Major(v) + if pathMajor == "" { + if m == "v0" || m == "v1" || semver.Build(v) == "+incompatible" { + return nil + } + pathMajor = "v0 or v1" + } else if pathMajor[0] == '/' || pathMajor[0] == '.' { + if m == pathMajor[1:] { + return nil + } + pathMajor = pathMajor[1:] + } + return &InvalidVersionError{ + Version: v, + Err: fmt.Errorf("should be %s, not %s", pathMajor, semver.Major(v)), + } +} + +// PathMajorPrefix returns the major-version tag prefix implied by pathMajor. +// An empty PathMajorPrefix allows either v0 or v1. +// +// Note that [MatchPathMajor] may accept some versions that do not actually begin +// with this prefix: namely, it accepts a 'v0.0.0-' prefix for a '.v1' +// pathMajor, even though that pathMajor implies 'v1' tagging. +func PathMajorPrefix(pathMajor string) string { + if pathMajor == "" { + return "" + } + if pathMajor[0] != '/' && pathMajor[0] != '.' { + panic("pathMajor suffix " + pathMajor + " passed to PathMajorPrefix lacks separator") + } + if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") { + pathMajor = strings.TrimSuffix(pathMajor, "-unstable") + } + m := pathMajor[1:] + if m != semver.Major(m) { + panic("pathMajor suffix " + pathMajor + "passed to PathMajorPrefix is not a valid major version") + } + return m +} + +// CanonicalVersion returns the canonical form of the version string v. +// It is the same as [semver.Canonical] except that it preserves the special build suffix "+incompatible". +func CanonicalVersion(v string) string { + cv := semver.Canonical(v) + if semver.Build(v) == "+incompatible" { + cv += "+incompatible" + } + return cv +} + +// Sort sorts the list by Path, breaking ties by comparing [Version] fields. +// The Version fields are interpreted as semantic versions (using [semver.Compare]) +// optionally followed by a tie-breaking suffix introduced by a slash character, +// like in "v0.0.1/go.mod". +func Sort(list []Version) { + slices.SortFunc(list, func(i, j Version) int { + if i.Path != j.Path { + return strings.Compare(i.Path, j.Path) + } + // To help go.sum formatting, allow version/file. + // Compare semver prefix by semver rules, + // file by string order. + vi := i.Version + vj := j.Version + var fi, fj string + if k := strings.Index(vi, "/"); k >= 0 { + vi, fi = vi[:k], vi[k:] + } + if k := strings.Index(vj, "/"); k >= 0 { + vj, fj = vj[:k], vj[k:] + } + if vi != vj { + return semver.Compare(vi, vj) + } + return cmp.Compare(fi, fj) + }) +} + +// EscapePath returns the escaped form of the given module path. +// It fails if the module path is invalid. +func EscapePath(path string) (escaped string, err error) { + if err := CheckPath(path); err != nil { + return "", err + } + + return escapeString(path) +} + +// EscapeVersion returns the escaped form of the given module version. +// Versions are allowed to be in non-semver form but must be valid file names +// and not contain exclamation marks. +func EscapeVersion(v string) (escaped string, err error) { + if err := checkElem(v, filePath); err != nil || strings.Contains(v, "!") { + return "", &InvalidVersionError{ + Version: v, + Err: fmt.Errorf("disallowed version string"), + } + } + return escapeString(v) +} + +func escapeString(s string) (escaped string, err error) { + haveUpper := false + for _, r := range s { + if r == '!' || r >= utf8.RuneSelf { + // This should be disallowed by CheckPath, but diagnose anyway. + // The correctness of the escaping loop below depends on it. + return "", fmt.Errorf("internal error: inconsistency in EscapePath") + } + if 'A' <= r && r <= 'Z' { + haveUpper = true + } + } + + if !haveUpper { + return s, nil + } + + var buf []byte + for _, r := range s { + if 'A' <= r && r <= 'Z' { + buf = append(buf, '!', byte(r+'a'-'A')) + } else { + buf = append(buf, byte(r)) + } + } + return string(buf), nil +} + +// UnescapePath returns the module path for the given escaped path. +// It fails if the escaped path is invalid or describes an invalid path. +func UnescapePath(escaped string) (path string, err error) { + path, ok := unescapeString(escaped) + if !ok { + return "", fmt.Errorf("invalid escaped module path %q", escaped) + } + if err := CheckPath(path); err != nil { + return "", fmt.Errorf("invalid escaped module path %q: %v", escaped, err) + } + return path, nil +} + +// UnescapeVersion returns the version string for the given escaped version. +// It fails if the escaped form is invalid or describes an invalid version. +// Versions are allowed to be in non-semver form but must be valid file names +// and not contain exclamation marks. +func UnescapeVersion(escaped string) (v string, err error) { + v, ok := unescapeString(escaped) + if !ok { + return "", fmt.Errorf("invalid escaped version %q", escaped) + } + if err := checkElem(v, filePath); err != nil { + return "", fmt.Errorf("invalid escaped version %q: %v", v, err) + } + return v, nil +} + +func unescapeString(escaped string) (string, bool) { + var buf []byte + + bang := false + for _, r := range escaped { + if r >= utf8.RuneSelf { + return "", false + } + if bang { + bang = false + if r < 'a' || 'z' < r { + return "", false + } + buf = append(buf, byte(r+'A'-'a')) + continue + } + if r == '!' { + bang = true + continue + } + if 'A' <= r && r <= 'Z' { + return "", false + } + buf = append(buf, byte(r)) + } + if bang { + return "", false + } + return string(buf), true +} + +// MatchPrefixPatterns reports whether any path prefix of target matches one of +// the glob patterns (as defined by [path.Match]) in the comma-separated globs +// list. This implements the algorithm used when matching a module path to the +// GOPRIVATE environment variable, as described by 'go help module-private'. +// +// It ignores any empty or malformed patterns in the list. +// Trailing slashes on patterns are ignored. +func MatchPrefixPatterns(globs, target string) bool { + for globs != "" { + // Extract next non-empty glob in comma-separated list. + var glob string + if before, after, ok := strings.Cut(globs, ","); ok { + glob, globs = before, after + } else { + glob, globs = globs, "" + } + glob = strings.TrimSuffix(glob, "/") + if glob == "" { + continue + } + + // A glob with N+1 path elements (N slashes) needs to be matched + // against the first N+1 path elements of target, + // which end just before the N+1'th slash. + n := strings.Count(glob, "/") + prefix := target + // Walk target, counting slashes, truncating at the N+1'th slash. + for i := 0; i < len(target); i++ { + if target[i] == '/' { + if n == 0 { + prefix = target[:i] + break + } + n-- + } + } + if n > 0 { + // Not enough prefix elements. + continue + } + matched, _ := path.Match(glob, prefix) + if matched { + return true + } + } + return false +} diff --git a/vendor/golang.org/x/mod/module/pseudo.go b/vendor/golang.org/x/mod/module/pseudo.go new file mode 100644 index 0000000..9cf19d3 --- /dev/null +++ b/vendor/golang.org/x/mod/module/pseudo.go @@ -0,0 +1,250 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Pseudo-versions +// +// Code authors are expected to tag the revisions they want users to use, +// including prereleases. However, not all authors tag versions at all, +// and not all commits a user might want to try will have tags. +// A pseudo-version is a version with a special form that allows us to +// address an untagged commit and order that version with respect to +// other versions we might encounter. +// +// A pseudo-version takes one of the general forms: +// +// (1) vX.0.0-yyyymmddhhmmss-abcdef123456 +// (2) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456 +// (3) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible +// (4) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456 +// (5) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible +// +// If there is no recently tagged version with the right major version vX, +// then form (1) is used, creating a space of pseudo-versions at the bottom +// of the vX version range, less than any tagged version, including the unlikely v0.0.0. +// +// If the most recent tagged version before the target commit is vX.Y.Z or vX.Y.Z+incompatible, +// then the pseudo-version uses form (2) or (3), making it a prerelease for the next +// possible semantic version after vX.Y.Z. The leading 0 segment in the prerelease string +// ensures that the pseudo-version compares less than possible future explicit prereleases +// like vX.Y.(Z+1)-rc1 or vX.Y.(Z+1)-1. +// +// If the most recent tagged version before the target commit is vX.Y.Z-pre or vX.Y.Z-pre+incompatible, +// then the pseudo-version uses form (4) or (5), making it a slightly later prerelease. + +package module + +import ( + "errors" + "fmt" + "strings" + "time" + + "golang.org/x/mod/internal/lazyregexp" + "golang.org/x/mod/semver" +) + +var pseudoVersionRE = lazyregexp.New(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$`) + +const PseudoVersionTimestampFormat = "20060102150405" + +// PseudoVersion returns a pseudo-version for the given major version ("v1") +// preexisting older tagged version ("" or "v1.2.3" or "v1.2.3-pre"), revision time, +// and revision identifier (usually a 12-byte commit hash prefix). +func PseudoVersion(major, older string, t time.Time, rev string) string { + if major == "" { + major = "v0" + } + segment := fmt.Sprintf("%s-%s", t.UTC().Format(PseudoVersionTimestampFormat), rev) + build := semver.Build(older) + older = semver.Canonical(older) + if older == "" { + return major + ".0.0-" + segment // form (1) + } + if semver.Prerelease(older) != "" { + return older + ".0." + segment + build // form (4), (5) + } + + // Form (2), (3). + // Extract patch from vMAJOR.MINOR.PATCH + i := strings.LastIndex(older, ".") + 1 + v, patch := older[:i], older[i:] + + // Reassemble. + return v + incDecimal(patch) + "-0." + segment + build +} + +// ZeroPseudoVersion returns a pseudo-version with a zero timestamp and +// revision, which may be used as a placeholder. +func ZeroPseudoVersion(major string) string { + return PseudoVersion(major, "", time.Time{}, "000000000000") +} + +// incDecimal returns the decimal string incremented by 1. +func incDecimal(decimal string) string { + // Scan right to left turning 9s to 0s until you find a digit to increment. + digits := []byte(decimal) + i := len(digits) - 1 + for ; i >= 0 && digits[i] == '9'; i-- { + digits[i] = '0' + } + if i >= 0 { + digits[i]++ + } else { + // digits is all zeros + digits[0] = '1' + digits = append(digits, '0') + } + return string(digits) +} + +// decDecimal returns the decimal string decremented by 1, or the empty string +// if the decimal is all zeroes. +func decDecimal(decimal string) string { + // Scan right to left turning 0s to 9s until you find a digit to decrement. + digits := []byte(decimal) + i := len(digits) - 1 + for ; i >= 0 && digits[i] == '0'; i-- { + digits[i] = '9' + } + if i < 0 { + // decimal is all zeros + return "" + } + if i == 0 && digits[i] == '1' && len(digits) > 1 { + digits = digits[1:] + } else { + digits[i]-- + } + return string(digits) +} + +// IsPseudoVersion reports whether v is a pseudo-version. +func IsPseudoVersion(v string) bool { + return strings.Count(v, "-") >= 2 && semver.IsValid(v) && pseudoVersionRE.MatchString(v) +} + +// IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base, +// timestamp, and revision, as returned by [ZeroPseudoVersion]. +func IsZeroPseudoVersion(v string) bool { + return v == ZeroPseudoVersion(semver.Major(v)) +} + +// PseudoVersionTime returns the time stamp of the pseudo-version v. +// It returns an error if v is not a pseudo-version or if the time stamp +// embedded in the pseudo-version is not a valid time. +func PseudoVersionTime(v string) (time.Time, error) { + _, timestamp, _, _, err := parsePseudoVersion(v) + if err != nil { + return time.Time{}, err + } + t, err := time.Parse("20060102150405", timestamp) + if err != nil { + return time.Time{}, &InvalidVersionError{ + Version: v, + Pseudo: true, + Err: fmt.Errorf("malformed time %q", timestamp), + } + } + return t, nil +} + +// PseudoVersionRev returns the revision identifier of the pseudo-version v. +// It returns an error if v is not a pseudo-version. +func PseudoVersionRev(v string) (rev string, err error) { + _, _, rev, _, err = parsePseudoVersion(v) + return +} + +// PseudoVersionBase returns the canonical parent version, if any, upon which +// the pseudo-version v is based. +// +// If v has no parent version (that is, if it is "vX.0.0-[…]"), +// PseudoVersionBase returns the empty string and a nil error. +func PseudoVersionBase(v string) (string, error) { + base, _, _, build, err := parsePseudoVersion(v) + if err != nil { + return "", err + } + + switch pre := semver.Prerelease(base); pre { + case "": + // vX.0.0-yyyymmddhhmmss-abcdef123456 → "" + if build != "" { + // Pseudo-versions of the form vX.0.0-yyyymmddhhmmss-abcdef123456+incompatible + // are nonsensical: the "vX.0.0-" prefix implies that there is no parent tag, + // but the "+incompatible" suffix implies that the major version of + // the parent tag is not compatible with the module's import path. + // + // There are a few such entries in the index generated by proxy.golang.org, + // but we believe those entries were generated by the proxy itself. + return "", &InvalidVersionError{ + Version: v, + Pseudo: true, + Err: fmt.Errorf("lacks base version, but has build metadata %q", build), + } + } + return "", nil + + case "-0": + // vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z + // vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z+incompatible + base = strings.TrimSuffix(base, pre) + i := strings.LastIndexByte(base, '.') + if i < 0 { + panic("base from parsePseudoVersion missing patch number: " + base) + } + patch := decDecimal(base[i+1:]) + if patch == "" { + // vX.0.0-0 is invalid, but has been observed in the wild in the index + // generated by requests to proxy.golang.org. + // + // NOTE(bcmills): I cannot find a historical bug that accounts for + // pseudo-versions of this form, nor have I seen such versions in any + // actual go.mod files. If we find actual examples of this form and a + // reasonable theory of how they came into existence, it seems fine to + // treat them as equivalent to vX.0.0 (especially since the invalid + // pseudo-versions have lower precedence than the real ones). For now, we + // reject them. + return "", &InvalidVersionError{ + Version: v, + Pseudo: true, + Err: fmt.Errorf("version before %s would have negative patch number", base), + } + } + return base[:i+1] + patch + build, nil + + default: + // vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z-pre + // vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z-pre+incompatible + if !strings.HasSuffix(base, ".0") { + panic(`base from parsePseudoVersion missing ".0" before date: ` + base) + } + return strings.TrimSuffix(base, ".0") + build, nil + } +} + +var errPseudoSyntax = errors.New("syntax error") + +func parsePseudoVersion(v string) (base, timestamp, rev, build string, err error) { + if !IsPseudoVersion(v) { + return "", "", "", "", &InvalidVersionError{ + Version: v, + Pseudo: true, + Err: errPseudoSyntax, + } + } + build = semver.Build(v) + v = strings.TrimSuffix(v, build) + j := strings.LastIndex(v, "-") + v, rev = v[:j], v[j+1:] + i := strings.LastIndex(v, "-") + if j := strings.LastIndex(v, "."); j > i { + base = v[:j] // "vX.Y.Z-pre.0" or "vX.Y.(Z+1)-0" + timestamp = v[j+1:] + } else { + base = v[:i] // "vX.0.0" + timestamp = v[i+1:] + } + return base, timestamp, rev, build, nil +} diff --git a/vendor/golang.org/x/mod/semver/semver.go b/vendor/golang.org/x/mod/semver/semver.go new file mode 100644 index 0000000..824b282 --- /dev/null +++ b/vendor/golang.org/x/mod/semver/semver.go @@ -0,0 +1,407 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package semver implements comparison of semantic version strings. +// In this package, semantic version strings must begin with a leading "v", +// as in "v1.0.0". +// +// The general form of a semantic version string accepted by this package is +// +// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]] +// +// where square brackets indicate optional parts of the syntax; +// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros; +// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers +// using only alphanumeric characters and hyphens; and +// all-numeric PRERELEASE identifiers must not have leading zeros. +// +// This package follows Semantic Versioning 2.0.0 (see semver.org) +// with two exceptions. First, it requires the "v" prefix. Second, it recognizes +// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes) +// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0. +package semver + +import ( + "slices" + "strings" +) + +// parsed returns the parsed form of a semantic version string. +type parsed struct { + major string + minor string + patch string + short string + prerelease string + build string +} + +// IsValid reports whether v is a valid semantic version string. +func IsValid(v string) bool { + _, ok := parse(v) + return ok +} + +// Canonical returns the canonical formatting of the semantic version v. +// It fills in any missing .MINOR or .PATCH and discards build metadata. +// Two semantic versions compare equal only if their canonical formatting +// is an identical string. +// The canonical invalid semantic version is the empty string. +func Canonical(v string) string { + p, ok := parse(v) + if !ok { + return "" + } + if p.build != "" { + return v[:len(v)-len(p.build)] + } + if p.short != "" { + return v + p.short + } + return v +} + +// Major returns the major version prefix of the semantic version v. +// For example, Major("v2.1.0") == "v2". +// If v is an invalid semantic version string, Major returns the empty string. +func Major(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return v[:1+len(pv.major)] +} + +// MajorMinor returns the major.minor version prefix of the semantic version v. +// For example, MajorMinor("v2.1.0") == "v2.1". +// If v is an invalid semantic version string, MajorMinor returns the empty string. +func MajorMinor(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + i := 1 + len(pv.major) + if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor { + return v[:j] + } + return v[:i] + "." + pv.minor +} + +// Prerelease returns the prerelease suffix of the semantic version v. +// For example, Prerelease("v2.1.0-pre+meta") == "-pre". +// If v is an invalid semantic version string, Prerelease returns the empty string. +func Prerelease(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return pv.prerelease +} + +// Build returns the build suffix of the semantic version v. +// For example, Build("v2.1.0+meta") == "+meta". +// If v is an invalid semantic version string, Build returns the empty string. +func Build(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return pv.build +} + +// Compare returns an integer comparing two versions according to +// semantic version precedence. +// The result will be 0 if v == w, -1 if v < w, or +1 if v > w. +// +// An invalid semantic version string is considered less than a valid one. +// All invalid semantic version strings compare equal to each other. +func Compare(v, w string) int { + pv, ok1 := parse(v) + pw, ok2 := parse(w) + if !ok1 && !ok2 { + return 0 + } + if !ok1 { + return -1 + } + if !ok2 { + return +1 + } + if c := compareInt(pv.major, pw.major); c != 0 { + return c + } + if c := compareInt(pv.minor, pw.minor); c != 0 { + return c + } + if c := compareInt(pv.patch, pw.patch); c != 0 { + return c + } + return comparePrerelease(pv.prerelease, pw.prerelease) +} + +// Max canonicalizes its arguments and then returns the version string +// that compares greater. +// +// Deprecated: use [Compare] instead. In most cases, returning a canonicalized +// version is not expected or desired. +func Max(v, w string) string { + v = Canonical(v) + w = Canonical(w) + if Compare(v, w) > 0 { + return v + } + return w +} + +// ByVersion implements [sort.Interface] for sorting semantic version strings. +type ByVersion []string + +func (vs ByVersion) Len() int { return len(vs) } +func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] } +func (vs ByVersion) Less(i, j int) bool { return compareVersion(vs[i], vs[j]) < 0 } + +// Sort sorts a list of semantic version strings using [Compare] and falls back +// to use [strings.Compare] if both versions are considered equal. +func Sort(list []string) { + slices.SortFunc(list, compareVersion) +} + +func compareVersion(a, b string) int { + cmp := Compare(a, b) + if cmp != 0 { + return cmp + } + return strings.Compare(a, b) +} + +func parse(v string) (p parsed, ok bool) { + if v == "" || v[0] != 'v' { + return + } + p.major, v, ok = parseInt(v[1:]) + if !ok { + return + } + if v == "" { + p.minor = "0" + p.patch = "0" + p.short = ".0.0" + return + } + if v[0] != '.' { + ok = false + return + } + p.minor, v, ok = parseInt(v[1:]) + if !ok { + return + } + if v == "" { + p.patch = "0" + p.short = ".0" + return + } + if v[0] != '.' { + ok = false + return + } + p.patch, v, ok = parseInt(v[1:]) + if !ok { + return + } + if len(v) > 0 && v[0] == '-' { + p.prerelease, v, ok = parsePrerelease(v) + if !ok { + return + } + } + if len(v) > 0 && v[0] == '+' { + p.build, v, ok = parseBuild(v) + if !ok { + return + } + } + if v != "" { + ok = false + return + } + ok = true + return +} + +func parseInt(v string) (t, rest string, ok bool) { + if v == "" { + return + } + if v[0] < '0' || '9' < v[0] { + return + } + i := 1 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + if v[0] == '0' && i != 1 { + return + } + return v[:i], v[i:], true +} + +func parsePrerelease(v string) (t, rest string, ok bool) { + // "A pre-release version MAY be denoted by appending a hyphen and + // a series of dot separated identifiers immediately following the patch version. + // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. + // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes." + if v == "" || v[0] != '-' { + return + } + i := 1 + start := 1 + for i < len(v) && v[i] != '+' { + if !isIdentChar(v[i]) && v[i] != '.' { + return + } + if v[i] == '.' { + if start == i || isBadNum(v[start:i]) { + return + } + start = i + 1 + } + i++ + } + if start == i || isBadNum(v[start:i]) { + return + } + return v[:i], v[i:], true +} + +func parseBuild(v string) (t, rest string, ok bool) { + if v == "" || v[0] != '+' { + return + } + i := 1 + start := 1 + for i < len(v) { + if !isIdentChar(v[i]) && v[i] != '.' { + return + } + if v[i] == '.' { + if start == i { + return + } + start = i + 1 + } + i++ + } + if start == i { + return + } + return v[:i], v[i:], true +} + +func isIdentChar(c byte) bool { + return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' +} + +func isBadNum(v string) bool { + i := 0 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + return i == len(v) && i > 1 && v[0] == '0' +} + +func isNum(v string) bool { + i := 0 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + return i == len(v) +} + +func compareInt(x, y string) int { + if x == y { + return 0 + } + if len(x) < len(y) { + return -1 + } + if len(x) > len(y) { + return +1 + } + if x < y { + return -1 + } else { + return +1 + } +} + +func comparePrerelease(x, y string) int { + // "When major, minor, and patch are equal, a pre-release version has + // lower precedence than a normal version. + // Example: 1.0.0-alpha < 1.0.0. + // Precedence for two pre-release versions with the same major, minor, + // and patch version MUST be determined by comparing each dot separated + // identifier from left to right until a difference is found as follows: + // identifiers consisting of only digits are compared numerically and + // identifiers with letters or hyphens are compared lexically in ASCII + // sort order. Numeric identifiers always have lower precedence than + // non-numeric identifiers. A larger set of pre-release fields has a + // higher precedence than a smaller set, if all of the preceding + // identifiers are equal. + // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < + // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0." + if x == y { + return 0 + } + if x == "" { + return +1 + } + if y == "" { + return -1 + } + for x != "" && y != "" { + x = x[1:] // skip - or . + y = y[1:] // skip - or . + var dx, dy string + dx, x = nextIdent(x) + dy, y = nextIdent(y) + if dx != dy { + ix := isNum(dx) + iy := isNum(dy) + if ix != iy { + if ix { + return -1 + } else { + return +1 + } + } + if ix { + if len(dx) < len(dy) { + return -1 + } + if len(dx) > len(dy) { + return +1 + } + } + if dx < dy { + return -1 + } else { + return +1 + } + } + } + if x == "" { + return -1 + } else { + return +1 + } +} + +func nextIdent(x string) (dx, rest string) { + i := 0 + for i < len(x) && x[i] != '.' { + i++ + } + return x[:i], x[i:] +} diff --git a/vendor/golang.org/x/sync/LICENSE b/vendor/golang.org/x/sync/LICENSE new file mode 100644 index 0000000..2a7cf70 --- /dev/null +++ b/vendor/golang.org/x/sync/LICENSE @@ -0,0 +1,27 @@ +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/sync/PATENTS b/vendor/golang.org/x/sync/PATENTS new file mode 100644 index 0000000..7330990 --- /dev/null +++ b/vendor/golang.org/x/sync/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go new file mode 100644 index 0000000..c261a8e --- /dev/null +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -0,0 +1,151 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package errgroup provides synchronization, error propagation, and Context +// cancellation for groups of goroutines working on subtasks of a common task. +// +// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks +// returning errors. +package errgroup + +import ( + "context" + "fmt" + "sync" +) + +type token struct{} + +// A Group is a collection of goroutines working on subtasks that are part of +// the same overall task. A Group should not be reused for different tasks. +// +// A zero Group is valid, has no limit on the number of active goroutines, +// and does not cancel on error. +type Group struct { + cancel func(error) + + wg sync.WaitGroup + + sem chan token + + errOnce sync.Once + err error +} + +func (g *Group) done() { + if g.sem != nil { + <-g.sem + } + g.wg.Done() +} + +// WithContext returns a new Group and an associated Context derived from ctx. +// +// The derived Context is canceled the first time a function passed to Go +// returns a non-nil error or the first time Wait returns, whichever occurs +// first. +func WithContext(ctx context.Context) (*Group, context.Context) { + ctx, cancel := context.WithCancelCause(ctx) + return &Group{cancel: cancel}, ctx +} + +// Wait blocks until all function calls from the Go method have returned, then +// returns the first non-nil error (if any) from them. +func (g *Group) Wait() error { + g.wg.Wait() + if g.cancel != nil { + g.cancel(g.err) + } + return g.err +} + +// Go calls the given function in a new goroutine. +// +// The first call to Go must happen before a Wait. +// It blocks until the new goroutine can be added without the number of +// goroutines in the group exceeding the configured limit. +// +// The first goroutine in the group that returns a non-nil error will +// cancel the associated Context, if any. The error will be returned +// by Wait. +func (g *Group) Go(f func() error) { + if g.sem != nil { + g.sem <- token{} + } + + g.wg.Add(1) + go func() { + defer g.done() + + // It is tempting to propagate panics from f() + // up to the goroutine that calls Wait, but + // it creates more problems than it solves: + // - it delays panics arbitrarily, + // making bugs harder to detect; + // - it turns f's panic stack into a mere value, + // hiding it from crash-monitoring tools; + // - it risks deadlocks that hide the panic entirely, + // if f's panic leaves the program in a state + // that prevents the Wait call from being reached. + // See #53757, #74275, #74304, #74306. + + if err := f(); err != nil { + g.errOnce.Do(func() { + g.err = err + if g.cancel != nil { + g.cancel(g.err) + } + }) + } + }() +} + +// TryGo calls the given function in a new goroutine only if the number of +// active goroutines in the group is currently below the configured limit. +// +// The return value reports whether the goroutine was started. +func (g *Group) TryGo(f func() error) bool { + if g.sem != nil { + select { + case g.sem <- token{}: + // Note: this allows barging if and only if channels in general allow barging. + default: + return false + } + } + + g.wg.Add(1) + go func() { + defer g.done() + + if err := f(); err != nil { + g.errOnce.Do(func() { + g.err = err + if g.cancel != nil { + g.cancel(g.err) + } + }) + } + }() + return true +} + +// SetLimit limits the number of active goroutines in this group to at most n. +// A negative value indicates no limit. +// A limit of zero will prevent any new goroutines from being added. +// +// Any subsequent call to the Go method will block until it can add an active +// goroutine without exceeding the configured limit. +// +// The limit must not be modified while any goroutines in the group are active. +func (g *Group) SetLimit(n int) { + if n < 0 { + g.sem = nil + return + } + if active := len(g.sem); active != 0 { + panic(fmt.Errorf("errgroup: modify limit while %v goroutines in the group are still active", active)) + } + g.sem = make(chan token, n) +} diff --git a/vendor/golang.org/x/sys/LICENSE b/vendor/golang.org/x/sys/LICENSE new file mode 100644 index 0000000..2a7cf70 --- /dev/null +++ b/vendor/golang.org/x/sys/LICENSE @@ -0,0 +1,27 @@ +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/sys/PATENTS b/vendor/golang.org/x/sys/PATENTS new file mode 100644 index 0000000..7330990 --- /dev/null +++ b/vendor/golang.org/x/sys/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/sys/windows/aliases.go b/vendor/golang.org/x/sys/windows/aliases.go new file mode 100644 index 0000000..9631796 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/aliases.go @@ -0,0 +1,13 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows + +package windows + +import "syscall" + +type Signal = syscall.Signal +type Errno = syscall.Errno +type SysProcAttr = syscall.SysProcAttr diff --git a/vendor/golang.org/x/sys/windows/dll_windows.go b/vendor/golang.org/x/sys/windows/dll_windows.go new file mode 100644 index 0000000..1157b06 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/dll_windows.go @@ -0,0 +1,380 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +import ( + "sync" + "sync/atomic" + "syscall" + "unsafe" +) + +// We need to use LoadLibrary and GetProcAddress from the Go runtime, because +// the these symbols are loaded by the system linker and are required to +// dynamically load additional symbols. Note that in the Go runtime, these +// return syscall.Handle and syscall.Errno, but these are the same, in fact, +// as windows.Handle and windows.Errno, and we intend to keep these the same. + +//go:linkname syscall_loadlibrary syscall.loadlibrary +func syscall_loadlibrary(filename *uint16) (handle Handle, err Errno) + +//go:linkname syscall_getprocaddress syscall.getprocaddress +func syscall_getprocaddress(handle Handle, procname *uint8) (proc uintptr, err Errno) + +// DLLError describes reasons for DLL load failures. +type DLLError struct { + Err error + ObjName string + Msg string +} + +func (e *DLLError) Error() string { return e.Msg } + +func (e *DLLError) Unwrap() error { return e.Err } + +// A DLL implements access to a single DLL. +type DLL struct { + Name string + Handle Handle +} + +// LoadDLL loads DLL file into memory. +// +// Warning: using LoadDLL without an absolute path name is subject to +// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL], +// or use [LoadLibraryEx] directly. +func LoadDLL(name string) (dll *DLL, err error) { + namep, err := UTF16PtrFromString(name) + if err != nil { + return nil, err + } + h, e := syscall_loadlibrary(namep) + if e != 0 { + return nil, &DLLError{ + Err: e, + ObjName: name, + Msg: "Failed to load " + name + ": " + e.Error(), + } + } + d := &DLL{ + Name: name, + Handle: h, + } + return d, nil +} + +// MustLoadDLL is like LoadDLL but panics if load operation fails. +func MustLoadDLL(name string) *DLL { + d, e := LoadDLL(name) + if e != nil { + panic(e) + } + return d +} + +// FindProc searches DLL d for procedure named name and returns *Proc +// if found. It returns an error if search fails. +func (d *DLL) FindProc(name string) (proc *Proc, err error) { + namep, err := BytePtrFromString(name) + if err != nil { + return nil, err + } + a, e := syscall_getprocaddress(d.Handle, namep) + if e != 0 { + return nil, &DLLError{ + Err: e, + ObjName: name, + Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(), + } + } + p := &Proc{ + Dll: d, + Name: name, + addr: a, + } + return p, nil +} + +// MustFindProc is like FindProc but panics if search fails. +func (d *DLL) MustFindProc(name string) *Proc { + p, e := d.FindProc(name) + if e != nil { + panic(e) + } + return p +} + +// FindProcByOrdinal searches DLL d for procedure by ordinal and returns *Proc +// if found. It returns an error if search fails. +func (d *DLL) FindProcByOrdinal(ordinal uintptr) (proc *Proc, err error) { + a, e := GetProcAddressByOrdinal(d.Handle, ordinal) + name := "#" + itoa(int(ordinal)) + if e != nil { + return nil, &DLLError{ + Err: e, + ObjName: name, + Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(), + } + } + p := &Proc{ + Dll: d, + Name: name, + addr: a, + } + return p, nil +} + +// MustFindProcByOrdinal is like FindProcByOrdinal but panics if search fails. +func (d *DLL) MustFindProcByOrdinal(ordinal uintptr) *Proc { + p, e := d.FindProcByOrdinal(ordinal) + if e != nil { + panic(e) + } + return p +} + +// Release unloads DLL d from memory. +func (d *DLL) Release() (err error) { + return FreeLibrary(d.Handle) +} + +// A Proc implements access to a procedure inside a DLL. +type Proc struct { + Dll *DLL + Name string + addr uintptr +} + +// Addr returns the address of the procedure represented by p. +// The return value can be passed to Syscall to run the procedure. +func (p *Proc) Addr() uintptr { + return p.addr +} + +//go:uintptrescapes + +// Call executes procedure p with arguments a. It will panic, if more than 15 arguments +// are supplied. +// +// The returned error is always non-nil, constructed from the result of GetLastError. +// Callers must inspect the primary return value to decide whether an error occurred +// (according to the semantics of the specific function being called) before consulting +// the error. The error will be guaranteed to contain windows.Errno. +func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { + return syscall.SyscallN(p.Addr(), a...) +} + +// A LazyDLL implements access to a single DLL. +// It will delay the load of the DLL until the first +// call to its Handle method or to one of its +// LazyProc's Addr method. +type LazyDLL struct { + Name string + + // System determines whether the DLL must be loaded from the + // Windows System directory, bypassing the normal DLL search + // path. + System bool + + mu sync.Mutex + dll *DLL // non nil once DLL is loaded +} + +// Load loads DLL file d.Name into memory. It returns an error if fails. +// Load will not try to load DLL, if it is already loaded into memory. +func (d *LazyDLL) Load() error { + // Non-racy version of: + // if d.dll != nil { + if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) != nil { + return nil + } + d.mu.Lock() + defer d.mu.Unlock() + if d.dll != nil { + return nil + } + + // kernel32.dll is special, since it's where LoadLibraryEx comes from. + // The kernel already special-cases its name, so it's always + // loaded from system32. + var dll *DLL + var err error + if d.Name == "kernel32.dll" { + dll, err = LoadDLL(d.Name) + } else { + dll, err = loadLibraryEx(d.Name, d.System) + } + if err != nil { + return err + } + + // Non-racy version of: + // d.dll = dll + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll)) + return nil +} + +// mustLoad is like Load but panics if search fails. +func (d *LazyDLL) mustLoad() { + e := d.Load() + if e != nil { + panic(e) + } +} + +// Handle returns d's module handle. +func (d *LazyDLL) Handle() uintptr { + d.mustLoad() + return uintptr(d.dll.Handle) +} + +// NewProc returns a LazyProc for accessing the named procedure in the DLL d. +func (d *LazyDLL) NewProc(name string) *LazyProc { + return &LazyProc{l: d, Name: name} +} + +// NewLazyDLL creates new LazyDLL associated with DLL file. +// +// Warning: using NewLazyDLL without an absolute path name is subject to +// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL]. +func NewLazyDLL(name string) *LazyDLL { + return &LazyDLL{Name: name} +} + +// NewLazySystemDLL is like NewLazyDLL, but will only +// search Windows System directory for the DLL if name is +// a base name (like "advapi32.dll"). +func NewLazySystemDLL(name string) *LazyDLL { + return &LazyDLL{Name: name, System: true} +} + +// A LazyProc implements access to a procedure inside a LazyDLL. +// It delays the lookup until the Addr method is called. +type LazyProc struct { + Name string + + mu sync.Mutex + l *LazyDLL + proc *Proc +} + +// Find searches DLL for procedure named p.Name. It returns +// an error if search fails. Find will not search procedure, +// if it is already found and loaded into memory. +func (p *LazyProc) Find() error { + // Non-racy version of: + // if p.proc == nil { + if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil { + p.mu.Lock() + defer p.mu.Unlock() + if p.proc == nil { + e := p.l.Load() + if e != nil { + return e + } + proc, e := p.l.dll.FindProc(p.Name) + if e != nil { + return e + } + // Non-racy version of: + // p.proc = proc + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc)) + } + } + return nil +} + +// mustFind is like Find but panics if search fails. +func (p *LazyProc) mustFind() { + e := p.Find() + if e != nil { + panic(e) + } +} + +// Addr returns the address of the procedure represented by p. +// The return value can be passed to Syscall to run the procedure. +// It will panic if the procedure cannot be found. +func (p *LazyProc) Addr() uintptr { + p.mustFind() + return p.proc.Addr() +} + +//go:uintptrescapes + +// Call executes procedure p with arguments a. It will panic, if more than 15 arguments +// are supplied. It will also panic if the procedure cannot be found. +// +// The returned error is always non-nil, constructed from the result of GetLastError. +// Callers must inspect the primary return value to decide whether an error occurred +// (according to the semantics of the specific function being called) before consulting +// the error. The error will be guaranteed to contain windows.Errno. +func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { + p.mustFind() + return p.proc.Call(a...) +} + +var canDoSearchSystem32Once struct { + sync.Once + v bool +} + +func initCanDoSearchSystem32() { + // https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: + // "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + // Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on + // systems that have KB2533623 installed. To determine whether the + // flags are available, use GetProcAddress to get the address of the + // AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories + // function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* + // flags can be used with LoadLibraryEx." + canDoSearchSystem32Once.v = (modkernel32.NewProc("AddDllDirectory").Find() == nil) +} + +func canDoSearchSystem32() bool { + canDoSearchSystem32Once.Do(initCanDoSearchSystem32) + return canDoSearchSystem32Once.v +} + +func isBaseName(name string) bool { + for _, c := range name { + if c == ':' || c == '/' || c == '\\' { + return false + } + } + return true +} + +// loadLibraryEx wraps the Windows LoadLibraryEx function. +// +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx +// +// If name is not an absolute path, LoadLibraryEx searches for the DLL +// in a variety of automatic locations unless constrained by flags. +// See: https://msdn.microsoft.com/en-us/library/ff919712%28VS.85%29.aspx +func loadLibraryEx(name string, system bool) (*DLL, error) { + loadDLL := name + var flags uintptr + if system { + if canDoSearchSystem32() { + flags = LOAD_LIBRARY_SEARCH_SYSTEM32 + } else if isBaseName(name) { + // WindowsXP or unpatched Windows machine + // trying to load "foo.dll" out of the system + // folder, but LoadLibraryEx doesn't support + // that yet on their system, so emulate it. + systemdir, err := GetSystemDirectory() + if err != nil { + return nil, err + } + loadDLL = systemdir + "\\" + name + } + } + h, err := LoadLibraryEx(loadDLL, 0, flags) + if err != nil { + return nil, err + } + return &DLL{Name: name, Handle: h}, nil +} diff --git a/vendor/golang.org/x/sys/windows/env_windows.go b/vendor/golang.org/x/sys/windows/env_windows.go new file mode 100644 index 0000000..d4577a4 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/env_windows.go @@ -0,0 +1,57 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Windows environment variables. + +package windows + +import ( + "syscall" + "unsafe" +) + +func Getenv(key string) (value string, found bool) { + return syscall.Getenv(key) +} + +func Setenv(key, value string) error { + return syscall.Setenv(key, value) +} + +func Clearenv() { + syscall.Clearenv() +} + +func Environ() []string { + return syscall.Environ() +} + +// Returns a default environment associated with the token, rather than the current +// process. If inheritExisting is true, then this environment also inherits the +// environment of the current process. +func (token Token) Environ(inheritExisting bool) (env []string, err error) { + var block *uint16 + err = CreateEnvironmentBlock(&block, token, inheritExisting) + if err != nil { + return nil, err + } + defer DestroyEnvironmentBlock(block) + size := unsafe.Sizeof(*block) + for *block != 0 { + // find NUL terminator + end := unsafe.Pointer(block) + for *(*uint16)(end) != 0 { + end = unsafe.Add(end, size) + } + + entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size) + env = append(env, UTF16ToString(entry)) + block = (*uint16)(unsafe.Add(end, size)) + } + return env, nil +} + +func Unsetenv(key string) error { + return syscall.Unsetenv(key) +} diff --git a/vendor/golang.org/x/sys/windows/eventlog.go b/vendor/golang.org/x/sys/windows/eventlog.go new file mode 100644 index 0000000..6c36695 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/eventlog.go @@ -0,0 +1,20 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows + +package windows + +const ( + EVENTLOG_SUCCESS = 0 + EVENTLOG_ERROR_TYPE = 1 + EVENTLOG_WARNING_TYPE = 2 + EVENTLOG_INFORMATION_TYPE = 4 + EVENTLOG_AUDIT_SUCCESS = 8 + EVENTLOG_AUDIT_FAILURE = 16 +) + +//sys RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) [failretval==0] = advapi32.RegisterEventSourceW +//sys DeregisterEventSource(handle Handle) (err error) = advapi32.DeregisterEventSource +//sys ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) = advapi32.ReportEventW diff --git a/vendor/golang.org/x/sys/windows/exec_windows.go b/vendor/golang.org/x/sys/windows/exec_windows.go new file mode 100644 index 0000000..9cabbb6 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/exec_windows.go @@ -0,0 +1,248 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Fork, exec, wait, etc. + +package windows + +import ( + errorspkg "errors" + "unsafe" +) + +// EscapeArg rewrites command line argument s as prescribed +// in http://msdn.microsoft.com/en-us/library/ms880421. +// This function returns "" (2 double quotes) if s is empty. +// Alternatively, these transformations are done: +// - every back slash (\) is doubled, but only if immediately +// followed by double quote ("); +// - every double quote (") is escaped by back slash (\); +// - finally, s is wrapped with double quotes (arg -> "arg"), +// but only if there is space or tab inside s. +func EscapeArg(s string) string { + if len(s) == 0 { + return `""` + } + n := len(s) + hasSpace := false + for i := 0; i < len(s); i++ { + switch s[i] { + case '"', '\\': + n++ + case ' ', '\t': + hasSpace = true + } + } + if hasSpace { + n += 2 // Reserve space for quotes. + } + if n == len(s) { + return s + } + + qs := make([]byte, n) + j := 0 + if hasSpace { + qs[j] = '"' + j++ + } + slashes := 0 + for i := 0; i < len(s); i++ { + switch s[i] { + default: + slashes = 0 + qs[j] = s[i] + case '\\': + slashes++ + qs[j] = s[i] + case '"': + for ; slashes > 0; slashes-- { + qs[j] = '\\' + j++ + } + qs[j] = '\\' + j++ + qs[j] = s[i] + } + j++ + } + if hasSpace { + for ; slashes > 0; slashes-- { + qs[j] = '\\' + j++ + } + qs[j] = '"' + j++ + } + return string(qs[:j]) +} + +// ComposeCommandLine escapes and joins the given arguments suitable for use as a Windows command line, +// in CreateProcess's CommandLine argument, CreateService/ChangeServiceConfig's BinaryPathName argument, +// or any program that uses CommandLineToArgv. +func ComposeCommandLine(args []string) string { + if len(args) == 0 { + return "" + } + + // Per https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw: + // “This function accepts command lines that contain a program name; the + // program name can be enclosed in quotation marks or not.” + // + // Unfortunately, it provides no means of escaping interior quotation marks + // within that program name, and we have no way to report them here. + prog := args[0] + mustQuote := len(prog) == 0 + for i := 0; i < len(prog); i++ { + c := prog[i] + if c <= ' ' || (c == '"' && i == 0) { + // Force quotes for not only the ASCII space and tab as described in the + // MSDN article, but also ASCII control characters. + // The documentation for CommandLineToArgvW doesn't say what happens when + // the first argument is not a valid program name, but it empirically + // seems to drop unquoted control characters. + mustQuote = true + break + } + } + var commandLine []byte + if mustQuote { + commandLine = make([]byte, 0, len(prog)+2) + commandLine = append(commandLine, '"') + for i := 0; i < len(prog); i++ { + c := prog[i] + if c == '"' { + // This quote would interfere with our surrounding quotes. + // We have no way to report an error, so just strip out + // the offending character instead. + continue + } + commandLine = append(commandLine, c) + } + commandLine = append(commandLine, '"') + } else { + if len(args) == 1 { + // args[0] is a valid command line representing itself. + // No need to allocate a new slice or string for it. + return prog + } + commandLine = []byte(prog) + } + + for _, arg := range args[1:] { + commandLine = append(commandLine, ' ') + // TODO(bcmills): since we're already appending to a slice, it would be nice + // to avoid the intermediate allocations of EscapeArg. + // Perhaps we can factor out an appendEscapedArg function. + commandLine = append(commandLine, EscapeArg(arg)...) + } + return string(commandLine) +} + +// DecomposeCommandLine breaks apart its argument command line into unescaped parts using CommandLineToArgv, +// as gathered from GetCommandLine, QUERY_SERVICE_CONFIG's BinaryPathName argument, or elsewhere that +// command lines are passed around. +// DecomposeCommandLine returns an error if commandLine contains NUL. +func DecomposeCommandLine(commandLine string) ([]string, error) { + if len(commandLine) == 0 { + return []string{}, nil + } + utf16CommandLine, err := UTF16FromString(commandLine) + if err != nil { + return nil, errorspkg.New("string with NUL passed to DecomposeCommandLine") + } + var argc int32 + argv, err := commandLineToArgv(&utf16CommandLine[0], &argc) + if err != nil { + return nil, err + } + defer LocalFree(Handle(unsafe.Pointer(argv))) + + var args []string + for _, p := range unsafe.Slice(argv, argc) { + args = append(args, UTF16PtrToString(p)) + } + return args, nil +} + +// CommandLineToArgv parses a Unicode command line string and sets +// argc to the number of parsed arguments. +// +// The returned memory should be freed using a single call to LocalFree. +// +// Note that although the return type of CommandLineToArgv indicates 8192 +// entries of up to 8192 characters each, the actual count of parsed arguments +// may exceed 8192, and the documentation for CommandLineToArgvW does not mention +// any bound on the lengths of the individual argument strings. +// (See https://go.dev/issue/63236.) +func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) { + argp, err := commandLineToArgv(cmd, argc) + argv = (*[8192]*[8192]uint16)(unsafe.Pointer(argp)) + return argv, err +} + +func CloseOnExec(fd Handle) { + SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0) +} + +// FullPath retrieves the full path of the specified file. +func FullPath(name string) (path string, err error) { + p, err := UTF16PtrFromString(name) + if err != nil { + return "", err + } + n := uint32(100) + for { + buf := make([]uint16, n) + n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil) + if err != nil { + return "", err + } + if n <= uint32(len(buf)) { + return UTF16ToString(buf[:n]), nil + } + } +} + +// NewProcThreadAttributeList allocates a new ProcThreadAttributeListContainer, with the requested maximum number of attributes. +func NewProcThreadAttributeList(maxAttrCount uint32) (*ProcThreadAttributeListContainer, error) { + var size uintptr + err := initializeProcThreadAttributeList(nil, maxAttrCount, 0, &size) + if err != ERROR_INSUFFICIENT_BUFFER { + if err == nil { + return nil, errorspkg.New("unable to query buffer size from InitializeProcThreadAttributeList") + } + return nil, err + } + alloc, err := LocalAlloc(LMEM_FIXED, uint32(size)) + if err != nil { + return nil, err + } + // size is guaranteed to be ≥1 by InitializeProcThreadAttributeList. + al := &ProcThreadAttributeListContainer{data: (*ProcThreadAttributeList)(unsafe.Pointer(alloc))} + err = initializeProcThreadAttributeList(al.data, maxAttrCount, 0, &size) + if err != nil { + return nil, err + } + return al, err +} + +// Update modifies the ProcThreadAttributeList using UpdateProcThreadAttribute. +func (al *ProcThreadAttributeListContainer) Update(attribute uintptr, value unsafe.Pointer, size uintptr) error { + al.pointers = append(al.pointers, value) + return updateProcThreadAttribute(al.data, 0, attribute, value, size, nil, nil) +} + +// Delete frees ProcThreadAttributeList's resources. +func (al *ProcThreadAttributeListContainer) Delete() { + deleteProcThreadAttributeList(al.data) + LocalFree(Handle(unsafe.Pointer(al.data))) + al.data = nil + al.pointers = nil +} + +// List returns the actual ProcThreadAttributeList to be passed to StartupInfoEx. +func (al *ProcThreadAttributeListContainer) List() *ProcThreadAttributeList { + return al.data +} diff --git a/vendor/golang.org/x/sys/windows/memory_windows.go b/vendor/golang.org/x/sys/windows/memory_windows.go new file mode 100644 index 0000000..6dc0920 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/memory_windows.go @@ -0,0 +1,48 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +const ( + MEM_COMMIT = 0x00001000 + MEM_RESERVE = 0x00002000 + MEM_DECOMMIT = 0x00004000 + MEM_RELEASE = 0x00008000 + MEM_RESET = 0x00080000 + MEM_TOP_DOWN = 0x00100000 + MEM_WRITE_WATCH = 0x00200000 + MEM_PHYSICAL = 0x00400000 + MEM_RESET_UNDO = 0x01000000 + MEM_LARGE_PAGES = 0x20000000 + + PAGE_NOACCESS = 0x00000001 + PAGE_READONLY = 0x00000002 + PAGE_READWRITE = 0x00000004 + PAGE_WRITECOPY = 0x00000008 + PAGE_EXECUTE = 0x00000010 + PAGE_EXECUTE_READ = 0x00000020 + PAGE_EXECUTE_READWRITE = 0x00000040 + PAGE_EXECUTE_WRITECOPY = 0x00000080 + PAGE_GUARD = 0x00000100 + PAGE_NOCACHE = 0x00000200 + PAGE_WRITECOMBINE = 0x00000400 + PAGE_TARGETS_INVALID = 0x40000000 + PAGE_TARGETS_NO_UPDATE = 0x40000000 + + QUOTA_LIMITS_HARDWS_MIN_DISABLE = 0x00000002 + QUOTA_LIMITS_HARDWS_MIN_ENABLE = 0x00000001 + QUOTA_LIMITS_HARDWS_MAX_DISABLE = 0x00000008 + QUOTA_LIMITS_HARDWS_MAX_ENABLE = 0x00000004 +) + +type MemoryBasicInformation struct { + BaseAddress uintptr + AllocationBase uintptr + AllocationProtect uint32 + PartitionId uint16 + RegionSize uintptr + State uint32 + Protect uint32 + Type uint32 +} diff --git a/vendor/golang.org/x/sys/windows/mkerrors.bash b/vendor/golang.org/x/sys/windows/mkerrors.bash new file mode 100644 index 0000000..58e0188 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/mkerrors.bash @@ -0,0 +1,70 @@ +#!/bin/bash + +# Copyright 2019 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +set -e +shopt -s nullglob + +winerror="$(printf '%s\n' "/mnt/c/Program Files (x86)/Windows Kits/"/*/Include/*/shared/winerror.h | sort -Vr | head -n 1)" +[[ -n $winerror ]] || { echo "Unable to find winerror.h" >&2; exit 1; } +ntstatus="$(printf '%s\n' "/mnt/c/Program Files (x86)/Windows Kits/"/*/Include/*/shared/ntstatus.h | sort -Vr | head -n 1)" +[[ -n $ntstatus ]] || { echo "Unable to find ntstatus.h" >&2; exit 1; } + +declare -A errors + +{ + echo "// Code generated by 'mkerrors.bash'; DO NOT EDIT." + echo + echo "package windows" + echo "import \"syscall\"" + echo "const (" + + while read -r line; do + unset vtype + if [[ $line =~ ^#define\ +([A-Z0-9_]+k?)\ +([A-Z0-9_]+\()?([A-Z][A-Z0-9_]+k?)\)? ]]; then + key="${BASH_REMATCH[1]}" + value="${BASH_REMATCH[3]}" + elif [[ $line =~ ^#define\ +([A-Z0-9_]+k?)\ +([A-Z0-9_]+\()?((0x)?[0-9A-Fa-f]+)L?\)? ]]; then + key="${BASH_REMATCH[1]}" + value="${BASH_REMATCH[3]}" + vtype="${BASH_REMATCH[2]}" + elif [[ $line =~ ^#define\ +([A-Z0-9_]+k?)\ +\(\(([A-Z]+)\)((0x)?[0-9A-Fa-f]+)L?\) ]]; then + key="${BASH_REMATCH[1]}" + value="${BASH_REMATCH[3]}" + vtype="${BASH_REMATCH[2]}" + else + continue + fi + [[ -n $key && -n $value ]] || continue + [[ -z ${errors["$key"]} ]] || continue + errors["$key"]="$value" + if [[ -v vtype ]]; then + if [[ $key == FACILITY_* || $key == NO_ERROR ]]; then + vtype="" + elif [[ $vtype == *HANDLE* || $vtype == *HRESULT* ]]; then + vtype="Handle" + else + vtype="syscall.Errno" + fi + last_vtype="$vtype" + else + vtype="" + if [[ $last_vtype == Handle && $value == NO_ERROR ]]; then + value="S_OK" + elif [[ $last_vtype == syscall.Errno && $value == NO_ERROR ]]; then + value="ERROR_SUCCESS" + fi + fi + + echo "$key $vtype = $value" + done < "$winerror" + + while read -r line; do + [[ $line =~ ^#define\ (STATUS_[^\s]+)\ +\(\(NTSTATUS\)((0x)?[0-9a-fA-F]+)L?\) ]] || continue + echo "${BASH_REMATCH[1]} NTStatus = ${BASH_REMATCH[2]}" + done < "$ntstatus" + + echo ")" +} | gofmt > "zerrors_windows.go" diff --git a/vendor/golang.org/x/sys/windows/mkknownfolderids.bash b/vendor/golang.org/x/sys/windows/mkknownfolderids.bash new file mode 100644 index 0000000..ab8924e --- /dev/null +++ b/vendor/golang.org/x/sys/windows/mkknownfolderids.bash @@ -0,0 +1,27 @@ +#!/bin/bash + +# Copyright 2019 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +set -e +shopt -s nullglob + +knownfolders="$(printf '%s\n' "/mnt/c/Program Files (x86)/Windows Kits/"/*/Include/*/um/KnownFolders.h | sort -Vr | head -n 1)" +[[ -n $knownfolders ]] || { echo "Unable to find KnownFolders.h" >&2; exit 1; } + +{ + echo "// Code generated by 'mkknownfolderids.bash'; DO NOT EDIT." + echo + echo "package windows" + echo "type KNOWNFOLDERID GUID" + echo "var (" + while read -r line; do + [[ $line =~ DEFINE_KNOWN_FOLDER\((FOLDERID_[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+)\) ]] || continue + printf "%s = &KNOWNFOLDERID{0x%08x, 0x%04x, 0x%04x, [8]byte{0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x}}\n" \ + "${BASH_REMATCH[1]}" $(( "${BASH_REMATCH[2]}" )) $(( "${BASH_REMATCH[3]}" )) $(( "${BASH_REMATCH[4]}" )) \ + $(( "${BASH_REMATCH[5]}" )) $(( "${BASH_REMATCH[6]}" )) $(( "${BASH_REMATCH[7]}" )) $(( "${BASH_REMATCH[8]}" )) \ + $(( "${BASH_REMATCH[9]}" )) $(( "${BASH_REMATCH[10]}" )) $(( "${BASH_REMATCH[11]}" )) $(( "${BASH_REMATCH[12]}" )) + done < "$knownfolders" + echo ")" +} | gofmt > "zknownfolderids_windows.go" diff --git a/vendor/golang.org/x/sys/windows/mksyscall.go b/vendor/golang.org/x/sys/windows/mksyscall.go new file mode 100644 index 0000000..dbcdb09 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/mksyscall.go @@ -0,0 +1,9 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build generate + +package windows + +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go eventlog.go service.go syscall_windows.go security_windows.go setupapi_windows.go diff --git a/vendor/golang.org/x/sys/windows/race.go b/vendor/golang.org/x/sys/windows/race.go new file mode 100644 index 0000000..0f1bdc3 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/race.go @@ -0,0 +1,30 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows && race + +package windows + +import ( + "runtime" + "unsafe" +) + +const raceenabled = true + +func raceAcquire(addr unsafe.Pointer) { + runtime.RaceAcquire(addr) +} + +func raceReleaseMerge(addr unsafe.Pointer) { + runtime.RaceReleaseMerge(addr) +} + +func raceReadRange(addr unsafe.Pointer, len int) { + runtime.RaceReadRange(addr, len) +} + +func raceWriteRange(addr unsafe.Pointer, len int) { + runtime.RaceWriteRange(addr, len) +} diff --git a/vendor/golang.org/x/sys/windows/race0.go b/vendor/golang.org/x/sys/windows/race0.go new file mode 100644 index 0000000..0c78da7 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/race0.go @@ -0,0 +1,25 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows && !race + +package windows + +import ( + "unsafe" +) + +const raceenabled = false + +func raceAcquire(addr unsafe.Pointer) { +} + +func raceReleaseMerge(addr unsafe.Pointer) { +} + +func raceReadRange(addr unsafe.Pointer, len int) { +} + +func raceWriteRange(addr unsafe.Pointer, len int) { +} diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go new file mode 100644 index 0000000..7836215 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/security_windows.go @@ -0,0 +1,1537 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +import ( + "syscall" + "unsafe" +) + +const ( + NameUnknown = 0 + NameFullyQualifiedDN = 1 + NameSamCompatible = 2 + NameDisplay = 3 + NameUniqueId = 6 + NameCanonical = 7 + NameUserPrincipal = 8 + NameCanonicalEx = 9 + NameServicePrincipal = 10 + NameDnsDomain = 12 +) + +// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. +// http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx +//sys TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW +//sys GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW + +// TranslateAccountName converts a directory service +// object name from one format to another. +func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) { + u, e := UTF16PtrFromString(username) + if e != nil { + return "", e + } + n := uint32(50) + for { + b := make([]uint16, n) + e = TranslateName(u, from, to, &b[0], &n) + if e == nil { + return UTF16ToString(b[:n]), nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return "", e + } + if n <= uint32(len(b)) { + return "", e + } + } +} + +const ( + // do not reorder + NetSetupUnknownStatus = iota + NetSetupUnjoined + NetSetupWorkgroupName + NetSetupDomainName +) + +type UserInfo10 struct { + Name *uint16 + Comment *uint16 + UsrComment *uint16 + FullName *uint16 +} + +//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo +//sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation +//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree +//sys NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) = netapi32.NetUserEnum + +const ( + // do not reorder + SidTypeUser = 1 + iota + SidTypeGroup + SidTypeDomain + SidTypeAlias + SidTypeWellKnownGroup + SidTypeDeletedAccount + SidTypeInvalid + SidTypeUnknown + SidTypeComputer + SidTypeLabel +) + +type SidIdentifierAuthority struct { + Value [6]byte +} + +var ( + SECURITY_NULL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}} + SECURITY_WORLD_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}} + SECURITY_LOCAL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}} + SECURITY_CREATOR_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}} + SECURITY_NON_UNIQUE_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}} + SECURITY_NT_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}} + SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}} +) + +const ( + SECURITY_NULL_RID = 0 + SECURITY_WORLD_RID = 0 + SECURITY_LOCAL_RID = 0 + SECURITY_CREATOR_OWNER_RID = 0 + SECURITY_CREATOR_GROUP_RID = 1 + SECURITY_DIALUP_RID = 1 + SECURITY_NETWORK_RID = 2 + SECURITY_BATCH_RID = 3 + SECURITY_INTERACTIVE_RID = 4 + SECURITY_LOGON_IDS_RID = 5 + SECURITY_SERVICE_RID = 6 + SECURITY_LOCAL_SYSTEM_RID = 18 + SECURITY_BUILTIN_DOMAIN_RID = 32 + SECURITY_PRINCIPAL_SELF_RID = 10 + SECURITY_CREATOR_OWNER_SERVER_RID = 0x2 + SECURITY_CREATOR_GROUP_SERVER_RID = 0x3 + SECURITY_LOGON_IDS_RID_COUNT = 0x3 + SECURITY_ANONYMOUS_LOGON_RID = 0x7 + SECURITY_PROXY_RID = 0x8 + SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9 + SECURITY_SERVER_LOGON_RID = SECURITY_ENTERPRISE_CONTROLLERS_RID + SECURITY_AUTHENTICATED_USER_RID = 0xb + SECURITY_RESTRICTED_CODE_RID = 0xc + SECURITY_NT_NON_UNIQUE_RID = 0x15 +) + +// Predefined domain-relative RIDs for local groups. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx +const ( + DOMAIN_ALIAS_RID_ADMINS = 0x220 + DOMAIN_ALIAS_RID_USERS = 0x221 + DOMAIN_ALIAS_RID_GUESTS = 0x222 + DOMAIN_ALIAS_RID_POWER_USERS = 0x223 + DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x224 + DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x225 + DOMAIN_ALIAS_RID_PRINT_OPS = 0x226 + DOMAIN_ALIAS_RID_BACKUP_OPS = 0x227 + DOMAIN_ALIAS_RID_REPLICATOR = 0x228 + DOMAIN_ALIAS_RID_RAS_SERVERS = 0x229 + DOMAIN_ALIAS_RID_PREW2KCOMPACCESS = 0x22a + DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS = 0x22b + DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS = 0x22c + DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d + DOMAIN_ALIAS_RID_MONITORING_USERS = 0x22e + DOMAIN_ALIAS_RID_LOGGING_USERS = 0x22f + DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS = 0x230 + DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS = 0x231 + DOMAIN_ALIAS_RID_DCOM_USERS = 0x232 + DOMAIN_ALIAS_RID_IUSERS = 0x238 + DOMAIN_ALIAS_RID_CRYPTO_OPERATORS = 0x239 + DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP = 0x23b + DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c + DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP = 0x23d + DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP = 0x23e +) + +//sys LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW +//sys LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW +//sys ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW +//sys ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW +//sys GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid +//sys CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid +//sys AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) = advapi32.AllocateAndInitializeSid +//sys createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) = advapi32.CreateWellKnownSid +//sys isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) = advapi32.IsWellKnownSid +//sys FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid +//sys EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid +//sys getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) = advapi32.GetSidIdentifierAuthority +//sys getSidSubAuthorityCount(sid *SID) (count *uint8) = advapi32.GetSidSubAuthorityCount +//sys getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) = advapi32.GetSidSubAuthority +//sys isValidSid(sid *SID) (isValid bool) = advapi32.IsValidSid + +// The security identifier (SID) structure is a variable-length +// structure used to uniquely identify users or groups. +type SID struct{} + +// StringToSid converts a string-format security identifier +// SID into a valid, functional SID. +func StringToSid(s string) (*SID, error) { + var sid *SID + p, e := UTF16PtrFromString(s) + if e != nil { + return nil, e + } + e = ConvertStringSidToSid(p, &sid) + if e != nil { + return nil, e + } + defer LocalFree((Handle)(unsafe.Pointer(sid))) + return sid.Copy() +} + +// LookupSID retrieves a security identifier SID for the account +// and the name of the domain on which the account was found. +// System specify target computer to search. +func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) { + if len(account) == 0 { + return nil, "", 0, syscall.EINVAL + } + acc, e := UTF16PtrFromString(account) + if e != nil { + return nil, "", 0, e + } + var sys *uint16 + if len(system) > 0 { + sys, e = UTF16PtrFromString(system) + if e != nil { + return nil, "", 0, e + } + } + n := uint32(50) + dn := uint32(50) + for { + b := make([]byte, n) + db := make([]uint16, dn) + sid = (*SID)(unsafe.Pointer(&b[0])) + e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType) + if e == nil { + return sid, UTF16ToString(db), accType, nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return nil, "", 0, e + } + if n <= uint32(len(b)) { + return nil, "", 0, e + } + } +} + +// String converts SID to a string format suitable for display, storage, or transmission. +func (sid *SID) String() string { + var s *uint16 + e := ConvertSidToStringSid(sid, &s) + if e != nil { + return "" + } + defer LocalFree((Handle)(unsafe.Pointer(s))) + return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]) +} + +// Len returns the length, in bytes, of a valid security identifier SID. +func (sid *SID) Len() int { + return int(GetLengthSid(sid)) +} + +// Copy creates a duplicate of security identifier SID. +func (sid *SID) Copy() (*SID, error) { + b := make([]byte, sid.Len()) + sid2 := (*SID)(unsafe.Pointer(&b[0])) + e := CopySid(uint32(len(b)), sid2, sid) + if e != nil { + return nil, e + } + return sid2, nil +} + +// IdentifierAuthority returns the identifier authority of the SID. +func (sid *SID) IdentifierAuthority() SidIdentifierAuthority { + return *getSidIdentifierAuthority(sid) +} + +// SubAuthorityCount returns the number of sub-authorities in the SID. +func (sid *SID) SubAuthorityCount() uint8 { + return *getSidSubAuthorityCount(sid) +} + +// SubAuthority returns the sub-authority of the SID as specified by +// the index, which must be less than sid.SubAuthorityCount(). +func (sid *SID) SubAuthority(idx uint32) uint32 { + if idx >= uint32(sid.SubAuthorityCount()) { + panic("sub-authority index out of range") + } + return *getSidSubAuthority(sid, idx) +} + +// IsValid returns whether the SID has a valid revision and length. +func (sid *SID) IsValid() bool { + return isValidSid(sid) +} + +// Equals compares two SIDs for equality. +func (sid *SID) Equals(sid2 *SID) bool { + return EqualSid(sid, sid2) +} + +// IsWellKnown determines whether the SID matches the well-known sidType. +func (sid *SID) IsWellKnown(sidType WELL_KNOWN_SID_TYPE) bool { + return isWellKnownSid(sid, sidType) +} + +// LookupAccount retrieves the name of the account for this SID +// and the name of the first domain on which this SID is found. +// System specify target computer to search for. +func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) { + var sys *uint16 + if len(system) > 0 { + sys, err = UTF16PtrFromString(system) + if err != nil { + return "", "", 0, err + } + } + n := uint32(50) + dn := uint32(50) + for { + b := make([]uint16, n) + db := make([]uint16, dn) + e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType) + if e == nil { + return UTF16ToString(b), UTF16ToString(db), accType, nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return "", "", 0, e + } + if n <= uint32(len(b)) { + return "", "", 0, e + } + } +} + +// Various types of pre-specified SIDs that can be synthesized and compared at runtime. +type WELL_KNOWN_SID_TYPE uint32 + +const ( + WinNullSid = 0 + WinWorldSid = 1 + WinLocalSid = 2 + WinCreatorOwnerSid = 3 + WinCreatorGroupSid = 4 + WinCreatorOwnerServerSid = 5 + WinCreatorGroupServerSid = 6 + WinNtAuthoritySid = 7 + WinDialupSid = 8 + WinNetworkSid = 9 + WinBatchSid = 10 + WinInteractiveSid = 11 + WinServiceSid = 12 + WinAnonymousSid = 13 + WinProxySid = 14 + WinEnterpriseControllersSid = 15 + WinSelfSid = 16 + WinAuthenticatedUserSid = 17 + WinRestrictedCodeSid = 18 + WinTerminalServerSid = 19 + WinRemoteLogonIdSid = 20 + WinLogonIdsSid = 21 + WinLocalSystemSid = 22 + WinLocalServiceSid = 23 + WinNetworkServiceSid = 24 + WinBuiltinDomainSid = 25 + WinBuiltinAdministratorsSid = 26 + WinBuiltinUsersSid = 27 + WinBuiltinGuestsSid = 28 + WinBuiltinPowerUsersSid = 29 + WinBuiltinAccountOperatorsSid = 30 + WinBuiltinSystemOperatorsSid = 31 + WinBuiltinPrintOperatorsSid = 32 + WinBuiltinBackupOperatorsSid = 33 + WinBuiltinReplicatorSid = 34 + WinBuiltinPreWindows2000CompatibleAccessSid = 35 + WinBuiltinRemoteDesktopUsersSid = 36 + WinBuiltinNetworkConfigurationOperatorsSid = 37 + WinAccountAdministratorSid = 38 + WinAccountGuestSid = 39 + WinAccountKrbtgtSid = 40 + WinAccountDomainAdminsSid = 41 + WinAccountDomainUsersSid = 42 + WinAccountDomainGuestsSid = 43 + WinAccountComputersSid = 44 + WinAccountControllersSid = 45 + WinAccountCertAdminsSid = 46 + WinAccountSchemaAdminsSid = 47 + WinAccountEnterpriseAdminsSid = 48 + WinAccountPolicyAdminsSid = 49 + WinAccountRasAndIasServersSid = 50 + WinNTLMAuthenticationSid = 51 + WinDigestAuthenticationSid = 52 + WinSChannelAuthenticationSid = 53 + WinThisOrganizationSid = 54 + WinOtherOrganizationSid = 55 + WinBuiltinIncomingForestTrustBuildersSid = 56 + WinBuiltinPerfMonitoringUsersSid = 57 + WinBuiltinPerfLoggingUsersSid = 58 + WinBuiltinAuthorizationAccessSid = 59 + WinBuiltinTerminalServerLicenseServersSid = 60 + WinBuiltinDCOMUsersSid = 61 + WinBuiltinIUsersSid = 62 + WinIUserSid = 63 + WinBuiltinCryptoOperatorsSid = 64 + WinUntrustedLabelSid = 65 + WinLowLabelSid = 66 + WinMediumLabelSid = 67 + WinHighLabelSid = 68 + WinSystemLabelSid = 69 + WinWriteRestrictedCodeSid = 70 + WinCreatorOwnerRightsSid = 71 + WinCacheablePrincipalsGroupSid = 72 + WinNonCacheablePrincipalsGroupSid = 73 + WinEnterpriseReadonlyControllersSid = 74 + WinAccountReadonlyControllersSid = 75 + WinBuiltinEventLogReadersGroup = 76 + WinNewEnterpriseReadonlyControllersSid = 77 + WinBuiltinCertSvcDComAccessGroup = 78 + WinMediumPlusLabelSid = 79 + WinLocalLogonSid = 80 + WinConsoleLogonSid = 81 + WinThisOrganizationCertificateSid = 82 + WinApplicationPackageAuthoritySid = 83 + WinBuiltinAnyPackageSid = 84 + WinCapabilityInternetClientSid = 85 + WinCapabilityInternetClientServerSid = 86 + WinCapabilityPrivateNetworkClientServerSid = 87 + WinCapabilityPicturesLibrarySid = 88 + WinCapabilityVideosLibrarySid = 89 + WinCapabilityMusicLibrarySid = 90 + WinCapabilityDocumentsLibrarySid = 91 + WinCapabilitySharedUserCertificatesSid = 92 + WinCapabilityEnterpriseAuthenticationSid = 93 + WinCapabilityRemovableStorageSid = 94 + WinBuiltinRDSRemoteAccessServersSid = 95 + WinBuiltinRDSEndpointServersSid = 96 + WinBuiltinRDSManagementServersSid = 97 + WinUserModeDriversSid = 98 + WinBuiltinHyperVAdminsSid = 99 + WinAccountCloneableControllersSid = 100 + WinBuiltinAccessControlAssistanceOperatorsSid = 101 + WinBuiltinRemoteManagementUsersSid = 102 + WinAuthenticationAuthorityAssertedSid = 103 + WinAuthenticationServiceAssertedSid = 104 + WinLocalAccountSid = 105 + WinLocalAccountAndAdministratorSid = 106 + WinAccountProtectedUsersSid = 107 + WinCapabilityAppointmentsSid = 108 + WinCapabilityContactsSid = 109 + WinAccountDefaultSystemManagedSid = 110 + WinBuiltinDefaultSystemManagedGroupSid = 111 + WinBuiltinStorageReplicaAdminsSid = 112 + WinAccountKeyAdminsSid = 113 + WinAccountEnterpriseKeyAdminsSid = 114 + WinAuthenticationKeyTrustSid = 115 + WinAuthenticationKeyPropertyMFASid = 116 + WinAuthenticationKeyPropertyAttestationSid = 117 + WinAuthenticationFreshKeyAuthSid = 118 + WinBuiltinDeviceOwnersSid = 119 +) + +// Creates a SID for a well-known predefined alias, generally using the constants of the form +// Win*Sid, for the local machine. +func CreateWellKnownSid(sidType WELL_KNOWN_SID_TYPE) (*SID, error) { + return CreateWellKnownDomainSid(sidType, nil) +} + +// Creates a SID for a well-known predefined alias, generally using the constants of the form +// Win*Sid, for the domain specified by the domainSid parameter. +func CreateWellKnownDomainSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID) (*SID, error) { + n := uint32(50) + for { + b := make([]byte, n) + sid := (*SID)(unsafe.Pointer(&b[0])) + err := createWellKnownSid(sidType, domainSid, sid, &n) + if err == nil { + return sid, nil + } + if err != ERROR_INSUFFICIENT_BUFFER { + return nil, err + } + if n <= uint32(len(b)) { + return nil, err + } + } +} + +const ( + // do not reorder + TOKEN_ASSIGN_PRIMARY = 1 << iota + TOKEN_DUPLICATE + TOKEN_IMPERSONATE + TOKEN_QUERY + TOKEN_QUERY_SOURCE + TOKEN_ADJUST_PRIVILEGES + TOKEN_ADJUST_GROUPS + TOKEN_ADJUST_DEFAULT + TOKEN_ADJUST_SESSIONID + + TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | + TOKEN_ASSIGN_PRIMARY | + TOKEN_DUPLICATE | + TOKEN_IMPERSONATE | + TOKEN_QUERY | + TOKEN_QUERY_SOURCE | + TOKEN_ADJUST_PRIVILEGES | + TOKEN_ADJUST_GROUPS | + TOKEN_ADJUST_DEFAULT | + TOKEN_ADJUST_SESSIONID + TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY + TOKEN_WRITE = STANDARD_RIGHTS_WRITE | + TOKEN_ADJUST_PRIVILEGES | + TOKEN_ADJUST_GROUPS | + TOKEN_ADJUST_DEFAULT + TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE +) + +const ( + // do not reorder + TokenUser = 1 + iota + TokenGroups + TokenPrivileges + TokenOwner + TokenPrimaryGroup + TokenDefaultDacl + TokenSource + TokenType + TokenImpersonationLevel + TokenStatistics + TokenRestrictedSids + TokenSessionId + TokenGroupsAndPrivileges + TokenSessionReference + TokenSandBoxInert + TokenAuditPolicy + TokenOrigin + TokenElevationType + TokenLinkedToken + TokenElevation + TokenHasRestrictions + TokenAccessInformation + TokenVirtualizationAllowed + TokenVirtualizationEnabled + TokenIntegrityLevel + TokenUIAccess + TokenMandatoryPolicy + TokenLogonSid + MaxTokenInfoClass +) + +// Group attributes inside of Tokengroups.Groups[i].Attributes +const ( + SE_GROUP_MANDATORY = 0x00000001 + SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002 + SE_GROUP_ENABLED = 0x00000004 + SE_GROUP_OWNER = 0x00000008 + SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010 + SE_GROUP_INTEGRITY = 0x00000020 + SE_GROUP_INTEGRITY_ENABLED = 0x00000040 + SE_GROUP_LOGON_ID = 0xC0000000 + SE_GROUP_RESOURCE = 0x20000000 + SE_GROUP_VALID_ATTRIBUTES = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED | SE_GROUP_OWNER | SE_GROUP_USE_FOR_DENY_ONLY | SE_GROUP_LOGON_ID | SE_GROUP_RESOURCE | SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED +) + +// Privilege attributes +const ( + SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001 + SE_PRIVILEGE_ENABLED = 0x00000002 + SE_PRIVILEGE_REMOVED = 0x00000004 + SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000 + SE_PRIVILEGE_VALID_ATTRIBUTES = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_REMOVED | SE_PRIVILEGE_USED_FOR_ACCESS +) + +// Token types +const ( + TokenPrimary = 1 + TokenImpersonation = 2 +) + +// Impersonation levels +const ( + SecurityAnonymous = 0 + SecurityIdentification = 1 + SecurityImpersonation = 2 + SecurityDelegation = 3 +) + +type LUID struct { + LowPart uint32 + HighPart int32 +} + +type LUIDAndAttributes struct { + Luid LUID + Attributes uint32 +} + +type SIDAndAttributes struct { + Sid *SID + Attributes uint32 +} + +type Tokenuser struct { + User SIDAndAttributes +} + +type Tokenprimarygroup struct { + PrimaryGroup *SID +} + +type Tokengroups struct { + GroupCount uint32 + Groups [1]SIDAndAttributes // Use AllGroups() for iterating. +} + +// AllGroups returns a slice that can be used to iterate over the groups in g. +func (g *Tokengroups) AllGroups() []SIDAndAttributes { + return (*[(1 << 28) - 1]SIDAndAttributes)(unsafe.Pointer(&g.Groups[0]))[:g.GroupCount:g.GroupCount] +} + +type Tokenprivileges struct { + PrivilegeCount uint32 + Privileges [1]LUIDAndAttributes // Use AllPrivileges() for iterating. +} + +// AllPrivileges returns a slice that can be used to iterate over the privileges in p. +func (p *Tokenprivileges) AllPrivileges() []LUIDAndAttributes { + return (*[(1 << 27) - 1]LUIDAndAttributes)(unsafe.Pointer(&p.Privileges[0]))[:p.PrivilegeCount:p.PrivilegeCount] +} + +type Tokenmandatorylabel struct { + Label SIDAndAttributes +} + +func (tml *Tokenmandatorylabel) Size() uint32 { + return uint32(unsafe.Sizeof(Tokenmandatorylabel{})) + GetLengthSid(tml.Label.Sid) +} + +// Authorization Functions +//sys checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership +//sys isTokenRestricted(tokenHandle Token) (ret bool, err error) [!failretval] = advapi32.IsTokenRestricted +//sys OpenProcessToken(process Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken +//sys OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) = advapi32.OpenThreadToken +//sys ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf +//sys RevertToSelf() (err error) = advapi32.RevertToSelf +//sys SetThreadToken(thread *Handle, token Token) (err error) = advapi32.SetThreadToken +//sys LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW +//sys AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) = advapi32.AdjustTokenPrivileges +//sys AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) = advapi32.AdjustTokenGroups +//sys GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation +//sys SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) = advapi32.SetTokenInformation +//sys DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) = advapi32.DuplicateTokenEx +//sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW +//sys getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW +//sys getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetWindowsDirectoryW +//sys getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemWindowsDirectoryW + +// An access token contains the security information for a logon session. +// The system creates an access token when a user logs on, and every +// process executed on behalf of the user has a copy of the token. +// The token identifies the user, the user's groups, and the user's +// privileges. The system uses the token to control access to securable +// objects and to control the ability of the user to perform various +// system-related operations on the local computer. +type Token Handle + +// OpenCurrentProcessToken opens an access token associated with current +// process with TOKEN_QUERY access. It is a real token that needs to be closed. +// +// Deprecated: Explicitly call OpenProcessToken(CurrentProcess(), ...) +// with the desired access instead, or use GetCurrentProcessToken for a +// TOKEN_QUERY token. +func OpenCurrentProcessToken() (Token, error) { + var token Token + err := OpenProcessToken(CurrentProcess(), TOKEN_QUERY, &token) + return token, err +} + +// GetCurrentProcessToken returns the access token associated with +// the current process. It is a pseudo token that does not need +// to be closed. +func GetCurrentProcessToken() Token { + return Token(^uintptr(4 - 1)) +} + +// GetCurrentThreadToken return the access token associated with +// the current thread. It is a pseudo token that does not need +// to be closed. +func GetCurrentThreadToken() Token { + return Token(^uintptr(5 - 1)) +} + +// GetCurrentThreadEffectiveToken returns the effective access token +// associated with the current thread. It is a pseudo token that does +// not need to be closed. +func GetCurrentThreadEffectiveToken() Token { + return Token(^uintptr(6 - 1)) +} + +// Close releases access to access token. +func (t Token) Close() error { + return CloseHandle(Handle(t)) +} + +// getInfo retrieves a specified type of information about an access token. +func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) { + n := uint32(initSize) + for { + b := make([]byte, n) + e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n) + if e == nil { + return unsafe.Pointer(&b[0]), nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return nil, e + } + if n <= uint32(len(b)) { + return nil, e + } + } +} + +// GetTokenUser retrieves access token t user account information. +func (t Token) GetTokenUser() (*Tokenuser, error) { + i, e := t.getInfo(TokenUser, 50) + if e != nil { + return nil, e + } + return (*Tokenuser)(i), nil +} + +// GetTokenGroups retrieves group accounts associated with access token t. +func (t Token) GetTokenGroups() (*Tokengroups, error) { + i, e := t.getInfo(TokenGroups, 50) + if e != nil { + return nil, e + } + return (*Tokengroups)(i), nil +} + +// GetTokenPrimaryGroup retrieves access token t primary group information. +// A pointer to a SID structure representing a group that will become +// the primary group of any objects created by a process using this access token. +func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) { + i, e := t.getInfo(TokenPrimaryGroup, 50) + if e != nil { + return nil, e + } + return (*Tokenprimarygroup)(i), nil +} + +// GetUserProfileDirectory retrieves path to the +// root directory of the access token t user's profile. +func (t Token) GetUserProfileDirectory() (string, error) { + n := uint32(100) + for { + b := make([]uint16, n) + e := GetUserProfileDirectory(t, &b[0], &n) + if e == nil { + return UTF16ToString(b), nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return "", e + } + if n <= uint32(len(b)) { + return "", e + } + } +} + +// IsElevated returns whether the current token is elevated from a UAC perspective. +func (token Token) IsElevated() bool { + var isElevated uint32 + var outLen uint32 + err := GetTokenInformation(token, TokenElevation, (*byte)(unsafe.Pointer(&isElevated)), uint32(unsafe.Sizeof(isElevated)), &outLen) + if err != nil { + return false + } + return outLen == uint32(unsafe.Sizeof(isElevated)) && isElevated != 0 +} + +// GetLinkedToken returns the linked token, which may be an elevated UAC token. +func (token Token) GetLinkedToken() (Token, error) { + var linkedToken Token + var outLen uint32 + err := GetTokenInformation(token, TokenLinkedToken, (*byte)(unsafe.Pointer(&linkedToken)), uint32(unsafe.Sizeof(linkedToken)), &outLen) + if err != nil { + return Token(0), err + } + return linkedToken, nil +} + +// GetSystemDirectory retrieves the path to current location of the system +// directory, which is typically, though not always, `C:\Windows\System32`. +func GetSystemDirectory() (string, error) { + n := uint32(MAX_PATH) + for { + b := make([]uint16, n) + l, e := getSystemDirectory(&b[0], n) + if e != nil { + return "", e + } + if l <= n { + return UTF16ToString(b[:l]), nil + } + n = l + } +} + +// GetWindowsDirectory retrieves the path to current location of the Windows +// directory, which is typically, though not always, `C:\Windows`. This may +// be a private user directory in the case that the application is running +// under a terminal server. +func GetWindowsDirectory() (string, error) { + n := uint32(MAX_PATH) + for { + b := make([]uint16, n) + l, e := getWindowsDirectory(&b[0], n) + if e != nil { + return "", e + } + if l <= n { + return UTF16ToString(b[:l]), nil + } + n = l + } +} + +// GetSystemWindowsDirectory retrieves the path to current location of the +// Windows directory, which is typically, though not always, `C:\Windows`. +func GetSystemWindowsDirectory() (string, error) { + n := uint32(MAX_PATH) + for { + b := make([]uint16, n) + l, e := getSystemWindowsDirectory(&b[0], n) + if e != nil { + return "", e + } + if l <= n { + return UTF16ToString(b[:l]), nil + } + n = l + } +} + +// IsMember reports whether the access token t is a member of the provided SID. +func (t Token) IsMember(sid *SID) (bool, error) { + var b int32 + if e := checkTokenMembership(t, sid, &b); e != nil { + return false, e + } + return b != 0, nil +} + +// IsRestricted reports whether the access token t is a restricted token. +func (t Token) IsRestricted() (isRestricted bool, err error) { + isRestricted, err = isTokenRestricted(t) + if !isRestricted && err == syscall.EINVAL { + // If err is EINVAL, this returned ERROR_SUCCESS indicating a non-restricted token. + err = nil + } + return +} + +const ( + WTS_CONSOLE_CONNECT = 0x1 + WTS_CONSOLE_DISCONNECT = 0x2 + WTS_REMOTE_CONNECT = 0x3 + WTS_REMOTE_DISCONNECT = 0x4 + WTS_SESSION_LOGON = 0x5 + WTS_SESSION_LOGOFF = 0x6 + WTS_SESSION_LOCK = 0x7 + WTS_SESSION_UNLOCK = 0x8 + WTS_SESSION_REMOTE_CONTROL = 0x9 + WTS_SESSION_CREATE = 0xa + WTS_SESSION_TERMINATE = 0xb +) + +const ( + WTSActive = 0 + WTSConnected = 1 + WTSConnectQuery = 2 + WTSShadow = 3 + WTSDisconnected = 4 + WTSIdle = 5 + WTSListen = 6 + WTSReset = 7 + WTSDown = 8 + WTSInit = 9 +) + +type WTSSESSION_NOTIFICATION struct { + Size uint32 + SessionID uint32 +} + +type WTS_SESSION_INFO struct { + SessionID uint32 + WindowStationName *uint16 + State uint32 +} + +//sys WTSQueryUserToken(session uint32, token *Token) (err error) = wtsapi32.WTSQueryUserToken +//sys WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW +//sys WTSFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory +//sys WTSGetActiveConsoleSessionId() (sessionID uint32) + +type ACL struct { + aclRevision byte + sbz1 byte + aclSize uint16 + AceCount uint16 + sbz2 uint16 +} + +type SECURITY_DESCRIPTOR struct { + revision byte + sbz1 byte + control SECURITY_DESCRIPTOR_CONTROL + owner *SID + group *SID + sacl *ACL + dacl *ACL +} + +type SECURITY_QUALITY_OF_SERVICE struct { + Length uint32 + ImpersonationLevel uint32 + ContextTrackingMode byte + EffectiveOnly byte +} + +// Constants for the ContextTrackingMode field of SECURITY_QUALITY_OF_SERVICE. +const ( + SECURITY_STATIC_TRACKING = 0 + SECURITY_DYNAMIC_TRACKING = 1 +) + +type SecurityAttributes struct { + Length uint32 + SecurityDescriptor *SECURITY_DESCRIPTOR + InheritHandle uint32 +} + +type SE_OBJECT_TYPE uint32 + +// Constants for type SE_OBJECT_TYPE +const ( + SE_UNKNOWN_OBJECT_TYPE = 0 + SE_FILE_OBJECT = 1 + SE_SERVICE = 2 + SE_PRINTER = 3 + SE_REGISTRY_KEY = 4 + SE_LMSHARE = 5 + SE_KERNEL_OBJECT = 6 + SE_WINDOW_OBJECT = 7 + SE_DS_OBJECT = 8 + SE_DS_OBJECT_ALL = 9 + SE_PROVIDER_DEFINED_OBJECT = 10 + SE_WMIGUID_OBJECT = 11 + SE_REGISTRY_WOW64_32KEY = 12 + SE_REGISTRY_WOW64_64KEY = 13 +) + +type SECURITY_INFORMATION uint32 + +// Constants for type SECURITY_INFORMATION +const ( + OWNER_SECURITY_INFORMATION = 0x00000001 + GROUP_SECURITY_INFORMATION = 0x00000002 + DACL_SECURITY_INFORMATION = 0x00000004 + SACL_SECURITY_INFORMATION = 0x00000008 + LABEL_SECURITY_INFORMATION = 0x00000010 + ATTRIBUTE_SECURITY_INFORMATION = 0x00000020 + SCOPE_SECURITY_INFORMATION = 0x00000040 + BACKUP_SECURITY_INFORMATION = 0x00010000 + PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000 + PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000 + UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000 + UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000 +) + +type SECURITY_DESCRIPTOR_CONTROL uint16 + +// Constants for type SECURITY_DESCRIPTOR_CONTROL +const ( + SE_OWNER_DEFAULTED = 0x0001 + SE_GROUP_DEFAULTED = 0x0002 + SE_DACL_PRESENT = 0x0004 + SE_DACL_DEFAULTED = 0x0008 + SE_SACL_PRESENT = 0x0010 + SE_SACL_DEFAULTED = 0x0020 + SE_DACL_AUTO_INHERIT_REQ = 0x0100 + SE_SACL_AUTO_INHERIT_REQ = 0x0200 + SE_DACL_AUTO_INHERITED = 0x0400 + SE_SACL_AUTO_INHERITED = 0x0800 + SE_DACL_PROTECTED = 0x1000 + SE_SACL_PROTECTED = 0x2000 + SE_RM_CONTROL_VALID = 0x4000 + SE_SELF_RELATIVE = 0x8000 +) + +type ACCESS_MASK uint32 + +// Constants for type ACCESS_MASK +const ( + DELETE = 0x00010000 + READ_CONTROL = 0x00020000 + WRITE_DAC = 0x00040000 + WRITE_OWNER = 0x00080000 + SYNCHRONIZE = 0x00100000 + STANDARD_RIGHTS_REQUIRED = 0x000F0000 + STANDARD_RIGHTS_READ = READ_CONTROL + STANDARD_RIGHTS_WRITE = READ_CONTROL + STANDARD_RIGHTS_EXECUTE = READ_CONTROL + STANDARD_RIGHTS_ALL = 0x001F0000 + SPECIFIC_RIGHTS_ALL = 0x0000FFFF + ACCESS_SYSTEM_SECURITY = 0x01000000 + MAXIMUM_ALLOWED = 0x02000000 + GENERIC_READ = 0x80000000 + GENERIC_WRITE = 0x40000000 + GENERIC_EXECUTE = 0x20000000 + GENERIC_ALL = 0x10000000 +) + +type ACCESS_MODE uint32 + +// Constants for type ACCESS_MODE +const ( + NOT_USED_ACCESS = 0 + GRANT_ACCESS = 1 + SET_ACCESS = 2 + DENY_ACCESS = 3 + REVOKE_ACCESS = 4 + SET_AUDIT_SUCCESS = 5 + SET_AUDIT_FAILURE = 6 +) + +// Constants for AceFlags and Inheritance fields +const ( + NO_INHERITANCE = 0x0 + SUB_OBJECTS_ONLY_INHERIT = 0x1 + SUB_CONTAINERS_ONLY_INHERIT = 0x2 + SUB_CONTAINERS_AND_OBJECTS_INHERIT = 0x3 + INHERIT_NO_PROPAGATE = 0x4 + INHERIT_ONLY = 0x8 + INHERITED_ACCESS_ENTRY = 0x10 + INHERITED_PARENT = 0x10000000 + INHERITED_GRANDPARENT = 0x20000000 + OBJECT_INHERIT_ACE = 0x1 + CONTAINER_INHERIT_ACE = 0x2 + NO_PROPAGATE_INHERIT_ACE = 0x4 + INHERIT_ONLY_ACE = 0x8 + INHERITED_ACE = 0x10 + VALID_INHERIT_FLAGS = 0x1F +) + +type MULTIPLE_TRUSTEE_OPERATION uint32 + +// Constants for MULTIPLE_TRUSTEE_OPERATION +const ( + NO_MULTIPLE_TRUSTEE = 0 + TRUSTEE_IS_IMPERSONATE = 1 +) + +type TRUSTEE_FORM uint32 + +// Constants for TRUSTEE_FORM +const ( + TRUSTEE_IS_SID = 0 + TRUSTEE_IS_NAME = 1 + TRUSTEE_BAD_FORM = 2 + TRUSTEE_IS_OBJECTS_AND_SID = 3 + TRUSTEE_IS_OBJECTS_AND_NAME = 4 +) + +type TRUSTEE_TYPE uint32 + +// Constants for TRUSTEE_TYPE +const ( + TRUSTEE_IS_UNKNOWN = 0 + TRUSTEE_IS_USER = 1 + TRUSTEE_IS_GROUP = 2 + TRUSTEE_IS_DOMAIN = 3 + TRUSTEE_IS_ALIAS = 4 + TRUSTEE_IS_WELL_KNOWN_GROUP = 5 + TRUSTEE_IS_DELETED = 6 + TRUSTEE_IS_INVALID = 7 + TRUSTEE_IS_COMPUTER = 8 +) + +// Constants for ObjectsPresent field +const ( + ACE_OBJECT_TYPE_PRESENT = 0x1 + ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x2 +) + +type EXPLICIT_ACCESS struct { + AccessPermissions ACCESS_MASK + AccessMode ACCESS_MODE + Inheritance uint32 + Trustee TRUSTEE +} + +// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header +type ACE_HEADER struct { + AceType uint8 + AceFlags uint8 + AceSize uint16 +} + +// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace +type ACCESS_ALLOWED_ACE struct { + Header ACE_HEADER + Mask ACCESS_MASK + SidStart uint32 +} + +const ( + // Constants for AceType + // https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header + ACCESS_ALLOWED_ACE_TYPE = 0 + ACCESS_DENIED_ACE_TYPE = 1 +) + +// This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions. +// +// Go pointers stored in a TrusteeValue must be pinned using [runtime.Pinner] +// for the lifetime of the TrusteeValue. +type TrusteeValue uintptr + +// TrusteeValueFromString is unsafe and should not be used. +// +// It returns a uintptr containing a reference to newly-allocated memory +// which will be freed by the garbage collector. +// There is no way for the caller to safely reference this memory. +// +// To create a [TrusteeValue] from a string, use: +// +// p, err := windows.UTF16PtrFromString(s) +// if err != nil { +// // handle error +// } +// +// // Pin the string for as long as it is used. +// var pinner runtime.Pinner +// pinner.Pin(p) +// defer pinner.Unpin() +// +// tv := TrusteeValue(unsafe.Pointer(p)) +// +// Deprecated: TrusteeValueFromString is unsafe and should not be used. +func TrusteeValueFromString(str string) TrusteeValue { + return TrusteeValue(unsafe.Pointer(StringToUTF16Ptr(str))) +} + +// TrusteeValueFromSID returns a [TrusteeValue] referencing sid. +// +// The caller must pin sid using a [runtime.Pinner] for the lifetime of the TrusteeValue. +func TrusteeValueFromSID(sid *SID) TrusteeValue { + return TrusteeValue(unsafe.Pointer(sid)) +} + +// TrusteeValueFromObjectsAndSid returns a [TrusteeValue] referencing objectsAndSid. +// +// The caller must pin objectsAndSid using a [runtime.Pinner] for the lifetime of the TrusteeValue. +func TrusteeValueFromObjectsAndSid(objectsAndSid *OBJECTS_AND_SID) TrusteeValue { + return TrusteeValue(unsafe.Pointer(objectsAndSid)) +} + +// TrusteeValueFromObjectsAndName returns a [TrusteeValue] referencing objectsAndName. +// +// The caller must pin objectsAndName using a [runtime.Pinner] for the lifetime of the TrusteeValue. +func TrusteeValueFromObjectsAndName(objectsAndName *OBJECTS_AND_NAME) TrusteeValue { + return TrusteeValue(unsafe.Pointer(objectsAndName)) +} + +type TRUSTEE struct { + MultipleTrustee *TRUSTEE + MultipleTrusteeOperation MULTIPLE_TRUSTEE_OPERATION + TrusteeForm TRUSTEE_FORM + TrusteeType TRUSTEE_TYPE + TrusteeValue TrusteeValue +} + +type OBJECTS_AND_SID struct { + ObjectsPresent uint32 + ObjectTypeGuid GUID + InheritedObjectTypeGuid GUID + Sid *SID +} + +type OBJECTS_AND_NAME struct { + ObjectsPresent uint32 + ObjectType SE_OBJECT_TYPE + ObjectTypeName *uint16 + InheritedObjectTypeName *uint16 + Name *uint16 +} + +//sys getSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) = advapi32.GetSecurityInfo +//sys SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetSecurityInfo +//sys getNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) = advapi32.GetNamedSecurityInfoW +//sys SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetNamedSecurityInfoW +//sys SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) = advapi32.SetKernelObjectSecurity + +//sys buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries uint32, accessEntries *EXPLICIT_ACCESS, countAuditEntries uint32, auditEntries *EXPLICIT_ACCESS, oldSecurityDescriptor *SECURITY_DESCRIPTOR, sizeNewSecurityDescriptor *uint32, newSecurityDescriptor **SECURITY_DESCRIPTOR) (ret error) = advapi32.BuildSecurityDescriptorW +//sys initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) = advapi32.InitializeSecurityDescriptor + +//sys getSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, control *SECURITY_DESCRIPTOR_CONTROL, revision *uint32) (err error) = advapi32.GetSecurityDescriptorControl +//sys getSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent *bool, dacl **ACL, daclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorDacl +//sys getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl **ACL, saclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorSacl +//sys getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorOwner +//sys getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorGroup +//sys getSecurityDescriptorLength(sd *SECURITY_DESCRIPTOR) (len uint32) = advapi32.GetSecurityDescriptorLength +//sys getSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) (ret error) [failretval!=0] = advapi32.GetSecurityDescriptorRMControl +//sys isValidSecurityDescriptor(sd *SECURITY_DESCRIPTOR) (isValid bool) = advapi32.IsValidSecurityDescriptor + +//sys setSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) (err error) = advapi32.SetSecurityDescriptorControl +//sys setSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent bool, dacl *ACL, daclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorDacl +//sys setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl *ACL, saclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorSacl +//sys setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaulted bool) (err error) = advapi32.SetSecurityDescriptorOwner +//sys setSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group *SID, groupDefaulted bool) (err error) = advapi32.SetSecurityDescriptorGroup +//sys setSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) = advapi32.SetSecurityDescriptorRMControl + +//sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW +//sys convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR, revision uint32, securityInformation SECURITY_INFORMATION, str **uint16, strLen *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW + +//sys makeAbsoluteSD(selfRelativeSD *SECURITY_DESCRIPTOR, absoluteSD *SECURITY_DESCRIPTOR, absoluteSDSize *uint32, dacl *ACL, daclSize *uint32, sacl *ACL, saclSize *uint32, owner *SID, ownerSize *uint32, group *SID, groupSize *uint32) (err error) = advapi32.MakeAbsoluteSD +//sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD + +//sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW +//sys GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) = advapi32.GetAce + +// Control returns the security descriptor control bits. +func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) { + err = getSecurityDescriptorControl(sd, &control, &revision) + return +} + +// SetControl sets the security descriptor control bits. +func (sd *SECURITY_DESCRIPTOR) SetControl(controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) error { + return setSecurityDescriptorControl(sd, controlBitsOfInterest, controlBitsToSet) +} + +// RMControl returns the security descriptor resource manager control bits. +func (sd *SECURITY_DESCRIPTOR) RMControl() (control uint8, err error) { + err = getSecurityDescriptorRMControl(sd, &control) + return +} + +// SetRMControl sets the security descriptor resource manager control bits. +func (sd *SECURITY_DESCRIPTOR) SetRMControl(rmControl uint8) { + setSecurityDescriptorRMControl(sd, &rmControl) +} + +// DACL returns the security descriptor DACL and whether it was defaulted. The dacl return value may be nil +// if a DACL exists but is an "empty DACL", meaning fully permissive. If the DACL does not exist, err returns +// ERROR_OBJECT_NOT_FOUND. +func (sd *SECURITY_DESCRIPTOR) DACL() (dacl *ACL, defaulted bool, err error) { + var present bool + err = getSecurityDescriptorDacl(sd, &present, &dacl, &defaulted) + if !present { + err = ERROR_OBJECT_NOT_FOUND + } + return +} + +// SetDACL sets the absolute security descriptor DACL. +func (absoluteSD *SECURITY_DESCRIPTOR) SetDACL(dacl *ACL, present, defaulted bool) error { + return setSecurityDescriptorDacl(absoluteSD, present, dacl, defaulted) +} + +// SACL returns the security descriptor SACL and whether it was defaulted. The sacl return value may be nil +// if a SACL exists but is an "empty SACL", meaning fully permissive. If the SACL does not exist, err returns +// ERROR_OBJECT_NOT_FOUND. +func (sd *SECURITY_DESCRIPTOR) SACL() (sacl *ACL, defaulted bool, err error) { + var present bool + err = getSecurityDescriptorSacl(sd, &present, &sacl, &defaulted) + if !present { + err = ERROR_OBJECT_NOT_FOUND + } + return +} + +// SetSACL sets the absolute security descriptor SACL. +func (absoluteSD *SECURITY_DESCRIPTOR) SetSACL(sacl *ACL, present, defaulted bool) error { + return setSecurityDescriptorSacl(absoluteSD, present, sacl, defaulted) +} + +// Owner returns the security descriptor owner and whether it was defaulted. +func (sd *SECURITY_DESCRIPTOR) Owner() (owner *SID, defaulted bool, err error) { + err = getSecurityDescriptorOwner(sd, &owner, &defaulted) + return +} + +// SetOwner sets the absolute security descriptor owner. +func (absoluteSD *SECURITY_DESCRIPTOR) SetOwner(owner *SID, defaulted bool) error { + return setSecurityDescriptorOwner(absoluteSD, owner, defaulted) +} + +// Group returns the security descriptor group and whether it was defaulted. +func (sd *SECURITY_DESCRIPTOR) Group() (group *SID, defaulted bool, err error) { + err = getSecurityDescriptorGroup(sd, &group, &defaulted) + return +} + +// SetGroup sets the absolute security descriptor owner. +func (absoluteSD *SECURITY_DESCRIPTOR) SetGroup(group *SID, defaulted bool) error { + return setSecurityDescriptorGroup(absoluteSD, group, defaulted) +} + +// Length returns the length of the security descriptor. +func (sd *SECURITY_DESCRIPTOR) Length() uint32 { + return getSecurityDescriptorLength(sd) +} + +// IsValid returns whether the security descriptor is valid. +func (sd *SECURITY_DESCRIPTOR) IsValid() bool { + return isValidSecurityDescriptor(sd) +} + +// String returns the SDDL form of the security descriptor, with a function signature that can be +// used with %v formatting directives. +func (sd *SECURITY_DESCRIPTOR) String() string { + var sddl *uint16 + err := convertSecurityDescriptorToStringSecurityDescriptor(sd, 1, 0xff, &sddl, nil) + if err != nil { + return "" + } + defer LocalFree(Handle(unsafe.Pointer(sddl))) + return UTF16PtrToString(sddl) +} + +// ToAbsolute converts a self-relative security descriptor into an absolute one. +func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DESCRIPTOR, err error) { + control, _, err := selfRelativeSD.Control() + if err != nil { + return + } + if control&SE_SELF_RELATIVE == 0 { + err = ERROR_INVALID_PARAMETER + return + } + var absoluteSDSize, daclSize, saclSize, ownerSize, groupSize uint32 + err = makeAbsoluteSD(selfRelativeSD, nil, &absoluteSDSize, + nil, &daclSize, nil, &saclSize, nil, &ownerSize, nil, &groupSize) + switch err { + case ERROR_INSUFFICIENT_BUFFER: + case nil: + // makeAbsoluteSD is expected to fail, but it succeeds. + return nil, ERROR_INTERNAL_ERROR + default: + return nil, err + } + if absoluteSDSize > 0 { + absoluteSD = new(SECURITY_DESCRIPTOR) + if unsafe.Sizeof(*absoluteSD) < uintptr(absoluteSDSize) { + panic("sizeof(SECURITY_DESCRIPTOR) too small") + } + } + var ( + dacl *ACL + sacl *ACL + owner *SID + group *SID + ) + if daclSize > 0 { + dacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, daclSize)))) + } + if saclSize > 0 { + sacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, saclSize)))) + } + if ownerSize > 0 { + owner = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, ownerSize)))) + } + if groupSize > 0 { + group = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, groupSize)))) + } + // We call into Windows via makeAbsoluteSD, which sets up + // pointers within absoluteSD that point to other chunks of memory + // we pass into makeAbsoluteSD, and that happens outside the view of the GC. + // We therefore take some care here to then verify the pointers are as we expect + // and set them explicitly in view of the GC. See https://go.dev/issue/73199. + // TODO: consider weak pointers once Go 1.24 is appropriate. See suggestion in https://go.dev/cl/663575. + err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize, + dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize) + if err != nil { + // Don't return absoluteSD, which might be partially initialized. + return nil, err + } + // Before using any fields, verify absoluteSD is in the format we expect according to Windows. + // See https://learn.microsoft.com/en-us/windows/win32/secauthz/absolute-and-self-relative-security-descriptors + absControl, _, err := absoluteSD.Control() + if err != nil { + panic("absoluteSD: " + err.Error()) + } + if absControl&SE_SELF_RELATIVE != 0 { + panic("absoluteSD not in absolute format") + } + if absoluteSD.dacl != dacl { + panic("dacl pointer mismatch") + } + if absoluteSD.sacl != sacl { + panic("sacl pointer mismatch") + } + if absoluteSD.owner != owner { + panic("owner pointer mismatch") + } + if absoluteSD.group != group { + panic("group pointer mismatch") + } + absoluteSD.dacl = dacl + absoluteSD.sacl = sacl + absoluteSD.owner = owner + absoluteSD.group = group + + return +} + +// ToSelfRelative converts an absolute security descriptor into a self-relative one. +func (absoluteSD *SECURITY_DESCRIPTOR) ToSelfRelative() (selfRelativeSD *SECURITY_DESCRIPTOR, err error) { + control, _, err := absoluteSD.Control() + if err != nil { + return + } + if control&SE_SELF_RELATIVE != 0 { + err = ERROR_INVALID_PARAMETER + return + } + var selfRelativeSDSize uint32 + err = makeSelfRelativeSD(absoluteSD, nil, &selfRelativeSDSize) + switch err { + case ERROR_INSUFFICIENT_BUFFER: + case nil: + // makeSelfRelativeSD is expected to fail, but it succeeds. + return nil, ERROR_INTERNAL_ERROR + default: + return nil, err + } + if selfRelativeSDSize > 0 { + selfRelativeSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, selfRelativeSDSize)[0])) + } + err = makeSelfRelativeSD(absoluteSD, selfRelativeSD, &selfRelativeSDSize) + return +} + +func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR { + sdLen := int(selfRelativeSD.Length()) + const min = int(unsafe.Sizeof(SECURITY_DESCRIPTOR{})) + if sdLen < min { + sdLen = min + } + + src := unsafe.Slice((*byte)(unsafe.Pointer(selfRelativeSD)), sdLen) + // SECURITY_DESCRIPTOR has pointers in it, which means checkptr expects for it to + // be aligned properly. When we're copying a Windows-allocated struct to a + // Go-allocated one, make sure that the Go allocation is aligned to the + // pointer size. + const psize = int(unsafe.Sizeof(uintptr(0))) + alloc := make([]uintptr, (sdLen+psize-1)/psize) + dst := unsafe.Slice((*byte)(unsafe.Pointer(&alloc[0])), sdLen) + copy(dst, src) + return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0])) +} + +// SecurityDescriptorFromString converts an SDDL string describing a security descriptor into a +// self-relative security descriptor object allocated on the Go heap. +func SecurityDescriptorFromString(sddl string) (sd *SECURITY_DESCRIPTOR, err error) { + var winHeapSD *SECURITY_DESCRIPTOR + err = convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &winHeapSD, nil) + if err != nil { + return + } + defer LocalFree(Handle(unsafe.Pointer(winHeapSD))) + return winHeapSD.copySelfRelativeSecurityDescriptor(), nil +} + +// GetSecurityInfo queries the security information for a given handle and returns the self-relative security +// descriptor result on the Go heap. +func GetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) { + var winHeapSD *SECURITY_DESCRIPTOR + err = getSecurityInfo(handle, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD) + if err != nil { + return + } + defer LocalFree(Handle(unsafe.Pointer(winHeapSD))) + return winHeapSD.copySelfRelativeSecurityDescriptor(), nil +} + +// GetNamedSecurityInfo queries the security information for a given named object and returns the self-relative security +// descriptor result on the Go heap. The security descriptor might be nil, even when err is nil, if the object exists +// but has no security descriptor. +func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) { + var winHeapSD *SECURITY_DESCRIPTOR + err = getNamedSecurityInfo(objectName, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD) + if err != nil { + return + } + if winHeapSD == nil { + return nil, nil + } + defer LocalFree(Handle(unsafe.Pointer(winHeapSD))) + return winHeapSD.copySelfRelativeSecurityDescriptor(), nil +} + +// BuildSecurityDescriptor makes a new security descriptor using the input trustees, explicit access lists, and +// prior security descriptor to be merged, any of which can be nil, returning the self-relative security descriptor +// result on the Go heap. +func BuildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, accessEntries []EXPLICIT_ACCESS, auditEntries []EXPLICIT_ACCESS, mergedSecurityDescriptor *SECURITY_DESCRIPTOR) (sd *SECURITY_DESCRIPTOR, err error) { + var winHeapSD *SECURITY_DESCRIPTOR + var winHeapSDSize uint32 + var firstAccessEntry *EXPLICIT_ACCESS + if len(accessEntries) > 0 { + firstAccessEntry = &accessEntries[0] + } + var firstAuditEntry *EXPLICIT_ACCESS + if len(auditEntries) > 0 { + firstAuditEntry = &auditEntries[0] + } + err = buildSecurityDescriptor(owner, group, uint32(len(accessEntries)), firstAccessEntry, uint32(len(auditEntries)), firstAuditEntry, mergedSecurityDescriptor, &winHeapSDSize, &winHeapSD) + if err != nil { + return + } + defer LocalFree(Handle(unsafe.Pointer(winHeapSD))) + return winHeapSD.copySelfRelativeSecurityDescriptor(), nil +} + +// NewSecurityDescriptor creates and initializes a new absolute security descriptor. +func NewSecurityDescriptor() (absoluteSD *SECURITY_DESCRIPTOR, err error) { + absoluteSD = &SECURITY_DESCRIPTOR{} + err = initializeSecurityDescriptor(absoluteSD, 1) + return +} + +// ACLFromEntries returns a new ACL on the Go heap containing a list of explicit entries as well as those of another ACL. +// Both explicitEntries and mergedACL are optional and can be nil. +func ACLFromEntries(explicitEntries []EXPLICIT_ACCESS, mergedACL *ACL) (acl *ACL, err error) { + var firstExplicitEntry *EXPLICIT_ACCESS + if len(explicitEntries) > 0 { + firstExplicitEntry = &explicitEntries[0] + } + var winHeapACL *ACL + err = setEntriesInAcl(uint32(len(explicitEntries)), firstExplicitEntry, mergedACL, &winHeapACL) + if err != nil { + return + } + defer LocalFree(Handle(unsafe.Pointer(winHeapACL))) + aclBytes := make([]byte, winHeapACL.aclSize) + copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes):len(aclBytes)]) + return (*ACL)(unsafe.Pointer(&aclBytes[0])), nil +} diff --git a/vendor/golang.org/x/sys/windows/service.go b/vendor/golang.org/x/sys/windows/service.go new file mode 100644 index 0000000..a9dc630 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/service.go @@ -0,0 +1,257 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows + +package windows + +const ( + SC_MANAGER_CONNECT = 1 + SC_MANAGER_CREATE_SERVICE = 2 + SC_MANAGER_ENUMERATE_SERVICE = 4 + SC_MANAGER_LOCK = 8 + SC_MANAGER_QUERY_LOCK_STATUS = 16 + SC_MANAGER_MODIFY_BOOT_CONFIG = 32 + SC_MANAGER_ALL_ACCESS = 0xf003f +) + +const ( + SERVICE_KERNEL_DRIVER = 1 + SERVICE_FILE_SYSTEM_DRIVER = 2 + SERVICE_ADAPTER = 4 + SERVICE_RECOGNIZER_DRIVER = 8 + SERVICE_WIN32_OWN_PROCESS = 16 + SERVICE_WIN32_SHARE_PROCESS = 32 + SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS + SERVICE_INTERACTIVE_PROCESS = 256 + SERVICE_DRIVER = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER + SERVICE_TYPE_ALL = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS + + SERVICE_BOOT_START = 0 + SERVICE_SYSTEM_START = 1 + SERVICE_AUTO_START = 2 + SERVICE_DEMAND_START = 3 + SERVICE_DISABLED = 4 + + SERVICE_ERROR_IGNORE = 0 + SERVICE_ERROR_NORMAL = 1 + SERVICE_ERROR_SEVERE = 2 + SERVICE_ERROR_CRITICAL = 3 + + SC_STATUS_PROCESS_INFO = 0 + + SC_ACTION_NONE = 0 + SC_ACTION_RESTART = 1 + SC_ACTION_REBOOT = 2 + SC_ACTION_RUN_COMMAND = 3 + + SERVICE_STOPPED = 1 + SERVICE_START_PENDING = 2 + SERVICE_STOP_PENDING = 3 + SERVICE_RUNNING = 4 + SERVICE_CONTINUE_PENDING = 5 + SERVICE_PAUSE_PENDING = 6 + SERVICE_PAUSED = 7 + SERVICE_NO_CHANGE = 0xffffffff + + SERVICE_ACCEPT_STOP = 1 + SERVICE_ACCEPT_PAUSE_CONTINUE = 2 + SERVICE_ACCEPT_SHUTDOWN = 4 + SERVICE_ACCEPT_PARAMCHANGE = 8 + SERVICE_ACCEPT_NETBINDCHANGE = 16 + SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 32 + SERVICE_ACCEPT_POWEREVENT = 64 + SERVICE_ACCEPT_SESSIONCHANGE = 128 + SERVICE_ACCEPT_PRESHUTDOWN = 256 + + SERVICE_CONTROL_STOP = 1 + SERVICE_CONTROL_PAUSE = 2 + SERVICE_CONTROL_CONTINUE = 3 + SERVICE_CONTROL_INTERROGATE = 4 + SERVICE_CONTROL_SHUTDOWN = 5 + SERVICE_CONTROL_PARAMCHANGE = 6 + SERVICE_CONTROL_NETBINDADD = 7 + SERVICE_CONTROL_NETBINDREMOVE = 8 + SERVICE_CONTROL_NETBINDENABLE = 9 + SERVICE_CONTROL_NETBINDDISABLE = 10 + SERVICE_CONTROL_DEVICEEVENT = 11 + SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12 + SERVICE_CONTROL_POWEREVENT = 13 + SERVICE_CONTROL_SESSIONCHANGE = 14 + SERVICE_CONTROL_PRESHUTDOWN = 15 + + SERVICE_ACTIVE = 1 + SERVICE_INACTIVE = 2 + SERVICE_STATE_ALL = 3 + + SERVICE_QUERY_CONFIG = 1 + SERVICE_CHANGE_CONFIG = 2 + SERVICE_QUERY_STATUS = 4 + SERVICE_ENUMERATE_DEPENDENTS = 8 + SERVICE_START = 16 + SERVICE_STOP = 32 + SERVICE_PAUSE_CONTINUE = 64 + SERVICE_INTERROGATE = 128 + SERVICE_USER_DEFINED_CONTROL = 256 + SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL + + SERVICE_RUNS_IN_SYSTEM_PROCESS = 1 + + SERVICE_CONFIG_DESCRIPTION = 1 + SERVICE_CONFIG_FAILURE_ACTIONS = 2 + SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3 + SERVICE_CONFIG_FAILURE_ACTIONS_FLAG = 4 + SERVICE_CONFIG_SERVICE_SID_INFO = 5 + SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 6 + SERVICE_CONFIG_PRESHUTDOWN_INFO = 7 + SERVICE_CONFIG_TRIGGER_INFO = 8 + SERVICE_CONFIG_PREFERRED_NODE = 9 + SERVICE_CONFIG_LAUNCH_PROTECTED = 12 + + SERVICE_SID_TYPE_NONE = 0 + SERVICE_SID_TYPE_UNRESTRICTED = 1 + SERVICE_SID_TYPE_RESTRICTED = 2 | SERVICE_SID_TYPE_UNRESTRICTED + + SC_ENUM_PROCESS_INFO = 0 + + SERVICE_NOTIFY_STATUS_CHANGE = 2 + SERVICE_NOTIFY_STOPPED = 0x00000001 + SERVICE_NOTIFY_START_PENDING = 0x00000002 + SERVICE_NOTIFY_STOP_PENDING = 0x00000004 + SERVICE_NOTIFY_RUNNING = 0x00000008 + SERVICE_NOTIFY_CONTINUE_PENDING = 0x00000010 + SERVICE_NOTIFY_PAUSE_PENDING = 0x00000020 + SERVICE_NOTIFY_PAUSED = 0x00000040 + SERVICE_NOTIFY_CREATED = 0x00000080 + SERVICE_NOTIFY_DELETED = 0x00000100 + SERVICE_NOTIFY_DELETE_PENDING = 0x00000200 + + SC_EVENT_DATABASE_CHANGE = 0 + SC_EVENT_PROPERTY_CHANGE = 1 + SC_EVENT_STATUS_CHANGE = 2 + + SERVICE_START_REASON_DEMAND = 0x00000001 + SERVICE_START_REASON_AUTO = 0x00000002 + SERVICE_START_REASON_TRIGGER = 0x00000004 + SERVICE_START_REASON_RESTART_ON_FAILURE = 0x00000008 + SERVICE_START_REASON_DELAYEDAUTO = 0x00000010 + + SERVICE_DYNAMIC_INFORMATION_LEVEL_START_REASON = 1 +) + +type ENUM_SERVICE_STATUS struct { + ServiceName *uint16 + DisplayName *uint16 + ServiceStatus SERVICE_STATUS +} + +type SERVICE_STATUS struct { + ServiceType uint32 + CurrentState uint32 + ControlsAccepted uint32 + Win32ExitCode uint32 + ServiceSpecificExitCode uint32 + CheckPoint uint32 + WaitHint uint32 +} + +type SERVICE_TABLE_ENTRY struct { + ServiceName *uint16 + ServiceProc uintptr +} + +type QUERY_SERVICE_CONFIG struct { + ServiceType uint32 + StartType uint32 + ErrorControl uint32 + BinaryPathName *uint16 + LoadOrderGroup *uint16 + TagId uint32 + Dependencies *uint16 + ServiceStartName *uint16 + DisplayName *uint16 +} + +type SERVICE_DESCRIPTION struct { + Description *uint16 +} + +type SERVICE_DELAYED_AUTO_START_INFO struct { + IsDelayedAutoStartUp uint32 +} + +type SERVICE_STATUS_PROCESS struct { + ServiceType uint32 + CurrentState uint32 + ControlsAccepted uint32 + Win32ExitCode uint32 + ServiceSpecificExitCode uint32 + CheckPoint uint32 + WaitHint uint32 + ProcessId uint32 + ServiceFlags uint32 +} + +type ENUM_SERVICE_STATUS_PROCESS struct { + ServiceName *uint16 + DisplayName *uint16 + ServiceStatusProcess SERVICE_STATUS_PROCESS +} + +type SERVICE_NOTIFY struct { + Version uint32 + NotifyCallback uintptr + Context uintptr + NotificationStatus uint32 + ServiceStatus SERVICE_STATUS_PROCESS + NotificationTriggered uint32 + ServiceNames *uint16 +} + +type SERVICE_FAILURE_ACTIONS struct { + ResetPeriod uint32 + RebootMsg *uint16 + Command *uint16 + ActionsCount uint32 + Actions *SC_ACTION +} + +type SERVICE_FAILURE_ACTIONS_FLAG struct { + FailureActionsOnNonCrashFailures int32 +} + +type SC_ACTION struct { + Type uint32 + Delay uint32 +} + +type QUERY_SERVICE_LOCK_STATUS struct { + IsLocked uint32 + LockOwner *uint16 + LockDuration uint32 +} + +//sys OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenSCManagerW +//sys CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle +//sys CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW +//sys OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW +//sys DeleteService(service Handle) (err error) = advapi32.DeleteService +//sys StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) = advapi32.StartServiceW +//sys QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) = advapi32.QueryServiceStatus +//sys QueryServiceLockStatus(mgr Handle, lockStatus *QUERY_SERVICE_LOCK_STATUS, bufSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceLockStatusW +//sys ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) = advapi32.ControlService +//sys StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) = advapi32.StartServiceCtrlDispatcherW +//sys SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) = advapi32.SetServiceStatus +//sys ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) = advapi32.ChangeServiceConfigW +//sys QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfigW +//sys ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) = advapi32.ChangeServiceConfig2W +//sys QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfig2W +//sys EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) = advapi32.EnumServicesStatusExW +//sys QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceStatusEx +//sys NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) = advapi32.NotifyServiceStatusChangeW +//sys SubscribeServiceChangeNotifications(service Handle, eventType uint32, callback uintptr, callbackCtx uintptr, subscription *uintptr) (ret error) = sechost.SubscribeServiceChangeNotifications? +//sys UnsubscribeServiceChangeNotifications(subscription uintptr) = sechost.UnsubscribeServiceChangeNotifications? +//sys RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, context uintptr) (handle Handle, err error) = advapi32.RegisterServiceCtrlHandlerExW +//sys QueryServiceDynamicInformation(service Handle, infoLevel uint32, dynamicInfo unsafe.Pointer) (err error) = advapi32.QueryServiceDynamicInformation? +//sys EnumDependentServices(service Handle, activityState uint32, services *ENUM_SERVICE_STATUS, buffSize uint32, bytesNeeded *uint32, servicesReturned *uint32) (err error) = advapi32.EnumDependentServicesW diff --git a/vendor/golang.org/x/sys/windows/setupapi_windows.go b/vendor/golang.org/x/sys/windows/setupapi_windows.go new file mode 100644 index 0000000..f812648 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/setupapi_windows.go @@ -0,0 +1,1425 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +import ( + "encoding/binary" + "errors" + "fmt" + "runtime" + "strings" + "syscall" + "unsafe" +) + +// This file contains functions that wrap SetupAPI.dll and CfgMgr32.dll, +// core system functions for managing hardware devices, drivers, and the PnP tree. +// Information about these APIs can be found at: +// https://docs.microsoft.com/en-us/windows-hardware/drivers/install/setupapi +// https://docs.microsoft.com/en-us/windows/win32/devinst/cfgmgr32- + +const ( + ERROR_EXPECTED_SECTION_NAME Errno = 0x20000000 | 0xC0000000 | 0 + ERROR_BAD_SECTION_NAME_LINE Errno = 0x20000000 | 0xC0000000 | 1 + ERROR_SECTION_NAME_TOO_LONG Errno = 0x20000000 | 0xC0000000 | 2 + ERROR_GENERAL_SYNTAX Errno = 0x20000000 | 0xC0000000 | 3 + ERROR_WRONG_INF_STYLE Errno = 0x20000000 | 0xC0000000 | 0x100 + ERROR_SECTION_NOT_FOUND Errno = 0x20000000 | 0xC0000000 | 0x101 + ERROR_LINE_NOT_FOUND Errno = 0x20000000 | 0xC0000000 | 0x102 + ERROR_NO_BACKUP Errno = 0x20000000 | 0xC0000000 | 0x103 + ERROR_NO_ASSOCIATED_CLASS Errno = 0x20000000 | 0xC0000000 | 0x200 + ERROR_CLASS_MISMATCH Errno = 0x20000000 | 0xC0000000 | 0x201 + ERROR_DUPLICATE_FOUND Errno = 0x20000000 | 0xC0000000 | 0x202 + ERROR_NO_DRIVER_SELECTED Errno = 0x20000000 | 0xC0000000 | 0x203 + ERROR_KEY_DOES_NOT_EXIST Errno = 0x20000000 | 0xC0000000 | 0x204 + ERROR_INVALID_DEVINST_NAME Errno = 0x20000000 | 0xC0000000 | 0x205 + ERROR_INVALID_CLASS Errno = 0x20000000 | 0xC0000000 | 0x206 + ERROR_DEVINST_ALREADY_EXISTS Errno = 0x20000000 | 0xC0000000 | 0x207 + ERROR_DEVINFO_NOT_REGISTERED Errno = 0x20000000 | 0xC0000000 | 0x208 + ERROR_INVALID_REG_PROPERTY Errno = 0x20000000 | 0xC0000000 | 0x209 + ERROR_NO_INF Errno = 0x20000000 | 0xC0000000 | 0x20A + ERROR_NO_SUCH_DEVINST Errno = 0x20000000 | 0xC0000000 | 0x20B + ERROR_CANT_LOAD_CLASS_ICON Errno = 0x20000000 | 0xC0000000 | 0x20C + ERROR_INVALID_CLASS_INSTALLER Errno = 0x20000000 | 0xC0000000 | 0x20D + ERROR_DI_DO_DEFAULT Errno = 0x20000000 | 0xC0000000 | 0x20E + ERROR_DI_NOFILECOPY Errno = 0x20000000 | 0xC0000000 | 0x20F + ERROR_INVALID_HWPROFILE Errno = 0x20000000 | 0xC0000000 | 0x210 + ERROR_NO_DEVICE_SELECTED Errno = 0x20000000 | 0xC0000000 | 0x211 + ERROR_DEVINFO_LIST_LOCKED Errno = 0x20000000 | 0xC0000000 | 0x212 + ERROR_DEVINFO_DATA_LOCKED Errno = 0x20000000 | 0xC0000000 | 0x213 + ERROR_DI_BAD_PATH Errno = 0x20000000 | 0xC0000000 | 0x214 + ERROR_NO_CLASSINSTALL_PARAMS Errno = 0x20000000 | 0xC0000000 | 0x215 + ERROR_FILEQUEUE_LOCKED Errno = 0x20000000 | 0xC0000000 | 0x216 + ERROR_BAD_SERVICE_INSTALLSECT Errno = 0x20000000 | 0xC0000000 | 0x217 + ERROR_NO_CLASS_DRIVER_LIST Errno = 0x20000000 | 0xC0000000 | 0x218 + ERROR_NO_ASSOCIATED_SERVICE Errno = 0x20000000 | 0xC0000000 | 0x219 + ERROR_NO_DEFAULT_DEVICE_INTERFACE Errno = 0x20000000 | 0xC0000000 | 0x21A + ERROR_DEVICE_INTERFACE_ACTIVE Errno = 0x20000000 | 0xC0000000 | 0x21B + ERROR_DEVICE_INTERFACE_REMOVED Errno = 0x20000000 | 0xC0000000 | 0x21C + ERROR_BAD_INTERFACE_INSTALLSECT Errno = 0x20000000 | 0xC0000000 | 0x21D + ERROR_NO_SUCH_INTERFACE_CLASS Errno = 0x20000000 | 0xC0000000 | 0x21E + ERROR_INVALID_REFERENCE_STRING Errno = 0x20000000 | 0xC0000000 | 0x21F + ERROR_INVALID_MACHINENAME Errno = 0x20000000 | 0xC0000000 | 0x220 + ERROR_REMOTE_COMM_FAILURE Errno = 0x20000000 | 0xC0000000 | 0x221 + ERROR_MACHINE_UNAVAILABLE Errno = 0x20000000 | 0xC0000000 | 0x222 + ERROR_NO_CONFIGMGR_SERVICES Errno = 0x20000000 | 0xC0000000 | 0x223 + ERROR_INVALID_PROPPAGE_PROVIDER Errno = 0x20000000 | 0xC0000000 | 0x224 + ERROR_NO_SUCH_DEVICE_INTERFACE Errno = 0x20000000 | 0xC0000000 | 0x225 + ERROR_DI_POSTPROCESSING_REQUIRED Errno = 0x20000000 | 0xC0000000 | 0x226 + ERROR_INVALID_COINSTALLER Errno = 0x20000000 | 0xC0000000 | 0x227 + ERROR_NO_COMPAT_DRIVERS Errno = 0x20000000 | 0xC0000000 | 0x228 + ERROR_NO_DEVICE_ICON Errno = 0x20000000 | 0xC0000000 | 0x229 + ERROR_INVALID_INF_LOGCONFIG Errno = 0x20000000 | 0xC0000000 | 0x22A + ERROR_DI_DONT_INSTALL Errno = 0x20000000 | 0xC0000000 | 0x22B + ERROR_INVALID_FILTER_DRIVER Errno = 0x20000000 | 0xC0000000 | 0x22C + ERROR_NON_WINDOWS_NT_DRIVER Errno = 0x20000000 | 0xC0000000 | 0x22D + ERROR_NON_WINDOWS_DRIVER Errno = 0x20000000 | 0xC0000000 | 0x22E + ERROR_NO_CATALOG_FOR_OEM_INF Errno = 0x20000000 | 0xC0000000 | 0x22F + ERROR_DEVINSTALL_QUEUE_NONNATIVE Errno = 0x20000000 | 0xC0000000 | 0x230 + ERROR_NOT_DISABLEABLE Errno = 0x20000000 | 0xC0000000 | 0x231 + ERROR_CANT_REMOVE_DEVINST Errno = 0x20000000 | 0xC0000000 | 0x232 + ERROR_INVALID_TARGET Errno = 0x20000000 | 0xC0000000 | 0x233 + ERROR_DRIVER_NONNATIVE Errno = 0x20000000 | 0xC0000000 | 0x234 + ERROR_IN_WOW64 Errno = 0x20000000 | 0xC0000000 | 0x235 + ERROR_SET_SYSTEM_RESTORE_POINT Errno = 0x20000000 | 0xC0000000 | 0x236 + ERROR_SCE_DISABLED Errno = 0x20000000 | 0xC0000000 | 0x238 + ERROR_UNKNOWN_EXCEPTION Errno = 0x20000000 | 0xC0000000 | 0x239 + ERROR_PNP_REGISTRY_ERROR Errno = 0x20000000 | 0xC0000000 | 0x23A + ERROR_REMOTE_REQUEST_UNSUPPORTED Errno = 0x20000000 | 0xC0000000 | 0x23B + ERROR_NOT_AN_INSTALLED_OEM_INF Errno = 0x20000000 | 0xC0000000 | 0x23C + ERROR_INF_IN_USE_BY_DEVICES Errno = 0x20000000 | 0xC0000000 | 0x23D + ERROR_DI_FUNCTION_OBSOLETE Errno = 0x20000000 | 0xC0000000 | 0x23E + ERROR_NO_AUTHENTICODE_CATALOG Errno = 0x20000000 | 0xC0000000 | 0x23F + ERROR_AUTHENTICODE_DISALLOWED Errno = 0x20000000 | 0xC0000000 | 0x240 + ERROR_AUTHENTICODE_TRUSTED_PUBLISHER Errno = 0x20000000 | 0xC0000000 | 0x241 + ERROR_AUTHENTICODE_TRUST_NOT_ESTABLISHED Errno = 0x20000000 | 0xC0000000 | 0x242 + ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED Errno = 0x20000000 | 0xC0000000 | 0x243 + ERROR_SIGNATURE_OSATTRIBUTE_MISMATCH Errno = 0x20000000 | 0xC0000000 | 0x244 + ERROR_ONLY_VALIDATE_VIA_AUTHENTICODE Errno = 0x20000000 | 0xC0000000 | 0x245 + ERROR_DEVICE_INSTALLER_NOT_READY Errno = 0x20000000 | 0xC0000000 | 0x246 + ERROR_DRIVER_STORE_ADD_FAILED Errno = 0x20000000 | 0xC0000000 | 0x247 + ERROR_DEVICE_INSTALL_BLOCKED Errno = 0x20000000 | 0xC0000000 | 0x248 + ERROR_DRIVER_INSTALL_BLOCKED Errno = 0x20000000 | 0xC0000000 | 0x249 + ERROR_WRONG_INF_TYPE Errno = 0x20000000 | 0xC0000000 | 0x24A + ERROR_FILE_HASH_NOT_IN_CATALOG Errno = 0x20000000 | 0xC0000000 | 0x24B + ERROR_DRIVER_STORE_DELETE_FAILED Errno = 0x20000000 | 0xC0000000 | 0x24C + ERROR_UNRECOVERABLE_STACK_OVERFLOW Errno = 0x20000000 | 0xC0000000 | 0x300 + EXCEPTION_SPAPI_UNRECOVERABLE_STACK_OVERFLOW Errno = ERROR_UNRECOVERABLE_STACK_OVERFLOW + ERROR_NO_DEFAULT_INTERFACE_DEVICE Errno = ERROR_NO_DEFAULT_DEVICE_INTERFACE + ERROR_INTERFACE_DEVICE_ACTIVE Errno = ERROR_DEVICE_INTERFACE_ACTIVE + ERROR_INTERFACE_DEVICE_REMOVED Errno = ERROR_DEVICE_INTERFACE_REMOVED + ERROR_NO_SUCH_INTERFACE_DEVICE Errno = ERROR_NO_SUCH_DEVICE_INTERFACE +) + +const ( + MAX_DEVICE_ID_LEN = 200 + MAX_DEVNODE_ID_LEN = MAX_DEVICE_ID_LEN + MAX_GUID_STRING_LEN = 39 // 38 chars + terminator null + MAX_CLASS_NAME_LEN = 32 + MAX_PROFILE_LEN = 80 + MAX_CONFIG_VALUE = 9999 + MAX_INSTANCE_VALUE = 9999 + CONFIGMG_VERSION = 0x0400 +) + +// Maximum string length constants +const ( + LINE_LEN = 256 // Windows 9x-compatible maximum for displayable strings coming from a device INF. + MAX_INF_STRING_LENGTH = 4096 // Actual maximum size of an INF string (including string substitutions). + MAX_INF_SECTION_NAME_LENGTH = 255 // For Windows 9x compatibility, INF section names should be constrained to 32 characters. + MAX_TITLE_LEN = 60 + MAX_INSTRUCTION_LEN = 256 + MAX_LABEL_LEN = 30 + MAX_SERVICE_NAME_LEN = 256 + MAX_SUBTITLE_LEN = 256 +) + +const ( + // SP_MAX_MACHINENAME_LENGTH defines maximum length of a machine name in the format expected by ConfigMgr32 CM_Connect_Machine (i.e., "\\\\MachineName\0"). + SP_MAX_MACHINENAME_LENGTH = MAX_PATH + 3 +) + +// HSPFILEQ is type for setup file queue +type HSPFILEQ uintptr + +// DevInfo holds reference to device information set +type DevInfo Handle + +// DEVINST is a handle usually recognized by cfgmgr32 APIs +type DEVINST uint32 + +// DevInfoData is a device information structure (references a device instance that is a member of a device information set) +type DevInfoData struct { + size uint32 + ClassGUID GUID + DevInst DEVINST + _ uintptr +} + +// DevInfoListDetailData is a structure for detailed information on a device information set (used for SetupDiGetDeviceInfoListDetail which supersedes the functionality of SetupDiGetDeviceInfoListClass). +type DevInfoListDetailData struct { + size uint32 // Use unsafeSizeOf method + ClassGUID GUID + RemoteMachineHandle Handle + remoteMachineName [SP_MAX_MACHINENAME_LENGTH]uint16 +} + +func (*DevInfoListDetailData) unsafeSizeOf() uint32 { + if unsafe.Sizeof(uintptr(0)) == 4 { + // Windows declares this with pshpack1.h + return uint32(unsafe.Offsetof(DevInfoListDetailData{}.remoteMachineName) + unsafe.Sizeof(DevInfoListDetailData{}.remoteMachineName)) + } + return uint32(unsafe.Sizeof(DevInfoListDetailData{})) +} + +func (data *DevInfoListDetailData) RemoteMachineName() string { + return UTF16ToString(data.remoteMachineName[:]) +} + +func (data *DevInfoListDetailData) SetRemoteMachineName(remoteMachineName string) error { + str, err := UTF16FromString(remoteMachineName) + if err != nil { + return err + } + copy(data.remoteMachineName[:], str) + return nil +} + +// DI_FUNCTION is function type for device installer +type DI_FUNCTION uint32 + +const ( + DIF_SELECTDEVICE DI_FUNCTION = 0x00000001 + DIF_INSTALLDEVICE DI_FUNCTION = 0x00000002 + DIF_ASSIGNRESOURCES DI_FUNCTION = 0x00000003 + DIF_PROPERTIES DI_FUNCTION = 0x00000004 + DIF_REMOVE DI_FUNCTION = 0x00000005 + DIF_FIRSTTIMESETUP DI_FUNCTION = 0x00000006 + DIF_FOUNDDEVICE DI_FUNCTION = 0x00000007 + DIF_SELECTCLASSDRIVERS DI_FUNCTION = 0x00000008 + DIF_VALIDATECLASSDRIVERS DI_FUNCTION = 0x00000009 + DIF_INSTALLCLASSDRIVERS DI_FUNCTION = 0x0000000A + DIF_CALCDISKSPACE DI_FUNCTION = 0x0000000B + DIF_DESTROYPRIVATEDATA DI_FUNCTION = 0x0000000C + DIF_VALIDATEDRIVER DI_FUNCTION = 0x0000000D + DIF_DETECT DI_FUNCTION = 0x0000000F + DIF_INSTALLWIZARD DI_FUNCTION = 0x00000010 + DIF_DESTROYWIZARDDATA DI_FUNCTION = 0x00000011 + DIF_PROPERTYCHANGE DI_FUNCTION = 0x00000012 + DIF_ENABLECLASS DI_FUNCTION = 0x00000013 + DIF_DETECTVERIFY DI_FUNCTION = 0x00000014 + DIF_INSTALLDEVICEFILES DI_FUNCTION = 0x00000015 + DIF_UNREMOVE DI_FUNCTION = 0x00000016 + DIF_SELECTBESTCOMPATDRV DI_FUNCTION = 0x00000017 + DIF_ALLOW_INSTALL DI_FUNCTION = 0x00000018 + DIF_REGISTERDEVICE DI_FUNCTION = 0x00000019 + DIF_NEWDEVICEWIZARD_PRESELECT DI_FUNCTION = 0x0000001A + DIF_NEWDEVICEWIZARD_SELECT DI_FUNCTION = 0x0000001B + DIF_NEWDEVICEWIZARD_PREANALYZE DI_FUNCTION = 0x0000001C + DIF_NEWDEVICEWIZARD_POSTANALYZE DI_FUNCTION = 0x0000001D + DIF_NEWDEVICEWIZARD_FINISHINSTALL DI_FUNCTION = 0x0000001E + DIF_INSTALLINTERFACES DI_FUNCTION = 0x00000020 + DIF_DETECTCANCEL DI_FUNCTION = 0x00000021 + DIF_REGISTER_COINSTALLERS DI_FUNCTION = 0x00000022 + DIF_ADDPROPERTYPAGE_ADVANCED DI_FUNCTION = 0x00000023 + DIF_ADDPROPERTYPAGE_BASIC DI_FUNCTION = 0x00000024 + DIF_TROUBLESHOOTER DI_FUNCTION = 0x00000026 + DIF_POWERMESSAGEWAKE DI_FUNCTION = 0x00000027 + DIF_ADDREMOTEPROPERTYPAGE_ADVANCED DI_FUNCTION = 0x00000028 + DIF_UPDATEDRIVER_UI DI_FUNCTION = 0x00000029 + DIF_FINISHINSTALL_ACTION DI_FUNCTION = 0x0000002A +) + +// DevInstallParams is device installation parameters structure (associated with a particular device information element, or globally with a device information set) +type DevInstallParams struct { + size uint32 + Flags DI_FLAGS + FlagsEx DI_FLAGSEX + hwndParent uintptr + InstallMsgHandler uintptr + InstallMsgHandlerContext uintptr + FileQueue HSPFILEQ + _ uintptr + _ uint32 + driverPath [MAX_PATH]uint16 +} + +func (params *DevInstallParams) DriverPath() string { + return UTF16ToString(params.driverPath[:]) +} + +func (params *DevInstallParams) SetDriverPath(driverPath string) error { + str, err := UTF16FromString(driverPath) + if err != nil { + return err + } + copy(params.driverPath[:], str) + return nil +} + +// DI_FLAGS is SP_DEVINSTALL_PARAMS.Flags values +type DI_FLAGS uint32 + +const ( + // Flags for choosing a device + DI_SHOWOEM DI_FLAGS = 0x00000001 // support Other... button + DI_SHOWCOMPAT DI_FLAGS = 0x00000002 // show compatibility list + DI_SHOWCLASS DI_FLAGS = 0x00000004 // show class list + DI_SHOWALL DI_FLAGS = 0x00000007 // both class & compat list shown + DI_NOVCP DI_FLAGS = 0x00000008 // don't create a new copy queue--use caller-supplied FileQueue + DI_DIDCOMPAT DI_FLAGS = 0x00000010 // Searched for compatible devices + DI_DIDCLASS DI_FLAGS = 0x00000020 // Searched for class devices + DI_AUTOASSIGNRES DI_FLAGS = 0x00000040 // No UI for resources if possible + + // Flags returned by DiInstallDevice to indicate need to reboot/restart + DI_NEEDRESTART DI_FLAGS = 0x00000080 // Reboot required to take effect + DI_NEEDREBOOT DI_FLAGS = 0x00000100 // "" + + // Flags for device installation + DI_NOBROWSE DI_FLAGS = 0x00000200 // no Browse... in InsertDisk + + // Flags set by DiBuildDriverInfoList + DI_MULTMFGS DI_FLAGS = 0x00000400 // Set if multiple manufacturers in class driver list + + // Flag indicates that device is disabled + DI_DISABLED DI_FLAGS = 0x00000800 // Set if device disabled + + // Flags for Device/Class Properties + DI_GENERALPAGE_ADDED DI_FLAGS = 0x00001000 + DI_RESOURCEPAGE_ADDED DI_FLAGS = 0x00002000 + + // Flag to indicate the setting properties for this Device (or class) caused a change so the Dev Mgr UI probably needs to be updated. + DI_PROPERTIES_CHANGE DI_FLAGS = 0x00004000 + + // Flag to indicate that the sorting from the INF file should be used. + DI_INF_IS_SORTED DI_FLAGS = 0x00008000 + + // Flag to indicate that only the INF specified by SP_DEVINSTALL_PARAMS.DriverPath should be searched. + DI_ENUMSINGLEINF DI_FLAGS = 0x00010000 + + // Flag that prevents ConfigMgr from removing/re-enumerating devices during device + // registration, installation, and deletion. + DI_DONOTCALLCONFIGMG DI_FLAGS = 0x00020000 + + // The following flag can be used to install a device disabled + DI_INSTALLDISABLED DI_FLAGS = 0x00040000 + + // Flag that causes SetupDiBuildDriverInfoList to build a device's compatible driver + // list from its existing class driver list, instead of the normal INF search. + DI_COMPAT_FROM_CLASS DI_FLAGS = 0x00080000 + + // This flag is set if the Class Install params should be used. + DI_CLASSINSTALLPARAMS DI_FLAGS = 0x00100000 + + // This flag is set if the caller of DiCallClassInstaller does NOT want the internal default action performed if the Class installer returns ERROR_DI_DO_DEFAULT. + DI_NODI_DEFAULTACTION DI_FLAGS = 0x00200000 + + // Flags for device installation + DI_QUIETINSTALL DI_FLAGS = 0x00800000 // don't confuse the user with questions or excess info + DI_NOFILECOPY DI_FLAGS = 0x01000000 // No file Copy necessary + DI_FORCECOPY DI_FLAGS = 0x02000000 // Force files to be copied from install path + DI_DRIVERPAGE_ADDED DI_FLAGS = 0x04000000 // Prop provider added Driver page. + DI_USECI_SELECTSTRINGS DI_FLAGS = 0x08000000 // Use Class Installer Provided strings in the Select Device Dlg + DI_OVERRIDE_INFFLAGS DI_FLAGS = 0x10000000 // Override INF flags + DI_PROPS_NOCHANGEUSAGE DI_FLAGS = 0x20000000 // No Enable/Disable in General Props + + DI_NOSELECTICONS DI_FLAGS = 0x40000000 // No small icons in select device dialogs + + DI_NOWRITE_IDS DI_FLAGS = 0x80000000 // Don't write HW & Compat IDs on install +) + +// DI_FLAGSEX is SP_DEVINSTALL_PARAMS.FlagsEx values +type DI_FLAGSEX uint32 + +const ( + DI_FLAGSEX_CI_FAILED DI_FLAGSEX = 0x00000004 // Failed to Load/Call class installer + DI_FLAGSEX_FINISHINSTALL_ACTION DI_FLAGSEX = 0x00000008 // Class/co-installer wants to get a DIF_FINISH_INSTALL action in client context. + DI_FLAGSEX_DIDINFOLIST DI_FLAGSEX = 0x00000010 // Did the Class Info List + DI_FLAGSEX_DIDCOMPATINFO DI_FLAGSEX = 0x00000020 // Did the Compat Info List + DI_FLAGSEX_FILTERCLASSES DI_FLAGSEX = 0x00000040 + DI_FLAGSEX_SETFAILEDINSTALL DI_FLAGSEX = 0x00000080 + DI_FLAGSEX_DEVICECHANGE DI_FLAGSEX = 0x00000100 + DI_FLAGSEX_ALWAYSWRITEIDS DI_FLAGSEX = 0x00000200 + DI_FLAGSEX_PROPCHANGE_PENDING DI_FLAGSEX = 0x00000400 // One or more device property sheets have had changes made to them, and need to have a DIF_PROPERTYCHANGE occur. + DI_FLAGSEX_ALLOWEXCLUDEDDRVS DI_FLAGSEX = 0x00000800 + DI_FLAGSEX_NOUIONQUERYREMOVE DI_FLAGSEX = 0x00001000 + DI_FLAGSEX_USECLASSFORCOMPAT DI_FLAGSEX = 0x00002000 // Use the device's class when building compat drv list. (Ignored if DI_COMPAT_FROM_CLASS flag is specified.) + DI_FLAGSEX_NO_DRVREG_MODIFY DI_FLAGSEX = 0x00008000 // Don't run AddReg and DelReg for device's software (driver) key. + DI_FLAGSEX_IN_SYSTEM_SETUP DI_FLAGSEX = 0x00010000 // Installation is occurring during initial system setup. + DI_FLAGSEX_INET_DRIVER DI_FLAGSEX = 0x00020000 // Driver came from Windows Update + DI_FLAGSEX_APPENDDRIVERLIST DI_FLAGSEX = 0x00040000 // Cause SetupDiBuildDriverInfoList to append a new driver list to an existing list. + DI_FLAGSEX_PREINSTALLBACKUP DI_FLAGSEX = 0x00080000 // not used + DI_FLAGSEX_BACKUPONREPLACE DI_FLAGSEX = 0x00100000 // not used + DI_FLAGSEX_DRIVERLIST_FROM_URL DI_FLAGSEX = 0x00200000 // build driver list from INF(s) retrieved from URL specified in SP_DEVINSTALL_PARAMS.DriverPath (empty string means Windows Update website) + DI_FLAGSEX_EXCLUDE_OLD_INET_DRIVERS DI_FLAGSEX = 0x00800000 // Don't include old Internet drivers when building a driver list. Ignored on Windows Vista and later. + DI_FLAGSEX_POWERPAGE_ADDED DI_FLAGSEX = 0x01000000 // class installer added their own power page + DI_FLAGSEX_FILTERSIMILARDRIVERS DI_FLAGSEX = 0x02000000 // only include similar drivers in class list + DI_FLAGSEX_INSTALLEDDRIVER DI_FLAGSEX = 0x04000000 // only add the installed driver to the class or compat driver list. Used in calls to SetupDiBuildDriverInfoList + DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE DI_FLAGSEX = 0x08000000 // Don't remove identical driver nodes from the class list + DI_FLAGSEX_ALTPLATFORM_DRVSEARCH DI_FLAGSEX = 0x10000000 // Build driver list based on alternate platform information specified in associated file queue + DI_FLAGSEX_RESTART_DEVICE_ONLY DI_FLAGSEX = 0x20000000 // only restart the device drivers are being installed on as opposed to restarting all devices using those drivers. + DI_FLAGSEX_RECURSIVESEARCH DI_FLAGSEX = 0x40000000 // Tell SetupDiBuildDriverInfoList to do a recursive search + DI_FLAGSEX_SEARCH_PUBLISHED_INFS DI_FLAGSEX = 0x80000000 // Tell SetupDiBuildDriverInfoList to do a "published INF" search +) + +// ClassInstallHeader is the first member of any class install parameters structure. It contains the device installation request code that defines the format of the rest of the install parameters structure. +type ClassInstallHeader struct { + size uint32 + InstallFunction DI_FUNCTION +} + +func MakeClassInstallHeader(installFunction DI_FUNCTION) *ClassInstallHeader { + hdr := &ClassInstallHeader{InstallFunction: installFunction} + hdr.size = uint32(unsafe.Sizeof(*hdr)) + return hdr +} + +// DICS_STATE specifies values indicating a change in a device's state +type DICS_STATE uint32 + +const ( + DICS_ENABLE DICS_STATE = 0x00000001 // The device is being enabled. + DICS_DISABLE DICS_STATE = 0x00000002 // The device is being disabled. + DICS_PROPCHANGE DICS_STATE = 0x00000003 // The properties of the device have changed. + DICS_START DICS_STATE = 0x00000004 // The device is being started (if the request is for the currently active hardware profile). + DICS_STOP DICS_STATE = 0x00000005 // The device is being stopped. The driver stack will be unloaded and the CSCONFIGFLAG_DO_NOT_START flag will be set for the device. +) + +// DICS_FLAG specifies the scope of a device property change +type DICS_FLAG uint32 + +const ( + DICS_FLAG_GLOBAL DICS_FLAG = 0x00000001 // make change in all hardware profiles + DICS_FLAG_CONFIGSPECIFIC DICS_FLAG = 0x00000002 // make change in specified profile only + DICS_FLAG_CONFIGGENERAL DICS_FLAG = 0x00000004 // 1 or more hardware profile-specific changes to follow (obsolete) +) + +// PropChangeParams is a structure corresponding to a DIF_PROPERTYCHANGE install function. +type PropChangeParams struct { + ClassInstallHeader ClassInstallHeader + StateChange DICS_STATE + Scope DICS_FLAG + HwProfile uint32 +} + +// DI_REMOVEDEVICE specifies the scope of the device removal +type DI_REMOVEDEVICE uint32 + +const ( + DI_REMOVEDEVICE_GLOBAL DI_REMOVEDEVICE = 0x00000001 // Make this change in all hardware profiles. Remove information about the device from the registry. + DI_REMOVEDEVICE_CONFIGSPECIFIC DI_REMOVEDEVICE = 0x00000002 // Make this change to only the hardware profile specified by HwProfile. this flag only applies to root-enumerated devices. When Windows removes the device from the last hardware profile in which it was configured, Windows performs a global removal. +) + +// RemoveDeviceParams is a structure corresponding to a DIF_REMOVE install function. +type RemoveDeviceParams struct { + ClassInstallHeader ClassInstallHeader + Scope DI_REMOVEDEVICE + HwProfile uint32 +} + +// DrvInfoData is driver information structure (member of a driver info list that may be associated with a particular device instance, or (globally) with a device information set) +type DrvInfoData struct { + size uint32 + DriverType uint32 + _ uintptr + description [LINE_LEN]uint16 + mfgName [LINE_LEN]uint16 + providerName [LINE_LEN]uint16 + DriverDate Filetime + DriverVersion uint64 +} + +func (data *DrvInfoData) Description() string { + return UTF16ToString(data.description[:]) +} + +func (data *DrvInfoData) SetDescription(description string) error { + str, err := UTF16FromString(description) + if err != nil { + return err + } + copy(data.description[:], str) + return nil +} + +func (data *DrvInfoData) MfgName() string { + return UTF16ToString(data.mfgName[:]) +} + +func (data *DrvInfoData) SetMfgName(mfgName string) error { + str, err := UTF16FromString(mfgName) + if err != nil { + return err + } + copy(data.mfgName[:], str) + return nil +} + +func (data *DrvInfoData) ProviderName() string { + return UTF16ToString(data.providerName[:]) +} + +func (data *DrvInfoData) SetProviderName(providerName string) error { + str, err := UTF16FromString(providerName) + if err != nil { + return err + } + copy(data.providerName[:], str) + return nil +} + +// IsNewer method returns true if DrvInfoData date and version is newer than supplied parameters. +func (data *DrvInfoData) IsNewer(driverDate Filetime, driverVersion uint64) bool { + if data.DriverDate.HighDateTime > driverDate.HighDateTime { + return true + } + if data.DriverDate.HighDateTime < driverDate.HighDateTime { + return false + } + + if data.DriverDate.LowDateTime > driverDate.LowDateTime { + return true + } + if data.DriverDate.LowDateTime < driverDate.LowDateTime { + return false + } + + if data.DriverVersion > driverVersion { + return true + } + if data.DriverVersion < driverVersion { + return false + } + + return false +} + +// DrvInfoDetailData is driver information details structure (provides detailed information about a particular driver information structure) +type DrvInfoDetailData struct { + size uint32 // Use unsafeSizeOf method + InfDate Filetime + compatIDsOffset uint32 + compatIDsLength uint32 + _ uintptr + sectionName [LINE_LEN]uint16 + infFileName [MAX_PATH]uint16 + drvDescription [LINE_LEN]uint16 + hardwareID [1]uint16 +} + +func (*DrvInfoDetailData) unsafeSizeOf() uint32 { + if unsafe.Sizeof(uintptr(0)) == 4 { + // Windows declares this with pshpack1.h + return uint32(unsafe.Offsetof(DrvInfoDetailData{}.hardwareID) + unsafe.Sizeof(DrvInfoDetailData{}.hardwareID)) + } + return uint32(unsafe.Sizeof(DrvInfoDetailData{})) +} + +func (data *DrvInfoDetailData) SectionName() string { + return UTF16ToString(data.sectionName[:]) +} + +func (data *DrvInfoDetailData) InfFileName() string { + return UTF16ToString(data.infFileName[:]) +} + +func (data *DrvInfoDetailData) DrvDescription() string { + return UTF16ToString(data.drvDescription[:]) +} + +func (data *DrvInfoDetailData) HardwareID() string { + if data.compatIDsOffset > 1 { + bufW := data.getBuf() + return UTF16ToString(bufW[:wcslen(bufW)]) + } + + return "" +} + +func (data *DrvInfoDetailData) CompatIDs() []string { + a := make([]string, 0) + + if data.compatIDsLength > 0 { + bufW := data.getBuf() + bufW = bufW[data.compatIDsOffset : data.compatIDsOffset+data.compatIDsLength] + for i := 0; i < len(bufW); { + j := i + wcslen(bufW[i:]) + if i < j { + a = append(a, UTF16ToString(bufW[i:j])) + } + i = j + 1 + } + } + + return a +} + +func (data *DrvInfoDetailData) getBuf() []uint16 { + len := (data.size - uint32(unsafe.Offsetof(data.hardwareID))) / 2 + sl := struct { + addr *uint16 + len int + cap int + }{&data.hardwareID[0], int(len), int(len)} + return *(*[]uint16)(unsafe.Pointer(&sl)) +} + +// IsCompatible method tests if given hardware ID matches the driver or is listed on the compatible ID list. +func (data *DrvInfoDetailData) IsCompatible(hwid string) bool { + hwidLC := strings.ToLower(hwid) + if strings.ToLower(data.HardwareID()) == hwidLC { + return true + } + a := data.CompatIDs() + for i := range a { + if strings.ToLower(a[i]) == hwidLC { + return true + } + } + + return false +} + +// DICD flags control SetupDiCreateDeviceInfo +type DICD uint32 + +const ( + DICD_GENERATE_ID DICD = 0x00000001 + DICD_INHERIT_CLASSDRVS DICD = 0x00000002 +) + +// SUOI flags control SetupUninstallOEMInf +type SUOI uint32 + +const ( + SUOI_FORCEDELETE SUOI = 0x0001 +) + +// SPDIT flags to distinguish between class drivers and +// device drivers. (Passed in 'DriverType' parameter of +// driver information list APIs) +type SPDIT uint32 + +const ( + SPDIT_NODRIVER SPDIT = 0x00000000 + SPDIT_CLASSDRIVER SPDIT = 0x00000001 + SPDIT_COMPATDRIVER SPDIT = 0x00000002 +) + +// DIGCF flags control what is included in the device information set built by SetupDiGetClassDevs +type DIGCF uint32 + +const ( + DIGCF_DEFAULT DIGCF = 0x00000001 // only valid with DIGCF_DEVICEINTERFACE + DIGCF_PRESENT DIGCF = 0x00000002 + DIGCF_ALLCLASSES DIGCF = 0x00000004 + DIGCF_PROFILE DIGCF = 0x00000008 + DIGCF_DEVICEINTERFACE DIGCF = 0x00000010 +) + +// DIREG specifies values for SetupDiCreateDevRegKey, SetupDiOpenDevRegKey, and SetupDiDeleteDevRegKey. +type DIREG uint32 + +const ( + DIREG_DEV DIREG = 0x00000001 // Open/Create/Delete device key + DIREG_DRV DIREG = 0x00000002 // Open/Create/Delete driver key + DIREG_BOTH DIREG = 0x00000004 // Delete both driver and Device key +) + +// SPDRP specifies device registry property codes +// (Codes marked as read-only (R) may only be used for +// SetupDiGetDeviceRegistryProperty) +// +// These values should cover the same set of registry properties +// as defined by the CM_DRP codes in cfgmgr32.h. +// +// Note that SPDRP codes are zero based while CM_DRP codes are one based! +type SPDRP uint32 + +const ( + SPDRP_DEVICEDESC SPDRP = 0x00000000 // DeviceDesc (R/W) + SPDRP_HARDWAREID SPDRP = 0x00000001 // HardwareID (R/W) + SPDRP_COMPATIBLEIDS SPDRP = 0x00000002 // CompatibleIDs (R/W) + SPDRP_SERVICE SPDRP = 0x00000004 // Service (R/W) + SPDRP_CLASS SPDRP = 0x00000007 // Class (R--tied to ClassGUID) + SPDRP_CLASSGUID SPDRP = 0x00000008 // ClassGUID (R/W) + SPDRP_DRIVER SPDRP = 0x00000009 // Driver (R/W) + SPDRP_CONFIGFLAGS SPDRP = 0x0000000A // ConfigFlags (R/W) + SPDRP_MFG SPDRP = 0x0000000B // Mfg (R/W) + SPDRP_FRIENDLYNAME SPDRP = 0x0000000C // FriendlyName (R/W) + SPDRP_LOCATION_INFORMATION SPDRP = 0x0000000D // LocationInformation (R/W) + SPDRP_PHYSICAL_DEVICE_OBJECT_NAME SPDRP = 0x0000000E // PhysicalDeviceObjectName (R) + SPDRP_CAPABILITIES SPDRP = 0x0000000F // Capabilities (R) + SPDRP_UI_NUMBER SPDRP = 0x00000010 // UiNumber (R) + SPDRP_UPPERFILTERS SPDRP = 0x00000011 // UpperFilters (R/W) + SPDRP_LOWERFILTERS SPDRP = 0x00000012 // LowerFilters (R/W) + SPDRP_BUSTYPEGUID SPDRP = 0x00000013 // BusTypeGUID (R) + SPDRP_LEGACYBUSTYPE SPDRP = 0x00000014 // LegacyBusType (R) + SPDRP_BUSNUMBER SPDRP = 0x00000015 // BusNumber (R) + SPDRP_ENUMERATOR_NAME SPDRP = 0x00000016 // Enumerator Name (R) + SPDRP_SECURITY SPDRP = 0x00000017 // Security (R/W, binary form) + SPDRP_SECURITY_SDS SPDRP = 0x00000018 // Security (W, SDS form) + SPDRP_DEVTYPE SPDRP = 0x00000019 // Device Type (R/W) + SPDRP_EXCLUSIVE SPDRP = 0x0000001A // Device is exclusive-access (R/W) + SPDRP_CHARACTERISTICS SPDRP = 0x0000001B // Device Characteristics (R/W) + SPDRP_ADDRESS SPDRP = 0x0000001C // Device Address (R) + SPDRP_UI_NUMBER_DESC_FORMAT SPDRP = 0x0000001D // UiNumberDescFormat (R/W) + SPDRP_DEVICE_POWER_DATA SPDRP = 0x0000001E // Device Power Data (R) + SPDRP_REMOVAL_POLICY SPDRP = 0x0000001F // Removal Policy (R) + SPDRP_REMOVAL_POLICY_HW_DEFAULT SPDRP = 0x00000020 // Hardware Removal Policy (R) + SPDRP_REMOVAL_POLICY_OVERRIDE SPDRP = 0x00000021 // Removal Policy Override (RW) + SPDRP_INSTALL_STATE SPDRP = 0x00000022 // Device Install State (R) + SPDRP_LOCATION_PATHS SPDRP = 0x00000023 // Device Location Paths (R) + SPDRP_BASE_CONTAINERID SPDRP = 0x00000024 // Base ContainerID (R) + + SPDRP_MAXIMUM_PROPERTY SPDRP = 0x00000025 // Upper bound on ordinals +) + +// DEVPROPTYPE represents the property-data-type identifier that specifies the +// data type of a device property value in the unified device property model. +type DEVPROPTYPE uint32 + +const ( + DEVPROP_TYPEMOD_ARRAY DEVPROPTYPE = 0x00001000 + DEVPROP_TYPEMOD_LIST DEVPROPTYPE = 0x00002000 + + DEVPROP_TYPE_EMPTY DEVPROPTYPE = 0x00000000 + DEVPROP_TYPE_NULL DEVPROPTYPE = 0x00000001 + DEVPROP_TYPE_SBYTE DEVPROPTYPE = 0x00000002 + DEVPROP_TYPE_BYTE DEVPROPTYPE = 0x00000003 + DEVPROP_TYPE_INT16 DEVPROPTYPE = 0x00000004 + DEVPROP_TYPE_UINT16 DEVPROPTYPE = 0x00000005 + DEVPROP_TYPE_INT32 DEVPROPTYPE = 0x00000006 + DEVPROP_TYPE_UINT32 DEVPROPTYPE = 0x00000007 + DEVPROP_TYPE_INT64 DEVPROPTYPE = 0x00000008 + DEVPROP_TYPE_UINT64 DEVPROPTYPE = 0x00000009 + DEVPROP_TYPE_FLOAT DEVPROPTYPE = 0x0000000A + DEVPROP_TYPE_DOUBLE DEVPROPTYPE = 0x0000000B + DEVPROP_TYPE_DECIMAL DEVPROPTYPE = 0x0000000C + DEVPROP_TYPE_GUID DEVPROPTYPE = 0x0000000D + DEVPROP_TYPE_CURRENCY DEVPROPTYPE = 0x0000000E + DEVPROP_TYPE_DATE DEVPROPTYPE = 0x0000000F + DEVPROP_TYPE_FILETIME DEVPROPTYPE = 0x00000010 + DEVPROP_TYPE_BOOLEAN DEVPROPTYPE = 0x00000011 + DEVPROP_TYPE_STRING DEVPROPTYPE = 0x00000012 + DEVPROP_TYPE_STRING_LIST DEVPROPTYPE = DEVPROP_TYPE_STRING | DEVPROP_TYPEMOD_LIST + DEVPROP_TYPE_SECURITY_DESCRIPTOR DEVPROPTYPE = 0x00000013 + DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING DEVPROPTYPE = 0x00000014 + DEVPROP_TYPE_DEVPROPKEY DEVPROPTYPE = 0x00000015 + DEVPROP_TYPE_DEVPROPTYPE DEVPROPTYPE = 0x00000016 + DEVPROP_TYPE_BINARY DEVPROPTYPE = DEVPROP_TYPE_BYTE | DEVPROP_TYPEMOD_ARRAY + DEVPROP_TYPE_ERROR DEVPROPTYPE = 0x00000017 + DEVPROP_TYPE_NTSTATUS DEVPROPTYPE = 0x00000018 + DEVPROP_TYPE_STRING_INDIRECT DEVPROPTYPE = 0x00000019 + + MAX_DEVPROP_TYPE DEVPROPTYPE = 0x00000019 + MAX_DEVPROP_TYPEMOD DEVPROPTYPE = 0x00002000 + + DEVPROP_MASK_TYPE DEVPROPTYPE = 0x00000FFF + DEVPROP_MASK_TYPEMOD DEVPROPTYPE = 0x0000F000 +) + +// DEVPROPGUID specifies a property category. +type DEVPROPGUID GUID + +// DEVPROPID uniquely identifies the property within the property category. +type DEVPROPID uint32 + +const DEVPROPID_FIRST_USABLE DEVPROPID = 2 + +// DEVPROPKEY represents a device property key for a device property in the +// unified device property model. +type DEVPROPKEY struct { + FmtID DEVPROPGUID + PID DEVPROPID +} + +// CONFIGRET is a return value or error code from cfgmgr32 APIs +type CONFIGRET uint32 + +func (ret CONFIGRET) Error() string { + if win32Error, ok := ret.Unwrap().(Errno); ok { + return fmt.Sprintf("%s (CfgMgr error: 0x%08x)", win32Error.Error(), uint32(ret)) + } + return fmt.Sprintf("CfgMgr error: 0x%08x", uint32(ret)) +} + +func (ret CONFIGRET) Win32Error(defaultError Errno) Errno { + return cm_MapCrToWin32Err(ret, defaultError) +} + +func (ret CONFIGRET) Unwrap() error { + const noMatch = Errno(^uintptr(0)) + win32Error := ret.Win32Error(noMatch) + if win32Error == noMatch { + return nil + } + return win32Error +} + +const ( + CR_SUCCESS CONFIGRET = 0x00000000 + CR_DEFAULT CONFIGRET = 0x00000001 + CR_OUT_OF_MEMORY CONFIGRET = 0x00000002 + CR_INVALID_POINTER CONFIGRET = 0x00000003 + CR_INVALID_FLAG CONFIGRET = 0x00000004 + CR_INVALID_DEVNODE CONFIGRET = 0x00000005 + CR_INVALID_DEVINST = CR_INVALID_DEVNODE + CR_INVALID_RES_DES CONFIGRET = 0x00000006 + CR_INVALID_LOG_CONF CONFIGRET = 0x00000007 + CR_INVALID_ARBITRATOR CONFIGRET = 0x00000008 + CR_INVALID_NODELIST CONFIGRET = 0x00000009 + CR_DEVNODE_HAS_REQS CONFIGRET = 0x0000000A + CR_DEVINST_HAS_REQS = CR_DEVNODE_HAS_REQS + CR_INVALID_RESOURCEID CONFIGRET = 0x0000000B + CR_DLVXD_NOT_FOUND CONFIGRET = 0x0000000C + CR_NO_SUCH_DEVNODE CONFIGRET = 0x0000000D + CR_NO_SUCH_DEVINST = CR_NO_SUCH_DEVNODE + CR_NO_MORE_LOG_CONF CONFIGRET = 0x0000000E + CR_NO_MORE_RES_DES CONFIGRET = 0x0000000F + CR_ALREADY_SUCH_DEVNODE CONFIGRET = 0x00000010 + CR_ALREADY_SUCH_DEVINST = CR_ALREADY_SUCH_DEVNODE + CR_INVALID_RANGE_LIST CONFIGRET = 0x00000011 + CR_INVALID_RANGE CONFIGRET = 0x00000012 + CR_FAILURE CONFIGRET = 0x00000013 + CR_NO_SUCH_LOGICAL_DEV CONFIGRET = 0x00000014 + CR_CREATE_BLOCKED CONFIGRET = 0x00000015 + CR_NOT_SYSTEM_VM CONFIGRET = 0x00000016 + CR_REMOVE_VETOED CONFIGRET = 0x00000017 + CR_APM_VETOED CONFIGRET = 0x00000018 + CR_INVALID_LOAD_TYPE CONFIGRET = 0x00000019 + CR_BUFFER_SMALL CONFIGRET = 0x0000001A + CR_NO_ARBITRATOR CONFIGRET = 0x0000001B + CR_NO_REGISTRY_HANDLE CONFIGRET = 0x0000001C + CR_REGISTRY_ERROR CONFIGRET = 0x0000001D + CR_INVALID_DEVICE_ID CONFIGRET = 0x0000001E + CR_INVALID_DATA CONFIGRET = 0x0000001F + CR_INVALID_API CONFIGRET = 0x00000020 + CR_DEVLOADER_NOT_READY CONFIGRET = 0x00000021 + CR_NEED_RESTART CONFIGRET = 0x00000022 + CR_NO_MORE_HW_PROFILES CONFIGRET = 0x00000023 + CR_DEVICE_NOT_THERE CONFIGRET = 0x00000024 + CR_NO_SUCH_VALUE CONFIGRET = 0x00000025 + CR_WRONG_TYPE CONFIGRET = 0x00000026 + CR_INVALID_PRIORITY CONFIGRET = 0x00000027 + CR_NOT_DISABLEABLE CONFIGRET = 0x00000028 + CR_FREE_RESOURCES CONFIGRET = 0x00000029 + CR_QUERY_VETOED CONFIGRET = 0x0000002A + CR_CANT_SHARE_IRQ CONFIGRET = 0x0000002B + CR_NO_DEPENDENT CONFIGRET = 0x0000002C + CR_SAME_RESOURCES CONFIGRET = 0x0000002D + CR_NO_SUCH_REGISTRY_KEY CONFIGRET = 0x0000002E + CR_INVALID_MACHINENAME CONFIGRET = 0x0000002F + CR_REMOTE_COMM_FAILURE CONFIGRET = 0x00000030 + CR_MACHINE_UNAVAILABLE CONFIGRET = 0x00000031 + CR_NO_CM_SERVICES CONFIGRET = 0x00000032 + CR_ACCESS_DENIED CONFIGRET = 0x00000033 + CR_CALL_NOT_IMPLEMENTED CONFIGRET = 0x00000034 + CR_INVALID_PROPERTY CONFIGRET = 0x00000035 + CR_DEVICE_INTERFACE_ACTIVE CONFIGRET = 0x00000036 + CR_NO_SUCH_DEVICE_INTERFACE CONFIGRET = 0x00000037 + CR_INVALID_REFERENCE_STRING CONFIGRET = 0x00000038 + CR_INVALID_CONFLICT_LIST CONFIGRET = 0x00000039 + CR_INVALID_INDEX CONFIGRET = 0x0000003A + CR_INVALID_STRUCTURE_SIZE CONFIGRET = 0x0000003B + NUM_CR_RESULTS CONFIGRET = 0x0000003C +) + +const ( + CM_GET_DEVICE_INTERFACE_LIST_PRESENT = 0 // only currently 'live' device interfaces + CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES = 1 // all registered device interfaces, live or not +) + +const ( + DN_ROOT_ENUMERATED = 0x00000001 // Was enumerated by ROOT + DN_DRIVER_LOADED = 0x00000002 // Has Register_Device_Driver + DN_ENUM_LOADED = 0x00000004 // Has Register_Enumerator + DN_STARTED = 0x00000008 // Is currently configured + DN_MANUAL = 0x00000010 // Manually installed + DN_NEED_TO_ENUM = 0x00000020 // May need reenumeration + DN_NOT_FIRST_TIME = 0x00000040 // Has received a config + DN_HARDWARE_ENUM = 0x00000080 // Enum generates hardware ID + DN_LIAR = 0x00000100 // Lied about can reconfig once + DN_HAS_MARK = 0x00000200 // Not CM_Create_DevInst lately + DN_HAS_PROBLEM = 0x00000400 // Need device installer + DN_FILTERED = 0x00000800 // Is filtered + DN_MOVED = 0x00001000 // Has been moved + DN_DISABLEABLE = 0x00002000 // Can be disabled + DN_REMOVABLE = 0x00004000 // Can be removed + DN_PRIVATE_PROBLEM = 0x00008000 // Has a private problem + DN_MF_PARENT = 0x00010000 // Multi function parent + DN_MF_CHILD = 0x00020000 // Multi function child + DN_WILL_BE_REMOVED = 0x00040000 // DevInst is being removed + DN_NOT_FIRST_TIMEE = 0x00080000 // Has received a config enumerate + DN_STOP_FREE_RES = 0x00100000 // When child is stopped, free resources + DN_REBAL_CANDIDATE = 0x00200000 // Don't skip during rebalance + DN_BAD_PARTIAL = 0x00400000 // This devnode's log_confs do not have same resources + DN_NT_ENUMERATOR = 0x00800000 // This devnode's is an NT enumerator + DN_NT_DRIVER = 0x01000000 // This devnode's is an NT driver + DN_NEEDS_LOCKING = 0x02000000 // Devnode need lock resume processing + DN_ARM_WAKEUP = 0x04000000 // Devnode can be the wakeup device + DN_APM_ENUMERATOR = 0x08000000 // APM aware enumerator + DN_APM_DRIVER = 0x10000000 // APM aware driver + DN_SILENT_INSTALL = 0x20000000 // Silent install + DN_NO_SHOW_IN_DM = 0x40000000 // No show in device manager + DN_BOOT_LOG_PROB = 0x80000000 // Had a problem during preassignment of boot log conf + DN_NEED_RESTART = DN_LIAR // System needs to be restarted for this Devnode to work properly + DN_DRIVER_BLOCKED = DN_NOT_FIRST_TIME // One or more drivers are blocked from loading for this Devnode + DN_LEGACY_DRIVER = DN_MOVED // This device is using a legacy driver + DN_CHILD_WITH_INVALID_ID = DN_HAS_MARK // One or more children have invalid IDs + DN_DEVICE_DISCONNECTED = DN_NEEDS_LOCKING // The function driver for a device reported that the device is not connected. Typically this means a wireless device is out of range. + DN_QUERY_REMOVE_PENDING = DN_MF_PARENT // Device is part of a set of related devices collectively pending query-removal + DN_QUERY_REMOVE_ACTIVE = DN_MF_CHILD // Device is actively engaged in a query-remove IRP + DN_CHANGEABLE_FLAGS = DN_NOT_FIRST_TIME | DN_HARDWARE_ENUM | DN_HAS_MARK | DN_DISABLEABLE | DN_REMOVABLE | DN_MF_CHILD | DN_MF_PARENT | DN_NOT_FIRST_TIMEE | DN_STOP_FREE_RES | DN_REBAL_CANDIDATE | DN_NT_ENUMERATOR | DN_NT_DRIVER | DN_SILENT_INSTALL | DN_NO_SHOW_IN_DM +) + +//sys setupDiCreateDeviceInfoListEx(classGUID *GUID, hwndParent uintptr, machineName *uint16, reserved uintptr) (handle DevInfo, err error) [failretval==DevInfo(InvalidHandle)] = setupapi.SetupDiCreateDeviceInfoListExW + +// SetupDiCreateDeviceInfoListEx function creates an empty device information set on a remote or a local computer and optionally associates the set with a device setup class. +func SetupDiCreateDeviceInfoListEx(classGUID *GUID, hwndParent uintptr, machineName string) (deviceInfoSet DevInfo, err error) { + var machineNameUTF16 *uint16 + if machineName != "" { + machineNameUTF16, err = UTF16PtrFromString(machineName) + if err != nil { + return + } + } + return setupDiCreateDeviceInfoListEx(classGUID, hwndParent, machineNameUTF16, 0) +} + +//sys setupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo, deviceInfoSetDetailData *DevInfoListDetailData) (err error) = setupapi.SetupDiGetDeviceInfoListDetailW + +// SetupDiGetDeviceInfoListDetail function retrieves information associated with a device information set including the class GUID, remote computer handle, and remote computer name. +func SetupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo) (deviceInfoSetDetailData *DevInfoListDetailData, err error) { + data := &DevInfoListDetailData{} + data.size = data.unsafeSizeOf() + + return data, setupDiGetDeviceInfoListDetail(deviceInfoSet, data) +} + +// DeviceInfoListDetail method retrieves information associated with a device information set including the class GUID, remote computer handle, and remote computer name. +func (deviceInfoSet DevInfo) DeviceInfoListDetail() (*DevInfoListDetailData, error) { + return SetupDiGetDeviceInfoListDetail(deviceInfoSet) +} + +//sys setupDiCreateDeviceInfo(deviceInfoSet DevInfo, DeviceName *uint16, classGUID *GUID, DeviceDescription *uint16, hwndParent uintptr, CreationFlags DICD, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiCreateDeviceInfoW + +// SetupDiCreateDeviceInfo function creates a new device information element and adds it as a new member to the specified device information set. +func SetupDiCreateDeviceInfo(deviceInfoSet DevInfo, deviceName string, classGUID *GUID, deviceDescription string, hwndParent uintptr, creationFlags DICD) (deviceInfoData *DevInfoData, err error) { + deviceNameUTF16, err := UTF16PtrFromString(deviceName) + if err != nil { + return + } + + var deviceDescriptionUTF16 *uint16 + if deviceDescription != "" { + deviceDescriptionUTF16, err = UTF16PtrFromString(deviceDescription) + if err != nil { + return + } + } + + data := &DevInfoData{} + data.size = uint32(unsafe.Sizeof(*data)) + + return data, setupDiCreateDeviceInfo(deviceInfoSet, deviceNameUTF16, classGUID, deviceDescriptionUTF16, hwndParent, creationFlags, data) +} + +// CreateDeviceInfo method creates a new device information element and adds it as a new member to the specified device information set. +func (deviceInfoSet DevInfo) CreateDeviceInfo(deviceName string, classGUID *GUID, deviceDescription string, hwndParent uintptr, creationFlags DICD) (*DevInfoData, error) { + return SetupDiCreateDeviceInfo(deviceInfoSet, deviceName, classGUID, deviceDescription, hwndParent, creationFlags) +} + +//sys setupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex uint32, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiEnumDeviceInfo + +// SetupDiEnumDeviceInfo function returns a DevInfoData structure that specifies a device information element in a device information set. +func SetupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex int) (*DevInfoData, error) { + data := &DevInfoData{} + data.size = uint32(unsafe.Sizeof(*data)) + + return data, setupDiEnumDeviceInfo(deviceInfoSet, uint32(memberIndex), data) +} + +// EnumDeviceInfo method returns a DevInfoData structure that specifies a device information element in a device information set. +func (deviceInfoSet DevInfo) EnumDeviceInfo(memberIndex int) (*DevInfoData, error) { + return SetupDiEnumDeviceInfo(deviceInfoSet, memberIndex) +} + +// SetupDiDestroyDeviceInfoList function deletes a device information set and frees all associated memory. +//sys SetupDiDestroyDeviceInfoList(deviceInfoSet DevInfo) (err error) = setupapi.SetupDiDestroyDeviceInfoList + +// Close method deletes a device information set and frees all associated memory. +func (deviceInfoSet DevInfo) Close() error { + return SetupDiDestroyDeviceInfoList(deviceInfoSet) +} + +//sys SetupDiBuildDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) = setupapi.SetupDiBuildDriverInfoList + +// BuildDriverInfoList method builds a list of drivers that is associated with a specific device or with the global class driver list for a device information set. +func (deviceInfoSet DevInfo) BuildDriverInfoList(deviceInfoData *DevInfoData, driverType SPDIT) error { + return SetupDiBuildDriverInfoList(deviceInfoSet, deviceInfoData, driverType) +} + +//sys SetupDiCancelDriverInfoSearch(deviceInfoSet DevInfo) (err error) = setupapi.SetupDiCancelDriverInfoSearch + +// CancelDriverInfoSearch method cancels a driver list search that is currently in progress in a different thread. +func (deviceInfoSet DevInfo) CancelDriverInfoSearch() error { + return SetupDiCancelDriverInfoSearch(deviceInfoSet) +} + +//sys setupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT, memberIndex uint32, driverInfoData *DrvInfoData) (err error) = setupapi.SetupDiEnumDriverInfoW + +// SetupDiEnumDriverInfo function enumerates the members of a driver list. +func SetupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT, memberIndex int) (*DrvInfoData, error) { + data := &DrvInfoData{} + data.size = uint32(unsafe.Sizeof(*data)) + + return data, setupDiEnumDriverInfo(deviceInfoSet, deviceInfoData, driverType, uint32(memberIndex), data) +} + +// EnumDriverInfo method enumerates the members of a driver list. +func (deviceInfoSet DevInfo) EnumDriverInfo(deviceInfoData *DevInfoData, driverType SPDIT, memberIndex int) (*DrvInfoData, error) { + return SetupDiEnumDriverInfo(deviceInfoSet, deviceInfoData, driverType, memberIndex) +} + +//sys setupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) = setupapi.SetupDiGetSelectedDriverW + +// SetupDiGetSelectedDriver function retrieves the selected driver for a device information set or a particular device information element. +func SetupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (*DrvInfoData, error) { + data := &DrvInfoData{} + data.size = uint32(unsafe.Sizeof(*data)) + + return data, setupDiGetSelectedDriver(deviceInfoSet, deviceInfoData, data) +} + +// SelectedDriver method retrieves the selected driver for a device information set or a particular device information element. +func (deviceInfoSet DevInfo) SelectedDriver(deviceInfoData *DevInfoData) (*DrvInfoData, error) { + return SetupDiGetSelectedDriver(deviceInfoSet, deviceInfoData) +} + +//sys SetupDiSetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) = setupapi.SetupDiSetSelectedDriverW + +// SetSelectedDriver method sets, or resets, the selected driver for a device information element or the selected class driver for a device information set. +func (deviceInfoSet DevInfo) SetSelectedDriver(deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) error { + return SetupDiSetSelectedDriver(deviceInfoSet, deviceInfoData, driverInfoData) +} + +//sys setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData, driverInfoDetailData *DrvInfoDetailData, driverInfoDetailDataSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetDriverInfoDetailW + +// SetupDiGetDriverInfoDetail function retrieves driver information detail for a device information set or a particular device information element in the device information set. +func SetupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (*DrvInfoDetailData, error) { + reqSize := uint32(2048) + for { + buf := make([]byte, reqSize) + data := (*DrvInfoDetailData)(unsafe.Pointer(&buf[0])) + data.size = data.unsafeSizeOf() + err := setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, data, uint32(len(buf)), &reqSize) + if err == ERROR_INSUFFICIENT_BUFFER { + continue + } + if err != nil { + return nil, err + } + data.size = reqSize + return data, nil + } +} + +// DriverInfoDetail method retrieves driver information detail for a device information set or a particular device information element in the device information set. +func (deviceInfoSet DevInfo) DriverInfoDetail(deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (*DrvInfoDetailData, error) { + return SetupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData) +} + +//sys SetupDiDestroyDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) = setupapi.SetupDiDestroyDriverInfoList + +// DestroyDriverInfoList method deletes a driver list. +func (deviceInfoSet DevInfo) DestroyDriverInfoList(deviceInfoData *DevInfoData, driverType SPDIT) error { + return SetupDiDestroyDriverInfoList(deviceInfoSet, deviceInfoData, driverType) +} + +//sys setupDiGetClassDevsEx(classGUID *GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, deviceInfoSet DevInfo, machineName *uint16, reserved uintptr) (handle DevInfo, err error) [failretval==DevInfo(InvalidHandle)] = setupapi.SetupDiGetClassDevsExW + +// SetupDiGetClassDevsEx function returns a handle to a device information set that contains requested device information elements for a local or a remote computer. +func SetupDiGetClassDevsEx(classGUID *GUID, enumerator string, hwndParent uintptr, flags DIGCF, deviceInfoSet DevInfo, machineName string) (handle DevInfo, err error) { + var enumeratorUTF16 *uint16 + if enumerator != "" { + enumeratorUTF16, err = UTF16PtrFromString(enumerator) + if err != nil { + return + } + } + var machineNameUTF16 *uint16 + if machineName != "" { + machineNameUTF16, err = UTF16PtrFromString(machineName) + if err != nil { + return + } + } + return setupDiGetClassDevsEx(classGUID, enumeratorUTF16, hwndParent, flags, deviceInfoSet, machineNameUTF16, 0) +} + +// SetupDiCallClassInstaller function calls the appropriate class installer, and any registered co-installers, with the specified installation request (DIF code). +//sys SetupDiCallClassInstaller(installFunction DI_FUNCTION, deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiCallClassInstaller + +// CallClassInstaller member calls the appropriate class installer, and any registered co-installers, with the specified installation request (DIF code). +func (deviceInfoSet DevInfo) CallClassInstaller(installFunction DI_FUNCTION, deviceInfoData *DevInfoData) error { + return SetupDiCallClassInstaller(installFunction, deviceInfoSet, deviceInfoData) +} + +// SetupDiOpenDevRegKey function opens a registry key for device-specific configuration information. +//sys SetupDiOpenDevRegKey(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (key Handle, err error) [failretval==InvalidHandle] = setupapi.SetupDiOpenDevRegKey + +// OpenDevRegKey method opens a registry key for device-specific configuration information. +func (deviceInfoSet DevInfo) OpenDevRegKey(DeviceInfoData *DevInfoData, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (Handle, error) { + return SetupDiOpenDevRegKey(deviceInfoSet, DeviceInfoData, Scope, HwProfile, KeyType, samDesired) +} + +//sys setupDiGetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, propertyKey *DEVPROPKEY, propertyType *DEVPROPTYPE, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32, flags uint32) (err error) = setupapi.SetupDiGetDevicePropertyW + +// SetupDiGetDeviceProperty function retrieves a specified device instance property. +func SetupDiGetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, propertyKey *DEVPROPKEY) (value interface{}, err error) { + reqSize := uint32(256) + for { + var dataType DEVPROPTYPE + buf := make([]byte, reqSize) + err = setupDiGetDeviceProperty(deviceInfoSet, deviceInfoData, propertyKey, &dataType, &buf[0], uint32(len(buf)), &reqSize, 0) + if err == ERROR_INSUFFICIENT_BUFFER { + continue + } + if err != nil { + return + } + switch dataType { + case DEVPROP_TYPE_STRING: + ret := UTF16ToString(bufToUTF16(buf)) + runtime.KeepAlive(buf) + return ret, nil + } + return nil, errors.New("unimplemented property type") + } +} + +//sys setupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyRegDataType *uint32, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetDeviceRegistryPropertyW + +// SetupDiGetDeviceRegistryProperty function retrieves a specified Plug and Play device property. +func SetupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP) (value interface{}, err error) { + reqSize := uint32(256) + for { + var dataType uint32 + buf := make([]byte, reqSize) + err = setupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, &dataType, &buf[0], uint32(len(buf)), &reqSize) + if err == ERROR_INSUFFICIENT_BUFFER { + continue + } + if err != nil { + return + } + return getRegistryValue(buf[:reqSize], dataType) + } +} + +func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) { + switch dataType { + case REG_SZ: + ret := UTF16ToString(bufToUTF16(buf)) + runtime.KeepAlive(buf) + return ret, nil + case REG_EXPAND_SZ: + value := UTF16ToString(bufToUTF16(buf)) + if value == "" { + return "", nil + } + p, err := syscall.UTF16PtrFromString(value) + if err != nil { + return "", err + } + ret := make([]uint16, 100) + for { + n, err := ExpandEnvironmentStrings(p, &ret[0], uint32(len(ret))) + if err != nil { + return "", err + } + if n <= uint32(len(ret)) { + return UTF16ToString(ret[:n]), nil + } + ret = make([]uint16, n) + } + case REG_BINARY: + return buf, nil + case REG_DWORD_LITTLE_ENDIAN: + return binary.LittleEndian.Uint32(buf), nil + case REG_DWORD_BIG_ENDIAN: + return binary.BigEndian.Uint32(buf), nil + case REG_MULTI_SZ: + bufW := bufToUTF16(buf) + a := []string{} + for i := 0; i < len(bufW); { + j := i + wcslen(bufW[i:]) + if i < j { + a = append(a, UTF16ToString(bufW[i:j])) + } + i = j + 1 + } + runtime.KeepAlive(buf) + return a, nil + case REG_QWORD_LITTLE_ENDIAN: + return binary.LittleEndian.Uint64(buf), nil + default: + return nil, fmt.Errorf("Unsupported registry value type: %v", dataType) + } +} + +// bufToUTF16 function reinterprets []byte buffer as []uint16 +func bufToUTF16(buf []byte) []uint16 { + sl := struct { + addr *uint16 + len int + cap int + }{(*uint16)(unsafe.Pointer(&buf[0])), len(buf) / 2, cap(buf) / 2} + return *(*[]uint16)(unsafe.Pointer(&sl)) +} + +// utf16ToBuf function reinterprets []uint16 as []byte +func utf16ToBuf(buf []uint16) []byte { + sl := struct { + addr *byte + len int + cap int + }{(*byte)(unsafe.Pointer(&buf[0])), len(buf) * 2, cap(buf) * 2} + return *(*[]byte)(unsafe.Pointer(&sl)) +} + +func wcslen(str []uint16) int { + for i := 0; i < len(str); i++ { + if str[i] == 0 { + return i + } + } + return len(str) +} + +// DeviceRegistryProperty method retrieves a specified Plug and Play device property. +func (deviceInfoSet DevInfo) DeviceRegistryProperty(deviceInfoData *DevInfoData, property SPDRP) (interface{}, error) { + return SetupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property) +} + +//sys setupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyBuffer *byte, propertyBufferSize uint32) (err error) = setupapi.SetupDiSetDeviceRegistryPropertyW + +// SetupDiSetDeviceRegistryProperty function sets a Plug and Play device property for a device. +func SetupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyBuffers []byte) error { + return setupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, &propertyBuffers[0], uint32(len(propertyBuffers))) +} + +// SetDeviceRegistryProperty function sets a Plug and Play device property for a device. +func (deviceInfoSet DevInfo) SetDeviceRegistryProperty(deviceInfoData *DevInfoData, property SPDRP, propertyBuffers []byte) error { + return SetupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, propertyBuffers) +} + +// SetDeviceRegistryPropertyString method sets a Plug and Play device property string for a device. +func (deviceInfoSet DevInfo) SetDeviceRegistryPropertyString(deviceInfoData *DevInfoData, property SPDRP, str string) error { + str16, err := UTF16FromString(str) + if err != nil { + return err + } + err = SetupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, utf16ToBuf(append(str16, 0))) + runtime.KeepAlive(str16) + return err +} + +//sys setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) = setupapi.SetupDiGetDeviceInstallParamsW + +// SetupDiGetDeviceInstallParams function retrieves device installation parameters for a device information set or a particular device information element. +func SetupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (*DevInstallParams, error) { + params := &DevInstallParams{} + params.size = uint32(unsafe.Sizeof(*params)) + + return params, setupDiGetDeviceInstallParams(deviceInfoSet, deviceInfoData, params) +} + +// DeviceInstallParams method retrieves device installation parameters for a device information set or a particular device information element. +func (deviceInfoSet DevInfo) DeviceInstallParams(deviceInfoData *DevInfoData) (*DevInstallParams, error) { + return SetupDiGetDeviceInstallParams(deviceInfoSet, deviceInfoData) +} + +//sys setupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, instanceId *uint16, instanceIdSize uint32, instanceIdRequiredSize *uint32) (err error) = setupapi.SetupDiGetDeviceInstanceIdW + +// SetupDiGetDeviceInstanceId function retrieves the instance ID of the device. +func SetupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (string, error) { + reqSize := uint32(1024) + for { + buf := make([]uint16, reqSize) + err := setupDiGetDeviceInstanceId(deviceInfoSet, deviceInfoData, &buf[0], uint32(len(buf)), &reqSize) + if err == ERROR_INSUFFICIENT_BUFFER { + continue + } + if err != nil { + return "", err + } + return UTF16ToString(buf), nil + } +} + +// DeviceInstanceID method retrieves the instance ID of the device. +func (deviceInfoSet DevInfo) DeviceInstanceID(deviceInfoData *DevInfoData) (string, error) { + return SetupDiGetDeviceInstanceId(deviceInfoSet, deviceInfoData) +} + +// SetupDiGetClassInstallParams function retrieves class installation parameters for a device information set or a particular device information element. +//sys SetupDiGetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetClassInstallParamsW + +// ClassInstallParams method retrieves class installation parameters for a device information set or a particular device information element. +func (deviceInfoSet DevInfo) ClassInstallParams(deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) error { + return SetupDiGetClassInstallParams(deviceInfoSet, deviceInfoData, classInstallParams, classInstallParamsSize, requiredSize) +} + +//sys SetupDiSetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) = setupapi.SetupDiSetDeviceInstallParamsW + +// SetDeviceInstallParams member sets device installation parameters for a device information set or a particular device information element. +func (deviceInfoSet DevInfo) SetDeviceInstallParams(deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) error { + return SetupDiSetDeviceInstallParams(deviceInfoSet, deviceInfoData, deviceInstallParams) +} + +// SetupDiSetClassInstallParams function sets or clears class install parameters for a device information set or a particular device information element. +//sys SetupDiSetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32) (err error) = setupapi.SetupDiSetClassInstallParamsW + +// SetClassInstallParams method sets or clears class install parameters for a device information set or a particular device information element. +func (deviceInfoSet DevInfo) SetClassInstallParams(deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32) error { + return SetupDiSetClassInstallParams(deviceInfoSet, deviceInfoData, classInstallParams, classInstallParamsSize) +} + +//sys setupDiClassNameFromGuidEx(classGUID *GUID, className *uint16, classNameSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) = setupapi.SetupDiClassNameFromGuidExW + +// SetupDiClassNameFromGuidEx function retrieves the class name associated with a class GUID. The class can be installed on a local or remote computer. +func SetupDiClassNameFromGuidEx(classGUID *GUID, machineName string) (className string, err error) { + var classNameUTF16 [MAX_CLASS_NAME_LEN]uint16 + + var machineNameUTF16 *uint16 + if machineName != "" { + machineNameUTF16, err = UTF16PtrFromString(machineName) + if err != nil { + return + } + } + + err = setupDiClassNameFromGuidEx(classGUID, &classNameUTF16[0], MAX_CLASS_NAME_LEN, nil, machineNameUTF16, 0) + if err != nil { + return + } + + className = UTF16ToString(classNameUTF16[:]) + return +} + +//sys setupDiClassGuidsFromNameEx(className *uint16, classGuidList *GUID, classGuidListSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) = setupapi.SetupDiClassGuidsFromNameExW + +// SetupDiClassGuidsFromNameEx function retrieves the GUIDs associated with the specified class name. This resulting list contains the classes currently installed on a local or remote computer. +func SetupDiClassGuidsFromNameEx(className string, machineName string) ([]GUID, error) { + classNameUTF16, err := UTF16PtrFromString(className) + if err != nil { + return nil, err + } + + var machineNameUTF16 *uint16 + if machineName != "" { + machineNameUTF16, err = UTF16PtrFromString(machineName) + if err != nil { + return nil, err + } + } + + reqSize := uint32(4) + for { + buf := make([]GUID, reqSize) + err = setupDiClassGuidsFromNameEx(classNameUTF16, &buf[0], uint32(len(buf)), &reqSize, machineNameUTF16, 0) + if err == ERROR_INSUFFICIENT_BUFFER { + continue + } + if err != nil { + return nil, err + } + return buf[:reqSize], nil + } +} + +//sys setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiGetSelectedDevice + +// SetupDiGetSelectedDevice function retrieves the selected device information element in a device information set. +func SetupDiGetSelectedDevice(deviceInfoSet DevInfo) (*DevInfoData, error) { + data := &DevInfoData{} + data.size = uint32(unsafe.Sizeof(*data)) + + return data, setupDiGetSelectedDevice(deviceInfoSet, data) +} + +// SelectedDevice method retrieves the selected device information element in a device information set. +func (deviceInfoSet DevInfo) SelectedDevice() (*DevInfoData, error) { + return SetupDiGetSelectedDevice(deviceInfoSet) +} + +// SetupDiSetSelectedDevice function sets a device information element as the selected member of a device information set. This function is typically used by an installation wizard. +//sys SetupDiSetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiSetSelectedDevice + +// SetSelectedDevice method sets a device information element as the selected member of a device information set. This function is typically used by an installation wizard. +func (deviceInfoSet DevInfo) SetSelectedDevice(deviceInfoData *DevInfoData) error { + return SetupDiSetSelectedDevice(deviceInfoSet, deviceInfoData) +} + +//sys setupUninstallOEMInf(infFileName *uint16, flags SUOI, reserved uintptr) (err error) = setupapi.SetupUninstallOEMInfW + +// SetupUninstallOEMInf uninstalls the specified driver. +func SetupUninstallOEMInf(infFileName string, flags SUOI) error { + infFileName16, err := UTF16PtrFromString(infFileName) + if err != nil { + return err + } + return setupUninstallOEMInf(infFileName16, flags, 0) +} + +//sys cm_MapCrToWin32Err(configRet CONFIGRET, defaultWin32Error Errno) (ret Errno) = CfgMgr32.CM_MapCrToWin32Err + +//sys cm_Get_Device_Interface_List_Size(len *uint32, interfaceClass *GUID, deviceID *uint16, flags uint32) (ret CONFIGRET) = CfgMgr32.CM_Get_Device_Interface_List_SizeW +//sys cm_Get_Device_Interface_List(interfaceClass *GUID, deviceID *uint16, buffer *uint16, bufferLen uint32, flags uint32) (ret CONFIGRET) = CfgMgr32.CM_Get_Device_Interface_ListW + +func CM_Get_Device_Interface_List(deviceID string, interfaceClass *GUID, flags uint32) ([]string, error) { + deviceID16, err := UTF16PtrFromString(deviceID) + if err != nil { + return nil, err + } + var buf []uint16 + var buflen uint32 + for { + if ret := cm_Get_Device_Interface_List_Size(&buflen, interfaceClass, deviceID16, flags); ret != CR_SUCCESS { + return nil, ret + } + buf = make([]uint16, buflen) + if ret := cm_Get_Device_Interface_List(interfaceClass, deviceID16, &buf[0], buflen, flags); ret == CR_SUCCESS { + break + } else if ret != CR_BUFFER_SMALL { + return nil, ret + } + } + var interfaces []string + for i := 0; i < len(buf); { + j := i + wcslen(buf[i:]) + if i < j { + interfaces = append(interfaces, UTF16ToString(buf[i:j])) + } + i = j + 1 + } + if interfaces == nil { + return nil, ERROR_NO_SUCH_DEVICE_INTERFACE + } + return interfaces, nil +} + +//sys cm_Get_DevNode_Status(status *uint32, problemNumber *uint32, devInst DEVINST, flags uint32) (ret CONFIGRET) = CfgMgr32.CM_Get_DevNode_Status + +func CM_Get_DevNode_Status(status *uint32, problemNumber *uint32, devInst DEVINST, flags uint32) error { + ret := cm_Get_DevNode_Status(status, problemNumber, devInst, flags) + if ret == CR_SUCCESS { + return nil + } + return ret +} diff --git a/vendor/golang.org/x/sys/windows/str.go b/vendor/golang.org/x/sys/windows/str.go new file mode 100644 index 0000000..6a4f9ce --- /dev/null +++ b/vendor/golang.org/x/sys/windows/str.go @@ -0,0 +1,22 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows + +package windows + +func itoa(val int) string { // do it here rather than with fmt to avoid dependency + if val < 0 { + return "-" + itoa(-val) + } + var buf [32]byte // big enough for int64 + i := len(buf) - 1 + for val >= 10 { + buf[i] = byte(val%10 + '0') + i-- + val /= 10 + } + buf[i] = byte(val + '0') + return string(buf[i:]) +} diff --git a/vendor/golang.org/x/sys/windows/syscall.go b/vendor/golang.org/x/sys/windows/syscall.go new file mode 100644 index 0000000..e85ed6b --- /dev/null +++ b/vendor/golang.org/x/sys/windows/syscall.go @@ -0,0 +1,104 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows + +// Package windows contains an interface to the low-level operating system +// primitives. OS details vary depending on the underlying system, and +// by default, godoc will display the OS-specific documentation for the current +// system. If you want godoc to display syscall documentation for another +// system, set $GOOS and $GOARCH to the desired system. For example, if +// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS +// to freebsd and $GOARCH to arm. +// +// The primary use of this package is inside other packages that provide a more +// portable interface to the system, such as "os", "time" and "net". Use +// those packages rather than this one if you can. +// +// For details of the functions and data types in this package consult +// the manuals for the appropriate operating system. +// +// These calls return err == nil to indicate success; otherwise +// err represents an operating system error describing the failure and +// holds a value of type syscall.Errno. +package windows // import "golang.org/x/sys/windows" + +import ( + "bytes" + "strings" + "syscall" + "unsafe" +) + +// ByteSliceFromString returns a NUL-terminated slice of bytes +// containing the text of s. If s contains a NUL byte at any +// location, it returns (nil, syscall.EINVAL). +func ByteSliceFromString(s string) ([]byte, error) { + if strings.IndexByte(s, 0) != -1 { + return nil, syscall.EINVAL + } + a := make([]byte, len(s)+1) + copy(a, s) + return a, nil +} + +// BytePtrFromString returns a pointer to a NUL-terminated array of +// bytes containing the text of s. If s contains a NUL byte at any +// location, it returns (nil, syscall.EINVAL). +func BytePtrFromString(s string) (*byte, error) { + a, err := ByteSliceFromString(s) + if err != nil { + return nil, err + } + return &a[0], nil +} + +// ByteSliceToString returns a string form of the text represented by the slice s, with a terminating NUL and any +// bytes after the NUL removed. +func ByteSliceToString(s []byte) string { + if i := bytes.IndexByte(s, 0); i != -1 { + s = s[:i] + } + return string(s) +} + +// BytePtrToString takes a pointer to a sequence of text and returns the corresponding string. +// If the pointer is nil, it returns the empty string. It assumes that the text sequence is terminated +// at a zero byte; if the zero byte is not present, the program may crash. +func BytePtrToString(p *byte) string { + if p == nil { + return "" + } + if *p == 0 { + return "" + } + + // Find NUL terminator. + n := 0 + for ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ { + ptr = unsafe.Pointer(uintptr(ptr) + 1) + } + + return string(unsafe.Slice(p, n)) +} + +// Single-word zero for use when we need a valid pointer to 0 bytes. +// See mksyscall.pl. +var _zero uintptr + +func (ts *Timespec) Unix() (sec int64, nsec int64) { + return int64(ts.Sec), int64(ts.Nsec) +} + +func (tv *Timeval) Unix() (sec int64, nsec int64) { + return int64(tv.Sec), int64(tv.Usec) * 1000 +} + +func (ts *Timespec) Nano() int64 { + return int64(ts.Sec)*1e9 + int64(ts.Nsec) +} + +func (tv *Timeval) Nano() int64 { + return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 +} diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go new file mode 100644 index 0000000..e6966b4 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -0,0 +1,1952 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Windows system calls. + +package windows + +import ( + errorspkg "errors" + "fmt" + "runtime" + "sync" + "syscall" + "time" + "unicode/utf16" + "unsafe" +) + +type ( + Handle uintptr + HWND uintptr +) + +const ( + InvalidHandle = ^Handle(0) + InvalidHWND = ^HWND(0) + + // Flags for DefineDosDevice. + DDD_EXACT_MATCH_ON_REMOVE = 0x00000004 + DDD_NO_BROADCAST_SYSTEM = 0x00000008 + DDD_RAW_TARGET_PATH = 0x00000001 + DDD_REMOVE_DEFINITION = 0x00000002 + + // Return values for GetDriveType. + DRIVE_UNKNOWN = 0 + DRIVE_NO_ROOT_DIR = 1 + DRIVE_REMOVABLE = 2 + DRIVE_FIXED = 3 + DRIVE_REMOTE = 4 + DRIVE_CDROM = 5 + DRIVE_RAMDISK = 6 + + // File system flags from GetVolumeInformation and GetVolumeInformationByHandle. + FILE_CASE_SENSITIVE_SEARCH = 0x00000001 + FILE_CASE_PRESERVED_NAMES = 0x00000002 + FILE_FILE_COMPRESSION = 0x00000010 + FILE_DAX_VOLUME = 0x20000000 + FILE_NAMED_STREAMS = 0x00040000 + FILE_PERSISTENT_ACLS = 0x00000008 + FILE_READ_ONLY_VOLUME = 0x00080000 + FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000 + FILE_SUPPORTS_ENCRYPTION = 0x00020000 + FILE_SUPPORTS_EXTENDED_ATTRIBUTES = 0x00800000 + FILE_SUPPORTS_HARD_LINKS = 0x00400000 + FILE_SUPPORTS_OBJECT_IDS = 0x00010000 + FILE_SUPPORTS_OPEN_BY_FILE_ID = 0x01000000 + FILE_SUPPORTS_REPARSE_POINTS = 0x00000080 + FILE_SUPPORTS_SPARSE_FILES = 0x00000040 + FILE_SUPPORTS_TRANSACTIONS = 0x00200000 + FILE_SUPPORTS_USN_JOURNAL = 0x02000000 + FILE_UNICODE_ON_DISK = 0x00000004 + FILE_VOLUME_IS_COMPRESSED = 0x00008000 + FILE_VOLUME_QUOTAS = 0x00000020 + + // Flags for LockFileEx. + LOCKFILE_FAIL_IMMEDIATELY = 0x00000001 + LOCKFILE_EXCLUSIVE_LOCK = 0x00000002 + + // Return value of SleepEx and other APC functions + WAIT_IO_COMPLETION = 0x000000C0 +) + +// StringToUTF16 is deprecated. Use UTF16FromString instead. +// If s contains a NUL byte this function panics instead of +// returning an error. +func StringToUTF16(s string) []uint16 { + a, err := UTF16FromString(s) + if err != nil { + panic("windows: string with NUL passed to StringToUTF16") + } + return a +} + +// UTF16FromString returns the UTF-16 encoding of the UTF-8 string +// s, with a terminating NUL added. If s contains a NUL byte at any +// location, it returns (nil, syscall.EINVAL). +func UTF16FromString(s string) ([]uint16, error) { + return syscall.UTF16FromString(s) +} + +// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s, +// with a terminating NUL and any bytes after the NUL removed. +func UTF16ToString(s []uint16) string { + return syscall.UTF16ToString(s) +} + +// StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead. +// If s contains a NUL byte this function panics instead of +// returning an error. +func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] } + +// UTF16PtrFromString returns pointer to the UTF-16 encoding of +// the UTF-8 string s, with a terminating NUL added. If s +// contains a NUL byte at any location, it returns (nil, syscall.EINVAL). +func UTF16PtrFromString(s string) (*uint16, error) { + a, err := UTF16FromString(s) + if err != nil { + return nil, err + } + return &a[0], nil +} + +// UTF16PtrToString takes a pointer to a UTF-16 sequence and returns the corresponding UTF-8 encoded string. +// If the pointer is nil, it returns the empty string. It assumes that the UTF-16 sequence is terminated +// at a zero word; if the zero word is not present, the program may crash. +func UTF16PtrToString(p *uint16) string { + if p == nil { + return "" + } + if *p == 0 { + return "" + } + + // Find NUL terminator. + n := 0 + for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ { + ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p)) + } + return UTF16ToString(unsafe.Slice(p, n)) +} + +func Getpagesize() int { return 4096 } + +// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention. +// This is useful when interoperating with Windows code requiring callbacks. +// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. +func NewCallback(fn interface{}) uintptr { + return syscall.NewCallback(fn) +} + +// NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention. +// This is useful when interoperating with Windows code requiring callbacks. +// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. +func NewCallbackCDecl(fn interface{}) uintptr { + return syscall.NewCallbackCDecl(fn) +} + +// windows api calls + +//sys GetLastError() (lasterr error) +//sys LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW +//sys LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) = LoadLibraryExW +//sys FreeLibrary(handle Handle) (err error) +//sys GetProcAddress(module Handle, procname string) (proc uintptr, err error) +//sys GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) = kernel32.GetModuleFileNameW +//sys GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) = kernel32.GetModuleHandleExW +//sys SetDefaultDllDirectories(directoryFlags uint32) (err error) +//sys AddDllDirectory(path *uint16) (cookie uintptr, err error) = kernel32.AddDllDirectory +//sys RemoveDllDirectory(cookie uintptr) (err error) = kernel32.RemoveDllDirectory +//sys SetDllDirectory(path string) (err error) = kernel32.SetDllDirectoryW +//sys GetVersion() (ver uint32, err error) +//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW +//sys ExitProcess(exitcode uint32) +//sys IsWow64Process(handle Handle, isWow64 *bool) (err error) = IsWow64Process +//sys IsWow64Process2(handle Handle, processMachine *uint16, nativeMachine *uint16) (err error) = IsWow64Process2? +//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW +//sys CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) [failretval==InvalidHandle] = CreateNamedPipeW +//sys ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) +//sys DisconnectNamedPipe(pipe Handle) (err error) +//sys GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) +//sys GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) +//sys GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) +//sys GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW +//sys SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) = SetNamedPipeHandleState +//sys readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = ReadFile +//sys writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = WriteFile +//sys GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) +//sys SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff] +//sys CloseHandle(handle Handle) (err error) +//sys GetStdHandle(stdhandle uint32) (handle Handle, err error) [failretval==InvalidHandle] +//sys SetStdHandle(stdhandle uint32, handle Handle) (err error) +//sys findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW +//sys findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW +//sys FindClose(handle Handle) (err error) +//sys GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) +//sys GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte, outBufferLen uint32) (err error) +//sys SetFileInformationByHandle(handle Handle, class uint32, inBuffer *byte, inBufferLen uint32) (err error) +//sys GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW +//sys SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW +//sys CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW +//sys RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW +//sys DeleteFile(path *uint16) (err error) = DeleteFileW +//sys MoveFile(from *uint16, to *uint16) (err error) = MoveFileW +//sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW +//sys LockFileEx(file Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) +//sys UnlockFileEx(file Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) +//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW +//sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW +//sys SetEndOfFile(handle Handle) (err error) +//sys SetFileValidData(handle Handle, validDataLength int64) (err error) +//sys GetSystemTimeAsFileTime(time *Filetime) +//sys GetSystemTimePreciseAsFileTime(time *Filetime) +//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] +//sys CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uintptr, threadcnt uint32) (handle Handle, err error) +//sys GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uintptr, overlapped **Overlapped, timeout uint32) (err error) +//sys PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uintptr, overlapped *Overlapped) (err error) +//sys CancelIo(s Handle) (err error) +//sys CancelIoEx(s Handle, o *Overlapped) (err error) +//sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW +//sys CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = advapi32.CreateProcessAsUserW +//sys initializeProcThreadAttributeList(attrlist *ProcThreadAttributeList, attrcount uint32, flags uint32, size *uintptr) (err error) = InitializeProcThreadAttributeList +//sys deleteProcThreadAttributeList(attrlist *ProcThreadAttributeList) = DeleteProcThreadAttributeList +//sys updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) = UpdateProcThreadAttribute +//sys OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error) +//sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW +//sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId +//sys LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) [failretval==0] = user32.LoadKeyboardLayoutW +//sys UnloadKeyboardLayout(hkl Handle) (err error) = user32.UnloadKeyboardLayout +//sys GetKeyboardLayout(tid uint32) (hkl Handle) = user32.GetKeyboardLayout +//sys ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) = user32.ToUnicodeEx +//sys GetShellWindow() (shellWindow HWND) = user32.GetShellWindow +//sys MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) [failretval==0] = user32.MessageBoxW +//sys ExitWindowsEx(flags uint32, reason uint32) (err error) = user32.ExitWindowsEx +//sys shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **uint16) (ret error) = shell32.SHGetKnownFolderPath +//sys TerminateProcess(handle Handle, exitcode uint32) (err error) +//sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) +//sys getStartupInfo(startupInfo *StartupInfo) = GetStartupInfoW +//sys GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) +//sys DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) +//sys WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff] +//sys waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff] = WaitForMultipleObjects +//sys GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW +//sys CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) +//sys GetFileType(filehandle Handle) (n uint32, err error) +//sys CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW +//sys CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext +//sys CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom +//sys GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW +//sys FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW +//sys GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW +//sys SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW +//sys ExpandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) = kernel32.ExpandEnvironmentStringsW +//sys CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock +//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock +//sys getTickCount64() (ms uint64) = kernel32.GetTickCount64 +//sys GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) +//sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) +//sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW +//sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW +//sys GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW +//sys GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW +//sys commandLineToArgv(cmd *uint16, argc *int32) (argv **uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW +//sys LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0] +//sys LocalAlloc(flags uint32, length uint32) (ptr uintptr, err error) +//sys SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) +//sys FlushFileBuffers(handle Handle) (err error) +//sys GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW +//sys GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW +//sys GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW +//sys GetFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW +//sys CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) [failretval == 0 || e1 == ERROR_ALREADY_EXISTS] = kernel32.CreateFileMappingW +//sys MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) +//sys UnmapViewOfFile(addr uintptr) (err error) +//sys FlushViewOfFile(addr uintptr, length uintptr) (err error) +//sys VirtualLock(addr uintptr, length uintptr) (err error) +//sys VirtualUnlock(addr uintptr, length uintptr) (err error) +//sys VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) = kernel32.VirtualAlloc +//sys VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) = kernel32.VirtualFree +//sys VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) = kernel32.VirtualProtect +//sys VirtualProtectEx(process Handle, address uintptr, size uintptr, newProtect uint32, oldProtect *uint32) (err error) = kernel32.VirtualProtectEx +//sys VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQuery +//sys VirtualQueryEx(process Handle, address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQueryEx +//sys ReadProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesRead *uintptr) (err error) = kernel32.ReadProcessMemory +//sys WriteProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesWritten *uintptr) (err error) = kernel32.WriteProcessMemory +//sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile +//sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW +//sys FindFirstChangeNotification(path string, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.FindFirstChangeNotificationW +//sys FindNextChangeNotification(handle Handle) (err error) +//sys FindCloseChangeNotification(handle Handle) (err error) +//sys CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW +//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) = crypt32.CertOpenStore +//sys CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore +//sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore +//sys CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore +//sys CertDeleteCertificateFromStore(certContext *CertContext) (err error) = crypt32.CertDeleteCertificateFromStore +//sys CertDuplicateCertificateContext(certContext *CertContext) (dupContext *CertContext) = crypt32.CertDuplicateCertificateContext +//sys PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) = crypt32.PFXImportCertStore +//sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain +//sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain +//sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext +//sys CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext +//sys CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy +//sys CertGetNameString(certContext *CertContext, nameType uint32, flags uint32, typePara unsafe.Pointer, name *uint16, size uint32) (chars uint32) = crypt32.CertGetNameStringW +//sys CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) = crypt32.CertFindExtension +//sys CertFindCertificateInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevCertContext *CertContext) (cert *CertContext, err error) [failretval==nil] = crypt32.CertFindCertificateInStore +//sys CertFindChainInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevChainContext *CertChainContext) (certchain *CertChainContext, err error) [failretval==nil] = crypt32.CertFindChainInStore +//sys CryptAcquireCertificatePrivateKey(cert *CertContext, flags uint32, parameters unsafe.Pointer, cryptProvOrNCryptKey *Handle, keySpec *uint32, callerFreeProvOrNCryptKey *bool) (err error) = crypt32.CryptAcquireCertificatePrivateKey +//sys CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) = crypt32.CryptQueryObject +//sys CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte, lenEncodedBytes uint32, flags uint32, decoded unsafe.Pointer, decodedLen *uint32) (err error) = crypt32.CryptDecodeObject +//sys CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) = crypt32.CryptProtectData +//sys CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) = crypt32.CryptUnprotectData +//sys WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) = wintrust.WinVerifyTrustEx +//sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW +//sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey +//sys RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW +//sys RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW +//sys RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW +//sys RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, event Handle, asynchronous bool) (regerrno error) = advapi32.RegNotifyChangeKeyValue +//sys GetCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId +//sys ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) = kernel32.ProcessIdToSessionId +//sys ClosePseudoConsole(console Handle) = kernel32.ClosePseudoConsole +//sys createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pconsole *Handle) (hr error) = kernel32.CreatePseudoConsole +//sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode +//sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode +//sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo +//sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition +//sys GetConsoleCP() (cp uint32, err error) = kernel32.GetConsoleCP +//sys GetConsoleOutputCP() (cp uint32, err error) = kernel32.GetConsoleOutputCP +//sys SetConsoleCP(cp uint32) (err error) = kernel32.SetConsoleCP +//sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP +//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW +//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW +//sys GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) = kernel32.GetNumberOfConsoleInputEvents +//sys FlushConsoleInputBuffer(console Handle) (err error) = kernel32.FlushConsoleInputBuffer +//sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole +//sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot +//sys Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW +//sys Module32Next(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32NextW +//sys Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW +//sys Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW +//sys Thread32First(snapshot Handle, threadEntry *ThreadEntry32) (err error) +//sys Thread32Next(snapshot Handle, threadEntry *ThreadEntry32) (err error) +//sys DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) +// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. +//sys CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW +//sys CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW +//sys GetCurrentThreadId() (id uint32) +//sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) [failretval == 0 || e1 == ERROR_ALREADY_EXISTS] = kernel32.CreateEventW +//sys CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) [failretval == 0 || e1 == ERROR_ALREADY_EXISTS] = kernel32.CreateEventExW +//sys OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) = kernel32.OpenEventW +//sys SetEvent(event Handle) (err error) = kernel32.SetEvent +//sys ResetEvent(event Handle) (err error) = kernel32.ResetEvent +//sys PulseEvent(event Handle) (err error) = kernel32.PulseEvent +//sys CreateMutex(mutexAttrs *SecurityAttributes, initialOwner bool, name *uint16) (handle Handle, err error) [failretval == 0 || e1 == ERROR_ALREADY_EXISTS] = kernel32.CreateMutexW +//sys CreateMutexEx(mutexAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) [failretval == 0 || e1 == ERROR_ALREADY_EXISTS] = kernel32.CreateMutexExW +//sys OpenMutex(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) = kernel32.OpenMutexW +//sys ReleaseMutex(mutex Handle) (err error) = kernel32.ReleaseMutex +//sys SleepEx(milliseconds uint32, alertable bool) (ret uint32) = kernel32.SleepEx +//sys CreateJobObject(jobAttr *SecurityAttributes, name *uint16) (handle Handle, err error) = kernel32.CreateJobObjectW +//sys AssignProcessToJobObject(job Handle, process Handle) (err error) = kernel32.AssignProcessToJobObject +//sys TerminateJobObject(job Handle, exitCode uint32) (err error) = kernel32.TerminateJobObject +//sys SetErrorMode(mode uint32) (ret uint32) = kernel32.SetErrorMode +//sys ResumeThread(thread Handle) (ret uint32, err error) [failretval==0xffffffff] = kernel32.ResumeThread +//sys SetPriorityClass(process Handle, priorityClass uint32) (err error) = kernel32.SetPriorityClass +//sys GetPriorityClass(process Handle) (ret uint32, err error) = kernel32.GetPriorityClass +//sys QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) = kernel32.QueryInformationJobObject +//sys SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error) +//sys GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err error) +//sys GetProcessId(process Handle) (id uint32, err error) +//sys QueryFullProcessImageName(proc Handle, flags uint32, exeName *uint16, size *uint32) (err error) = kernel32.QueryFullProcessImageNameW +//sys OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (handle Handle, err error) +//sys SetProcessPriorityBoost(process Handle, disable bool) (err error) = kernel32.SetProcessPriorityBoost +//sys GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32) +//sys SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error) +//sys ClearCommBreak(handle Handle) (err error) +//sys ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error) +//sys EscapeCommFunction(handle Handle, dwFunc uint32) (err error) +//sys GetCommState(handle Handle, lpDCB *DCB) (err error) +//sys GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error) +//sys GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) +//sys PurgeComm(handle Handle, dwFlags uint32) (err error) +//sys SetCommBreak(handle Handle) (err error) +//sys SetCommMask(handle Handle, dwEvtMask uint32) (err error) +//sys SetCommState(handle Handle, lpDCB *DCB) (err error) +//sys SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) +//sys SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error) +//sys WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error) +//sys GetActiveProcessorCount(groupNumber uint16) (ret uint32) +//sys GetMaximumProcessorCount(groupNumber uint16) (ret uint32) +//sys EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) = user32.EnumWindows +//sys EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) = user32.EnumChildWindows +//sys GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) = user32.GetClassNameW +//sys GetDesktopWindow() (hwnd HWND) = user32.GetDesktopWindow +//sys GetForegroundWindow() (hwnd HWND) = user32.GetForegroundWindow +//sys IsWindow(hwnd HWND) (isWindow bool) = user32.IsWindow +//sys IsWindowUnicode(hwnd HWND) (isUnicode bool) = user32.IsWindowUnicode +//sys IsWindowVisible(hwnd HWND) (isVisible bool) = user32.IsWindowVisible +//sys GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) = user32.GetGUIThreadInfo +//sys GetLargePageMinimum() (size uintptr) + +// Volume Management Functions +//sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW +//sys DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) = DeleteVolumeMountPointW +//sys FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeW +//sys FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeMountPointW +//sys FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) = FindNextVolumeW +//sys FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) = FindNextVolumeMountPointW +//sys FindVolumeClose(findVolume Handle) (err error) +//sys FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) +//sys GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) = GetDiskFreeSpaceExW +//sys GetDriveType(rootPathName *uint16) (driveType uint32) = GetDriveTypeW +//sys GetLogicalDrives() (drivesBitMask uint32, err error) [failretval==0] +//sys GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) [failretval==0] = GetLogicalDriveStringsW +//sys GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationW +//sys GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationByHandleW +//sys GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) = GetVolumeNameForVolumeMountPointW +//sys GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) = GetVolumePathNameW +//sys GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) = GetVolumePathNamesForVolumeNameW +//sys QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) [failretval==0] = QueryDosDeviceW +//sys SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) = SetVolumeLabelW +//sys SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) = SetVolumeMountPointW +//sys InitiateSystemShutdownEx(machineName *uint16, message *uint16, timeout uint32, forceAppsClosed bool, rebootAfterShutdown bool, reason uint32) (err error) = advapi32.InitiateSystemShutdownExW +//sys SetProcessShutdownParameters(level uint32, flags uint32) (err error) = kernel32.SetProcessShutdownParameters +//sys GetProcessShutdownParameters(level *uint32, flags *uint32) (err error) = kernel32.GetProcessShutdownParameters +//sys clsidFromString(lpsz *uint16, pclsid *GUID) (ret error) = ole32.CLSIDFromString +//sys stringFromGUID2(rguid *GUID, lpsz *uint16, cchMax int32) (chars int32) = ole32.StringFromGUID2 +//sys coCreateGuid(pguid *GUID) (ret error) = ole32.CoCreateGuid +//sys CoTaskMemFree(address unsafe.Pointer) = ole32.CoTaskMemFree +//sys CoInitializeEx(reserved uintptr, coInit uint32) (ret error) = ole32.CoInitializeEx +//sys CoUninitialize() = ole32.CoUninitialize +//sys CoGetObject(name *uint16, bindOpts *BIND_OPTS3, guid *GUID, functionTable **uintptr) (ret error) = ole32.CoGetObject +//sys getProcessPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetProcessPreferredUILanguages +//sys getThreadPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetThreadPreferredUILanguages +//sys getUserPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetUserPreferredUILanguages +//sys getSystemPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetSystemPreferredUILanguages +//sys findResource(module Handle, name uintptr, resType uintptr) (resInfo Handle, err error) = kernel32.FindResourceW +//sys SizeofResource(module Handle, resInfo Handle) (size uint32, err error) = kernel32.SizeofResource +//sys LoadResource(module Handle, resInfo Handle) (resData Handle, err error) = kernel32.LoadResource +//sys LockResource(resData Handle) (addr uintptr, err error) = kernel32.LockResource + +// Version APIs +//sys GetFileVersionInfoSize(filename string, zeroHandle *Handle) (bufSize uint32, err error) = version.GetFileVersionInfoSizeW +//sys GetFileVersionInfo(filename string, handle uint32, bufSize uint32, buffer unsafe.Pointer) (err error) = version.GetFileVersionInfoW +//sys VerQueryValue(block unsafe.Pointer, subBlock string, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) = version.VerQueryValueW + +// Process Status API (PSAPI) +//sys enumProcesses(processIds *uint32, nSize uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses +//sys EnumProcessModules(process Handle, module *Handle, cb uint32, cbNeeded *uint32) (err error) = psapi.EnumProcessModules +//sys EnumProcessModulesEx(process Handle, module *Handle, cb uint32, cbNeeded *uint32, filterFlag uint32) (err error) = psapi.EnumProcessModulesEx +//sys GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb uint32) (err error) = psapi.GetModuleInformation +//sys GetModuleFileNameEx(process Handle, module Handle, filename *uint16, size uint32) (err error) = psapi.GetModuleFileNameExW +//sys GetModuleBaseName(process Handle, module Handle, baseName *uint16, size uint32) (err error) = psapi.GetModuleBaseNameW +//sys QueryWorkingSetEx(process Handle, pv uintptr, cb uint32) (err error) = psapi.QueryWorkingSetEx + +// NT Native APIs +//sys rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) = ntdll.RtlNtStatusToDosErrorNoTeb +//sys rtlGetVersion(info *OsVersionInfoEx) (ntstatus error) = ntdll.RtlGetVersion +//sys rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) = ntdll.RtlGetNtVersionNumbers +//sys RtlGetCurrentPeb() (peb *PEB) = ntdll.RtlGetCurrentPeb +//sys RtlInitUnicodeString(destinationString *NTUnicodeString, sourceString *uint16) = ntdll.RtlInitUnicodeString +//sys RtlInitString(destinationString *NTString, sourceString *byte) = ntdll.RtlInitString +//sys NtCreateFile(handle *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, allocationSize *int64, attributes uint32, share uint32, disposition uint32, options uint32, eabuffer uintptr, ealength uint32) (ntstatus error) = ntdll.NtCreateFile +//sys NtCreateNamedPipeFile(pipe *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (ntstatus error) = ntdll.NtCreateNamedPipeFile +//sys NtQueryInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, outBuffer *byte, outBufferLen uint32, class uint32) (ntstatus error) = ntdll.NtQueryInformationFile +//sys NtSetInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, inBufferLen uint32, class uint32) (ntstatus error) = ntdll.NtSetInformationFile +//sys RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) = ntdll.RtlDosPathNameToNtPathName_U_WithStatus +//sys RtlDosPathNameToRelativeNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) = ntdll.RtlDosPathNameToRelativeNtPathName_U_WithStatus +//sys RtlDefaultNpAcl(acl **ACL) (ntstatus error) = ntdll.RtlDefaultNpAcl +//sys NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32, retLen *uint32) (ntstatus error) = ntdll.NtQueryInformationProcess +//sys NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32) (ntstatus error) = ntdll.NtSetInformationProcess +//sys NtQuerySystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32, retLen *uint32) (ntstatus error) = ntdll.NtQuerySystemInformation +//sys NtSetSystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32) (ntstatus error) = ntdll.NtSetSystemInformation +//sys NtQueryEaFile(handle Handle, iosb *IO_STATUS_BLOCK, outBuffer *byte, outBufferLen uint32, returnSingleEntry bool, eaList *byte, eaListLen uint32, eaIndex *uint32, restartScan bool) (ntstatus error) = ntdll.NtQueryEaFile +//sys NtSetEaFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, inBufferLen uint32) (ntstatus error) = ntdll.NtSetEaFile +//sys RtlAddFunctionTable(functionTable *RUNTIME_FUNCTION, entryCount uint32, baseAddress uintptr) (ret bool) = ntdll.RtlAddFunctionTable +//sys RtlDeleteFunctionTable(functionTable *RUNTIME_FUNCTION) (ret bool) = ntdll.RtlDeleteFunctionTable + +// Desktop Window Manager API (Dwmapi) +//sys DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) = dwmapi.DwmGetWindowAttribute +//sys DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) = dwmapi.DwmSetWindowAttribute + +// Windows Multimedia API +//sys TimeBeginPeriod (period uint32) (err error) [failretval != 0] = winmm.timeBeginPeriod +//sys TimeEndPeriod (period uint32) (err error) [failretval != 0] = winmm.timeEndPeriod + +// syscall interface implementation for other packages + +// GetCurrentProcess returns the handle for the current process. +// It is a pseudo handle that does not need to be closed. +// The returned error is always nil. +// +// Deprecated: use CurrentProcess for the same Handle without the nil +// error. +func GetCurrentProcess() (Handle, error) { + return CurrentProcess(), nil +} + +// CurrentProcess returns the handle for the current process. +// It is a pseudo handle that does not need to be closed. +func CurrentProcess() Handle { return Handle(^uintptr(1 - 1)) } + +// GetCurrentThread returns the handle for the current thread. +// It is a pseudo handle that does not need to be closed. +// The returned error is always nil. +// +// Deprecated: use CurrentThread for the same Handle without the nil +// error. +func GetCurrentThread() (Handle, error) { + return CurrentThread(), nil +} + +// CurrentThread returns the handle for the current thread. +// It is a pseudo handle that does not need to be closed. +func CurrentThread() Handle { return Handle(^uintptr(2 - 1)) } + +// GetProcAddressByOrdinal retrieves the address of the exported +// function from module by ordinal. +func GetProcAddressByOrdinal(module Handle, ordinal uintptr) (proc uintptr, err error) { + r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0) + proc = uintptr(r0) + if proc == 0 { + err = errnoErr(e1) + } + return +} + +func Exit(code int) { ExitProcess(uint32(code)) } + +func makeInheritSa() *SecurityAttributes { + var sa SecurityAttributes + sa.Length = uint32(unsafe.Sizeof(sa)) + sa.InheritHandle = 1 + return &sa +} + +func Open(path string, mode int, perm uint32) (fd Handle, err error) { + if len(path) == 0 { + return InvalidHandle, ERROR_FILE_NOT_FOUND + } + pathp, err := UTF16PtrFromString(path) + if err != nil { + return InvalidHandle, err + } + var access uint32 + switch mode & (O_RDONLY | O_WRONLY | O_RDWR) { + case O_RDONLY: + access = GENERIC_READ + case O_WRONLY: + access = GENERIC_WRITE + case O_RDWR: + access = GENERIC_READ | GENERIC_WRITE + } + if mode&O_CREAT != 0 { + access |= GENERIC_WRITE + } + if mode&O_APPEND != 0 { + access &^= GENERIC_WRITE + access |= FILE_APPEND_DATA + } + sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE) + var sa *SecurityAttributes + if mode&O_CLOEXEC == 0 { + sa = makeInheritSa() + } + var createmode uint32 + switch { + case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL): + createmode = CREATE_NEW + case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC): + createmode = CREATE_ALWAYS + case mode&O_CREAT == O_CREAT: + createmode = OPEN_ALWAYS + case mode&O_TRUNC == O_TRUNC: + createmode = TRUNCATE_EXISTING + default: + createmode = OPEN_EXISTING + } + var attrs uint32 = FILE_ATTRIBUTE_NORMAL + if perm&S_IWRITE == 0 { + attrs = FILE_ATTRIBUTE_READONLY + } + h, e := CreateFile(pathp, access, sharemode, sa, createmode, attrs, 0) + return h, e +} + +func Read(fd Handle, p []byte) (n int, err error) { + var done uint32 + e := ReadFile(fd, p, &done, nil) + if e != nil { + if e == ERROR_BROKEN_PIPE { + // NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin + return 0, nil + } + return 0, e + } + return int(done), nil +} + +func Write(fd Handle, p []byte) (n int, err error) { + if raceenabled { + raceReleaseMerge(unsafe.Pointer(&ioSync)) + } + var done uint32 + e := WriteFile(fd, p, &done, nil) + if e != nil { + return 0, e + } + return int(done), nil +} + +func ReadFile(fd Handle, p []byte, done *uint32, overlapped *Overlapped) error { + err := readFile(fd, p, done, overlapped) + if raceenabled { + if *done > 0 { + raceWriteRange(unsafe.Pointer(&p[0]), int(*done)) + } + raceAcquire(unsafe.Pointer(&ioSync)) + } + return err +} + +func WriteFile(fd Handle, p []byte, done *uint32, overlapped *Overlapped) error { + if raceenabled { + raceReleaseMerge(unsafe.Pointer(&ioSync)) + } + err := writeFile(fd, p, done, overlapped) + if raceenabled && *done > 0 { + raceReadRange(unsafe.Pointer(&p[0]), int(*done)) + } + return err +} + +var ioSync int64 + +func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) { + var w uint32 + switch whence { + case 0: + w = FILE_BEGIN + case 1: + w = FILE_CURRENT + case 2: + w = FILE_END + } + hi := int32(offset >> 32) + lo := int32(offset) + // use GetFileType to check pipe, pipe can't do seek + ft, _ := GetFileType(fd) + if ft == FILE_TYPE_PIPE { + return 0, syscall.EPIPE + } + rlo, e := SetFilePointer(fd, lo, &hi, w) + if e != nil { + return 0, e + } + return int64(hi)<<32 + int64(rlo), nil +} + +func Close(fd Handle) (err error) { + return CloseHandle(fd) +} + +var ( + Stdin = getStdHandle(STD_INPUT_HANDLE) + Stdout = getStdHandle(STD_OUTPUT_HANDLE) + Stderr = getStdHandle(STD_ERROR_HANDLE) +) + +func getStdHandle(stdhandle uint32) (fd Handle) { + r, _ := GetStdHandle(stdhandle) + return r +} + +const ImplementsGetwd = true + +func Getwd() (wd string, err error) { + b := make([]uint16, 300) + n, e := GetCurrentDirectory(uint32(len(b)), &b[0]) + if e != nil { + return "", e + } + return string(utf16.Decode(b[0:n])), nil +} + +func Chdir(path string) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return SetCurrentDirectory(pathp) +} + +func Mkdir(path string, mode uint32) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return CreateDirectory(pathp, nil) +} + +func Rmdir(path string) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return RemoveDirectory(pathp) +} + +func Unlink(path string) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return DeleteFile(pathp) +} + +func Rename(oldpath, newpath string) (err error) { + from, err := UTF16PtrFromString(oldpath) + if err != nil { + return err + } + to, err := UTF16PtrFromString(newpath) + if err != nil { + return err + } + return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING) +} + +func ComputerName() (name string, err error) { + var n uint32 = MAX_COMPUTERNAME_LENGTH + 1 + b := make([]uint16, n) + e := GetComputerName(&b[0], &n) + if e != nil { + return "", e + } + return string(utf16.Decode(b[0:n])), nil +} + +func DurationSinceBoot() time.Duration { + return time.Duration(getTickCount64()) * time.Millisecond +} + +func Ftruncate(fd Handle, length int64) (err error) { + type _FILE_END_OF_FILE_INFO struct { + EndOfFile int64 + } + var info _FILE_END_OF_FILE_INFO + info.EndOfFile = length + return SetFileInformationByHandle(fd, FileEndOfFileInfo, (*byte)(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info))) +} + +func Gettimeofday(tv *Timeval) (err error) { + var ft Filetime + GetSystemTimeAsFileTime(&ft) + *tv = NsecToTimeval(ft.Nanoseconds()) + return nil +} + +func Pipe(p []Handle) (err error) { + if len(p) != 2 { + return syscall.EINVAL + } + var r, w Handle + e := CreatePipe(&r, &w, makeInheritSa(), 0) + if e != nil { + return e + } + p[0] = r + p[1] = w + return nil +} + +func Utimes(path string, tv []Timeval) (err error) { + if len(tv) != 2 { + return syscall.EINVAL + } + pathp, e := UTF16PtrFromString(path) + if e != nil { + return e + } + h, e := CreateFile(pathp, + FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) + if e != nil { + return e + } + defer CloseHandle(h) + a := NsecToFiletime(tv[0].Nanoseconds()) + w := NsecToFiletime(tv[1].Nanoseconds()) + return SetFileTime(h, nil, &a, &w) +} + +func UtimesNano(path string, ts []Timespec) (err error) { + if len(ts) != 2 { + return syscall.EINVAL + } + pathp, e := UTF16PtrFromString(path) + if e != nil { + return e + } + h, e := CreateFile(pathp, + FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) + if e != nil { + return e + } + defer CloseHandle(h) + a := NsecToFiletime(TimespecToNsec(ts[0])) + w := NsecToFiletime(TimespecToNsec(ts[1])) + return SetFileTime(h, nil, &a, &w) +} + +func Fsync(fd Handle) (err error) { + return FlushFileBuffers(fd) +} + +func Chmod(path string, mode uint32) (err error) { + p, e := UTF16PtrFromString(path) + if e != nil { + return e + } + attrs, e := GetFileAttributes(p) + if e != nil { + return e + } + if mode&S_IWRITE != 0 { + attrs &^= FILE_ATTRIBUTE_READONLY + } else { + attrs |= FILE_ATTRIBUTE_READONLY + } + return SetFileAttributes(p, attrs) +} + +func LoadGetSystemTimePreciseAsFileTime() error { + return procGetSystemTimePreciseAsFileTime.Find() +} + +func LoadCancelIoEx() error { + return procCancelIoEx.Find() +} + +func LoadSetFileCompletionNotificationModes() error { + return procSetFileCompletionNotificationModes.Find() +} + +func WaitForMultipleObjects(handles []Handle, waitAll bool, waitMilliseconds uint32) (event uint32, err error) { + // Every other win32 array API takes arguments as "pointer, count", except for this function. So we + // can't declare it as a usual [] type, because mksyscall will use the opposite order. We therefore + // trivially stub this ourselves. + + var handlePtr *Handle + if len(handles) > 0 { + handlePtr = &handles[0] + } + return waitForMultipleObjects(uint32(len(handles)), uintptr(unsafe.Pointer(handlePtr)), waitAll, waitMilliseconds) +} + +// net api calls + +const socket_error = uintptr(^uint32(0)) + +//sys WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup +//sys WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup +//sys WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl +//sys WSALookupServiceBegin(querySet *WSAQUERYSET, flags uint32, handle *Handle) (err error) [failretval==socket_error] = ws2_32.WSALookupServiceBeginW +//sys WSALookupServiceNext(handle Handle, flags uint32, size *int32, querySet *WSAQUERYSET) (err error) [failretval==socket_error] = ws2_32.WSALookupServiceNextW +//sys WSALookupServiceEnd(handle Handle) (err error) [failretval==socket_error] = ws2_32.WSALookupServiceEnd +//sys socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket +//sys sendto(s Handle, buf []byte, flags int32, to unsafe.Pointer, tolen int32) (err error) [failretval==socket_error] = ws2_32.sendto +//sys recvfrom(s Handle, buf []byte, flags int32, from *RawSockaddrAny, fromlen *int32) (n int32, err error) [failretval==-1] = ws2_32.recvfrom +//sys Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt +//sys Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt +//sys bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind +//sys connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect +//sys getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname +//sys getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername +//sys listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen +//sys shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown +//sys Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket +//sys AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx +//sys GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs +//sys WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv +//sys WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend +//sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom +//sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo +//sys WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.WSASocketW +//sys WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err error) [failretval!=0] = ws2_32.WSADuplicateSocketW +//sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname +//sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname +//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs +//sys GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname +//sys DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W +//sys DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree +//sys DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W +//sys GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW +//sys FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW +//sys GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry +//sys GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo +//sys SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes +//sys WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW +//sys WSAGetOverlappedResult(h Handle, o *Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult +//sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses +//sys GetACP() (acp uint32) = kernel32.GetACP +//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar +//sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx +//sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex +//sys GetIfTable2Ex(level uint32, table **MibIfTable2) (errcode error) = iphlpapi.GetIfTable2Ex +//sys GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) = iphlpapi.GetIpForwardEntry2 +//sys GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) = iphlpapi.GetIpForwardTable2 +//sys GetIpInterfaceEntry(row *MibIpInterfaceRow) (errcode error) = iphlpapi.GetIpInterfaceEntry +//sys GetIpInterfaceTable(family uint16, table **MibIpInterfaceTable) (errcode error) = iphlpapi.GetIpInterfaceTable +//sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry +//sys GetUnicastIpAddressTable(family uint16, table **MibUnicastIpAddressTable) (errcode error) = iphlpapi.GetUnicastIpAddressTable +//sys FreeMibTable(memory unsafe.Pointer) = iphlpapi.FreeMibTable +//sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange +//sys NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyRouteChange2 +//sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange +//sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2 +//sys IsProcessorFeaturePresent(ProcessorFeature uint32) (ret bool) = kernel32.IsProcessorFeaturePresent + +// For testing: clients can set this flag to force +// creation of IPv6 sockets to return EAFNOSUPPORT. +var SocketDisableIPv6 bool + +type RawSockaddrInet4 struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]uint8 +} + +type RawSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +// RawSockaddrInet is a union that contains an IPv4, an IPv6 address, or an address family. See +// https://learn.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-sockaddr_inet. +// +// A [*RawSockaddrInet] may be converted to a [*RawSockaddrInet4] or [*RawSockaddrInet6] using +// unsafe, depending on the address family. +type RawSockaddrInet struct { + Family uint16 + Port uint16 + Data [6]uint32 +} + +type RawSockaddr struct { + Family uint16 + Data [14]int8 +} + +type RawSockaddrAny struct { + Addr RawSockaddr + Pad [100]int8 +} + +type Sockaddr interface { + sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs +} + +type SockaddrInet4 struct { + Port int + Addr [4]byte + raw RawSockaddrInet4 +} + +func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) { + if sa.Port < 0 || sa.Port > 0xFFFF { + return nil, 0, syscall.EINVAL + } + sa.raw.Family = AF_INET + p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) + p[0] = byte(sa.Port >> 8) + p[1] = byte(sa.Port) + sa.raw.Addr = sa.Addr + return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil +} + +type SockaddrInet6 struct { + Port int + ZoneId uint32 + Addr [16]byte + raw RawSockaddrInet6 +} + +func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) { + if sa.Port < 0 || sa.Port > 0xFFFF { + return nil, 0, syscall.EINVAL + } + sa.raw.Family = AF_INET6 + p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) + p[0] = byte(sa.Port >> 8) + p[1] = byte(sa.Port) + sa.raw.Scope_id = sa.ZoneId + sa.raw.Addr = sa.Addr + return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil +} + +type RawSockaddrUnix struct { + Family uint16 + Path [UNIX_PATH_MAX]int8 +} + +type SockaddrUnix struct { + Name string + raw RawSockaddrUnix +} + +func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { + name := sa.Name + n := len(name) + if n > len(sa.raw.Path) { + return nil, 0, syscall.EINVAL + } + if n == len(sa.raw.Path) && name[0] != '@' { + return nil, 0, syscall.EINVAL + } + sa.raw.Family = AF_UNIX + for i := 0; i < n; i++ { + sa.raw.Path[i] = int8(name[i]) + } + // length is family (uint16), name, NUL. + sl := int32(2) + if n > 0 { + sl += int32(n) + 1 + } + if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) { + // Check sl > 3 so we don't change unnamed socket behavior. + sa.raw.Path[0] = 0 + // Don't count trailing NUL for abstract address. + sl-- + } + + return unsafe.Pointer(&sa.raw), sl, nil +} + +type RawSockaddrBth struct { + AddressFamily [2]byte + BtAddr [8]byte + ServiceClassId [16]byte + Port [4]byte +} + +type SockaddrBth struct { + BtAddr uint64 + ServiceClassId GUID + Port uint32 + + raw RawSockaddrBth +} + +func (sa *SockaddrBth) sockaddr() (unsafe.Pointer, int32, error) { + family := AF_BTH + sa.raw = RawSockaddrBth{ + AddressFamily: *(*[2]byte)(unsafe.Pointer(&family)), + BtAddr: *(*[8]byte)(unsafe.Pointer(&sa.BtAddr)), + Port: *(*[4]byte)(unsafe.Pointer(&sa.Port)), + ServiceClassId: *(*[16]byte)(unsafe.Pointer(&sa.ServiceClassId)), + } + return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil +} + +func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) { + switch rsa.Addr.Family { + case AF_UNIX: + pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) + sa := new(SockaddrUnix) + if pp.Path[0] == 0 { + // "Abstract" Unix domain socket. + // Rewrite leading NUL as @ for textual display. + // (This is the standard convention.) + // Not friendly to overwrite in place, + // but the callers below don't care. + pp.Path[0] = '@' + } + + // Assume path ends at NUL. + // This is not technically the Linux semantics for + // abstract Unix domain sockets--they are supposed + // to be uninterpreted fixed-size binary blobs--but + // everyone uses this convention. + n := 0 + for n < len(pp.Path) && pp.Path[n] != 0 { + n++ + } + sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n)) + return sa, nil + + case AF_INET: + pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) + sa := new(SockaddrInet4) + p := (*[2]byte)(unsafe.Pointer(&pp.Port)) + sa.Port = int(p[0])<<8 + int(p[1]) + sa.Addr = pp.Addr + return sa, nil + + case AF_INET6: + pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) + sa := new(SockaddrInet6) + p := (*[2]byte)(unsafe.Pointer(&pp.Port)) + sa.Port = int(p[0])<<8 + int(p[1]) + sa.ZoneId = pp.Scope_id + sa.Addr = pp.Addr + return sa, nil + } + return nil, syscall.EAFNOSUPPORT +} + +func Socket(domain, typ, proto int) (fd Handle, err error) { + if domain == AF_INET6 && SocketDisableIPv6 { + return InvalidHandle, syscall.EAFNOSUPPORT + } + return socket(int32(domain), int32(typ), int32(proto)) +} + +func SetsockoptInt(fd Handle, level, opt int, value int) (err error) { + v := int32(value) + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v))) +} + +func Bind(fd Handle, sa Sockaddr) (err error) { + ptr, n, err := sa.sockaddr() + if err != nil { + return err + } + return bind(fd, ptr, n) +} + +func Connect(fd Handle, sa Sockaddr) (err error) { + ptr, n, err := sa.sockaddr() + if err != nil { + return err + } + return connect(fd, ptr, n) +} + +func GetBestInterfaceEx(sa Sockaddr, pdwBestIfIndex *uint32) (err error) { + ptr, _, err := sa.sockaddr() + if err != nil { + return err + } + return getBestInterfaceEx(ptr, pdwBestIfIndex) +} + +func Getsockname(fd Handle) (sa Sockaddr, err error) { + var rsa RawSockaddrAny + l := int32(unsafe.Sizeof(rsa)) + if err = getsockname(fd, &rsa, &l); err != nil { + return + } + return rsa.Sockaddr() +} + +func Getpeername(fd Handle) (sa Sockaddr, err error) { + var rsa RawSockaddrAny + l := int32(unsafe.Sizeof(rsa)) + if err = getpeername(fd, &rsa, &l); err != nil { + return + } + return rsa.Sockaddr() +} + +func Listen(s Handle, n int) (err error) { + return listen(s, int32(n)) +} + +func Shutdown(fd Handle, how int) (err error) { + return shutdown(fd, int32(how)) +} + +func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) { + var rsa unsafe.Pointer + var l int32 + if to != nil { + rsa, l, err = to.sockaddr() + if err != nil { + return err + } + } + return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine) +} + +func LoadGetAddrInfo() error { + return procGetAddrInfoW.Find() +} + +var connectExFunc struct { + once sync.Once + addr uintptr + err error +} + +func LoadConnectEx() error { + connectExFunc.once.Do(func() { + var s Handle + s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) + if connectExFunc.err != nil { + return + } + defer CloseHandle(s) + var n uint32 + connectExFunc.err = WSAIoctl(s, + SIO_GET_EXTENSION_FUNCTION_POINTER, + (*byte)(unsafe.Pointer(&WSAID_CONNECTEX)), + uint32(unsafe.Sizeof(WSAID_CONNECTEX)), + (*byte)(unsafe.Pointer(&connectExFunc.addr)), + uint32(unsafe.Sizeof(connectExFunc.addr)), + &n, nil, 0) + }) + return connectExFunc.err +} + +func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error { + err := LoadConnectEx() + if err != nil { + return errorspkg.New("failed to find ConnectEx: " + err.Error()) + } + ptr, n, err := sa.sockaddr() + if err != nil { + return err + } + return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped) +} + +var sendRecvMsgFunc struct { + once sync.Once + sendAddr uintptr + recvAddr uintptr + err error +} + +func loadWSASendRecvMsg() error { + sendRecvMsgFunc.once.Do(func() { + var s Handle + s, sendRecvMsgFunc.err = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) + if sendRecvMsgFunc.err != nil { + return + } + defer CloseHandle(s) + var n uint32 + sendRecvMsgFunc.err = WSAIoctl(s, + SIO_GET_EXTENSION_FUNCTION_POINTER, + (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)), + uint32(unsafe.Sizeof(WSAID_WSARECVMSG)), + (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)), + uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)), + &n, nil, 0) + if sendRecvMsgFunc.err != nil { + return + } + sendRecvMsgFunc.err = WSAIoctl(s, + SIO_GET_EXTENSION_FUNCTION_POINTER, + (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)), + uint32(unsafe.Sizeof(WSAID_WSASENDMSG)), + (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)), + uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)), + &n, nil, 0) + }) + return sendRecvMsgFunc.err +} + +func WSASendMsg(fd Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *Overlapped, croutine *byte) error { + err := loadWSASendRecvMsg() + if err != nil { + return err + } + r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + err = errnoErr(e1) + } + return err +} + +func WSARecvMsg(fd Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *Overlapped, croutine *byte) error { + err := loadWSASendRecvMsg() + if err != nil { + return err + } + r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0) + if r1 == socket_error { + err = errnoErr(e1) + } + return err +} + +// Invented structures to support what package os expects. +type Rusage struct { + CreationTime Filetime + ExitTime Filetime + KernelTime Filetime + UserTime Filetime +} + +type WaitStatus struct { + ExitCode uint32 +} + +func (w WaitStatus) Exited() bool { return true } + +func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) } + +func (w WaitStatus) Signal() Signal { return -1 } + +func (w WaitStatus) CoreDump() bool { return false } + +func (w WaitStatus) Stopped() bool { return false } + +func (w WaitStatus) Continued() bool { return false } + +func (w WaitStatus) StopSignal() Signal { return -1 } + +func (w WaitStatus) Signaled() bool { return false } + +func (w WaitStatus) TrapCause() int { return -1 } + +// Timespec is an invented structure on Windows, but here for +// consistency with the corresponding package for other operating systems. +type Timespec struct { + Sec int64 + Nsec int64 +} + +func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } + +func NsecToTimespec(nsec int64) (ts Timespec) { + ts.Sec = nsec / 1e9 + ts.Nsec = nsec % 1e9 + return +} + +// TODO(brainman): fix all needed for net + +func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, syscall.EWINDOWS } + +func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) { + var rsa RawSockaddrAny + l := int32(unsafe.Sizeof(rsa)) + n32, err := recvfrom(fd, p, int32(flags), &rsa, &l) + n = int(n32) + if err != nil { + return + } + from, err = rsa.Sockaddr() + return +} + +func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error) { + ptr, l, err := to.sockaddr() + if err != nil { + return err + } + return sendto(fd, p, int32(flags), ptr, l) +} + +func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return syscall.EWINDOWS } + +// The Linger struct is wrong but we only noticed after Go 1. +// sysLinger is the real system call structure. + +// BUG(brainman): The definition of Linger is not appropriate for direct use +// with Setsockopt and Getsockopt. +// Use SetsockoptLinger instead. + +type Linger struct { + Onoff int32 + Linger int32 +} + +type sysLinger struct { + Onoff uint16 + Linger uint16 +} + +type IPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type IPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +func GetsockoptInt(fd Handle, level, opt int) (int, error) { + v := int32(0) + l := int32(unsafe.Sizeof(v)) + err := Getsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), &l) + return int(v), err +} + +func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { + sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)} + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys))) +} + +func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) { + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4) +} + +func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) { + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) +} + +func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { + return syscall.EWINDOWS +} + +func EnumProcesses(processIds []uint32, bytesReturned *uint32) error { + // EnumProcesses syscall expects the size parameter to be in bytes, but the code generated with mksyscall uses + // the length of the processIds slice instead. Hence, this wrapper function is added to fix the discrepancy. + var p *uint32 + if len(processIds) > 0 { + p = &processIds[0] + } + size := uint32(len(processIds) * 4) + return enumProcesses(p, size, bytesReturned) +} + +func Getpid() (pid int) { return int(GetCurrentProcessId()) } + +func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) { + // NOTE(rsc): The Win32finddata struct is wrong for the system call: + // the two paths are each one uint16 short. Use the correct struct, + // a win32finddata1, and then copy the results out. + // There is no loss of expressivity here, because the final + // uint16, if it is used, is supposed to be a NUL, and Go doesn't need that. + // For Go 1.1, we might avoid the allocation of win32finddata1 here + // by adding a final Bug [2]uint16 field to the struct and then + // adjusting the fields in the result directly. + var data1 win32finddata1 + handle, err = findFirstFile1(name, &data1) + if err == nil { + copyFindData(data, &data1) + } + return +} + +func FindNextFile(handle Handle, data *Win32finddata) (err error) { + var data1 win32finddata1 + err = findNextFile1(handle, &data1) + if err == nil { + copyFindData(data, &data1) + } + return +} + +func getProcessEntry(pid int) (*ProcessEntry32, error) { + snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) + if err != nil { + return nil, err + } + defer CloseHandle(snapshot) + var procEntry ProcessEntry32 + procEntry.Size = uint32(unsafe.Sizeof(procEntry)) + if err = Process32First(snapshot, &procEntry); err != nil { + return nil, err + } + for { + if procEntry.ProcessID == uint32(pid) { + return &procEntry, nil + } + err = Process32Next(snapshot, &procEntry) + if err != nil { + return nil, err + } + } +} + +func Getppid() (ppid int) { + pe, err := getProcessEntry(Getpid()) + if err != nil { + return -1 + } + return int(pe.ParentProcessID) +} + +// TODO(brainman): fix all needed for os +func Fchdir(fd Handle) (err error) { return syscall.EWINDOWS } +func Link(oldpath, newpath string) (err error) { return syscall.EWINDOWS } +func Symlink(path, link string) (err error) { return syscall.EWINDOWS } + +func Fchmod(fd Handle, mode uint32) (err error) { return syscall.EWINDOWS } +func Chown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS } +func Lchown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS } +func Fchown(fd Handle, uid int, gid int) (err error) { return syscall.EWINDOWS } + +func Getuid() (uid int) { return -1 } +func Geteuid() (euid int) { return -1 } +func Getgid() (gid int) { return -1 } +func Getegid() (egid int) { return -1 } +func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS } + +func LoadCreateSymbolicLink() error { + return procCreateSymbolicLinkW.Find() +} + +// Readlink returns the destination of the named symbolic link. +func Readlink(path string, buf []byte) (n int, err error) { + fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0) + if err != nil { + return -1, err + } + defer CloseHandle(fd) + + rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE) + var bytesReturned uint32 + err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil) + if err != nil { + return -1, err + } + + rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0])) + var s string + switch rdb.ReparseTag { + case IO_REPARSE_TAG_SYMLINK: + data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) + p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) + s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) + case IO_REPARSE_TAG_MOUNT_POINT: + data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) + p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) + s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) + default: + // the path is not a symlink or junction but another type of reparse + // point + return -1, syscall.ENOENT + } + n = copy(buf, []byte(s)) + + return n, nil +} + +// GUIDFromString parses a string in the form of +// "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" into a GUID. +func GUIDFromString(str string) (GUID, error) { + guid := GUID{} + str16, err := syscall.UTF16PtrFromString(str) + if err != nil { + return guid, err + } + err = clsidFromString(str16, &guid) + if err != nil { + return guid, err + } + return guid, nil +} + +// GenerateGUID creates a new random GUID. +func GenerateGUID() (GUID, error) { + guid := GUID{} + err := coCreateGuid(&guid) + if err != nil { + return guid, err + } + return guid, nil +} + +// String returns the canonical string form of the GUID, +// in the form of "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}". +func (guid GUID) String() string { + var str [100]uint16 + chars := stringFromGUID2(&guid, &str[0], int32(len(str))) + if chars <= 1 { + return "" + } + return string(utf16.Decode(str[:chars-1])) +} + +// KnownFolderPath returns a well-known folder path for the current user, specified by one of +// the FOLDERID_ constants, and chosen and optionally created based on a KF_ flag. +func KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, error) { + return Token(0).KnownFolderPath(folderID, flags) +} + +// KnownFolderPath returns a well-known folder path for the user token, specified by one of +// the FOLDERID_ constants, and chosen and optionally created based on a KF_ flag. +func (t Token) KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, error) { + var p *uint16 + err := shGetKnownFolderPath(folderID, flags, t, &p) + if err != nil { + return "", err + } + defer CoTaskMemFree(unsafe.Pointer(p)) + return UTF16PtrToString(p), nil +} + +// RtlGetVersion returns the version of the underlying operating system, ignoring +// manifest semantics but is affected by the application compatibility layer. +func RtlGetVersion() *OsVersionInfoEx { + info := &OsVersionInfoEx{} + info.osVersionInfoSize = uint32(unsafe.Sizeof(*info)) + // According to documentation, this function always succeeds. + // The function doesn't even check the validity of the + // osVersionInfoSize member. Disassembling ntdll.dll indicates + // that the documentation is indeed correct about that. + _ = rtlGetVersion(info) + return info +} + +// RtlGetNtVersionNumbers returns the version of the underlying operating system, +// ignoring manifest semantics and the application compatibility layer. +func RtlGetNtVersionNumbers() (majorVersion, minorVersion, buildNumber uint32) { + rtlGetNtVersionNumbers(&majorVersion, &minorVersion, &buildNumber) + buildNumber &= 0xffff + return +} + +// GetProcessPreferredUILanguages retrieves the process preferred UI languages. +func GetProcessPreferredUILanguages(flags uint32) ([]string, error) { + return getUILanguages(flags, getProcessPreferredUILanguages) +} + +// GetThreadPreferredUILanguages retrieves the thread preferred UI languages for the current thread. +func GetThreadPreferredUILanguages(flags uint32) ([]string, error) { + return getUILanguages(flags, getThreadPreferredUILanguages) +} + +// GetUserPreferredUILanguages retrieves information about the user preferred UI languages. +func GetUserPreferredUILanguages(flags uint32) ([]string, error) { + return getUILanguages(flags, getUserPreferredUILanguages) +} + +// GetSystemPreferredUILanguages retrieves the system preferred UI languages. +func GetSystemPreferredUILanguages(flags uint32) ([]string, error) { + return getUILanguages(flags, getSystemPreferredUILanguages) +} + +func getUILanguages(flags uint32, f func(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) error) ([]string, error) { + size := uint32(128) + for { + var numLanguages uint32 + buf := make([]uint16, size) + err := f(flags, &numLanguages, &buf[0], &size) + if err == ERROR_INSUFFICIENT_BUFFER { + continue + } + if err != nil { + return nil, err + } + buf = buf[:size] + if numLanguages == 0 || len(buf) == 0 { // GetProcessPreferredUILanguages may return numLanguages==0 with "\0\0" + return []string{}, nil + } + if buf[len(buf)-1] == 0 { + buf = buf[:len(buf)-1] // remove terminating null + } + languages := make([]string, 0, numLanguages) + from := 0 + for i, c := range buf { + if c == 0 { + languages = append(languages, string(utf16.Decode(buf[from:i]))) + from = i + 1 + } + } + return languages, nil + } +} + +func SetConsoleCursorPosition(console Handle, position Coord) error { + return setConsoleCursorPosition(console, *((*uint32)(unsafe.Pointer(&position)))) +} + +func GetStartupInfo(startupInfo *StartupInfo) error { + getStartupInfo(startupInfo) + return nil +} + +func (s NTStatus) Errno() syscall.Errno { + return rtlNtStatusToDosErrorNoTeb(s) +} + +func langID(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) } + +func (s NTStatus) Error() string { + b := make([]uint16, 300) + n, err := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_ARGUMENT_ARRAY, modntdll.Handle(), uint32(s), langID(LANG_ENGLISH, SUBLANG_ENGLISH_US), b, nil) + if err != nil { + return fmt.Sprintf("NTSTATUS 0x%08x", uint32(s)) + } + // trim terminating \r and \n + for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- { + } + return string(utf16.Decode(b[:n])) +} + +// NewNTUnicodeString returns a new NTUnicodeString structure for use with native +// NT APIs that work over the NTUnicodeString type. Note that most Windows APIs +// do not use NTUnicodeString, and instead UTF16PtrFromString should be used for +// the more common *uint16 string type. +func NewNTUnicodeString(s string) (*NTUnicodeString, error) { + s16, err := UTF16FromString(s) + if err != nil { + return nil, err + } + n := len(s16) * 2 + if n > (1<<16)-1 { + return nil, syscall.EINVAL + } + return &NTUnicodeString{ + Length: uint16(n) - 2, // subtract 2 bytes for the NULL terminator + MaximumLength: uint16(n), + Buffer: &s16[0], + }, nil +} + +// Slice returns a uint16 slice that aliases the data in the NTUnicodeString. +func (s *NTUnicodeString) Slice() []uint16 { + // Note: this rounds the length down, if it happens + // to (incorrectly) be odd. Probably safer than rounding up. + return unsafe.Slice(s.Buffer, s.MaximumLength/2)[:s.Length/2] +} + +func (s *NTUnicodeString) String() string { + return UTF16ToString(s.Slice()) +} + +// NewNTString returns a new NTString structure for use with native +// NT APIs that work over the NTString type. Note that most Windows APIs +// do not use NTString, and instead UTF16PtrFromString should be used for +// the more common *uint16 string type. +func NewNTString(s string) (*NTString, error) { + var nts NTString + s8, err := ByteSliceFromString(s) + if err != nil { + return nil, err + } + // The source string plus its terminating NUL must fit within MAX_USHORT. + if len(s8) > MAX_USHORT { + return nil, syscall.EINVAL + } + RtlInitString(&nts, &s8[0]) + return &nts, nil +} + +// Slice returns a byte slice that aliases the data in the NTString. +func (s *NTString) Slice() []byte { + slice := unsafe.Slice(s.Buffer, s.MaximumLength) + return slice[:s.Length] +} + +func (s *NTString) String() string { + return ByteSliceToString(s.Slice()) +} + +// FindResource resolves a resource of the given name and resource type. +func FindResource(module Handle, name, resType ResourceIDOrString) (Handle, error) { + var namePtr, resTypePtr uintptr + var name16, resType16 *uint16 + var err error + resolvePtr := func(i interface{}, keep **uint16) (uintptr, error) { + switch v := i.(type) { + case string: + *keep, err = UTF16PtrFromString(v) + if err != nil { + return 0, err + } + return uintptr(unsafe.Pointer(*keep)), nil + case ResourceID: + return uintptr(v), nil + } + return 0, errorspkg.New("parameter must be a ResourceID or a string") + } + namePtr, err = resolvePtr(name, &name16) + if err != nil { + return 0, err + } + resTypePtr, err = resolvePtr(resType, &resType16) + if err != nil { + return 0, err + } + resInfo, err := findResource(module, namePtr, resTypePtr) + runtime.KeepAlive(name16) + runtime.KeepAlive(resType16) + return resInfo, err +} + +func LoadResourceData(module, resInfo Handle) (data []byte, err error) { + size, err := SizeofResource(module, resInfo) + if err != nil { + return + } + resData, err := LoadResource(module, resInfo) + if err != nil { + return + } + ptr, err := LockResource(resData) + if err != nil { + return + } + data = unsafe.Slice((*byte)(unsafe.Pointer(ptr)), size) + return +} + +// PSAPI_WORKING_SET_EX_BLOCK contains extended working set information for a page. +type PSAPI_WORKING_SET_EX_BLOCK uint64 + +// Valid returns the validity of this page. +// If this bit is 1, the subsequent members are valid; otherwise they should be ignored. +func (b PSAPI_WORKING_SET_EX_BLOCK) Valid() bool { + return (b & 1) == 1 +} + +// ShareCount is the number of processes that share this page. The maximum value of this member is 7. +func (b PSAPI_WORKING_SET_EX_BLOCK) ShareCount() uint64 { + return b.intField(1, 3) +} + +// Win32Protection is the memory protection attributes of the page. For a list of values, see +// https://docs.microsoft.com/en-us/windows/win32/memory/memory-protection-constants +func (b PSAPI_WORKING_SET_EX_BLOCK) Win32Protection() uint64 { + return b.intField(4, 11) +} + +// Shared returns the shared status of this page. +// If this bit is 1, the page can be shared. +func (b PSAPI_WORKING_SET_EX_BLOCK) Shared() bool { + return (b & (1 << 15)) == 1 +} + +// Node is the NUMA node. The maximum value of this member is 63. +func (b PSAPI_WORKING_SET_EX_BLOCK) Node() uint64 { + return b.intField(16, 6) +} + +// Locked returns the locked status of this page. +// If this bit is 1, the virtual page is locked in physical memory. +func (b PSAPI_WORKING_SET_EX_BLOCK) Locked() bool { + return (b & (1 << 22)) == 1 +} + +// LargePage returns the large page status of this page. +// If this bit is 1, the page is a large page. +func (b PSAPI_WORKING_SET_EX_BLOCK) LargePage() bool { + return (b & (1 << 23)) == 1 +} + +// Bad returns the bad status of this page. +// If this bit is 1, the page is has been reported as bad. +func (b PSAPI_WORKING_SET_EX_BLOCK) Bad() bool { + return (b & (1 << 31)) == 1 +} + +// intField extracts an integer field in the PSAPI_WORKING_SET_EX_BLOCK union. +func (b PSAPI_WORKING_SET_EX_BLOCK) intField(start, length int) uint64 { + var mask PSAPI_WORKING_SET_EX_BLOCK + for pos := start; pos < start+length; pos++ { + mask |= (1 << pos) + } + + masked := b & mask + return uint64(masked >> start) +} + +// PSAPI_WORKING_SET_EX_INFORMATION contains extended working set information for a process. +type PSAPI_WORKING_SET_EX_INFORMATION struct { + // The virtual address. + VirtualAddress Pointer + // A PSAPI_WORKING_SET_EX_BLOCK union that indicates the attributes of the page at VirtualAddress. + VirtualAttributes PSAPI_WORKING_SET_EX_BLOCK +} + +// CreatePseudoConsole creates a windows pseudo console. +func CreatePseudoConsole(size Coord, in Handle, out Handle, flags uint32, pconsole *Handle) error { + // We need this wrapper to manually cast Coord to uint32. The autogenerated wrappers only + // accept arguments that can be casted to uintptr, and Coord can't. + return createPseudoConsole(*((*uint32)(unsafe.Pointer(&size))), in, out, flags, pconsole) +} + +// ResizePseudoConsole resizes the internal buffers of the pseudo console to the width and height specified in `size`. +func ResizePseudoConsole(pconsole Handle, size Coord) error { + // We need this wrapper to manually cast Coord to uint32. The autogenerated wrappers only + // accept arguments that can be casted to uintptr, and Coord can't. + return resizePseudoConsole(pconsole, *((*uint32)(unsafe.Pointer(&size)))) +} + +// DCB constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-dcb. +const ( + CBR_110 = 110 + CBR_300 = 300 + CBR_600 = 600 + CBR_1200 = 1200 + CBR_2400 = 2400 + CBR_4800 = 4800 + CBR_9600 = 9600 + CBR_14400 = 14400 + CBR_19200 = 19200 + CBR_38400 = 38400 + CBR_57600 = 57600 + CBR_115200 = 115200 + CBR_128000 = 128000 + CBR_256000 = 256000 + + DTR_CONTROL_DISABLE = 0x00000000 + DTR_CONTROL_ENABLE = 0x00000010 + DTR_CONTROL_HANDSHAKE = 0x00000020 + + RTS_CONTROL_DISABLE = 0x00000000 + RTS_CONTROL_ENABLE = 0x00001000 + RTS_CONTROL_HANDSHAKE = 0x00002000 + RTS_CONTROL_TOGGLE = 0x00003000 + + NOPARITY = 0 + ODDPARITY = 1 + EVENPARITY = 2 + MARKPARITY = 3 + SPACEPARITY = 4 + + ONESTOPBIT = 0 + ONE5STOPBITS = 1 + TWOSTOPBITS = 2 +) + +// EscapeCommFunction constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-escapecommfunction. +const ( + SETXOFF = 1 + SETXON = 2 + SETRTS = 3 + CLRRTS = 4 + SETDTR = 5 + CLRDTR = 6 + SETBREAK = 8 + CLRBREAK = 9 +) + +// PurgeComm constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-purgecomm. +const ( + PURGE_TXABORT = 0x0001 + PURGE_RXABORT = 0x0002 + PURGE_TXCLEAR = 0x0004 + PURGE_RXCLEAR = 0x0008 +) + +// SetCommMask constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setcommmask. +const ( + EV_RXCHAR = 0x0001 + EV_RXFLAG = 0x0002 + EV_TXEMPTY = 0x0004 + EV_CTS = 0x0008 + EV_DSR = 0x0010 + EV_RLSD = 0x0020 + EV_BREAK = 0x0040 + EV_ERR = 0x0080 + EV_RING = 0x0100 +) diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go new file mode 100644 index 0000000..643737d --- /dev/null +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -0,0 +1,4058 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +import ( + "net" + "syscall" + "unsafe" +) + +// NTStatus corresponds with NTSTATUS, error values returned by ntdll.dll and +// other native functions. +type NTStatus uint32 + +const ( + // Invented values to support what package os expects. + O_RDONLY = 0x00000 + O_WRONLY = 0x00001 + O_RDWR = 0x00002 + O_CREAT = 0x00040 + O_EXCL = 0x00080 + O_NOCTTY = 0x00100 + O_TRUNC = 0x00200 + O_NONBLOCK = 0x00800 + O_APPEND = 0x00400 + O_SYNC = 0x01000 + O_ASYNC = 0x02000 + O_CLOEXEC = 0x80000 +) + +const ( + // More invented values for signals + SIGHUP = Signal(0x1) + SIGINT = Signal(0x2) + SIGQUIT = Signal(0x3) + SIGILL = Signal(0x4) + SIGTRAP = Signal(0x5) + SIGABRT = Signal(0x6) + SIGBUS = Signal(0x7) + SIGFPE = Signal(0x8) + SIGKILL = Signal(0x9) + SIGSEGV = Signal(0xb) + SIGPIPE = Signal(0xd) + SIGALRM = Signal(0xe) + SIGTERM = Signal(0xf) +) + +var signals = [...]string{ + 1: "hangup", + 2: "interrupt", + 3: "quit", + 4: "illegal instruction", + 5: "trace/breakpoint trap", + 6: "aborted", + 7: "bus error", + 8: "floating point exception", + 9: "killed", + 10: "user defined signal 1", + 11: "segmentation fault", + 12: "user defined signal 2", + 13: "broken pipe", + 14: "alarm clock", + 15: "terminated", +} + +// File flags for [os.OpenFile]. The O_ prefix is used to indicate +// that these flags are specific to the OpenFile function. +const ( + O_FILE_FLAG_OPEN_NO_RECALL = FILE_FLAG_OPEN_NO_RECALL + O_FILE_FLAG_OPEN_REPARSE_POINT = FILE_FLAG_OPEN_REPARSE_POINT + O_FILE_FLAG_SESSION_AWARE = FILE_FLAG_SESSION_AWARE + O_FILE_FLAG_POSIX_SEMANTICS = FILE_FLAG_POSIX_SEMANTICS + O_FILE_FLAG_BACKUP_SEMANTICS = FILE_FLAG_BACKUP_SEMANTICS + O_FILE_FLAG_DELETE_ON_CLOSE = FILE_FLAG_DELETE_ON_CLOSE + O_FILE_FLAG_SEQUENTIAL_SCAN = FILE_FLAG_SEQUENTIAL_SCAN + O_FILE_FLAG_RANDOM_ACCESS = FILE_FLAG_RANDOM_ACCESS + O_FILE_FLAG_NO_BUFFERING = FILE_FLAG_NO_BUFFERING + O_FILE_FLAG_OVERLAPPED = FILE_FLAG_OVERLAPPED + O_FILE_FLAG_WRITE_THROUGH = FILE_FLAG_WRITE_THROUGH +) + +const ( + FILE_READ_DATA = 0x00000001 + FILE_READ_ATTRIBUTES = 0x00000080 + FILE_READ_EA = 0x00000008 + FILE_WRITE_DATA = 0x00000002 + FILE_WRITE_ATTRIBUTES = 0x00000100 + FILE_WRITE_EA = 0x00000010 + FILE_APPEND_DATA = 0x00000004 + FILE_EXECUTE = 0x00000020 + + FILE_GENERIC_READ = STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE + FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE + FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE + + FILE_LIST_DIRECTORY = 0x00000001 + FILE_TRAVERSE = 0x00000020 + + FILE_SHARE_READ = 0x00000001 + FILE_SHARE_WRITE = 0x00000002 + FILE_SHARE_DELETE = 0x00000004 + + FILE_ATTRIBUTE_READONLY = 0x00000001 + FILE_ATTRIBUTE_HIDDEN = 0x00000002 + FILE_ATTRIBUTE_SYSTEM = 0x00000004 + FILE_ATTRIBUTE_DIRECTORY = 0x00000010 + FILE_ATTRIBUTE_ARCHIVE = 0x00000020 + FILE_ATTRIBUTE_DEVICE = 0x00000040 + FILE_ATTRIBUTE_NORMAL = 0x00000080 + FILE_ATTRIBUTE_TEMPORARY = 0x00000100 + FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200 + FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400 + FILE_ATTRIBUTE_COMPRESSED = 0x00000800 + FILE_ATTRIBUTE_OFFLINE = 0x00001000 + FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000 + FILE_ATTRIBUTE_ENCRYPTED = 0x00004000 + FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x00008000 + FILE_ATTRIBUTE_VIRTUAL = 0x00010000 + FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x00020000 + FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x00040000 + FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x00400000 + + INVALID_FILE_ATTRIBUTES = 0xffffffff + + CREATE_NEW = 1 + CREATE_ALWAYS = 2 + OPEN_EXISTING = 3 + OPEN_ALWAYS = 4 + TRUNCATE_EXISTING = 5 + + FILE_FLAG_OPEN_REQUIRING_OPLOCK = 0x00040000 + FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000 + FILE_FLAG_OPEN_NO_RECALL = 0x00100000 + FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000 + FILE_FLAG_SESSION_AWARE = 0x00800000 + FILE_FLAG_POSIX_SEMANTICS = 0x01000000 + FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 + FILE_FLAG_DELETE_ON_CLOSE = 0x04000000 + FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000 + FILE_FLAG_RANDOM_ACCESS = 0x10000000 + FILE_FLAG_NO_BUFFERING = 0x20000000 + FILE_FLAG_OVERLAPPED = 0x40000000 + FILE_FLAG_WRITE_THROUGH = 0x80000000 + + HANDLE_FLAG_INHERIT = 0x00000001 + STARTF_USESTDHANDLES = 0x00000100 + STARTF_USESHOWWINDOW = 0x00000001 + DUPLICATE_CLOSE_SOURCE = 0x00000001 + DUPLICATE_SAME_ACCESS = 0x00000002 + + STD_INPUT_HANDLE = -10 & (1<<32 - 1) + STD_OUTPUT_HANDLE = -11 & (1<<32 - 1) + STD_ERROR_HANDLE = -12 & (1<<32 - 1) + + FILE_BEGIN = 0 + FILE_CURRENT = 1 + FILE_END = 2 + + LANG_ENGLISH = 0x09 + SUBLANG_ENGLISH_US = 0x01 + + FORMAT_MESSAGE_ALLOCATE_BUFFER = 256 + FORMAT_MESSAGE_IGNORE_INSERTS = 512 + FORMAT_MESSAGE_FROM_STRING = 1024 + FORMAT_MESSAGE_FROM_HMODULE = 2048 + FORMAT_MESSAGE_FROM_SYSTEM = 4096 + FORMAT_MESSAGE_ARGUMENT_ARRAY = 8192 + FORMAT_MESSAGE_MAX_WIDTH_MASK = 255 + + MAX_USHORT = 0xffff + MAX_PATH = 260 + MAX_LONG_PATH = 32768 + + MAX_MODULE_NAME32 = 255 + + MAX_COMPUTERNAME_LENGTH = 15 + + MAX_DHCPV6_DUID_LENGTH = 130 + + MAX_DNS_SUFFIX_STRING_LENGTH = 256 + + TIME_ZONE_ID_UNKNOWN = 0 + TIME_ZONE_ID_STANDARD = 1 + + TIME_ZONE_ID_DAYLIGHT = 2 + IGNORE = 0 + INFINITE = 0xffffffff + + WAIT_ABANDONED = 0x00000080 + WAIT_OBJECT_0 = 0x00000000 + WAIT_FAILED = 0xFFFFFFFF + + // Access rights for process. + PROCESS_ALL_ACCESS = 0xFFFF + PROCESS_CREATE_PROCESS = 0x0080 + PROCESS_CREATE_THREAD = 0x0002 + PROCESS_DUP_HANDLE = 0x0040 + PROCESS_QUERY_INFORMATION = 0x0400 + PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 + PROCESS_SET_INFORMATION = 0x0200 + PROCESS_SET_QUOTA = 0x0100 + PROCESS_SUSPEND_RESUME = 0x0800 + PROCESS_TERMINATE = 0x0001 + PROCESS_VM_OPERATION = 0x0008 + PROCESS_VM_READ = 0x0010 + PROCESS_VM_WRITE = 0x0020 + + // Access rights for thread. + THREAD_DIRECT_IMPERSONATION = 0x0200 + THREAD_GET_CONTEXT = 0x0008 + THREAD_IMPERSONATE = 0x0100 + THREAD_QUERY_INFORMATION = 0x0040 + THREAD_QUERY_LIMITED_INFORMATION = 0x0800 + THREAD_SET_CONTEXT = 0x0010 + THREAD_SET_INFORMATION = 0x0020 + THREAD_SET_LIMITED_INFORMATION = 0x0400 + THREAD_SET_THREAD_TOKEN = 0x0080 + THREAD_SUSPEND_RESUME = 0x0002 + THREAD_TERMINATE = 0x0001 + + FILE_MAP_COPY = 0x01 + FILE_MAP_WRITE = 0x02 + FILE_MAP_READ = 0x04 + FILE_MAP_EXECUTE = 0x20 + + CTRL_C_EVENT = 0 + CTRL_BREAK_EVENT = 1 + CTRL_CLOSE_EVENT = 2 + CTRL_LOGOFF_EVENT = 5 + CTRL_SHUTDOWN_EVENT = 6 + + // Windows reserves errors >= 1<<29 for application use. + APPLICATION_ERROR = 1 << 29 +) + +const ( + // Process creation flags. + CREATE_BREAKAWAY_FROM_JOB = 0x01000000 + CREATE_DEFAULT_ERROR_MODE = 0x04000000 + CREATE_NEW_CONSOLE = 0x00000010 + CREATE_NEW_PROCESS_GROUP = 0x00000200 + CREATE_NO_WINDOW = 0x08000000 + CREATE_PROTECTED_PROCESS = 0x00040000 + CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000 + CREATE_SEPARATE_WOW_VDM = 0x00000800 + CREATE_SHARED_WOW_VDM = 0x00001000 + CREATE_SUSPENDED = 0x00000004 + CREATE_UNICODE_ENVIRONMENT = 0x00000400 + DEBUG_ONLY_THIS_PROCESS = 0x00000002 + DEBUG_PROCESS = 0x00000001 + DETACHED_PROCESS = 0x00000008 + EXTENDED_STARTUPINFO_PRESENT = 0x00080000 + INHERIT_PARENT_AFFINITY = 0x00010000 +) + +const ( + // attributes for ProcThreadAttributeList + PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000 + PROC_THREAD_ATTRIBUTE_HANDLE_LIST = 0x00020002 + PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY = 0x00030003 + PROC_THREAD_ATTRIBUTE_PREFERRED_NODE = 0x00020004 + PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR = 0x00030005 + PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = 0x00020007 + PROC_THREAD_ATTRIBUTE_UMS_THREAD = 0x00030006 + PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL = 0x0002000b + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x00020016 +) + +const ( + // flags for CreateToolhelp32Snapshot + TH32CS_SNAPHEAPLIST = 0x01 + TH32CS_SNAPPROCESS = 0x02 + TH32CS_SNAPTHREAD = 0x04 + TH32CS_SNAPMODULE = 0x08 + TH32CS_SNAPMODULE32 = 0x10 + TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD + TH32CS_INHERIT = 0x80000000 +) + +const ( + // flags for EnumProcessModulesEx + LIST_MODULES_32BIT = 0x01 + LIST_MODULES_64BIT = 0x02 + LIST_MODULES_ALL = 0x03 + LIST_MODULES_DEFAULT = 0x00 +) + +const ( + // filters for ReadDirectoryChangesW and FindFirstChangeNotificationW + FILE_NOTIFY_CHANGE_FILE_NAME = 0x001 + FILE_NOTIFY_CHANGE_DIR_NAME = 0x002 + FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x004 + FILE_NOTIFY_CHANGE_SIZE = 0x008 + FILE_NOTIFY_CHANGE_LAST_WRITE = 0x010 + FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x020 + FILE_NOTIFY_CHANGE_CREATION = 0x040 + FILE_NOTIFY_CHANGE_SECURITY = 0x100 +) + +const ( + // do not reorder + FILE_ACTION_ADDED = iota + 1 + FILE_ACTION_REMOVED + FILE_ACTION_MODIFIED + FILE_ACTION_RENAMED_OLD_NAME + FILE_ACTION_RENAMED_NEW_NAME +) + +const ( + // wincrypt.h + /* certenrolld_begin -- PROV_RSA_*/ + PROV_RSA_FULL = 1 + PROV_RSA_SIG = 2 + PROV_DSS = 3 + PROV_FORTEZZA = 4 + PROV_MS_EXCHANGE = 5 + PROV_SSL = 6 + PROV_RSA_SCHANNEL = 12 + PROV_DSS_DH = 13 + PROV_EC_ECDSA_SIG = 14 + PROV_EC_ECNRA_SIG = 15 + PROV_EC_ECDSA_FULL = 16 + PROV_EC_ECNRA_FULL = 17 + PROV_DH_SCHANNEL = 18 + PROV_SPYRUS_LYNKS = 20 + PROV_RNG = 21 + PROV_INTEL_SEC = 22 + PROV_REPLACE_OWF = 23 + PROV_RSA_AES = 24 + + /* dwFlags definitions for CryptAcquireContext */ + CRYPT_VERIFYCONTEXT = 0xF0000000 + CRYPT_NEWKEYSET = 0x00000008 + CRYPT_DELETEKEYSET = 0x00000010 + CRYPT_MACHINE_KEYSET = 0x00000020 + CRYPT_SILENT = 0x00000040 + CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080 + + /* Flags for PFXImportCertStore */ + CRYPT_EXPORTABLE = 0x00000001 + CRYPT_USER_PROTECTED = 0x00000002 + CRYPT_USER_KEYSET = 0x00001000 + PKCS12_PREFER_CNG_KSP = 0x00000100 + PKCS12_ALWAYS_CNG_KSP = 0x00000200 + PKCS12_ALLOW_OVERWRITE_KEY = 0x00004000 + PKCS12_NO_PERSIST_KEY = 0x00008000 + PKCS12_INCLUDE_EXTENDED_PROPERTIES = 0x00000010 + + /* Flags for CryptAcquireCertificatePrivateKey */ + CRYPT_ACQUIRE_CACHE_FLAG = 0x00000001 + CRYPT_ACQUIRE_USE_PROV_INFO_FLAG = 0x00000002 + CRYPT_ACQUIRE_COMPARE_KEY_FLAG = 0x00000004 + CRYPT_ACQUIRE_NO_HEALING = 0x00000008 + CRYPT_ACQUIRE_SILENT_FLAG = 0x00000040 + CRYPT_ACQUIRE_WINDOW_HANDLE_FLAG = 0x00000080 + CRYPT_ACQUIRE_NCRYPT_KEY_FLAGS_MASK = 0x00070000 + CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG = 0x00010000 + CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG = 0x00020000 + CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG = 0x00040000 + + /* pdwKeySpec for CryptAcquireCertificatePrivateKey */ + AT_KEYEXCHANGE = 1 + AT_SIGNATURE = 2 + CERT_NCRYPT_KEY_SPEC = 0xFFFFFFFF + + /* Default usage match type is AND with value zero */ + USAGE_MATCH_TYPE_AND = 0 + USAGE_MATCH_TYPE_OR = 1 + + /* msgAndCertEncodingType values for CertOpenStore function */ + X509_ASN_ENCODING = 0x00000001 + PKCS_7_ASN_ENCODING = 0x00010000 + + /* storeProvider values for CertOpenStore function */ + CERT_STORE_PROV_MSG = 1 + CERT_STORE_PROV_MEMORY = 2 + CERT_STORE_PROV_FILE = 3 + CERT_STORE_PROV_REG = 4 + CERT_STORE_PROV_PKCS7 = 5 + CERT_STORE_PROV_SERIALIZED = 6 + CERT_STORE_PROV_FILENAME_A = 7 + CERT_STORE_PROV_FILENAME_W = 8 + CERT_STORE_PROV_FILENAME = CERT_STORE_PROV_FILENAME_W + CERT_STORE_PROV_SYSTEM_A = 9 + CERT_STORE_PROV_SYSTEM_W = 10 + CERT_STORE_PROV_SYSTEM = CERT_STORE_PROV_SYSTEM_W + CERT_STORE_PROV_COLLECTION = 11 + CERT_STORE_PROV_SYSTEM_REGISTRY_A = 12 + CERT_STORE_PROV_SYSTEM_REGISTRY_W = 13 + CERT_STORE_PROV_SYSTEM_REGISTRY = CERT_STORE_PROV_SYSTEM_REGISTRY_W + CERT_STORE_PROV_PHYSICAL_W = 14 + CERT_STORE_PROV_PHYSICAL = CERT_STORE_PROV_PHYSICAL_W + CERT_STORE_PROV_SMART_CARD_W = 15 + CERT_STORE_PROV_SMART_CARD = CERT_STORE_PROV_SMART_CARD_W + CERT_STORE_PROV_LDAP_W = 16 + CERT_STORE_PROV_LDAP = CERT_STORE_PROV_LDAP_W + CERT_STORE_PROV_PKCS12 = 17 + + /* store characteristics (low WORD of flag) for CertOpenStore function */ + CERT_STORE_NO_CRYPT_RELEASE_FLAG = 0x00000001 + CERT_STORE_SET_LOCALIZED_NAME_FLAG = 0x00000002 + CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004 + CERT_STORE_DELETE_FLAG = 0x00000010 + CERT_STORE_UNSAFE_PHYSICAL_FLAG = 0x00000020 + CERT_STORE_SHARE_STORE_FLAG = 0x00000040 + CERT_STORE_SHARE_CONTEXT_FLAG = 0x00000080 + CERT_STORE_MANIFOLD_FLAG = 0x00000100 + CERT_STORE_ENUM_ARCHIVED_FLAG = 0x00000200 + CERT_STORE_UPDATE_KEYID_FLAG = 0x00000400 + CERT_STORE_BACKUP_RESTORE_FLAG = 0x00000800 + CERT_STORE_MAXIMUM_ALLOWED_FLAG = 0x00001000 + CERT_STORE_CREATE_NEW_FLAG = 0x00002000 + CERT_STORE_OPEN_EXISTING_FLAG = 0x00004000 + CERT_STORE_READONLY_FLAG = 0x00008000 + + /* store locations (high WORD of flag) for CertOpenStore function */ + CERT_SYSTEM_STORE_CURRENT_USER = 0x00010000 + CERT_SYSTEM_STORE_LOCAL_MACHINE = 0x00020000 + CERT_SYSTEM_STORE_CURRENT_SERVICE = 0x00040000 + CERT_SYSTEM_STORE_SERVICES = 0x00050000 + CERT_SYSTEM_STORE_USERS = 0x00060000 + CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY = 0x00070000 + CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY = 0x00080000 + CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE = 0x00090000 + CERT_SYSTEM_STORE_UNPROTECTED_FLAG = 0x40000000 + CERT_SYSTEM_STORE_RELOCATE_FLAG = 0x80000000 + + /* Miscellaneous high-WORD flags for CertOpenStore function */ + CERT_REGISTRY_STORE_REMOTE_FLAG = 0x00010000 + CERT_REGISTRY_STORE_SERIALIZED_FLAG = 0x00020000 + CERT_REGISTRY_STORE_ROAMING_FLAG = 0x00040000 + CERT_REGISTRY_STORE_MY_IE_DIRTY_FLAG = 0x00080000 + CERT_REGISTRY_STORE_LM_GPT_FLAG = 0x01000000 + CERT_REGISTRY_STORE_CLIENT_GPT_FLAG = 0x80000000 + CERT_FILE_STORE_COMMIT_ENABLE_FLAG = 0x00010000 + CERT_LDAP_STORE_SIGN_FLAG = 0x00010000 + CERT_LDAP_STORE_AREC_EXCLUSIVE_FLAG = 0x00020000 + CERT_LDAP_STORE_OPENED_FLAG = 0x00040000 + CERT_LDAP_STORE_UNBIND_FLAG = 0x00080000 + + /* addDisposition values for CertAddCertificateContextToStore function */ + CERT_STORE_ADD_NEW = 1 + CERT_STORE_ADD_USE_EXISTING = 2 + CERT_STORE_ADD_REPLACE_EXISTING = 3 + CERT_STORE_ADD_ALWAYS = 4 + CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES = 5 + CERT_STORE_ADD_NEWER = 6 + CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES = 7 + + /* ErrorStatus values for CertTrustStatus struct */ + CERT_TRUST_NO_ERROR = 0x00000000 + CERT_TRUST_IS_NOT_TIME_VALID = 0x00000001 + CERT_TRUST_IS_REVOKED = 0x00000004 + CERT_TRUST_IS_NOT_SIGNATURE_VALID = 0x00000008 + CERT_TRUST_IS_NOT_VALID_FOR_USAGE = 0x00000010 + CERT_TRUST_IS_UNTRUSTED_ROOT = 0x00000020 + CERT_TRUST_REVOCATION_STATUS_UNKNOWN = 0x00000040 + CERT_TRUST_IS_CYCLIC = 0x00000080 + CERT_TRUST_INVALID_EXTENSION = 0x00000100 + CERT_TRUST_INVALID_POLICY_CONSTRAINTS = 0x00000200 + CERT_TRUST_INVALID_BASIC_CONSTRAINTS = 0x00000400 + CERT_TRUST_INVALID_NAME_CONSTRAINTS = 0x00000800 + CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT = 0x00001000 + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT = 0x00002000 + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT = 0x00004000 + CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT = 0x00008000 + CERT_TRUST_IS_PARTIAL_CHAIN = 0x00010000 + CERT_TRUST_CTL_IS_NOT_TIME_VALID = 0x00020000 + CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID = 0x00040000 + CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE = 0x00080000 + CERT_TRUST_HAS_WEAK_SIGNATURE = 0x00100000 + CERT_TRUST_IS_OFFLINE_REVOCATION = 0x01000000 + CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY = 0x02000000 + CERT_TRUST_IS_EXPLICIT_DISTRUST = 0x04000000 + CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT = 0x08000000 + + /* InfoStatus values for CertTrustStatus struct */ + CERT_TRUST_HAS_EXACT_MATCH_ISSUER = 0x00000001 + CERT_TRUST_HAS_KEY_MATCH_ISSUER = 0x00000002 + CERT_TRUST_HAS_NAME_MATCH_ISSUER = 0x00000004 + CERT_TRUST_IS_SELF_SIGNED = 0x00000008 + CERT_TRUST_HAS_PREFERRED_ISSUER = 0x00000100 + CERT_TRUST_HAS_ISSUANCE_CHAIN_POLICY = 0x00000400 + CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS = 0x00000400 + CERT_TRUST_IS_PEER_TRUSTED = 0x00000800 + CERT_TRUST_HAS_CRL_VALIDITY_EXTENDED = 0x00001000 + CERT_TRUST_IS_FROM_EXCLUSIVE_TRUST_STORE = 0x00002000 + CERT_TRUST_IS_CA_TRUSTED = 0x00004000 + CERT_TRUST_IS_COMPLEX_CHAIN = 0x00010000 + + /* Certificate Information Flags */ + CERT_INFO_VERSION_FLAG = 1 + CERT_INFO_SERIAL_NUMBER_FLAG = 2 + CERT_INFO_SIGNATURE_ALGORITHM_FLAG = 3 + CERT_INFO_ISSUER_FLAG = 4 + CERT_INFO_NOT_BEFORE_FLAG = 5 + CERT_INFO_NOT_AFTER_FLAG = 6 + CERT_INFO_SUBJECT_FLAG = 7 + CERT_INFO_SUBJECT_PUBLIC_KEY_INFO_FLAG = 8 + CERT_INFO_ISSUER_UNIQUE_ID_FLAG = 9 + CERT_INFO_SUBJECT_UNIQUE_ID_FLAG = 10 + CERT_INFO_EXTENSION_FLAG = 11 + + /* dwFindType for CertFindCertificateInStore */ + CERT_COMPARE_MASK = 0xFFFF + CERT_COMPARE_SHIFT = 16 + CERT_COMPARE_ANY = 0 + CERT_COMPARE_SHA1_HASH = 1 + CERT_COMPARE_NAME = 2 + CERT_COMPARE_ATTR = 3 + CERT_COMPARE_MD5_HASH = 4 + CERT_COMPARE_PROPERTY = 5 + CERT_COMPARE_PUBLIC_KEY = 6 + CERT_COMPARE_HASH = CERT_COMPARE_SHA1_HASH + CERT_COMPARE_NAME_STR_A = 7 + CERT_COMPARE_NAME_STR_W = 8 + CERT_COMPARE_KEY_SPEC = 9 + CERT_COMPARE_ENHKEY_USAGE = 10 + CERT_COMPARE_CTL_USAGE = CERT_COMPARE_ENHKEY_USAGE + CERT_COMPARE_SUBJECT_CERT = 11 + CERT_COMPARE_ISSUER_OF = 12 + CERT_COMPARE_EXISTING = 13 + CERT_COMPARE_SIGNATURE_HASH = 14 + CERT_COMPARE_KEY_IDENTIFIER = 15 + CERT_COMPARE_CERT_ID = 16 + CERT_COMPARE_CROSS_CERT_DIST_POINTS = 17 + CERT_COMPARE_PUBKEY_MD5_HASH = 18 + CERT_COMPARE_SUBJECT_INFO_ACCESS = 19 + CERT_COMPARE_HASH_STR = 20 + CERT_COMPARE_HAS_PRIVATE_KEY = 21 + CERT_FIND_ANY = (CERT_COMPARE_ANY << CERT_COMPARE_SHIFT) + CERT_FIND_SHA1_HASH = (CERT_COMPARE_SHA1_HASH << CERT_COMPARE_SHIFT) + CERT_FIND_MD5_HASH = (CERT_COMPARE_MD5_HASH << CERT_COMPARE_SHIFT) + CERT_FIND_SIGNATURE_HASH = (CERT_COMPARE_SIGNATURE_HASH << CERT_COMPARE_SHIFT) + CERT_FIND_KEY_IDENTIFIER = (CERT_COMPARE_KEY_IDENTIFIER << CERT_COMPARE_SHIFT) + CERT_FIND_HASH = CERT_FIND_SHA1_HASH + CERT_FIND_PROPERTY = (CERT_COMPARE_PROPERTY << CERT_COMPARE_SHIFT) + CERT_FIND_PUBLIC_KEY = (CERT_COMPARE_PUBLIC_KEY << CERT_COMPARE_SHIFT) + CERT_FIND_SUBJECT_NAME = (CERT_COMPARE_NAME<> 32 & 0xffffffff) + return ft +} + +type Win32finddata struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + FileSizeHigh uint32 + FileSizeLow uint32 + Reserved0 uint32 + Reserved1 uint32 + FileName [MAX_PATH - 1]uint16 + AlternateFileName [13]uint16 +} + +// This is the actual system call structure. +// Win32finddata is what we committed to in Go 1. +type win32finddata1 struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + FileSizeHigh uint32 + FileSizeLow uint32 + Reserved0 uint32 + Reserved1 uint32 + FileName [MAX_PATH]uint16 + AlternateFileName [14]uint16 + + // The Microsoft documentation for this struct¹ describes three additional + // fields: dwFileType, dwCreatorType, and wFinderFlags. However, those fields + // are empirically only present in the macOS port of the Win32 API,² and thus + // not needed for binaries built for Windows. + // + // ¹ https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-win32_find_dataw describe + // ² https://golang.org/issue/42637#issuecomment-760715755. +} + +func copyFindData(dst *Win32finddata, src *win32finddata1) { + dst.FileAttributes = src.FileAttributes + dst.CreationTime = src.CreationTime + dst.LastAccessTime = src.LastAccessTime + dst.LastWriteTime = src.LastWriteTime + dst.FileSizeHigh = src.FileSizeHigh + dst.FileSizeLow = src.FileSizeLow + dst.Reserved0 = src.Reserved0 + dst.Reserved1 = src.Reserved1 + + // The src is 1 element bigger than dst, but it must be NUL. + copy(dst.FileName[:], src.FileName[:]) + copy(dst.AlternateFileName[:], src.AlternateFileName[:]) +} + +type ByHandleFileInformation struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + VolumeSerialNumber uint32 + FileSizeHigh uint32 + FileSizeLow uint32 + NumberOfLinks uint32 + FileIndexHigh uint32 + FileIndexLow uint32 +} + +const ( + GetFileExInfoStandard = 0 + GetFileExMaxInfoLevel = 1 +) + +type Win32FileAttributeData struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + FileSizeHigh uint32 + FileSizeLow uint32 +} + +// ShowWindow constants +const ( + // winuser.h + SW_HIDE = 0 + SW_NORMAL = 1 + SW_SHOWNORMAL = 1 + SW_SHOWMINIMIZED = 2 + SW_SHOWMAXIMIZED = 3 + SW_MAXIMIZE = 3 + SW_SHOWNOACTIVATE = 4 + SW_SHOW = 5 + SW_MINIMIZE = 6 + SW_SHOWMINNOACTIVE = 7 + SW_SHOWNA = 8 + SW_RESTORE = 9 + SW_SHOWDEFAULT = 10 + SW_FORCEMINIMIZE = 11 +) + +type StartupInfo struct { + Cb uint32 + _ *uint16 + Desktop *uint16 + Title *uint16 + X uint32 + Y uint32 + XSize uint32 + YSize uint32 + XCountChars uint32 + YCountChars uint32 + FillAttribute uint32 + Flags uint32 + ShowWindow uint16 + _ uint16 + _ *byte + StdInput Handle + StdOutput Handle + StdErr Handle +} + +type StartupInfoEx struct { + StartupInfo + ProcThreadAttributeList *ProcThreadAttributeList +} + +// ProcThreadAttributeList is a placeholder type to represent a PROC_THREAD_ATTRIBUTE_LIST. +// +// To create a *ProcThreadAttributeList, use NewProcThreadAttributeList, update +// it with ProcThreadAttributeListContainer.Update, free its memory using +// ProcThreadAttributeListContainer.Delete, and access the list itself using +// ProcThreadAttributeListContainer.List. +type ProcThreadAttributeList struct{} + +type ProcThreadAttributeListContainer struct { + data *ProcThreadAttributeList + pointers []unsafe.Pointer +} + +type ProcessInformation struct { + Process Handle + Thread Handle + ProcessId uint32 + ThreadId uint32 +} + +type ProcessEntry32 struct { + Size uint32 + Usage uint32 + ProcessID uint32 + DefaultHeapID uintptr + ModuleID uint32 + Threads uint32 + ParentProcessID uint32 + PriClassBase int32 + Flags uint32 + ExeFile [MAX_PATH]uint16 +} + +type ThreadEntry32 struct { + Size uint32 + Usage uint32 + ThreadID uint32 + OwnerProcessID uint32 + BasePri int32 + DeltaPri int32 + Flags uint32 +} + +type ModuleEntry32 struct { + Size uint32 + ModuleID uint32 + ProcessID uint32 + GlblcntUsage uint32 + ProccntUsage uint32 + ModBaseAddr uintptr + ModBaseSize uint32 + ModuleHandle Handle + Module [MAX_MODULE_NAME32 + 1]uint16 + ExePath [MAX_PATH]uint16 +} + +const SizeofModuleEntry32 = unsafe.Sizeof(ModuleEntry32{}) + +type Systemtime struct { + Year uint16 + Month uint16 + DayOfWeek uint16 + Day uint16 + Hour uint16 + Minute uint16 + Second uint16 + Milliseconds uint16 +} + +type Timezoneinformation struct { + Bias int32 + StandardName [32]uint16 + StandardDate Systemtime + StandardBias int32 + DaylightName [32]uint16 + DaylightDate Systemtime + DaylightBias int32 +} + +// Socket related. + +const ( + AF_UNSPEC = 0 + AF_UNIX = 1 + AF_INET = 2 + AF_NETBIOS = 17 + AF_INET6 = 23 + AF_IRDA = 26 + AF_BTH = 32 + + SOCK_STREAM = 1 + SOCK_DGRAM = 2 + SOCK_RAW = 3 + SOCK_RDM = 4 + SOCK_SEQPACKET = 5 + + IPPROTO_IP = 0 + IPPROTO_ICMP = 1 + IPPROTO_IGMP = 2 + BTHPROTO_RFCOMM = 3 + IPPROTO_TCP = 6 + IPPROTO_UDP = 17 + IPPROTO_IPV6 = 41 + IPPROTO_ICMPV6 = 58 + IPPROTO_RM = 113 + + SOL_SOCKET = 0xffff + SO_REUSEADDR = 4 + SO_KEEPALIVE = 8 + SO_DONTROUTE = 16 + SO_BROADCAST = 32 + SO_LINGER = 128 + SO_RCVBUF = 0x1002 + SO_SNDTIMEO = 0x1005 + SO_RCVTIMEO = 0x1006 + SO_SNDBUF = 0x1001 + SO_UPDATE_ACCEPT_CONTEXT = 0x700b + SO_UPDATE_CONNECT_CONTEXT = 0x7010 + + IOC_OUT = 0x40000000 + IOC_IN = 0x80000000 + IOC_VENDOR = 0x18000000 + IOC_INOUT = IOC_IN | IOC_OUT + IOC_WS2 = 0x08000000 + SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6 + SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4 + SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12 + SIO_UDP_NETRESET = IOC_IN | IOC_VENDOR | 15 + + // cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460 + + IP_HDRINCL = 0x2 + IP_TOS = 0x3 + IP_TTL = 0x4 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_TTL = 0xa + IP_MULTICAST_LOOP = 0xb + IP_ADD_MEMBERSHIP = 0xc + IP_DROP_MEMBERSHIP = 0xd + IP_PKTINFO = 0x13 + IP_MTU_DISCOVER = 0x47 + + IPV6_V6ONLY = 0x1b + IPV6_UNICAST_HOPS = 0x4 + IPV6_MULTICAST_IF = 0x9 + IPV6_MULTICAST_HOPS = 0xa + IPV6_MULTICAST_LOOP = 0xb + IPV6_JOIN_GROUP = 0xc + IPV6_LEAVE_GROUP = 0xd + IPV6_PKTINFO = 0x13 + IPV6_MTU_DISCOVER = 0x47 + + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_DONTROUTE = 0x4 + MSG_WAITALL = 0x8 + + MSG_TRUNC = 0x0100 + MSG_CTRUNC = 0x0200 + MSG_BCAST = 0x0400 + MSG_MCAST = 0x0800 + + SOMAXCONN = 0x7fffffff + + TCP_NODELAY = 1 + TCP_EXPEDITED_1122 = 2 + TCP_KEEPALIVE = 3 + TCP_MAXSEG = 4 + TCP_MAXRT = 5 + TCP_STDURG = 6 + TCP_NOURG = 7 + TCP_ATMARK = 8 + TCP_NOSYNRETRIES = 9 + TCP_TIMESTAMPS = 10 + TCP_OFFLOAD_PREFERENCE = 11 + TCP_CONGESTION_ALGORITHM = 12 + TCP_DELAY_FIN_ACK = 13 + TCP_MAXRTMS = 14 + TCP_FASTOPEN = 15 + TCP_KEEPCNT = 16 + TCP_KEEPIDLE = TCP_KEEPALIVE + TCP_KEEPINTVL = 17 + TCP_FAIL_CONNECT_ON_ICMP_ERROR = 18 + TCP_ICMP_ERROR_INFO = 19 + + UDP_NOCHECKSUM = 1 + UDP_SEND_MSG_SIZE = 2 + UDP_RECV_MAX_COALESCED_SIZE = 3 + UDP_CHECKSUM_COVERAGE = 20 + + UDP_COALESCED_INFO = 3 + + SHUT_RD = 0 + SHUT_WR = 1 + SHUT_RDWR = 2 + + WSADESCRIPTION_LEN = 256 + WSASYS_STATUS_LEN = 128 +) + +// enum PMTUD_STATE from ws2ipdef.h +const ( + IP_PMTUDISC_NOT_SET = 0 + IP_PMTUDISC_DO = 1 + IP_PMTUDISC_DONT = 2 + IP_PMTUDISC_PROBE = 3 + IP_PMTUDISC_MAX = 4 +) + +type WSABuf struct { + Len uint32 + Buf *byte +} + +type WSAMsg struct { + Name *syscall.RawSockaddrAny + Namelen int32 + Buffers *WSABuf + BufferCount uint32 + Control WSABuf + Flags uint32 +} + +type WSACMSGHDR struct { + Len uintptr + Level int32 + Type int32 +} + +type IN_PKTINFO struct { + Addr [4]byte + Ifindex uint32 +} + +type IN6_PKTINFO struct { + Addr [16]byte + Ifindex uint32 +} + +// Flags for WSASocket +const ( + WSA_FLAG_OVERLAPPED = 0x01 + WSA_FLAG_MULTIPOINT_C_ROOT = 0x02 + WSA_FLAG_MULTIPOINT_C_LEAF = 0x04 + WSA_FLAG_MULTIPOINT_D_ROOT = 0x08 + WSA_FLAG_MULTIPOINT_D_LEAF = 0x10 + WSA_FLAG_ACCESS_SYSTEM_SECURITY = 0x40 + WSA_FLAG_NO_HANDLE_INHERIT = 0x80 + WSA_FLAG_REGISTERED_IO = 0x100 +) + +// Invented values to support what package os expects. +const ( + S_IFMT = 0x1f000 + S_IFIFO = 0x1000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFBLK = 0x6000 + S_IFREG = 0x8000 + S_IFLNK = 0xa000 + S_IFSOCK = 0xc000 + S_ISUID = 0x800 + S_ISGID = 0x400 + S_ISVTX = 0x200 + S_IRUSR = 0x100 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXUSR = 0x40 +) + +const ( + FILE_TYPE_CHAR = 0x0002 + FILE_TYPE_DISK = 0x0001 + FILE_TYPE_PIPE = 0x0003 + FILE_TYPE_REMOTE = 0x8000 + FILE_TYPE_UNKNOWN = 0x0000 +) + +type Hostent struct { + Name *byte + Aliases **byte + AddrType uint16 + Length uint16 + AddrList **byte +} + +type Protoent struct { + Name *byte + Aliases **byte + Proto uint16 +} + +const ( + DNS_TYPE_A = 0x0001 + DNS_TYPE_NS = 0x0002 + DNS_TYPE_MD = 0x0003 + DNS_TYPE_MF = 0x0004 + DNS_TYPE_CNAME = 0x0005 + DNS_TYPE_SOA = 0x0006 + DNS_TYPE_MB = 0x0007 + DNS_TYPE_MG = 0x0008 + DNS_TYPE_MR = 0x0009 + DNS_TYPE_NULL = 0x000a + DNS_TYPE_WKS = 0x000b + DNS_TYPE_PTR = 0x000c + DNS_TYPE_HINFO = 0x000d + DNS_TYPE_MINFO = 0x000e + DNS_TYPE_MX = 0x000f + DNS_TYPE_TEXT = 0x0010 + DNS_TYPE_RP = 0x0011 + DNS_TYPE_AFSDB = 0x0012 + DNS_TYPE_X25 = 0x0013 + DNS_TYPE_ISDN = 0x0014 + DNS_TYPE_RT = 0x0015 + DNS_TYPE_NSAP = 0x0016 + DNS_TYPE_NSAPPTR = 0x0017 + DNS_TYPE_SIG = 0x0018 + DNS_TYPE_KEY = 0x0019 + DNS_TYPE_PX = 0x001a + DNS_TYPE_GPOS = 0x001b + DNS_TYPE_AAAA = 0x001c + DNS_TYPE_LOC = 0x001d + DNS_TYPE_NXT = 0x001e + DNS_TYPE_EID = 0x001f + DNS_TYPE_NIMLOC = 0x0020 + DNS_TYPE_SRV = 0x0021 + DNS_TYPE_ATMA = 0x0022 + DNS_TYPE_NAPTR = 0x0023 + DNS_TYPE_KX = 0x0024 + DNS_TYPE_CERT = 0x0025 + DNS_TYPE_A6 = 0x0026 + DNS_TYPE_DNAME = 0x0027 + DNS_TYPE_SINK = 0x0028 + DNS_TYPE_OPT = 0x0029 + DNS_TYPE_DS = 0x002B + DNS_TYPE_RRSIG = 0x002E + DNS_TYPE_NSEC = 0x002F + DNS_TYPE_DNSKEY = 0x0030 + DNS_TYPE_DHCID = 0x0031 + DNS_TYPE_UINFO = 0x0064 + DNS_TYPE_UID = 0x0065 + DNS_TYPE_GID = 0x0066 + DNS_TYPE_UNSPEC = 0x0067 + DNS_TYPE_ADDRS = 0x00f8 + DNS_TYPE_TKEY = 0x00f9 + DNS_TYPE_TSIG = 0x00fa + DNS_TYPE_IXFR = 0x00fb + DNS_TYPE_AXFR = 0x00fc + DNS_TYPE_MAILB = 0x00fd + DNS_TYPE_MAILA = 0x00fe + DNS_TYPE_ALL = 0x00ff + DNS_TYPE_ANY = 0x00ff + DNS_TYPE_WINS = 0xff01 + DNS_TYPE_WINSR = 0xff02 + DNS_TYPE_NBSTAT = 0xff01 +) + +const ( + // flags inside DNSRecord.Dw + DnsSectionQuestion = 0x0000 + DnsSectionAnswer = 0x0001 + DnsSectionAuthority = 0x0002 + DnsSectionAdditional = 0x0003 +) + +const ( + // flags of WSALookupService + LUP_DEEP = 0x0001 + LUP_CONTAINERS = 0x0002 + LUP_NOCONTAINERS = 0x0004 + LUP_NEAREST = 0x0008 + LUP_RETURN_NAME = 0x0010 + LUP_RETURN_TYPE = 0x0020 + LUP_RETURN_VERSION = 0x0040 + LUP_RETURN_COMMENT = 0x0080 + LUP_RETURN_ADDR = 0x0100 + LUP_RETURN_BLOB = 0x0200 + LUP_RETURN_ALIASES = 0x0400 + LUP_RETURN_QUERY_STRING = 0x0800 + LUP_RETURN_ALL = 0x0FF0 + LUP_RES_SERVICE = 0x8000 + + LUP_FLUSHCACHE = 0x1000 + LUP_FLUSHPREVIOUS = 0x2000 + + LUP_NON_AUTHORITATIVE = 0x4000 + LUP_SECURE = 0x8000 + LUP_RETURN_PREFERRED_NAMES = 0x10000 + LUP_DNS_ONLY = 0x20000 + + LUP_ADDRCONFIG = 0x100000 + LUP_DUAL_ADDR = 0x200000 + LUP_FILESERVER = 0x400000 + LUP_DISABLE_IDN_ENCODING = 0x00800000 + LUP_API_ANSI = 0x01000000 + + LUP_RESOLUTION_HANDLE = 0x80000000 +) + +const ( + // values of WSAQUERYSET's namespace + NS_ALL = 0 + NS_DNS = 12 + NS_NLA = 15 + NS_BTH = 16 + NS_EMAIL = 37 + NS_PNRPNAME = 38 + NS_PNRPCLOUD = 39 +) + +type DNSSRVData struct { + Target *uint16 + Priority uint16 + Weight uint16 + Port uint16 + Pad uint16 +} + +type DNSPTRData struct { + Host *uint16 +} + +type DNSMXData struct { + NameExchange *uint16 + Preference uint16 + Pad uint16 +} + +type DNSTXTData struct { + StringCount uint16 + StringArray [1]*uint16 +} + +type DNSRecord struct { + Next *DNSRecord + Name *uint16 + Type uint16 + Length uint16 + Dw uint32 + Ttl uint32 + Reserved uint32 + Data [40]byte +} + +const ( + TF_DISCONNECT = 1 + TF_REUSE_SOCKET = 2 + TF_WRITE_BEHIND = 4 + TF_USE_DEFAULT_WORKER = 0 + TF_USE_SYSTEM_THREAD = 16 + TF_USE_KERNEL_APC = 32 +) + +type TransmitFileBuffers struct { + Head uintptr + HeadLength uint32 + Tail uintptr + TailLength uint32 +} + +const ( + IFF_UP = 1 + IFF_BROADCAST = 2 + IFF_LOOPBACK = 4 + IFF_POINTTOPOINT = 8 + IFF_MULTICAST = 16 +) + +const SIO_GET_INTERFACE_LIST = 0x4004747F + +// TODO(mattn): SockaddrGen is union of sockaddr/sockaddr_in/sockaddr_in6_old. +// will be fixed to change variable type as suitable. + +type SockaddrGen [24]byte + +type InterfaceInfo struct { + Flags uint32 + Address SockaddrGen + BroadcastAddress SockaddrGen + Netmask SockaddrGen +} + +type IpAddressString struct { + String [16]byte +} + +type IpMaskString IpAddressString + +type IpAddrString struct { + Next *IpAddrString + IpAddress IpAddressString + IpMask IpMaskString + Context uint32 +} + +const MAX_ADAPTER_NAME_LENGTH = 256 +const MAX_ADAPTER_DESCRIPTION_LENGTH = 128 +const MAX_ADAPTER_ADDRESS_LENGTH = 8 + +type IpAdapterInfo struct { + Next *IpAdapterInfo + ComboIndex uint32 + AdapterName [MAX_ADAPTER_NAME_LENGTH + 4]byte + Description [MAX_ADAPTER_DESCRIPTION_LENGTH + 4]byte + AddressLength uint32 + Address [MAX_ADAPTER_ADDRESS_LENGTH]byte + Index uint32 + Type uint32 + DhcpEnabled uint32 + CurrentIpAddress *IpAddrString + IpAddressList IpAddrString + GatewayList IpAddrString + DhcpServer IpAddrString + HaveWins bool + PrimaryWinsServer IpAddrString + SecondaryWinsServer IpAddrString + LeaseObtained int64 + LeaseExpires int64 +} + +const MAXLEN_PHYSADDR = 8 +const MAX_INTERFACE_NAME_LEN = 256 +const MAXLEN_IFDESCR = 256 + +type MibIfRow struct { + Name [MAX_INTERFACE_NAME_LEN]uint16 + Index uint32 + Type uint32 + Mtu uint32 + Speed uint32 + PhysAddrLen uint32 + PhysAddr [MAXLEN_PHYSADDR]byte + AdminStatus uint32 + OperStatus uint32 + LastChange uint32 + InOctets uint32 + InUcastPkts uint32 + InNUcastPkts uint32 + InDiscards uint32 + InErrors uint32 + InUnknownProtos uint32 + OutOctets uint32 + OutUcastPkts uint32 + OutNUcastPkts uint32 + OutDiscards uint32 + OutErrors uint32 + OutQLen uint32 + DescrLen uint32 + Descr [MAXLEN_IFDESCR]byte +} + +type CertInfo struct { + Version uint32 + SerialNumber CryptIntegerBlob + SignatureAlgorithm CryptAlgorithmIdentifier + Issuer CertNameBlob + NotBefore Filetime + NotAfter Filetime + Subject CertNameBlob + SubjectPublicKeyInfo CertPublicKeyInfo + IssuerUniqueId CryptBitBlob + SubjectUniqueId CryptBitBlob + CountExtensions uint32 + Extensions *CertExtension +} + +type CertExtension struct { + ObjId *byte + Critical int32 + Value CryptObjidBlob +} + +type CryptAlgorithmIdentifier struct { + ObjId *byte + Parameters CryptObjidBlob +} + +type CertPublicKeyInfo struct { + Algorithm CryptAlgorithmIdentifier + PublicKey CryptBitBlob +} + +type DataBlob struct { + Size uint32 + Data *byte +} +type CryptIntegerBlob DataBlob +type CryptUintBlob DataBlob +type CryptObjidBlob DataBlob +type CertNameBlob DataBlob +type CertRdnValueBlob DataBlob +type CertBlob DataBlob +type CrlBlob DataBlob +type CryptDataBlob DataBlob +type CryptHashBlob DataBlob +type CryptDigestBlob DataBlob +type CryptDerBlob DataBlob +type CryptAttrBlob DataBlob + +type CryptBitBlob struct { + Size uint32 + Data *byte + UnusedBits uint32 +} + +type CertContext struct { + EncodingType uint32 + EncodedCert *byte + Length uint32 + CertInfo *CertInfo + Store Handle +} + +type CertChainContext struct { + Size uint32 + TrustStatus CertTrustStatus + ChainCount uint32 + Chains **CertSimpleChain + LowerQualityChainCount uint32 + LowerQualityChains **CertChainContext + HasRevocationFreshnessTime uint32 + RevocationFreshnessTime uint32 +} + +type CertTrustListInfo struct { + // Not implemented +} + +type CertSimpleChain struct { + Size uint32 + TrustStatus CertTrustStatus + NumElements uint32 + Elements **CertChainElement + TrustListInfo *CertTrustListInfo + HasRevocationFreshnessTime uint32 + RevocationFreshnessTime uint32 +} + +type CertChainElement struct { + Size uint32 + CertContext *CertContext + TrustStatus CertTrustStatus + RevocationInfo *CertRevocationInfo + IssuanceUsage *CertEnhKeyUsage + ApplicationUsage *CertEnhKeyUsage + ExtendedErrorInfo *uint16 +} + +type CertRevocationCrlInfo struct { + // Not implemented +} + +type CertRevocationInfo struct { + Size uint32 + RevocationResult uint32 + RevocationOid *byte + OidSpecificInfo Pointer + HasFreshnessTime uint32 + FreshnessTime uint32 + CrlInfo *CertRevocationCrlInfo +} + +type CertTrustStatus struct { + ErrorStatus uint32 + InfoStatus uint32 +} + +type CertUsageMatch struct { + Type uint32 + Usage CertEnhKeyUsage +} + +type CertEnhKeyUsage struct { + Length uint32 + UsageIdentifiers **byte +} + +type CertChainPara struct { + Size uint32 + RequestedUsage CertUsageMatch + RequstedIssuancePolicy CertUsageMatch + URLRetrievalTimeout uint32 + CheckRevocationFreshnessTime uint32 + RevocationFreshnessTime uint32 + CacheResync *Filetime +} + +type CertChainPolicyPara struct { + Size uint32 + Flags uint32 + ExtraPolicyPara Pointer +} + +type SSLExtraCertChainPolicyPara struct { + Size uint32 + AuthType uint32 + Checks uint32 + ServerName *uint16 +} + +type CertChainPolicyStatus struct { + Size uint32 + Error uint32 + ChainIndex uint32 + ElementIndex uint32 + ExtraPolicyStatus Pointer +} + +type CertPolicyInfo struct { + Identifier *byte + CountQualifiers uint32 + Qualifiers *CertPolicyQualifierInfo +} + +type CertPoliciesInfo struct { + Count uint32 + PolicyInfos *CertPolicyInfo +} + +type CertPolicyQualifierInfo struct { + // Not implemented +} + +type CertStrongSignPara struct { + Size uint32 + InfoChoice uint32 + InfoOrSerializedInfoOrOID unsafe.Pointer +} + +type CryptProtectPromptStruct struct { + Size uint32 + PromptFlags uint32 + App HWND + Prompt *uint16 +} + +type CertChainFindByIssuerPara struct { + Size uint32 + UsageIdentifier *byte + KeySpec uint32 + AcquirePrivateKeyFlags uint32 + IssuerCount uint32 + Issuer Pointer + FindCallback Pointer + FindArg Pointer + IssuerChainIndex *uint32 + IssuerElementIndex *uint32 +} + +type WinTrustData struct { + Size uint32 + PolicyCallbackData uintptr + SIPClientData uintptr + UIChoice uint32 + RevocationChecks uint32 + UnionChoice uint32 + FileOrCatalogOrBlobOrSgnrOrCert unsafe.Pointer + StateAction uint32 + StateData Handle + URLReference *uint16 + ProvFlags uint32 + UIContext uint32 + SignatureSettings *WinTrustSignatureSettings +} + +type WinTrustFileInfo struct { + Size uint32 + FilePath *uint16 + File Handle + KnownSubject *GUID +} + +type WinTrustSignatureSettings struct { + Size uint32 + Index uint32 + Flags uint32 + SecondarySigs uint32 + VerifiedSigIndex uint32 + CryptoPolicy *CertStrongSignPara +} + +const ( + // do not reorder + HKEY_CLASSES_ROOT = 0x80000000 + iota + HKEY_CURRENT_USER + HKEY_LOCAL_MACHINE + HKEY_USERS + HKEY_PERFORMANCE_DATA + HKEY_CURRENT_CONFIG + HKEY_DYN_DATA + + KEY_QUERY_VALUE = 1 + KEY_SET_VALUE = 2 + KEY_CREATE_SUB_KEY = 4 + KEY_ENUMERATE_SUB_KEYS = 8 + KEY_NOTIFY = 16 + KEY_CREATE_LINK = 32 + KEY_WRITE = 0x20006 + KEY_EXECUTE = 0x20019 + KEY_READ = 0x20019 + KEY_WOW64_64KEY = 0x0100 + KEY_WOW64_32KEY = 0x0200 + KEY_ALL_ACCESS = 0xf003f +) + +const ( + // do not reorder + REG_NONE = iota + REG_SZ + REG_EXPAND_SZ + REG_BINARY + REG_DWORD_LITTLE_ENDIAN + REG_DWORD_BIG_ENDIAN + REG_LINK + REG_MULTI_SZ + REG_RESOURCE_LIST + REG_FULL_RESOURCE_DESCRIPTOR + REG_RESOURCE_REQUIREMENTS_LIST + REG_QWORD_LITTLE_ENDIAN + REG_DWORD = REG_DWORD_LITTLE_ENDIAN + REG_QWORD = REG_QWORD_LITTLE_ENDIAN +) + +const ( + EVENT_MODIFY_STATE = 0x0002 + EVENT_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3 + + MUTANT_QUERY_STATE = 0x0001 + MUTANT_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | MUTANT_QUERY_STATE + + SEMAPHORE_MODIFY_STATE = 0x0002 + SEMAPHORE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3 + + TIMER_QUERY_STATE = 0x0001 + TIMER_MODIFY_STATE = 0x0002 + TIMER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | TIMER_QUERY_STATE | TIMER_MODIFY_STATE + + MUTEX_MODIFY_STATE = MUTANT_QUERY_STATE + MUTEX_ALL_ACCESS = MUTANT_ALL_ACCESS + + CREATE_EVENT_MANUAL_RESET = 0x1 + CREATE_EVENT_INITIAL_SET = 0x2 + CREATE_MUTEX_INITIAL_OWNER = 0x1 +) + +type AddrinfoW struct { + Flags int32 + Family int32 + Socktype int32 + Protocol int32 + Addrlen uintptr + Canonname *uint16 + Addr uintptr + Next *AddrinfoW +} + +const ( + AI_PASSIVE = 1 + AI_CANONNAME = 2 + AI_NUMERICHOST = 4 +) + +type GUID struct { + Data1 uint32 + Data2 uint16 + Data3 uint16 + Data4 [8]byte +} + +var WSAID_CONNECTEX = GUID{ + 0x25a207b9, + 0xddf3, + 0x4660, + [8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}, +} + +var WSAID_WSASENDMSG = GUID{ + 0xa441e712, + 0x754f, + 0x43ca, + [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d}, +} + +var WSAID_WSARECVMSG = GUID{ + 0xf689d7c8, + 0x6f1f, + 0x436b, + [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22}, +} + +const ( + FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1 + FILE_SKIP_SET_EVENT_ON_HANDLE = 2 +) + +const ( + WSAPROTOCOL_LEN = 255 + MAX_PROTOCOL_CHAIN = 7 + BASE_PROTOCOL = 1 + LAYERED_PROTOCOL = 0 + + XP1_CONNECTIONLESS = 0x00000001 + XP1_GUARANTEED_DELIVERY = 0x00000002 + XP1_GUARANTEED_ORDER = 0x00000004 + XP1_MESSAGE_ORIENTED = 0x00000008 + XP1_PSEUDO_STREAM = 0x00000010 + XP1_GRACEFUL_CLOSE = 0x00000020 + XP1_EXPEDITED_DATA = 0x00000040 + XP1_CONNECT_DATA = 0x00000080 + XP1_DISCONNECT_DATA = 0x00000100 + XP1_SUPPORT_BROADCAST = 0x00000200 + XP1_SUPPORT_MULTIPOINT = 0x00000400 + XP1_MULTIPOINT_CONTROL_PLANE = 0x00000800 + XP1_MULTIPOINT_DATA_PLANE = 0x00001000 + XP1_QOS_SUPPORTED = 0x00002000 + XP1_UNI_SEND = 0x00008000 + XP1_UNI_RECV = 0x00010000 + XP1_IFS_HANDLES = 0x00020000 + XP1_PARTIAL_MESSAGE = 0x00040000 + XP1_SAN_SUPPORT_SDP = 0x00080000 + + PFL_MULTIPLE_PROTO_ENTRIES = 0x00000001 + PFL_RECOMMENDED_PROTO_ENTRY = 0x00000002 + PFL_HIDDEN = 0x00000004 + PFL_MATCHES_PROTOCOL_ZERO = 0x00000008 + PFL_NETWORKDIRECT_PROVIDER = 0x00000010 +) + +type WSAProtocolInfo struct { + ServiceFlags1 uint32 + ServiceFlags2 uint32 + ServiceFlags3 uint32 + ServiceFlags4 uint32 + ProviderFlags uint32 + ProviderId GUID + CatalogEntryId uint32 + ProtocolChain WSAProtocolChain + Version int32 + AddressFamily int32 + MaxSockAddr int32 + MinSockAddr int32 + SocketType int32 + Protocol int32 + ProtocolMaxOffset int32 + NetworkByteOrder int32 + SecurityScheme int32 + MessageSize uint32 + ProviderReserved uint32 + ProtocolName [WSAPROTOCOL_LEN + 1]uint16 +} + +type WSAProtocolChain struct { + ChainLen int32 + ChainEntries [MAX_PROTOCOL_CHAIN]uint32 +} + +type TCPKeepalive struct { + OnOff uint32 + Time uint32 + Interval uint32 +} + +type symbolicLinkReparseBuffer struct { + SubstituteNameOffset uint16 + SubstituteNameLength uint16 + PrintNameOffset uint16 + PrintNameLength uint16 + Flags uint32 + PathBuffer [1]uint16 +} + +type mountPointReparseBuffer struct { + SubstituteNameOffset uint16 + SubstituteNameLength uint16 + PrintNameOffset uint16 + PrintNameLength uint16 + PathBuffer [1]uint16 +} + +type reparseDataBuffer struct { + ReparseTag uint32 + ReparseDataLength uint16 + Reserved uint16 + + // GenericReparseBuffer + reparseBuffer byte +} + +const ( + FSCTL_CREATE_OR_GET_OBJECT_ID = 0x0900C0 + FSCTL_DELETE_OBJECT_ID = 0x0900A0 + FSCTL_DELETE_REPARSE_POINT = 0x0900AC + FSCTL_DUPLICATE_EXTENTS_TO_FILE = 0x098344 + FSCTL_DUPLICATE_EXTENTS_TO_FILE_EX = 0x0983E8 + FSCTL_FILESYSTEM_GET_STATISTICS = 0x090060 + FSCTL_FILE_LEVEL_TRIM = 0x098208 + FSCTL_FIND_FILES_BY_SID = 0x09008F + FSCTL_GET_COMPRESSION = 0x09003C + FSCTL_GET_INTEGRITY_INFORMATION = 0x09027C + FSCTL_GET_NTFS_VOLUME_DATA = 0x090064 + FSCTL_GET_REFS_VOLUME_DATA = 0x0902D8 + FSCTL_GET_OBJECT_ID = 0x09009C + FSCTL_GET_REPARSE_POINT = 0x0900A8 + FSCTL_GET_RETRIEVAL_POINTER_COUNT = 0x09042B + FSCTL_GET_RETRIEVAL_POINTERS = 0x090073 + FSCTL_GET_RETRIEVAL_POINTERS_AND_REFCOUNT = 0x0903D3 + FSCTL_IS_PATHNAME_VALID = 0x09002C + FSCTL_LMR_SET_LINK_TRACKING_INFORMATION = 0x1400EC + FSCTL_MARK_HANDLE = 0x0900FC + FSCTL_OFFLOAD_READ = 0x094264 + FSCTL_OFFLOAD_WRITE = 0x098268 + FSCTL_PIPE_PEEK = 0x11400C + FSCTL_PIPE_TRANSCEIVE = 0x11C017 + FSCTL_PIPE_WAIT = 0x110018 + FSCTL_QUERY_ALLOCATED_RANGES = 0x0940CF + FSCTL_QUERY_FAT_BPB = 0x090058 + FSCTL_QUERY_FILE_REGIONS = 0x090284 + FSCTL_QUERY_ON_DISK_VOLUME_INFO = 0x09013C + FSCTL_QUERY_SPARING_INFO = 0x090138 + FSCTL_READ_FILE_USN_DATA = 0x0900EB + FSCTL_RECALL_FILE = 0x090117 + FSCTL_REFS_STREAM_SNAPSHOT_MANAGEMENT = 0x090440 + FSCTL_SET_COMPRESSION = 0x09C040 + FSCTL_SET_DEFECT_MANAGEMENT = 0x098134 + FSCTL_SET_ENCRYPTION = 0x0900D7 + FSCTL_SET_INTEGRITY_INFORMATION = 0x09C280 + FSCTL_SET_INTEGRITY_INFORMATION_EX = 0x090380 + FSCTL_SET_OBJECT_ID = 0x090098 + FSCTL_SET_OBJECT_ID_EXTENDED = 0x0900BC + FSCTL_SET_REPARSE_POINT = 0x0900A4 + FSCTL_SET_SPARSE = 0x0900C4 + FSCTL_SET_ZERO_DATA = 0x0980C8 + FSCTL_SET_ZERO_ON_DEALLOCATION = 0x090194 + FSCTL_SIS_COPYFILE = 0x090100 + FSCTL_WRITE_USN_CLOSE_RECORD = 0x0900EF + + MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024 + IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003 + IO_REPARSE_TAG_SYMLINK = 0xA000000C + SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1 +) + +// FILE_ZERO_DATA_INFORMATION from winioctl.h +type FileZeroDataInformation struct { + FileOffset int64 + BeyondFinalZero int64 +} + +const ( + ComputerNameNetBIOS = 0 + ComputerNameDnsHostname = 1 + ComputerNameDnsDomain = 2 + ComputerNameDnsFullyQualified = 3 + ComputerNamePhysicalNetBIOS = 4 + ComputerNamePhysicalDnsHostname = 5 + ComputerNamePhysicalDnsDomain = 6 + ComputerNamePhysicalDnsFullyQualified = 7 + ComputerNameMax = 8 +) + +// For MessageBox() +const ( + MB_OK = 0x00000000 + MB_OKCANCEL = 0x00000001 + MB_ABORTRETRYIGNORE = 0x00000002 + MB_YESNOCANCEL = 0x00000003 + MB_YESNO = 0x00000004 + MB_RETRYCANCEL = 0x00000005 + MB_CANCELTRYCONTINUE = 0x00000006 + MB_ICONHAND = 0x00000010 + MB_ICONQUESTION = 0x00000020 + MB_ICONEXCLAMATION = 0x00000030 + MB_ICONASTERISK = 0x00000040 + MB_USERICON = 0x00000080 + MB_ICONWARNING = MB_ICONEXCLAMATION + MB_ICONERROR = MB_ICONHAND + MB_ICONINFORMATION = MB_ICONASTERISK + MB_ICONSTOP = MB_ICONHAND + MB_DEFBUTTON1 = 0x00000000 + MB_DEFBUTTON2 = 0x00000100 + MB_DEFBUTTON3 = 0x00000200 + MB_DEFBUTTON4 = 0x00000300 + MB_APPLMODAL = 0x00000000 + MB_SYSTEMMODAL = 0x00001000 + MB_TASKMODAL = 0x00002000 + MB_HELP = 0x00004000 + MB_NOFOCUS = 0x00008000 + MB_SETFOREGROUND = 0x00010000 + MB_DEFAULT_DESKTOP_ONLY = 0x00020000 + MB_TOPMOST = 0x00040000 + MB_RIGHT = 0x00080000 + MB_RTLREADING = 0x00100000 + MB_SERVICE_NOTIFICATION = 0x00200000 +) + +const ( + MOVEFILE_REPLACE_EXISTING = 0x1 + MOVEFILE_COPY_ALLOWED = 0x2 + MOVEFILE_DELAY_UNTIL_REBOOT = 0x4 + MOVEFILE_WRITE_THROUGH = 0x8 + MOVEFILE_CREATE_HARDLINK = 0x10 + MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20 +) + +// Flags for GetAdaptersAddresses, see +// https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses. +const ( + GAA_FLAG_SKIP_UNICAST = 0x1 + GAA_FLAG_SKIP_ANYCAST = 0x2 + GAA_FLAG_SKIP_MULTICAST = 0x4 + GAA_FLAG_SKIP_DNS_SERVER = 0x8 + GAA_FLAG_INCLUDE_PREFIX = 0x10 + GAA_FLAG_SKIP_FRIENDLY_NAME = 0x20 + GAA_FLAG_INCLUDE_WINS_INFO = 0x40 + GAA_FLAG_INCLUDE_GATEWAYS = 0x80 + GAA_FLAG_INCLUDE_ALL_INTERFACES = 0x100 + GAA_FLAG_INCLUDE_ALL_COMPARTMENTS = 0x200 + GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER = 0x400 +) + +const ( + IF_TYPE_OTHER = 1 + IF_TYPE_ETHERNET_CSMACD = 6 + IF_TYPE_ISO88025_TOKENRING = 9 + IF_TYPE_PPP = 23 + IF_TYPE_SOFTWARE_LOOPBACK = 24 + IF_TYPE_ATM = 37 + IF_TYPE_IEEE80211 = 71 + IF_TYPE_TUNNEL = 131 + IF_TYPE_IEEE1394 = 144 +) + +// Enum NL_PREFIX_ORIGIN for [IpAdapterUnicastAddress], see +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_prefix_origin +const ( + IpPrefixOriginOther = 0 + IpPrefixOriginManual = 1 + IpPrefixOriginWellKnown = 2 + IpPrefixOriginDhcp = 3 + IpPrefixOriginRouterAdvertisement = 4 + IpPrefixOriginUnchanged = 1 << 4 +) + +// Enum NL_SUFFIX_ORIGIN for [IpAdapterUnicastAddress], see +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_suffix_origin +const ( + NlsoOther = 0 + NlsoManual = 1 + NlsoWellKnown = 2 + NlsoDhcp = 3 + NlsoLinkLayerAddress = 4 + NlsoRandom = 5 + IpSuffixOriginOther = 0 + IpSuffixOriginManual = 1 + IpSuffixOriginWellKnown = 2 + IpSuffixOriginDhcp = 3 + IpSuffixOriginLinkLayerAddress = 4 + IpSuffixOriginRandom = 5 + IpSuffixOriginUnchanged = 1 << 4 +) + +// Enum NL_DAD_STATE for [IpAdapterUnicastAddress], see +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_dad_state +const ( + NldsInvalid = 0 + NldsTentative = 1 + NldsDuplicate = 2 + NldsDeprecated = 3 + NldsPreferred = 4 + IpDadStateInvalid = 0 + IpDadStateTentative = 1 + IpDadStateDuplicate = 2 + IpDadStateDeprecated = 3 + IpDadStatePreferred = 4 +) + +type SocketAddress struct { + Sockaddr *syscall.RawSockaddrAny + SockaddrLength int32 +} + +// IP returns an IPv4 or IPv6 address, or nil if the underlying SocketAddress is neither. +func (addr *SocketAddress) IP() net.IP { + if uintptr(addr.SockaddrLength) >= unsafe.Sizeof(RawSockaddrInet4{}) && addr.Sockaddr.Addr.Family == AF_INET { + return (*RawSockaddrInet4)(unsafe.Pointer(addr.Sockaddr)).Addr[:] + } else if uintptr(addr.SockaddrLength) >= unsafe.Sizeof(RawSockaddrInet6{}) && addr.Sockaddr.Addr.Family == AF_INET6 { + return (*RawSockaddrInet6)(unsafe.Pointer(addr.Sockaddr)).Addr[:] + } + return nil +} + +type IpAdapterUnicastAddress struct { + Length uint32 + Flags uint32 + Next *IpAdapterUnicastAddress + Address SocketAddress + PrefixOrigin int32 + SuffixOrigin int32 + DadState int32 + ValidLifetime uint32 + PreferredLifetime uint32 + LeaseLifetime uint32 + OnLinkPrefixLength uint8 +} + +type IpAdapterAnycastAddress struct { + Length uint32 + Flags uint32 + Next *IpAdapterAnycastAddress + Address SocketAddress +} + +type IpAdapterMulticastAddress struct { + Length uint32 + Flags uint32 + Next *IpAdapterMulticastAddress + Address SocketAddress +} + +type IpAdapterDnsServerAdapter struct { + Length uint32 + Reserved uint32 + Next *IpAdapterDnsServerAdapter + Address SocketAddress +} + +type IpAdapterPrefix struct { + Length uint32 + Flags uint32 + Next *IpAdapterPrefix + Address SocketAddress + PrefixLength uint32 +} + +type IpAdapterAddresses struct { + Length uint32 + IfIndex uint32 + Next *IpAdapterAddresses + AdapterName *byte + FirstUnicastAddress *IpAdapterUnicastAddress + FirstAnycastAddress *IpAdapterAnycastAddress + FirstMulticastAddress *IpAdapterMulticastAddress + FirstDnsServerAddress *IpAdapterDnsServerAdapter + DnsSuffix *uint16 + Description *uint16 + FriendlyName *uint16 + PhysicalAddress [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte + PhysicalAddressLength uint32 + Flags uint32 + Mtu uint32 + IfType uint32 + OperStatus uint32 + Ipv6IfIndex uint32 + ZoneIndices [16]uint32 + FirstPrefix *IpAdapterPrefix + TransmitLinkSpeed uint64 + ReceiveLinkSpeed uint64 + FirstWinsServerAddress *IpAdapterWinsServerAddress + FirstGatewayAddress *IpAdapterGatewayAddress + Ipv4Metric uint32 + Ipv6Metric uint32 + Luid uint64 + Dhcpv4Server SocketAddress + CompartmentId uint32 + NetworkGuid GUID + ConnectionType uint32 + TunnelType uint32 + Dhcpv6Server SocketAddress + Dhcpv6ClientDuid [MAX_DHCPV6_DUID_LENGTH]byte + Dhcpv6ClientDuidLength uint32 + Dhcpv6Iaid uint32 + FirstDnsSuffix *IpAdapterDNSSuffix +} + +type IpAdapterWinsServerAddress struct { + Length uint32 + Reserved uint32 + Next *IpAdapterWinsServerAddress + Address SocketAddress +} + +type IpAdapterGatewayAddress struct { + Length uint32 + Reserved uint32 + Next *IpAdapterGatewayAddress + Address SocketAddress +} + +type IpAdapterDNSSuffix struct { + Next *IpAdapterDNSSuffix + String [MAX_DNS_SUFFIX_STRING_LENGTH]uint16 +} + +const ( + IfOperStatusUp = 1 + IfOperStatusDown = 2 + IfOperStatusTesting = 3 + IfOperStatusUnknown = 4 + IfOperStatusDormant = 5 + IfOperStatusNotPresent = 6 + IfOperStatusLowerLayerDown = 7 +) + +const ( + IF_MAX_PHYS_ADDRESS_LENGTH = 32 + IF_MAX_STRING_SIZE = 256 +) + +// MIB_IF_ENTRY_LEVEL enumeration from netioapi.h or +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2ex. +const ( + MibIfEntryNormal = 0 + MibIfEntryNormalWithoutStatistics = 2 +) + +// MIB_NOTIFICATION_TYPE enumeration from netioapi.h or +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ne-netioapi-mib_notification_type. +const ( + MibParameterNotification = 0 + MibAddInstance = 1 + MibDeleteInstance = 2 + MibInitialNotification = 3 +) + +// MibIfRow2 stores information about a particular interface. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2. +type MibIfRow2 struct { + InterfaceLuid uint64 + InterfaceIndex uint32 + InterfaceGuid GUID + Alias [IF_MAX_STRING_SIZE + 1]uint16 + Description [IF_MAX_STRING_SIZE + 1]uint16 + PhysicalAddressLength uint32 + PhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8 + PermanentPhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8 + Mtu uint32 + Type uint32 + TunnelType uint32 + MediaType uint32 + PhysicalMediumType uint32 + AccessType uint32 + DirectionType uint32 + InterfaceAndOperStatusFlags uint8 + OperStatus uint32 + AdminStatus uint32 + MediaConnectState uint32 + NetworkGuid GUID + ConnectionType uint32 + TransmitLinkSpeed uint64 + ReceiveLinkSpeed uint64 + InOctets uint64 + InUcastPkts uint64 + InNUcastPkts uint64 + InDiscards uint64 + InErrors uint64 + InUnknownProtos uint64 + InUcastOctets uint64 + InMulticastOctets uint64 + InBroadcastOctets uint64 + OutOctets uint64 + OutUcastPkts uint64 + OutNUcastPkts uint64 + OutDiscards uint64 + OutErrors uint64 + OutUcastOctets uint64 + OutMulticastOctets uint64 + OutBroadcastOctets uint64 + OutQLen uint64 +} + +// MIB_IF_TABLE_LEVEL enumeration from netioapi.h or +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ne-netioapi-mib_if_table_level. +const ( + MibIfTableNormal = 0 + MibIfTableRaw = 1 + MibIfTableNormalWithoutStatistics = 2 +) + +// MibIfTable2 contains a table of logical and physical interface entries. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_table2. +type MibIfTable2 struct { + NumEntries uint32 + Table [1]MibIfRow2 +} + +// IP_ADDRESS_PREFIX stores an IP address prefix. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-ip_address_prefix. +type IpAddressPrefix struct { + Prefix RawSockaddrInet + PrefixLength uint8 +} + +// NL_ROUTE_ORIGIN enumeration from nldef.h or +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_origin. +const ( + NlroManual = 0 + NlroWellKnown = 1 + NlroDHCP = 2 + NlroRouterAdvertisement = 3 + Nlro6to4 = 4 +) + +// NL_ROUTE_ORIGIN enumeration from nldef.h or +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_protocol. +const ( + MIB_IPPROTO_OTHER = 1 + MIB_IPPROTO_LOCAL = 2 + MIB_IPPROTO_NETMGMT = 3 + MIB_IPPROTO_ICMP = 4 + MIB_IPPROTO_EGP = 5 + MIB_IPPROTO_GGP = 6 + MIB_IPPROTO_HELLO = 7 + MIB_IPPROTO_RIP = 8 + MIB_IPPROTO_IS_IS = 9 + MIB_IPPROTO_ES_IS = 10 + MIB_IPPROTO_CISCO = 11 + MIB_IPPROTO_BBN = 12 + MIB_IPPROTO_OSPF = 13 + MIB_IPPROTO_BGP = 14 + MIB_IPPROTO_IDPR = 15 + MIB_IPPROTO_EIGRP = 16 + MIB_IPPROTO_DVMRP = 17 + MIB_IPPROTO_RPL = 18 + MIB_IPPROTO_DHCP = 19 + MIB_IPPROTO_NT_AUTOSTATIC = 10002 + MIB_IPPROTO_NT_STATIC = 10006 + MIB_IPPROTO_NT_STATIC_NON_DOD = 10007 +) + +// MIB_IPFORWARD_ROW2 stores information about an IP route entry. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_row2. +type MibIpForwardRow2 struct { + InterfaceLuid uint64 + InterfaceIndex uint32 + DestinationPrefix IpAddressPrefix + NextHop RawSockaddrInet + SitePrefixLength uint8 + ValidLifetime uint32 + PreferredLifetime uint32 + Metric uint32 + Protocol uint32 + Loopback uint8 + AutoconfigureAddress uint8 + Publish uint8 + Immortal uint8 + Age uint32 + Origin uint32 +} + +// MIB_IPFORWARD_TABLE2 contains a table of IP route entries. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_table2. +type MibIpForwardTable2 struct { + NumEntries uint32 + Table [1]MibIpForwardRow2 +} + +// Rows returns the IP route entries in the table. +func (t *MibIpForwardTable2) Rows() []MibIpForwardRow2 { + return unsafe.Slice(&t.Table[0], t.NumEntries) +} + +// MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row. +type MibUnicastIpAddressRow struct { + Address RawSockaddrInet6 // SOCKADDR_INET union + InterfaceLuid uint64 + InterfaceIndex uint32 + PrefixOrigin uint32 + SuffixOrigin uint32 + ValidLifetime uint32 + PreferredLifetime uint32 + OnLinkPrefixLength uint8 + SkipAsSource uint8 + DadState uint32 + ScopeId uint32 + CreationTimeStamp Filetime +} + +// MibUnicastIpAddressTable contains a table of unicast IP address entries. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_table. +type MibUnicastIpAddressTable struct { + NumEntries uint32 + Table [1]MibUnicastIpAddressRow +} + +const ScopeLevelCount = 16 + +// MIB_IPINTERFACE_ROW stores interface management information for a particular IP address family on a network interface. +// See https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipinterface_row. +type MibIpInterfaceRow struct { + Family uint16 + InterfaceLuid uint64 + InterfaceIndex uint32 + MaxReassemblySize uint32 + InterfaceIdentifier uint64 + MinRouterAdvertisementInterval uint32 + MaxRouterAdvertisementInterval uint32 + AdvertisingEnabled uint8 + ForwardingEnabled uint8 + WeakHostSend uint8 + WeakHostReceive uint8 + UseAutomaticMetric uint8 + UseNeighborUnreachabilityDetection uint8 + ManagedAddressConfigurationSupported uint8 + OtherStatefulConfigurationSupported uint8 + AdvertiseDefaultRoute uint8 + RouterDiscoveryBehavior uint32 + DadTransmits uint32 + BaseReachableTime uint32 + RetransmitTime uint32 + PathMtuDiscoveryTimeout uint32 + LinkLocalAddressBehavior uint32 + LinkLocalAddressTimeout uint32 + ZoneIndices [ScopeLevelCount]uint32 + SitePrefixLength uint32 + Metric uint32 + NlMtu uint32 + Connected uint8 + SupportsWakeUpPatterns uint8 + SupportsNeighborDiscovery uint8 + SupportsRouterDiscovery uint8 + ReachableTime uint32 + TransmitOffload uint32 + ReceiveOffload uint32 + DisableDefaultRoutes uint8 +} + +// MibIpInterfaceTable contains a table of IP interface entries. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipinterface_table. +type MibIpInterfaceTable struct { + NumEntries uint32 + Table [1]MibIpInterfaceRow +} + +// Console related constants used for the mode parameter to SetConsoleMode. See +// https://docs.microsoft.com/en-us/windows/console/setconsolemode for details. + +const ( + ENABLE_PROCESSED_INPUT = 0x1 + ENABLE_LINE_INPUT = 0x2 + ENABLE_ECHO_INPUT = 0x4 + ENABLE_WINDOW_INPUT = 0x8 + ENABLE_MOUSE_INPUT = 0x10 + ENABLE_INSERT_MODE = 0x20 + ENABLE_QUICK_EDIT_MODE = 0x40 + ENABLE_EXTENDED_FLAGS = 0x80 + ENABLE_AUTO_POSITION = 0x100 + ENABLE_VIRTUAL_TERMINAL_INPUT = 0x200 + + ENABLE_PROCESSED_OUTPUT = 0x1 + ENABLE_WRAP_AT_EOL_OUTPUT = 0x2 + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4 + DISABLE_NEWLINE_AUTO_RETURN = 0x8 + ENABLE_LVB_GRID_WORLDWIDE = 0x10 +) + +// Pseudo console related constants used for the flags parameter to +// CreatePseudoConsole. See: https://learn.microsoft.com/en-us/windows/console/createpseudoconsole +const ( + PSEUDOCONSOLE_INHERIT_CURSOR = 0x1 +) + +type Coord struct { + X int16 + Y int16 +} + +type SmallRect struct { + Left int16 + Top int16 + Right int16 + Bottom int16 +} + +// Used with GetConsoleScreenBuffer to retrieve information about a console +// screen buffer. See +// https://docs.microsoft.com/en-us/windows/console/console-screen-buffer-info-str +// for details. + +type ConsoleScreenBufferInfo struct { + Size Coord + CursorPosition Coord + Attributes uint16 + Window SmallRect + MaximumWindowSize Coord +} + +const UNIX_PATH_MAX = 108 // defined in afunix.h + +const ( + // flags for JOBOBJECT_BASIC_LIMIT_INFORMATION.LimitFlags + JOB_OBJECT_LIMIT_ACTIVE_PROCESS = 0x00000008 + JOB_OBJECT_LIMIT_AFFINITY = 0x00000010 + JOB_OBJECT_LIMIT_BREAKAWAY_OK = 0x00000800 + JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION = 0x00000400 + JOB_OBJECT_LIMIT_JOB_MEMORY = 0x00000200 + JOB_OBJECT_LIMIT_JOB_TIME = 0x00000004 + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000 + JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME = 0x00000040 + JOB_OBJECT_LIMIT_PRIORITY_CLASS = 0x00000020 + JOB_OBJECT_LIMIT_PROCESS_MEMORY = 0x00000100 + JOB_OBJECT_LIMIT_PROCESS_TIME = 0x00000002 + JOB_OBJECT_LIMIT_SCHEDULING_CLASS = 0x00000080 + JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK = 0x00001000 + JOB_OBJECT_LIMIT_SUBSET_AFFINITY = 0x00004000 + JOB_OBJECT_LIMIT_WORKINGSET = 0x00000001 +) + +type IO_COUNTERS struct { + ReadOperationCount uint64 + WriteOperationCount uint64 + OtherOperationCount uint64 + ReadTransferCount uint64 + WriteTransferCount uint64 + OtherTransferCount uint64 +} + +type JOBOBJECT_EXTENDED_LIMIT_INFORMATION struct { + BasicLimitInformation JOBOBJECT_BASIC_LIMIT_INFORMATION + IoInfo IO_COUNTERS + ProcessMemoryLimit uintptr + JobMemoryLimit uintptr + PeakProcessMemoryUsed uintptr + PeakJobMemoryUsed uintptr +} + +const ( + // UIRestrictionsClass + JOB_OBJECT_UILIMIT_DESKTOP = 0x00000040 + JOB_OBJECT_UILIMIT_DISPLAYSETTINGS = 0x00000010 + JOB_OBJECT_UILIMIT_EXITWINDOWS = 0x00000080 + JOB_OBJECT_UILIMIT_GLOBALATOMS = 0x00000020 + JOB_OBJECT_UILIMIT_HANDLES = 0x00000001 + JOB_OBJECT_UILIMIT_READCLIPBOARD = 0x00000002 + JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS = 0x00000008 + JOB_OBJECT_UILIMIT_WRITECLIPBOARD = 0x00000004 +) + +type JOBOBJECT_BASIC_UI_RESTRICTIONS struct { + UIRestrictionsClass uint32 +} + +const ( + // JobObjectInformationClass for QueryInformationJobObject and SetInformationJobObject + JobObjectAssociateCompletionPortInformation = 7 + JobObjectBasicAccountingInformation = 1 + JobObjectBasicAndIoAccountingInformation = 8 + JobObjectBasicLimitInformation = 2 + JobObjectBasicProcessIdList = 3 + JobObjectBasicUIRestrictions = 4 + JobObjectCpuRateControlInformation = 15 + JobObjectEndOfJobTimeInformation = 6 + JobObjectExtendedLimitInformation = 9 + JobObjectGroupInformation = 11 + JobObjectGroupInformationEx = 14 + JobObjectLimitViolationInformation = 13 + JobObjectLimitViolationInformation2 = 34 + JobObjectNetRateControlInformation = 32 + JobObjectNotificationLimitInformation = 12 + JobObjectNotificationLimitInformation2 = 33 + JobObjectSecurityLimitInformation = 5 +) + +const ( + KF_FLAG_DEFAULT = 0x00000000 + KF_FLAG_FORCE_APP_DATA_REDIRECTION = 0x00080000 + KF_FLAG_RETURN_FILTER_REDIRECTION_TARGET = 0x00040000 + KF_FLAG_FORCE_PACKAGE_REDIRECTION = 0x00020000 + KF_FLAG_NO_PACKAGE_REDIRECTION = 0x00010000 + KF_FLAG_FORCE_APPCONTAINER_REDIRECTION = 0x00020000 + KF_FLAG_NO_APPCONTAINER_REDIRECTION = 0x00010000 + KF_FLAG_CREATE = 0x00008000 + KF_FLAG_DONT_VERIFY = 0x00004000 + KF_FLAG_DONT_UNEXPAND = 0x00002000 + KF_FLAG_NO_ALIAS = 0x00001000 + KF_FLAG_INIT = 0x00000800 + KF_FLAG_DEFAULT_PATH = 0x00000400 + KF_FLAG_NOT_PARENT_RELATIVE = 0x00000200 + KF_FLAG_SIMPLE_IDLIST = 0x00000100 + KF_FLAG_ALIAS_ONLY = 0x80000000 +) + +type OsVersionInfoEx struct { + osVersionInfoSize uint32 + MajorVersion uint32 + MinorVersion uint32 + BuildNumber uint32 + PlatformId uint32 + CsdVersion [128]uint16 + ServicePackMajor uint16 + ServicePackMinor uint16 + SuiteMask uint16 + ProductType byte + _ byte +} + +const ( + EWX_LOGOFF = 0x00000000 + EWX_SHUTDOWN = 0x00000001 + EWX_REBOOT = 0x00000002 + EWX_FORCE = 0x00000004 + EWX_POWEROFF = 0x00000008 + EWX_FORCEIFHUNG = 0x00000010 + EWX_QUICKRESOLVE = 0x00000020 + EWX_RESTARTAPPS = 0x00000040 + EWX_HYBRID_SHUTDOWN = 0x00400000 + EWX_BOOTOPTIONS = 0x01000000 + + SHTDN_REASON_FLAG_COMMENT_REQUIRED = 0x01000000 + SHTDN_REASON_FLAG_DIRTY_PROBLEM_ID_REQUIRED = 0x02000000 + SHTDN_REASON_FLAG_CLEAN_UI = 0x04000000 + SHTDN_REASON_FLAG_DIRTY_UI = 0x08000000 + SHTDN_REASON_FLAG_USER_DEFINED = 0x40000000 + SHTDN_REASON_FLAG_PLANNED = 0x80000000 + SHTDN_REASON_MAJOR_OTHER = 0x00000000 + SHTDN_REASON_MAJOR_NONE = 0x00000000 + SHTDN_REASON_MAJOR_HARDWARE = 0x00010000 + SHTDN_REASON_MAJOR_OPERATINGSYSTEM = 0x00020000 + SHTDN_REASON_MAJOR_SOFTWARE = 0x00030000 + SHTDN_REASON_MAJOR_APPLICATION = 0x00040000 + SHTDN_REASON_MAJOR_SYSTEM = 0x00050000 + SHTDN_REASON_MAJOR_POWER = 0x00060000 + SHTDN_REASON_MAJOR_LEGACY_API = 0x00070000 + SHTDN_REASON_MINOR_OTHER = 0x00000000 + SHTDN_REASON_MINOR_NONE = 0x000000ff + SHTDN_REASON_MINOR_MAINTENANCE = 0x00000001 + SHTDN_REASON_MINOR_INSTALLATION = 0x00000002 + SHTDN_REASON_MINOR_UPGRADE = 0x00000003 + SHTDN_REASON_MINOR_RECONFIG = 0x00000004 + SHTDN_REASON_MINOR_HUNG = 0x00000005 + SHTDN_REASON_MINOR_UNSTABLE = 0x00000006 + SHTDN_REASON_MINOR_DISK = 0x00000007 + SHTDN_REASON_MINOR_PROCESSOR = 0x00000008 + SHTDN_REASON_MINOR_NETWORKCARD = 0x00000009 + SHTDN_REASON_MINOR_POWER_SUPPLY = 0x0000000a + SHTDN_REASON_MINOR_CORDUNPLUGGED = 0x0000000b + SHTDN_REASON_MINOR_ENVIRONMENT = 0x0000000c + SHTDN_REASON_MINOR_HARDWARE_DRIVER = 0x0000000d + SHTDN_REASON_MINOR_OTHERDRIVER = 0x0000000e + SHTDN_REASON_MINOR_BLUESCREEN = 0x0000000F + SHTDN_REASON_MINOR_SERVICEPACK = 0x00000010 + SHTDN_REASON_MINOR_HOTFIX = 0x00000011 + SHTDN_REASON_MINOR_SECURITYFIX = 0x00000012 + SHTDN_REASON_MINOR_SECURITY = 0x00000013 + SHTDN_REASON_MINOR_NETWORK_CONNECTIVITY = 0x00000014 + SHTDN_REASON_MINOR_WMI = 0x00000015 + SHTDN_REASON_MINOR_SERVICEPACK_UNINSTALL = 0x00000016 + SHTDN_REASON_MINOR_HOTFIX_UNINSTALL = 0x00000017 + SHTDN_REASON_MINOR_SECURITYFIX_UNINSTALL = 0x00000018 + SHTDN_REASON_MINOR_MMC = 0x00000019 + SHTDN_REASON_MINOR_SYSTEMRESTORE = 0x0000001a + SHTDN_REASON_MINOR_TERMSRV = 0x00000020 + SHTDN_REASON_MINOR_DC_PROMOTION = 0x00000021 + SHTDN_REASON_MINOR_DC_DEMOTION = 0x00000022 + SHTDN_REASON_UNKNOWN = SHTDN_REASON_MINOR_NONE + SHTDN_REASON_LEGACY_API = SHTDN_REASON_MAJOR_LEGACY_API | SHTDN_REASON_FLAG_PLANNED + SHTDN_REASON_VALID_BIT_MASK = 0xc0ffffff + + SHUTDOWN_NORETRY = 0x1 +) + +// Flags used for GetModuleHandleEx +const ( + GET_MODULE_HANDLE_EX_FLAG_PIN = 1 + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT = 2 + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS = 4 +) + +// MUI function flag values +const ( + MUI_LANGUAGE_ID = 0x4 + MUI_LANGUAGE_NAME = 0x8 + MUI_MERGE_SYSTEM_FALLBACK = 0x10 + MUI_MERGE_USER_FALLBACK = 0x20 + MUI_UI_FALLBACK = MUI_MERGE_SYSTEM_FALLBACK | MUI_MERGE_USER_FALLBACK + MUI_THREAD_LANGUAGES = 0x40 + MUI_CONSOLE_FILTER = 0x100 + MUI_COMPLEX_SCRIPT_FILTER = 0x200 + MUI_RESET_FILTERS = 0x001 + MUI_USER_PREFERRED_UI_LANGUAGES = 0x10 + MUI_USE_INSTALLED_LANGUAGES = 0x20 + MUI_USE_SEARCH_ALL_LANGUAGES = 0x40 + MUI_LANG_NEUTRAL_PE_FILE = 0x100 + MUI_NON_LANG_NEUTRAL_FILE = 0x200 + MUI_MACHINE_LANGUAGE_SETTINGS = 0x400 + MUI_FILETYPE_NOT_LANGUAGE_NEUTRAL = 0x001 + MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN = 0x002 + MUI_FILETYPE_LANGUAGE_NEUTRAL_MUI = 0x004 + MUI_QUERY_TYPE = 0x001 + MUI_QUERY_CHECKSUM = 0x002 + MUI_QUERY_LANGUAGE_NAME = 0x004 + MUI_QUERY_RESOURCE_TYPES = 0x008 + MUI_FILEINFO_VERSION = 0x001 + + MUI_FULL_LANGUAGE = 0x01 + MUI_PARTIAL_LANGUAGE = 0x02 + MUI_LIP_LANGUAGE = 0x04 + MUI_LANGUAGE_INSTALLED = 0x20 + MUI_LANGUAGE_LICENSED = 0x40 +) + +// FILE_INFO_BY_HANDLE_CLASS constants for SetFileInformationByHandle/GetFileInformationByHandleEx +const ( + FileBasicInfo = 0 + FileStandardInfo = 1 + FileNameInfo = 2 + FileRenameInfo = 3 + FileDispositionInfo = 4 + FileAllocationInfo = 5 + FileEndOfFileInfo = 6 + FileStreamInfo = 7 + FileCompressionInfo = 8 + FileAttributeTagInfo = 9 + FileIdBothDirectoryInfo = 10 + FileIdBothDirectoryRestartInfo = 11 + FileIoPriorityHintInfo = 12 + FileRemoteProtocolInfo = 13 + FileFullDirectoryInfo = 14 + FileFullDirectoryRestartInfo = 15 + FileStorageInfo = 16 + FileAlignmentInfo = 17 + FileIdInfo = 18 + FileIdExtdDirectoryInfo = 19 + FileIdExtdDirectoryRestartInfo = 20 + FileDispositionInfoEx = 21 + FileRenameInfoEx = 22 + FileCaseSensitiveInfo = 23 + FileNormalizedNameInfo = 24 +) + +// LoadLibrary flags for determining from where to search for a DLL +const ( + DONT_RESOLVE_DLL_REFERENCES = 0x1 + LOAD_LIBRARY_AS_DATAFILE = 0x2 + LOAD_WITH_ALTERED_SEARCH_PATH = 0x8 + LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x10 + LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x20 + LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x40 + LOAD_LIBRARY_REQUIRE_SIGNED_TARGET = 0x80 + LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x100 + LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x200 + LOAD_LIBRARY_SEARCH_USER_DIRS = 0x400 + LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x800 + LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x1000 + LOAD_LIBRARY_SAFE_CURRENT_DIRS = 0x00002000 + LOAD_LIBRARY_SEARCH_SYSTEM32_NO_FORWARDER = 0x00004000 + LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY = 0x00008000 +) + +// RegNotifyChangeKeyValue notifyFilter flags. +const ( + // REG_NOTIFY_CHANGE_NAME notifies the caller if a subkey is added or deleted. + REG_NOTIFY_CHANGE_NAME = 0x00000001 + + // REG_NOTIFY_CHANGE_ATTRIBUTES notifies the caller of changes to the attributes of the key, such as the security descriptor information. + REG_NOTIFY_CHANGE_ATTRIBUTES = 0x00000002 + + // REG_NOTIFY_CHANGE_LAST_SET notifies the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value. + REG_NOTIFY_CHANGE_LAST_SET = 0x00000004 + + // REG_NOTIFY_CHANGE_SECURITY notifies the caller of changes to the security descriptor of the key. + REG_NOTIFY_CHANGE_SECURITY = 0x00000008 + + // REG_NOTIFY_THREAD_AGNOSTIC indicates that the lifetime of the registration must not be tied to the lifetime of the thread issuing the RegNotifyChangeKeyValue call. Note: This flag value is only supported in Windows 8 and later. + REG_NOTIFY_THREAD_AGNOSTIC = 0x10000000 +) + +type CommTimeouts struct { + ReadIntervalTimeout uint32 + ReadTotalTimeoutMultiplier uint32 + ReadTotalTimeoutConstant uint32 + WriteTotalTimeoutMultiplier uint32 + WriteTotalTimeoutConstant uint32 +} + +// NTUnicodeString is a UTF-16 string for NT native APIs, corresponding to UNICODE_STRING. +type NTUnicodeString struct { + // Note: Length and MaximumLength are in *bytes*, not uint16s. + // They should always be even. + Length uint16 + MaximumLength uint16 + Buffer *uint16 +} + +// NTString is an ANSI string for NT native APIs, corresponding to STRING. +type NTString struct { + Length uint16 + MaximumLength uint16 + Buffer *byte +} + +type LIST_ENTRY struct { + Flink *LIST_ENTRY + Blink *LIST_ENTRY +} + +type RUNTIME_FUNCTION struct { + BeginAddress uint32 + EndAddress uint32 + UnwindData uint32 +} + +type LDR_DATA_TABLE_ENTRY struct { + reserved1 [2]uintptr + InMemoryOrderLinks LIST_ENTRY + reserved2 [2]uintptr + DllBase uintptr + reserved3 [2]uintptr + FullDllName NTUnicodeString + reserved4 [8]byte + reserved5 [3]uintptr + reserved6 uintptr + TimeDateStamp uint32 +} + +type PEB_LDR_DATA struct { + reserved1 [8]byte + reserved2 [3]uintptr + InMemoryOrderModuleList LIST_ENTRY +} + +type CURDIR struct { + DosPath NTUnicodeString + Handle Handle +} + +type RTL_DRIVE_LETTER_CURDIR struct { + Flags uint16 + Length uint16 + TimeStamp uint32 + DosPath NTString +} + +type RTL_USER_PROCESS_PARAMETERS struct { + MaximumLength, Length uint32 + + Flags, DebugFlags uint32 + + ConsoleHandle Handle + ConsoleFlags uint32 + StandardInput, StandardOutput, StandardError Handle + + CurrentDirectory CURDIR + DllPath NTUnicodeString + ImagePathName NTUnicodeString + CommandLine NTUnicodeString + Environment unsafe.Pointer + + StartingX, StartingY, CountX, CountY, CountCharsX, CountCharsY, FillAttribute uint32 + + WindowFlags, ShowWindowFlags uint32 + WindowTitle, DesktopInfo, ShellInfo, RuntimeData NTUnicodeString + CurrentDirectories [32]RTL_DRIVE_LETTER_CURDIR + + EnvironmentSize, EnvironmentVersion uintptr + + PackageDependencyData unsafe.Pointer + ProcessGroupId uint32 + LoaderThreads uint32 + + RedirectionDllName NTUnicodeString + HeapPartitionName NTUnicodeString + DefaultThreadpoolCpuSetMasks uintptr + DefaultThreadpoolCpuSetMaskCount uint32 +} + +type PEB struct { + reserved1 [2]byte + BeingDebugged byte + BitField byte + reserved3 uintptr + ImageBaseAddress uintptr + Ldr *PEB_LDR_DATA + ProcessParameters *RTL_USER_PROCESS_PARAMETERS + reserved4 [3]uintptr + AtlThunkSListPtr uintptr + reserved5 uintptr + reserved6 uint32 + reserved7 uintptr + reserved8 uint32 + AtlThunkSListPtr32 uint32 + reserved9 [45]uintptr + reserved10 [96]byte + PostProcessInitRoutine uintptr + reserved11 [128]byte + reserved12 [1]uintptr + SessionId uint32 +} + +type OBJECT_ATTRIBUTES struct { + Length uint32 + RootDirectory Handle + ObjectName *NTUnicodeString + Attributes uint32 + SecurityDescriptor *SECURITY_DESCRIPTOR + SecurityQoS *SECURITY_QUALITY_OF_SERVICE +} + +// Values for the Attributes member of OBJECT_ATTRIBUTES. +const ( + OBJ_INHERIT = 0x00000002 + OBJ_PERMANENT = 0x00000010 + OBJ_EXCLUSIVE = 0x00000020 + OBJ_CASE_INSENSITIVE = 0x00000040 + OBJ_OPENIF = 0x00000080 + OBJ_OPENLINK = 0x00000100 + OBJ_KERNEL_HANDLE = 0x00000200 + OBJ_FORCE_ACCESS_CHECK = 0x00000400 + OBJ_IGNORE_IMPERSONATED_DEVICEMAP = 0x00000800 + OBJ_DONT_REPARSE = 0x00001000 + OBJ_VALID_ATTRIBUTES = 0x00001FF2 +) + +type IO_STATUS_BLOCK struct { + Status NTStatus + Information uintptr +} + +type RTLP_CURDIR_REF struct { + RefCount int32 + Handle Handle +} + +type RTL_RELATIVE_NAME struct { + RelativeName NTUnicodeString + ContainingDirectory Handle + CurDirRef *RTLP_CURDIR_REF +} + +const ( + // CreateDisposition flags for NtCreateFile and NtCreateNamedPipeFile. + FILE_SUPERSEDE = 0x00000000 + FILE_OPEN = 0x00000001 + FILE_CREATE = 0x00000002 + FILE_OPEN_IF = 0x00000003 + FILE_OVERWRITE = 0x00000004 + FILE_OVERWRITE_IF = 0x00000005 + FILE_MAXIMUM_DISPOSITION = 0x00000005 + + // CreateOptions flags for NtCreateFile and NtCreateNamedPipeFile. + FILE_DIRECTORY_FILE = 0x00000001 + FILE_WRITE_THROUGH = 0x00000002 + FILE_SEQUENTIAL_ONLY = 0x00000004 + FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008 + FILE_SYNCHRONOUS_IO_ALERT = 0x00000010 + FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020 + FILE_NON_DIRECTORY_FILE = 0x00000040 + FILE_CREATE_TREE_CONNECTION = 0x00000080 + FILE_COMPLETE_IF_OPLOCKED = 0x00000100 + FILE_NO_EA_KNOWLEDGE = 0x00000200 + FILE_OPEN_REMOTE_INSTANCE = 0x00000400 + FILE_RANDOM_ACCESS = 0x00000800 + FILE_DELETE_ON_CLOSE = 0x00001000 + FILE_OPEN_BY_FILE_ID = 0x00002000 + FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000 + FILE_NO_COMPRESSION = 0x00008000 + FILE_OPEN_REQUIRING_OPLOCK = 0x00010000 + FILE_DISALLOW_EXCLUSIVE = 0x00020000 + FILE_RESERVE_OPFILTER = 0x00100000 + FILE_OPEN_REPARSE_POINT = 0x00200000 + FILE_OPEN_NO_RECALL = 0x00400000 + FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000 + + // Parameter constants for NtCreateNamedPipeFile. + + FILE_PIPE_BYTE_STREAM_TYPE = 0x00000000 + FILE_PIPE_MESSAGE_TYPE = 0x00000001 + + FILE_PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000 + FILE_PIPE_REJECT_REMOTE_CLIENTS = 0x00000002 + + FILE_PIPE_TYPE_VALID_MASK = 0x00000003 + + FILE_PIPE_BYTE_STREAM_MODE = 0x00000000 + FILE_PIPE_MESSAGE_MODE = 0x00000001 + + FILE_PIPE_QUEUE_OPERATION = 0x00000000 + FILE_PIPE_COMPLETE_OPERATION = 0x00000001 + + FILE_PIPE_INBOUND = 0x00000000 + FILE_PIPE_OUTBOUND = 0x00000001 + FILE_PIPE_FULL_DUPLEX = 0x00000002 + + FILE_PIPE_DISCONNECTED_STATE = 0x00000001 + FILE_PIPE_LISTENING_STATE = 0x00000002 + FILE_PIPE_CONNECTED_STATE = 0x00000003 + FILE_PIPE_CLOSING_STATE = 0x00000004 + + FILE_PIPE_CLIENT_END = 0x00000000 + FILE_PIPE_SERVER_END = 0x00000001 +) + +const ( + // FileInformationClass for NtSetInformationFile/NtQueryInformationFile, see + // https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ne-wdm-_file_information_class + FileBasicInformation = 4 + FileEaInformation = 7 + FileRenameInformation = 10 + FileDispositionInformation = 13 + FilePositionInformation = 14 + FileEndOfFileInformation = 20 + FileValidDataLengthInformation = 39 + FileShortNameInformation = 40 + FileIoPriorityHintInformation = 43 + FileReplaceCompletionInformation = 61 + FileDispositionInformationEx = 64 + FileCaseSensitiveInformation = 71 + FileLinkInformation = 72 + FileCaseSensitiveInformationForceAccessCheck = 75 + FileKnownFolderInformation = 76 + + // Flags for FILE_RENAME_INFORMATION + FILE_RENAME_REPLACE_IF_EXISTS = 0x00000001 + FILE_RENAME_POSIX_SEMANTICS = 0x00000002 + FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE = 0x00000004 + FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE = 0x00000008 + FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE = 0x00000010 + FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE = 0x00000020 + FILE_RENAME_PRESERVE_AVAILABLE_SPACE = 0x00000030 + FILE_RENAME_IGNORE_READONLY_ATTRIBUTE = 0x00000040 + FILE_RENAME_FORCE_RESIZE_TARGET_SR = 0x00000080 + FILE_RENAME_FORCE_RESIZE_SOURCE_SR = 0x00000100 + FILE_RENAME_FORCE_RESIZE_SR = 0x00000180 + + // Flags for FILE_DISPOSITION_INFORMATION_EX + FILE_DISPOSITION_DO_NOT_DELETE = 0x00000000 + FILE_DISPOSITION_DELETE = 0x00000001 + FILE_DISPOSITION_POSIX_SEMANTICS = 0x00000002 + FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK = 0x00000004 + FILE_DISPOSITION_ON_CLOSE = 0x00000008 + FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE = 0x00000010 + + // Flags for FILE_CASE_SENSITIVE_INFORMATION + FILE_CS_FLAG_CASE_SENSITIVE_DIR = 0x00000001 + + // Flags for FILE_LINK_INFORMATION + FILE_LINK_REPLACE_IF_EXISTS = 0x00000001 + FILE_LINK_POSIX_SEMANTICS = 0x00000002 + FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE = 0x00000008 + FILE_LINK_NO_INCREASE_AVAILABLE_SPACE = 0x00000010 + FILE_LINK_NO_DECREASE_AVAILABLE_SPACE = 0x00000020 + FILE_LINK_PRESERVE_AVAILABLE_SPACE = 0x00000030 + FILE_LINK_IGNORE_READONLY_ATTRIBUTE = 0x00000040 + FILE_LINK_FORCE_RESIZE_TARGET_SR = 0x00000080 + FILE_LINK_FORCE_RESIZE_SOURCE_SR = 0x00000100 + FILE_LINK_FORCE_RESIZE_SR = 0x00000180 +) + +// ProcessInformationClasses for NtQueryInformationProcess and NtSetInformationProcess. +const ( + ProcessBasicInformation = iota + ProcessQuotaLimits + ProcessIoCounters + ProcessVmCounters + ProcessTimes + ProcessBasePriority + ProcessRaisePriority + ProcessDebugPort + ProcessExceptionPort + ProcessAccessToken + ProcessLdtInformation + ProcessLdtSize + ProcessDefaultHardErrorMode + ProcessIoPortHandlers + ProcessPooledUsageAndLimits + ProcessWorkingSetWatch + ProcessUserModeIOPL + ProcessEnableAlignmentFaultFixup + ProcessPriorityClass + ProcessWx86Information + ProcessHandleCount + ProcessAffinityMask + ProcessPriorityBoost + ProcessDeviceMap + ProcessSessionInformation + ProcessForegroundInformation + ProcessWow64Information + ProcessImageFileName + ProcessLUIDDeviceMapsEnabled + ProcessBreakOnTermination + ProcessDebugObjectHandle + ProcessDebugFlags + ProcessHandleTracing + ProcessIoPriority + ProcessExecuteFlags + ProcessTlsInformation + ProcessCookie + ProcessImageInformation + ProcessCycleTime + ProcessPagePriority + ProcessInstrumentationCallback + ProcessThreadStackAllocation + ProcessWorkingSetWatchEx + ProcessImageFileNameWin32 + ProcessImageFileMapping + ProcessAffinityUpdateMode + ProcessMemoryAllocationMode + ProcessGroupInformation + ProcessTokenVirtualizationEnabled + ProcessConsoleHostProcess + ProcessWindowInformation + ProcessHandleInformation + ProcessMitigationPolicy + ProcessDynamicFunctionTableInformation + ProcessHandleCheckingMode + ProcessKeepAliveCount + ProcessRevokeFileHandles + ProcessWorkingSetControl + ProcessHandleTable + ProcessCheckStackExtentsMode + ProcessCommandLineInformation + ProcessProtectionInformation + ProcessMemoryExhaustion + ProcessFaultInformation + ProcessTelemetryIdInformation + ProcessCommitReleaseInformation + ProcessDefaultCpuSetsInformation + ProcessAllowedCpuSetsInformation + ProcessSubsystemProcess + ProcessJobMemoryInformation + ProcessInPrivate + ProcessRaiseUMExceptionOnInvalidHandleClose + ProcessIumChallengeResponse + ProcessChildProcessInformation + ProcessHighGraphicsPriorityInformation + ProcessSubsystemInformation + ProcessEnergyValues + ProcessActivityThrottleState + ProcessActivityThrottlePolicy + ProcessWin32kSyscallFilterInformation + ProcessDisableSystemAllowedCpuSets + ProcessWakeInformation + ProcessEnergyTrackingState + ProcessManageWritesToExecutableMemory + ProcessCaptureTrustletLiveDump + ProcessTelemetryCoverage + ProcessEnclaveInformation + ProcessEnableReadWriteVmLogging + ProcessUptimeInformation + ProcessImageSection + ProcessDebugAuthInformation + ProcessSystemResourceManagement + ProcessSequenceNumber + ProcessLoaderDetour + ProcessSecurityDomainInformation + ProcessCombineSecurityDomainsInformation + ProcessEnableLogging + ProcessLeapSecondInformation + ProcessFiberShadowStackAllocation + ProcessFreeFiberShadowStackAllocation + ProcessAltSystemCallInformation + ProcessDynamicEHContinuationTargets + ProcessDynamicEnforcedCetCompatibleRanges +) + +type PROCESS_BASIC_INFORMATION struct { + ExitStatus NTStatus + PebBaseAddress *PEB + AffinityMask uintptr + BasePriority int32 + UniqueProcessId uintptr + InheritedFromUniqueProcessId uintptr +} + +type SYSTEM_PROCESS_INFORMATION struct { + NextEntryOffset uint32 + NumberOfThreads uint32 + WorkingSetPrivateSize int64 + HardFaultCount uint32 + NumberOfThreadsHighWatermark uint32 + CycleTime uint64 + CreateTime int64 + UserTime int64 + KernelTime int64 + ImageName NTUnicodeString + BasePriority int32 + UniqueProcessID uintptr + InheritedFromUniqueProcessID uintptr + HandleCount uint32 + SessionID uint32 + UniqueProcessKey *uint32 + PeakVirtualSize uintptr + VirtualSize uintptr + PageFaultCount uint32 + PeakWorkingSetSize uintptr + WorkingSetSize uintptr + QuotaPeakPagedPoolUsage uintptr + QuotaPagedPoolUsage uintptr + QuotaPeakNonPagedPoolUsage uintptr + QuotaNonPagedPoolUsage uintptr + PagefileUsage uintptr + PeakPagefileUsage uintptr + PrivatePageCount uintptr + ReadOperationCount int64 + WriteOperationCount int64 + OtherOperationCount int64 + ReadTransferCount int64 + WriteTransferCount int64 + OtherTransferCount int64 +} + +// SystemInformationClasses for NtQuerySystemInformation and NtSetSystemInformation +const ( + SystemBasicInformation = iota + SystemProcessorInformation + SystemPerformanceInformation + SystemTimeOfDayInformation + SystemPathInformation + SystemProcessInformation + SystemCallCountInformation + SystemDeviceInformation + SystemProcessorPerformanceInformation + SystemFlagsInformation + SystemCallTimeInformation + SystemModuleInformation + SystemLocksInformation + SystemStackTraceInformation + SystemPagedPoolInformation + SystemNonPagedPoolInformation + SystemHandleInformation + SystemObjectInformation + SystemPageFileInformation + SystemVdmInstemulInformation + SystemVdmBopInformation + SystemFileCacheInformation + SystemPoolTagInformation + SystemInterruptInformation + SystemDpcBehaviorInformation + SystemFullMemoryInformation + SystemLoadGdiDriverInformation + SystemUnloadGdiDriverInformation + SystemTimeAdjustmentInformation + SystemSummaryMemoryInformation + SystemMirrorMemoryInformation + SystemPerformanceTraceInformation + systemObsolete0 + SystemExceptionInformation + SystemCrashDumpStateInformation + SystemKernelDebuggerInformation + SystemContextSwitchInformation + SystemRegistryQuotaInformation + SystemExtendServiceTableInformation + SystemPrioritySeperation + SystemVerifierAddDriverInformation + SystemVerifierRemoveDriverInformation + SystemProcessorIdleInformation + SystemLegacyDriverInformation + SystemCurrentTimeZoneInformation + SystemLookasideInformation + SystemTimeSlipNotification + SystemSessionCreate + SystemSessionDetach + SystemSessionInformation + SystemRangeStartInformation + SystemVerifierInformation + SystemVerifierThunkExtend + SystemSessionProcessInformation + SystemLoadGdiDriverInSystemSpace + SystemNumaProcessorMap + SystemPrefetcherInformation + SystemExtendedProcessInformation + SystemRecommendedSharedDataAlignment + SystemComPlusPackage + SystemNumaAvailableMemory + SystemProcessorPowerInformation + SystemEmulationBasicInformation + SystemEmulationProcessorInformation + SystemExtendedHandleInformation + SystemLostDelayedWriteInformation + SystemBigPoolInformation + SystemSessionPoolTagInformation + SystemSessionMappedViewInformation + SystemHotpatchInformation + SystemObjectSecurityMode + SystemWatchdogTimerHandler + SystemWatchdogTimerInformation + SystemLogicalProcessorInformation + SystemWow64SharedInformationObsolete + SystemRegisterFirmwareTableInformationHandler + SystemFirmwareTableInformation + SystemModuleInformationEx + SystemVerifierTriageInformation + SystemSuperfetchInformation + SystemMemoryListInformation + SystemFileCacheInformationEx + SystemThreadPriorityClientIdInformation + SystemProcessorIdleCycleTimeInformation + SystemVerifierCancellationInformation + SystemProcessorPowerInformationEx + SystemRefTraceInformation + SystemSpecialPoolInformation + SystemProcessIdInformation + SystemErrorPortInformation + SystemBootEnvironmentInformation + SystemHypervisorInformation + SystemVerifierInformationEx + SystemTimeZoneInformation + SystemImageFileExecutionOptionsInformation + SystemCoverageInformation + SystemPrefetchPatchInformation + SystemVerifierFaultsInformation + SystemSystemPartitionInformation + SystemSystemDiskInformation + SystemProcessorPerformanceDistribution + SystemNumaProximityNodeInformation + SystemDynamicTimeZoneInformation + SystemCodeIntegrityInformation + SystemProcessorMicrocodeUpdateInformation + SystemProcessorBrandString + SystemVirtualAddressInformation + SystemLogicalProcessorAndGroupInformation + SystemProcessorCycleTimeInformation + SystemStoreInformation + SystemRegistryAppendString + SystemAitSamplingValue + SystemVhdBootInformation + SystemCpuQuotaInformation + SystemNativeBasicInformation + systemSpare1 + SystemLowPriorityIoInformation + SystemTpmBootEntropyInformation + SystemVerifierCountersInformation + SystemPagedPoolInformationEx + SystemSystemPtesInformationEx + SystemNodeDistanceInformation + SystemAcpiAuditInformation + SystemBasicPerformanceInformation + SystemQueryPerformanceCounterInformation + SystemSessionBigPoolInformation + SystemBootGraphicsInformation + SystemScrubPhysicalMemoryInformation + SystemBadPageInformation + SystemProcessorProfileControlArea + SystemCombinePhysicalMemoryInformation + SystemEntropyInterruptTimingCallback + SystemConsoleInformation + SystemPlatformBinaryInformation + SystemThrottleNotificationInformation + SystemHypervisorProcessorCountInformation + SystemDeviceDataInformation + SystemDeviceDataEnumerationInformation + SystemMemoryTopologyInformation + SystemMemoryChannelInformation + SystemBootLogoInformation + SystemProcessorPerformanceInformationEx + systemSpare0 + SystemSecureBootPolicyInformation + SystemPageFileInformationEx + SystemSecureBootInformation + SystemEntropyInterruptTimingRawInformation + SystemPortableWorkspaceEfiLauncherInformation + SystemFullProcessInformation + SystemKernelDebuggerInformationEx + SystemBootMetadataInformation + SystemSoftRebootInformation + SystemElamCertificateInformation + SystemOfflineDumpConfigInformation + SystemProcessorFeaturesInformation + SystemRegistryReconciliationInformation + SystemEdidInformation + SystemManufacturingInformation + SystemEnergyEstimationConfigInformation + SystemHypervisorDetailInformation + SystemProcessorCycleStatsInformation + SystemVmGenerationCountInformation + SystemTrustedPlatformModuleInformation + SystemKernelDebuggerFlags + SystemCodeIntegrityPolicyInformation + SystemIsolatedUserModeInformation + SystemHardwareSecurityTestInterfaceResultsInformation + SystemSingleModuleInformation + SystemAllowedCpuSetsInformation + SystemDmaProtectionInformation + SystemInterruptCpuSetsInformation + SystemSecureBootPolicyFullInformation + SystemCodeIntegrityPolicyFullInformation + SystemAffinitizedInterruptProcessorInformation + SystemRootSiloInformation +) + +type RTL_PROCESS_MODULE_INFORMATION struct { + Section Handle + MappedBase uintptr + ImageBase uintptr + ImageSize uint32 + Flags uint32 + LoadOrderIndex uint16 + InitOrderIndex uint16 + LoadCount uint16 + OffsetToFileName uint16 + FullPathName [256]byte +} + +type RTL_PROCESS_MODULES struct { + NumberOfModules uint32 + Modules [1]RTL_PROCESS_MODULE_INFORMATION +} + +// Constants for LocalAlloc flags. +const ( + LMEM_FIXED = 0x0 + LMEM_MOVEABLE = 0x2 + LMEM_NOCOMPACT = 0x10 + LMEM_NODISCARD = 0x20 + LMEM_ZEROINIT = 0x40 + LMEM_MODIFY = 0x80 + LMEM_DISCARDABLE = 0xf00 + LMEM_VALID_FLAGS = 0xf72 + LMEM_INVALID_HANDLE = 0x8000 + LHND = LMEM_MOVEABLE | LMEM_ZEROINIT + LPTR = LMEM_FIXED | LMEM_ZEROINIT + NONZEROLHND = LMEM_MOVEABLE + NONZEROLPTR = LMEM_FIXED +) + +// Constants for the CreateNamedPipe-family of functions. +const ( + PIPE_ACCESS_INBOUND = 0x1 + PIPE_ACCESS_OUTBOUND = 0x2 + PIPE_ACCESS_DUPLEX = 0x3 + + PIPE_CLIENT_END = 0x0 + PIPE_SERVER_END = 0x1 + + PIPE_WAIT = 0x0 + PIPE_NOWAIT = 0x1 + PIPE_READMODE_BYTE = 0x0 + PIPE_READMODE_MESSAGE = 0x2 + PIPE_TYPE_BYTE = 0x0 + PIPE_TYPE_MESSAGE = 0x4 + PIPE_ACCEPT_REMOTE_CLIENTS = 0x0 + PIPE_REJECT_REMOTE_CLIENTS = 0x8 + + PIPE_UNLIMITED_INSTANCES = 255 +) + +// Constants for security attributes when opening named pipes. +const ( + SECURITY_ANONYMOUS = SecurityAnonymous << 16 + SECURITY_IDENTIFICATION = SecurityIdentification << 16 + SECURITY_IMPERSONATION = SecurityImpersonation << 16 + SECURITY_DELEGATION = SecurityDelegation << 16 + + SECURITY_CONTEXT_TRACKING = 0x40000 + SECURITY_EFFECTIVE_ONLY = 0x80000 + + SECURITY_SQOS_PRESENT = 0x100000 + SECURITY_VALID_SQOS_FLAGS = 0x1f0000 +) + +// ResourceID represents a 16-bit resource identifier, traditionally created with the MAKEINTRESOURCE macro. +type ResourceID uint16 + +// ResourceIDOrString must be either a ResourceID, to specify a resource or resource type by ID, +// or a string, to specify a resource or resource type by name. +type ResourceIDOrString interface{} + +// Predefined resource names and types. +var ( + // Predefined names. + CREATEPROCESS_MANIFEST_RESOURCE_ID ResourceID = 1 + ISOLATIONAWARE_MANIFEST_RESOURCE_ID ResourceID = 2 + ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID ResourceID = 3 + ISOLATIONPOLICY_MANIFEST_RESOURCE_ID ResourceID = 4 + ISOLATIONPOLICY_BROWSER_MANIFEST_RESOURCE_ID ResourceID = 5 + MINIMUM_RESERVED_MANIFEST_RESOURCE_ID ResourceID = 1 // inclusive + MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID ResourceID = 16 // inclusive + + // Predefined types. + RT_CURSOR ResourceID = 1 + RT_BITMAP ResourceID = 2 + RT_ICON ResourceID = 3 + RT_MENU ResourceID = 4 + RT_DIALOG ResourceID = 5 + RT_STRING ResourceID = 6 + RT_FONTDIR ResourceID = 7 + RT_FONT ResourceID = 8 + RT_ACCELERATOR ResourceID = 9 + RT_RCDATA ResourceID = 10 + RT_MESSAGETABLE ResourceID = 11 + RT_GROUP_CURSOR ResourceID = 12 + RT_GROUP_ICON ResourceID = 14 + RT_VERSION ResourceID = 16 + RT_DLGINCLUDE ResourceID = 17 + RT_PLUGPLAY ResourceID = 19 + RT_VXD ResourceID = 20 + RT_ANICURSOR ResourceID = 21 + RT_ANIICON ResourceID = 22 + RT_HTML ResourceID = 23 + RT_MANIFEST ResourceID = 24 +) + +type VS_FIXEDFILEINFO struct { + Signature uint32 + StrucVersion uint32 + FileVersionMS uint32 + FileVersionLS uint32 + ProductVersionMS uint32 + ProductVersionLS uint32 + FileFlagsMask uint32 + FileFlags uint32 + FileOS uint32 + FileType uint32 + FileSubtype uint32 + FileDateMS uint32 + FileDateLS uint32 +} + +type COAUTHIDENTITY struct { + User *uint16 + UserLength uint32 + Domain *uint16 + DomainLength uint32 + Password *uint16 + PasswordLength uint32 + Flags uint32 +} + +type COAUTHINFO struct { + AuthnSvc uint32 + AuthzSvc uint32 + ServerPrincName *uint16 + AuthnLevel uint32 + ImpersonationLevel uint32 + AuthIdentityData *COAUTHIDENTITY + Capabilities uint32 +} + +type COSERVERINFO struct { + Reserved1 uint32 + Aame *uint16 + AuthInfo *COAUTHINFO + Reserved2 uint32 +} + +type BIND_OPTS3 struct { + CbStruct uint32 + Flags uint32 + Mode uint32 + TickCountDeadline uint32 + TrackFlags uint32 + ClassContext uint32 + Locale uint32 + ServerInfo *COSERVERINFO + Hwnd HWND +} + +const ( + CLSCTX_INPROC_SERVER = 0x1 + CLSCTX_INPROC_HANDLER = 0x2 + CLSCTX_LOCAL_SERVER = 0x4 + CLSCTX_INPROC_SERVER16 = 0x8 + CLSCTX_REMOTE_SERVER = 0x10 + CLSCTX_INPROC_HANDLER16 = 0x20 + CLSCTX_RESERVED1 = 0x40 + CLSCTX_RESERVED2 = 0x80 + CLSCTX_RESERVED3 = 0x100 + CLSCTX_RESERVED4 = 0x200 + CLSCTX_NO_CODE_DOWNLOAD = 0x400 + CLSCTX_RESERVED5 = 0x800 + CLSCTX_NO_CUSTOM_MARSHAL = 0x1000 + CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000 + CLSCTX_NO_FAILURE_LOG = 0x4000 + CLSCTX_DISABLE_AAA = 0x8000 + CLSCTX_ENABLE_AAA = 0x10000 + CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000 + CLSCTX_ACTIVATE_32_BIT_SERVER = 0x40000 + CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000 + CLSCTX_ENABLE_CLOAKING = 0x100000 + CLSCTX_APPCONTAINER = 0x400000 + CLSCTX_ACTIVATE_AAA_AS_IU = 0x800000 + CLSCTX_PS_DLL = 0x80000000 + + COINIT_MULTITHREADED = 0x0 + COINIT_APARTMENTTHREADED = 0x2 + COINIT_DISABLE_OLE1DDE = 0x4 + COINIT_SPEED_OVER_MEMORY = 0x8 +) + +// Flag for QueryFullProcessImageName. +const PROCESS_NAME_NATIVE = 1 + +type ModuleInfo struct { + BaseOfDll uintptr + SizeOfImage uint32 + EntryPoint uintptr +} + +const ALL_PROCESSOR_GROUPS = 0xFFFF + +type Rect struct { + Left int32 + Top int32 + Right int32 + Bottom int32 +} + +type GUIThreadInfo struct { + Size uint32 + Flags uint32 + Active HWND + Focus HWND + Capture HWND + MenuOwner HWND + MoveSize HWND + CaretHandle HWND + CaretRect Rect +} + +const ( + DWMWA_NCRENDERING_ENABLED = 1 + DWMWA_NCRENDERING_POLICY = 2 + DWMWA_TRANSITIONS_FORCEDISABLED = 3 + DWMWA_ALLOW_NCPAINT = 4 + DWMWA_CAPTION_BUTTON_BOUNDS = 5 + DWMWA_NONCLIENT_RTL_LAYOUT = 6 + DWMWA_FORCE_ICONIC_REPRESENTATION = 7 + DWMWA_FLIP3D_POLICY = 8 + DWMWA_EXTENDED_FRAME_BOUNDS = 9 + DWMWA_HAS_ICONIC_BITMAP = 10 + DWMWA_DISALLOW_PEEK = 11 + DWMWA_EXCLUDED_FROM_PEEK = 12 + DWMWA_CLOAK = 13 + DWMWA_CLOAKED = 14 + DWMWA_FREEZE_REPRESENTATION = 15 + DWMWA_PASSIVE_UPDATE_MODE = 16 + DWMWA_USE_HOSTBACKDROPBRUSH = 17 + DWMWA_USE_IMMERSIVE_DARK_MODE = 20 + DWMWA_WINDOW_CORNER_PREFERENCE = 33 + DWMWA_BORDER_COLOR = 34 + DWMWA_CAPTION_COLOR = 35 + DWMWA_TEXT_COLOR = 36 + DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37 +) + +type WSAQUERYSET struct { + Size uint32 + ServiceInstanceName *uint16 + ServiceClassId *GUID + Version *WSAVersion + Comment *uint16 + NameSpace uint32 + NSProviderId *GUID + Context *uint16 + NumberOfProtocols uint32 + AfpProtocols *AFProtocols + QueryString *uint16 + NumberOfCsAddrs uint32 + SaBuffer *CSAddrInfo + OutputFlags uint32 + Blob *BLOB +} + +type WSAVersion struct { + Version uint32 + EnumerationOfComparison int32 +} + +type AFProtocols struct { + AddressFamily int32 + Protocol int32 +} + +type CSAddrInfo struct { + LocalAddr SocketAddress + RemoteAddr SocketAddress + SocketType int32 + Protocol int32 +} + +type BLOB struct { + Size uint32 + BlobData *byte +} + +type ComStat struct { + Flags uint32 + CBInQue uint32 + CBOutQue uint32 +} + +type DCB struct { + DCBlength uint32 + BaudRate uint32 + Flags uint32 + wReserved uint16 + XonLim uint16 + XoffLim uint16 + ByteSize uint8 + Parity uint8 + StopBits uint8 + XonChar byte + XoffChar byte + ErrorChar byte + EofChar byte + EvtChar byte + wReserved1 uint16 +} + +// Keyboard Layout Flags. +// See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadkeyboardlayoutw +const ( + KLF_ACTIVATE = 0x00000001 + KLF_SUBSTITUTE_OK = 0x00000002 + KLF_REORDER = 0x00000008 + KLF_REPLACELANG = 0x00000010 + KLF_NOTELLSHELL = 0x00000080 + KLF_SETFORPROCESS = 0x00000100 +) + +// Virtual Key codes +// https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes +const ( + VK_LBUTTON = 0x01 + VK_RBUTTON = 0x02 + VK_CANCEL = 0x03 + VK_MBUTTON = 0x04 + VK_XBUTTON1 = 0x05 + VK_XBUTTON2 = 0x06 + VK_BACK = 0x08 + VK_TAB = 0x09 + VK_CLEAR = 0x0C + VK_RETURN = 0x0D + VK_SHIFT = 0x10 + VK_CONTROL = 0x11 + VK_MENU = 0x12 + VK_PAUSE = 0x13 + VK_CAPITAL = 0x14 + VK_KANA = 0x15 + VK_HANGEUL = 0x15 + VK_HANGUL = 0x15 + VK_IME_ON = 0x16 + VK_JUNJA = 0x17 + VK_FINAL = 0x18 + VK_HANJA = 0x19 + VK_KANJI = 0x19 + VK_IME_OFF = 0x1A + VK_ESCAPE = 0x1B + VK_CONVERT = 0x1C + VK_NONCONVERT = 0x1D + VK_ACCEPT = 0x1E + VK_MODECHANGE = 0x1F + VK_SPACE = 0x20 + VK_PRIOR = 0x21 + VK_NEXT = 0x22 + VK_END = 0x23 + VK_HOME = 0x24 + VK_LEFT = 0x25 + VK_UP = 0x26 + VK_RIGHT = 0x27 + VK_DOWN = 0x28 + VK_SELECT = 0x29 + VK_PRINT = 0x2A + VK_EXECUTE = 0x2B + VK_SNAPSHOT = 0x2C + VK_INSERT = 0x2D + VK_DELETE = 0x2E + VK_HELP = 0x2F + VK_LWIN = 0x5B + VK_RWIN = 0x5C + VK_APPS = 0x5D + VK_SLEEP = 0x5F + VK_NUMPAD0 = 0x60 + VK_NUMPAD1 = 0x61 + VK_NUMPAD2 = 0x62 + VK_NUMPAD3 = 0x63 + VK_NUMPAD4 = 0x64 + VK_NUMPAD5 = 0x65 + VK_NUMPAD6 = 0x66 + VK_NUMPAD7 = 0x67 + VK_NUMPAD8 = 0x68 + VK_NUMPAD9 = 0x69 + VK_MULTIPLY = 0x6A + VK_ADD = 0x6B + VK_SEPARATOR = 0x6C + VK_SUBTRACT = 0x6D + VK_DECIMAL = 0x6E + VK_DIVIDE = 0x6F + VK_F1 = 0x70 + VK_F2 = 0x71 + VK_F3 = 0x72 + VK_F4 = 0x73 + VK_F5 = 0x74 + VK_F6 = 0x75 + VK_F7 = 0x76 + VK_F8 = 0x77 + VK_F9 = 0x78 + VK_F10 = 0x79 + VK_F11 = 0x7A + VK_F12 = 0x7B + VK_F13 = 0x7C + VK_F14 = 0x7D + VK_F15 = 0x7E + VK_F16 = 0x7F + VK_F17 = 0x80 + VK_F18 = 0x81 + VK_F19 = 0x82 + VK_F20 = 0x83 + VK_F21 = 0x84 + VK_F22 = 0x85 + VK_F23 = 0x86 + VK_F24 = 0x87 + VK_NUMLOCK = 0x90 + VK_SCROLL = 0x91 + VK_OEM_NEC_EQUAL = 0x92 + VK_OEM_FJ_JISHO = 0x92 + VK_OEM_FJ_MASSHOU = 0x93 + VK_OEM_FJ_TOUROKU = 0x94 + VK_OEM_FJ_LOYA = 0x95 + VK_OEM_FJ_ROYA = 0x96 + VK_LSHIFT = 0xA0 + VK_RSHIFT = 0xA1 + VK_LCONTROL = 0xA2 + VK_RCONTROL = 0xA3 + VK_LMENU = 0xA4 + VK_RMENU = 0xA5 + VK_BROWSER_BACK = 0xA6 + VK_BROWSER_FORWARD = 0xA7 + VK_BROWSER_REFRESH = 0xA8 + VK_BROWSER_STOP = 0xA9 + VK_BROWSER_SEARCH = 0xAA + VK_BROWSER_FAVORITES = 0xAB + VK_BROWSER_HOME = 0xAC + VK_VOLUME_MUTE = 0xAD + VK_VOLUME_DOWN = 0xAE + VK_VOLUME_UP = 0xAF + VK_MEDIA_NEXT_TRACK = 0xB0 + VK_MEDIA_PREV_TRACK = 0xB1 + VK_MEDIA_STOP = 0xB2 + VK_MEDIA_PLAY_PAUSE = 0xB3 + VK_LAUNCH_MAIL = 0xB4 + VK_LAUNCH_MEDIA_SELECT = 0xB5 + VK_LAUNCH_APP1 = 0xB6 + VK_LAUNCH_APP2 = 0xB7 + VK_OEM_1 = 0xBA + VK_OEM_PLUS = 0xBB + VK_OEM_COMMA = 0xBC + VK_OEM_MINUS = 0xBD + VK_OEM_PERIOD = 0xBE + VK_OEM_2 = 0xBF + VK_OEM_3 = 0xC0 + VK_OEM_4 = 0xDB + VK_OEM_5 = 0xDC + VK_OEM_6 = 0xDD + VK_OEM_7 = 0xDE + VK_OEM_8 = 0xDF + VK_OEM_AX = 0xE1 + VK_OEM_102 = 0xE2 + VK_ICO_HELP = 0xE3 + VK_ICO_00 = 0xE4 + VK_PROCESSKEY = 0xE5 + VK_ICO_CLEAR = 0xE6 + VK_OEM_RESET = 0xE9 + VK_OEM_JUMP = 0xEA + VK_OEM_PA1 = 0xEB + VK_OEM_PA2 = 0xEC + VK_OEM_PA3 = 0xED + VK_OEM_WSCTRL = 0xEE + VK_OEM_CUSEL = 0xEF + VK_OEM_ATTN = 0xF0 + VK_OEM_FINISH = 0xF1 + VK_OEM_COPY = 0xF2 + VK_OEM_AUTO = 0xF3 + VK_OEM_ENLW = 0xF4 + VK_OEM_BACKTAB = 0xF5 + VK_ATTN = 0xF6 + VK_CRSEL = 0xF7 + VK_EXSEL = 0xF8 + VK_EREOF = 0xF9 + VK_PLAY = 0xFA + VK_ZOOM = 0xFB + VK_NONAME = 0xFC + VK_PA1 = 0xFD + VK_OEM_CLEAR = 0xFE +) + +// Mouse button constants. +// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str +const ( + FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001 + RIGHTMOST_BUTTON_PRESSED = 0x0002 + FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004 + FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008 + FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010 +) + +// Control key state constaints. +// https://docs.microsoft.com/en-us/windows/console/key-event-record-str +// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str +const ( + CAPSLOCK_ON = 0x0080 + ENHANCED_KEY = 0x0100 + LEFT_ALT_PRESSED = 0x0002 + LEFT_CTRL_PRESSED = 0x0008 + NUMLOCK_ON = 0x0020 + RIGHT_ALT_PRESSED = 0x0001 + RIGHT_CTRL_PRESSED = 0x0004 + SCROLLLOCK_ON = 0x0040 + SHIFT_PRESSED = 0x0010 +) + +// Mouse event record event flags. +// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str +const ( + MOUSE_MOVED = 0x0001 + DOUBLE_CLICK = 0x0002 + MOUSE_WHEELED = 0x0004 + MOUSE_HWHEELED = 0x0008 +) + +// Input Record Event Types +// https://learn.microsoft.com/en-us/windows/console/input-record-str +const ( + FOCUS_EVENT = 0x0010 + KEY_EVENT = 0x0001 + MENU_EVENT = 0x0008 + MOUSE_EVENT = 0x0002 + WINDOW_BUFFER_SIZE_EVENT = 0x0004 +) + +// The processor features to be tested for IsProcessorFeaturePresent, see +// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent +const ( + PF_ARM_64BIT_LOADSTORE_ATOMIC = 25 + PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE = 24 + PF_ARM_EXTERNAL_CACHE_AVAILABLE = 26 + PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE = 27 + PF_ARM_VFP_32_REGISTERS_AVAILABLE = 18 + PF_3DNOW_INSTRUCTIONS_AVAILABLE = 7 + PF_CHANNELS_ENABLED = 16 + PF_COMPARE_EXCHANGE_DOUBLE = 2 + PF_COMPARE_EXCHANGE128 = 14 + PF_COMPARE64_EXCHANGE128 = 15 + PF_FASTFAIL_AVAILABLE = 23 + PF_FLOATING_POINT_EMULATED = 1 + PF_FLOATING_POINT_PRECISION_ERRATA = 0 + PF_MMX_INSTRUCTIONS_AVAILABLE = 3 + PF_NX_ENABLED = 12 + PF_PAE_ENABLED = 9 + PF_RDTSC_INSTRUCTION_AVAILABLE = 8 + PF_RDWRFSGSBASE_AVAILABLE = 22 + PF_SECOND_LEVEL_ADDRESS_TRANSLATION = 20 + PF_SSE3_INSTRUCTIONS_AVAILABLE = 13 + PF_SSSE3_INSTRUCTIONS_AVAILABLE = 36 + PF_SSE4_1_INSTRUCTIONS_AVAILABLE = 37 + PF_SSE4_2_INSTRUCTIONS_AVAILABLE = 38 + PF_AVX_INSTRUCTIONS_AVAILABLE = 39 + PF_AVX2_INSTRUCTIONS_AVAILABLE = 40 + PF_AVX512F_INSTRUCTIONS_AVAILABLE = 41 + PF_VIRT_FIRMWARE_ENABLED = 21 + PF_XMMI_INSTRUCTIONS_AVAILABLE = 6 + PF_XMMI64_INSTRUCTIONS_AVAILABLE = 10 + PF_XSAVE_ENABLED = 17 + PF_ARM_V8_INSTRUCTIONS_AVAILABLE = 29 + PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE = 30 + PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE = 31 + PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE = 34 + PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE = 43 + PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE = 44 + PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE = 45 + PF_ARM_SVE_INSTRUCTIONS_AVAILABLE = 46 + PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE = 47 + PF_ARM_SVE2_1_INSTRUCTIONS_AVAILABLE = 48 + PF_ARM_SVE_AES_INSTRUCTIONS_AVAILABLE = 49 + PF_ARM_SVE_PMULL128_INSTRUCTIONS_AVAILABLE = 50 + PF_ARM_SVE_BITPERM_INSTRUCTIONS_AVAILABLE = 51 + PF_ARM_SVE_BF16_INSTRUCTIONS_AVAILABLE = 52 + PF_ARM_SVE_EBF16_INSTRUCTIONS_AVAILABLE = 53 + PF_ARM_SVE_B16B16_INSTRUCTIONS_AVAILABLE = 54 + PF_ARM_SVE_SHA3_INSTRUCTIONS_AVAILABLE = 55 + PF_ARM_SVE_SM4_INSTRUCTIONS_AVAILABLE = 56 + PF_ARM_SVE_I8MM_INSTRUCTIONS_AVAILABLE = 57 + PF_ARM_SVE_F32MM_INSTRUCTIONS_AVAILABLE = 58 + PF_ARM_SVE_F64MM_INSTRUCTIONS_AVAILABLE = 59 + PF_BMI2_INSTRUCTIONS_AVAILABLE = 60 + PF_MOVDIR64B_INSTRUCTION_AVAILABLE = 61 + PF_ARM_LSE2_AVAILABLE = 62 + PF_ARM_SHA3_INSTRUCTIONS_AVAILABLE = 64 + PF_ARM_SHA512_INSTRUCTIONS_AVAILABLE = 65 + PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE = 66 + PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE = 67 + PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE = 68 + PF_ARM_V86_EBF16_INSTRUCTIONS_AVAILABLE = 69 + PF_ARM_SME_INSTRUCTIONS_AVAILABLE = 70 + PF_ARM_SME2_INSTRUCTIONS_AVAILABLE = 71 + PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE = 72 + PF_ARM_SME2_2_INSTRUCTIONS_AVAILABLE = 73 + PF_ARM_SME_AES_INSTRUCTIONS_AVAILABLE = 74 + PF_ARM_SME_SBITPERM_INSTRUCTIONS_AVAILABLE = 75 + PF_ARM_SME_SF8MM4_INSTRUCTIONS_AVAILABLE = 76 + PF_ARM_SME_SF8MM8_INSTRUCTIONS_AVAILABLE = 77 + PF_ARM_SME_SF8DP2_INSTRUCTIONS_AVAILABLE = 78 + PF_ARM_SME_SF8DP4_INSTRUCTIONS_AVAILABLE = 79 + PF_ARM_SME_SF8FMA_INSTRUCTIONS_AVAILABLE = 80 + PF_ARM_SME_F8F32_INSTRUCTIONS_AVAILABLE = 81 + PF_ARM_SME_F8F16_INSTRUCTIONS_AVAILABLE = 82 + PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE = 83 + PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE = 84 + PF_ARM_SME_F64F64_INSTRUCTIONS_AVAILABLE = 85 + PF_ARM_SME_I16I64_INSTRUCTIONS_AVAILABLE = 86 + PF_ARM_SME_LUTv2_INSTRUCTIONS_AVAILABLE = 87 + PF_ARM_SME_FA64_INSTRUCTIONS_AVAILABLE = 88 + PF_UMONITOR_INSTRUCTION_AVAILABLE = 89 +) diff --git a/vendor/golang.org/x/sys/windows/types_windows_386.go b/vendor/golang.org/x/sys/windows/types_windows_386.go new file mode 100644 index 0000000..8bce3e2 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/types_windows_386.go @@ -0,0 +1,35 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +type WSAData struct { + Version uint16 + HighVersion uint16 + Description [WSADESCRIPTION_LEN + 1]byte + SystemStatus [WSASYS_STATUS_LEN + 1]byte + MaxSockets uint16 + MaxUdpDg uint16 + VendorInfo *byte +} + +type Servent struct { + Name *byte + Aliases **byte + Port uint16 + Proto *byte +} + +type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { + PerProcessUserTimeLimit int64 + PerJobUserTimeLimit int64 + LimitFlags uint32 + MinimumWorkingSetSize uintptr + MaximumWorkingSetSize uintptr + ActiveProcessLimit uint32 + Affinity uintptr + PriorityClass uint32 + SchedulingClass uint32 + _ uint32 // pad to 8 byte boundary +} diff --git a/vendor/golang.org/x/sys/windows/types_windows_amd64.go b/vendor/golang.org/x/sys/windows/types_windows_amd64.go new file mode 100644 index 0000000..fdddc0c --- /dev/null +++ b/vendor/golang.org/x/sys/windows/types_windows_amd64.go @@ -0,0 +1,34 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +type WSAData struct { + Version uint16 + HighVersion uint16 + MaxSockets uint16 + MaxUdpDg uint16 + VendorInfo *byte + Description [WSADESCRIPTION_LEN + 1]byte + SystemStatus [WSASYS_STATUS_LEN + 1]byte +} + +type Servent struct { + Name *byte + Aliases **byte + Proto *byte + Port uint16 +} + +type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { + PerProcessUserTimeLimit int64 + PerJobUserTimeLimit int64 + LimitFlags uint32 + MinimumWorkingSetSize uintptr + MaximumWorkingSetSize uintptr + ActiveProcessLimit uint32 + Affinity uintptr + PriorityClass uint32 + SchedulingClass uint32 +} diff --git a/vendor/golang.org/x/sys/windows/types_windows_arm64.go b/vendor/golang.org/x/sys/windows/types_windows_arm64.go new file mode 100644 index 0000000..fdddc0c --- /dev/null +++ b/vendor/golang.org/x/sys/windows/types_windows_arm64.go @@ -0,0 +1,34 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +type WSAData struct { + Version uint16 + HighVersion uint16 + MaxSockets uint16 + MaxUdpDg uint16 + VendorInfo *byte + Description [WSADESCRIPTION_LEN + 1]byte + SystemStatus [WSASYS_STATUS_LEN + 1]byte +} + +type Servent struct { + Name *byte + Aliases **byte + Proto *byte + Port uint16 +} + +type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { + PerProcessUserTimeLimit int64 + PerJobUserTimeLimit int64 + LimitFlags uint32 + MinimumWorkingSetSize uintptr + MaximumWorkingSetSize uintptr + ActiveProcessLimit uint32 + Affinity uintptr + PriorityClass uint32 + SchedulingClass uint32 +} diff --git a/vendor/golang.org/x/sys/windows/zerrors_windows.go b/vendor/golang.org/x/sys/windows/zerrors_windows.go new file mode 100644 index 0000000..0cf658f --- /dev/null +++ b/vendor/golang.org/x/sys/windows/zerrors_windows.go @@ -0,0 +1,9468 @@ +// Code generated by 'mkerrors.bash'; DO NOT EDIT. + +package windows + +import "syscall" + +const ( + FACILITY_NULL = 0 + FACILITY_RPC = 1 + FACILITY_DISPATCH = 2 + FACILITY_STORAGE = 3 + FACILITY_ITF = 4 + FACILITY_WIN32 = 7 + FACILITY_WINDOWS = 8 + FACILITY_SSPI = 9 + FACILITY_SECURITY = 9 + FACILITY_CONTROL = 10 + FACILITY_CERT = 11 + FACILITY_INTERNET = 12 + FACILITY_MEDIASERVER = 13 + FACILITY_MSMQ = 14 + FACILITY_SETUPAPI = 15 + FACILITY_SCARD = 16 + FACILITY_COMPLUS = 17 + FACILITY_AAF = 18 + FACILITY_URT = 19 + FACILITY_ACS = 20 + FACILITY_DPLAY = 21 + FACILITY_UMI = 22 + FACILITY_SXS = 23 + FACILITY_WINDOWS_CE = 24 + FACILITY_HTTP = 25 + FACILITY_USERMODE_COMMONLOG = 26 + FACILITY_WER = 27 + FACILITY_USERMODE_FILTER_MANAGER = 31 + FACILITY_BACKGROUNDCOPY = 32 + FACILITY_CONFIGURATION = 33 + FACILITY_WIA = 33 + FACILITY_STATE_MANAGEMENT = 34 + FACILITY_METADIRECTORY = 35 + FACILITY_WINDOWSUPDATE = 36 + FACILITY_DIRECTORYSERVICE = 37 + FACILITY_GRAPHICS = 38 + FACILITY_SHELL = 39 + FACILITY_NAP = 39 + FACILITY_TPM_SERVICES = 40 + FACILITY_TPM_SOFTWARE = 41 + FACILITY_UI = 42 + FACILITY_XAML = 43 + FACILITY_ACTION_QUEUE = 44 + FACILITY_PLA = 48 + FACILITY_WINDOWS_SETUP = 48 + FACILITY_FVE = 49 + FACILITY_FWP = 50 + FACILITY_WINRM = 51 + FACILITY_NDIS = 52 + FACILITY_USERMODE_HYPERVISOR = 53 + FACILITY_CMI = 54 + FACILITY_USERMODE_VIRTUALIZATION = 55 + FACILITY_USERMODE_VOLMGR = 56 + FACILITY_BCD = 57 + FACILITY_USERMODE_VHD = 58 + FACILITY_USERMODE_HNS = 59 + FACILITY_SDIAG = 60 + FACILITY_WEBSERVICES = 61 + FACILITY_WINPE = 61 + FACILITY_WPN = 62 + FACILITY_WINDOWS_STORE = 63 + FACILITY_INPUT = 64 + FACILITY_EAP = 66 + FACILITY_WINDOWS_DEFENDER = 80 + FACILITY_OPC = 81 + FACILITY_XPS = 82 + FACILITY_MBN = 84 + FACILITY_POWERSHELL = 84 + FACILITY_RAS = 83 + FACILITY_P2P_INT = 98 + FACILITY_P2P = 99 + FACILITY_DAF = 100 + FACILITY_BLUETOOTH_ATT = 101 + FACILITY_AUDIO = 102 + FACILITY_STATEREPOSITORY = 103 + FACILITY_VISUALCPP = 109 + FACILITY_SCRIPT = 112 + FACILITY_PARSE = 113 + FACILITY_BLB = 120 + FACILITY_BLB_CLI = 121 + FACILITY_WSBAPP = 122 + FACILITY_BLBUI = 128 + FACILITY_USN = 129 + FACILITY_USERMODE_VOLSNAP = 130 + FACILITY_TIERING = 131 + FACILITY_WSB_ONLINE = 133 + FACILITY_ONLINE_ID = 134 + FACILITY_DEVICE_UPDATE_AGENT = 135 + FACILITY_DRVSERVICING = 136 + FACILITY_DLS = 153 + FACILITY_DELIVERY_OPTIMIZATION = 208 + FACILITY_USERMODE_SPACES = 231 + FACILITY_USER_MODE_SECURITY_CORE = 232 + FACILITY_USERMODE_LICENSING = 234 + FACILITY_SOS = 160 + FACILITY_DEBUGGERS = 176 + FACILITY_SPP = 256 + FACILITY_RESTORE = 256 + FACILITY_DMSERVER = 256 + FACILITY_DEPLOYMENT_SERVICES_SERVER = 257 + FACILITY_DEPLOYMENT_SERVICES_IMAGING = 258 + FACILITY_DEPLOYMENT_SERVICES_MANAGEMENT = 259 + FACILITY_DEPLOYMENT_SERVICES_UTIL = 260 + FACILITY_DEPLOYMENT_SERVICES_BINLSVC = 261 + FACILITY_DEPLOYMENT_SERVICES_PXE = 263 + FACILITY_DEPLOYMENT_SERVICES_TFTP = 264 + FACILITY_DEPLOYMENT_SERVICES_TRANSPORT_MANAGEMENT = 272 + FACILITY_DEPLOYMENT_SERVICES_DRIVER_PROVISIONING = 278 + FACILITY_DEPLOYMENT_SERVICES_MULTICAST_SERVER = 289 + FACILITY_DEPLOYMENT_SERVICES_MULTICAST_CLIENT = 290 + FACILITY_DEPLOYMENT_SERVICES_CONTENT_PROVIDER = 293 + FACILITY_LINGUISTIC_SERVICES = 305 + FACILITY_AUDIOSTREAMING = 1094 + FACILITY_ACCELERATOR = 1536 + FACILITY_WMAAECMA = 1996 + FACILITY_DIRECTMUSIC = 2168 + FACILITY_DIRECT3D10 = 2169 + FACILITY_DXGI = 2170 + FACILITY_DXGI_DDI = 2171 + FACILITY_DIRECT3D11 = 2172 + FACILITY_DIRECT3D11_DEBUG = 2173 + FACILITY_DIRECT3D12 = 2174 + FACILITY_DIRECT3D12_DEBUG = 2175 + FACILITY_LEAP = 2184 + FACILITY_AUDCLNT = 2185 + FACILITY_WINCODEC_DWRITE_DWM = 2200 + FACILITY_WINML = 2192 + FACILITY_DIRECT2D = 2201 + FACILITY_DEFRAG = 2304 + FACILITY_USERMODE_SDBUS = 2305 + FACILITY_JSCRIPT = 2306 + FACILITY_PIDGENX = 2561 + FACILITY_EAS = 85 + FACILITY_WEB = 885 + FACILITY_WEB_SOCKET = 886 + FACILITY_MOBILE = 1793 + FACILITY_SQLITE = 1967 + FACILITY_UTC = 1989 + FACILITY_WEP = 2049 + FACILITY_SYNCENGINE = 2050 + FACILITY_XBOX = 2339 + FACILITY_GAME = 2340 + FACILITY_PIX = 2748 + ERROR_SUCCESS syscall.Errno = 0 + NO_ERROR = 0 + SEC_E_OK Handle = 0x00000000 + ERROR_INVALID_FUNCTION syscall.Errno = 1 + ERROR_FILE_NOT_FOUND syscall.Errno = 2 + ERROR_PATH_NOT_FOUND syscall.Errno = 3 + ERROR_TOO_MANY_OPEN_FILES syscall.Errno = 4 + ERROR_ACCESS_DENIED syscall.Errno = 5 + ERROR_INVALID_HANDLE syscall.Errno = 6 + ERROR_ARENA_TRASHED syscall.Errno = 7 + ERROR_NOT_ENOUGH_MEMORY syscall.Errno = 8 + ERROR_INVALID_BLOCK syscall.Errno = 9 + ERROR_BAD_ENVIRONMENT syscall.Errno = 10 + ERROR_BAD_FORMAT syscall.Errno = 11 + ERROR_INVALID_ACCESS syscall.Errno = 12 + ERROR_INVALID_DATA syscall.Errno = 13 + ERROR_OUTOFMEMORY syscall.Errno = 14 + ERROR_INVALID_DRIVE syscall.Errno = 15 + ERROR_CURRENT_DIRECTORY syscall.Errno = 16 + ERROR_NOT_SAME_DEVICE syscall.Errno = 17 + ERROR_NO_MORE_FILES syscall.Errno = 18 + ERROR_WRITE_PROTECT syscall.Errno = 19 + ERROR_BAD_UNIT syscall.Errno = 20 + ERROR_NOT_READY syscall.Errno = 21 + ERROR_BAD_COMMAND syscall.Errno = 22 + ERROR_CRC syscall.Errno = 23 + ERROR_BAD_LENGTH syscall.Errno = 24 + ERROR_SEEK syscall.Errno = 25 + ERROR_NOT_DOS_DISK syscall.Errno = 26 + ERROR_SECTOR_NOT_FOUND syscall.Errno = 27 + ERROR_OUT_OF_PAPER syscall.Errno = 28 + ERROR_WRITE_FAULT syscall.Errno = 29 + ERROR_READ_FAULT syscall.Errno = 30 + ERROR_GEN_FAILURE syscall.Errno = 31 + ERROR_SHARING_VIOLATION syscall.Errno = 32 + ERROR_LOCK_VIOLATION syscall.Errno = 33 + ERROR_WRONG_DISK syscall.Errno = 34 + ERROR_SHARING_BUFFER_EXCEEDED syscall.Errno = 36 + ERROR_HANDLE_EOF syscall.Errno = 38 + ERROR_HANDLE_DISK_FULL syscall.Errno = 39 + ERROR_NOT_SUPPORTED syscall.Errno = 50 + ERROR_REM_NOT_LIST syscall.Errno = 51 + ERROR_DUP_NAME syscall.Errno = 52 + ERROR_BAD_NETPATH syscall.Errno = 53 + ERROR_NETWORK_BUSY syscall.Errno = 54 + ERROR_DEV_NOT_EXIST syscall.Errno = 55 + ERROR_TOO_MANY_CMDS syscall.Errno = 56 + ERROR_ADAP_HDW_ERR syscall.Errno = 57 + ERROR_BAD_NET_RESP syscall.Errno = 58 + ERROR_UNEXP_NET_ERR syscall.Errno = 59 + ERROR_BAD_REM_ADAP syscall.Errno = 60 + ERROR_PRINTQ_FULL syscall.Errno = 61 + ERROR_NO_SPOOL_SPACE syscall.Errno = 62 + ERROR_PRINT_CANCELLED syscall.Errno = 63 + ERROR_NETNAME_DELETED syscall.Errno = 64 + ERROR_NETWORK_ACCESS_DENIED syscall.Errno = 65 + ERROR_BAD_DEV_TYPE syscall.Errno = 66 + ERROR_BAD_NET_NAME syscall.Errno = 67 + ERROR_TOO_MANY_NAMES syscall.Errno = 68 + ERROR_TOO_MANY_SESS syscall.Errno = 69 + ERROR_SHARING_PAUSED syscall.Errno = 70 + ERROR_REQ_NOT_ACCEP syscall.Errno = 71 + ERROR_REDIR_PAUSED syscall.Errno = 72 + ERROR_FILE_EXISTS syscall.Errno = 80 + ERROR_CANNOT_MAKE syscall.Errno = 82 + ERROR_FAIL_I24 syscall.Errno = 83 + ERROR_OUT_OF_STRUCTURES syscall.Errno = 84 + ERROR_ALREADY_ASSIGNED syscall.Errno = 85 + ERROR_INVALID_PASSWORD syscall.Errno = 86 + ERROR_INVALID_PARAMETER syscall.Errno = 87 + ERROR_NET_WRITE_FAULT syscall.Errno = 88 + ERROR_NO_PROC_SLOTS syscall.Errno = 89 + ERROR_TOO_MANY_SEMAPHORES syscall.Errno = 100 + ERROR_EXCL_SEM_ALREADY_OWNED syscall.Errno = 101 + ERROR_SEM_IS_SET syscall.Errno = 102 + ERROR_TOO_MANY_SEM_REQUESTS syscall.Errno = 103 + ERROR_INVALID_AT_INTERRUPT_TIME syscall.Errno = 104 + ERROR_SEM_OWNER_DIED syscall.Errno = 105 + ERROR_SEM_USER_LIMIT syscall.Errno = 106 + ERROR_DISK_CHANGE syscall.Errno = 107 + ERROR_DRIVE_LOCKED syscall.Errno = 108 + ERROR_BROKEN_PIPE syscall.Errno = 109 + ERROR_OPEN_FAILED syscall.Errno = 110 + ERROR_BUFFER_OVERFLOW syscall.Errno = 111 + ERROR_DISK_FULL syscall.Errno = 112 + ERROR_NO_MORE_SEARCH_HANDLES syscall.Errno = 113 + ERROR_INVALID_TARGET_HANDLE syscall.Errno = 114 + ERROR_INVALID_CATEGORY syscall.Errno = 117 + ERROR_INVALID_VERIFY_SWITCH syscall.Errno = 118 + ERROR_BAD_DRIVER_LEVEL syscall.Errno = 119 + ERROR_CALL_NOT_IMPLEMENTED syscall.Errno = 120 + ERROR_SEM_TIMEOUT syscall.Errno = 121 + ERROR_INSUFFICIENT_BUFFER syscall.Errno = 122 + ERROR_INVALID_NAME syscall.Errno = 123 + ERROR_INVALID_LEVEL syscall.Errno = 124 + ERROR_NO_VOLUME_LABEL syscall.Errno = 125 + ERROR_MOD_NOT_FOUND syscall.Errno = 126 + ERROR_PROC_NOT_FOUND syscall.Errno = 127 + ERROR_WAIT_NO_CHILDREN syscall.Errno = 128 + ERROR_CHILD_NOT_COMPLETE syscall.Errno = 129 + ERROR_DIRECT_ACCESS_HANDLE syscall.Errno = 130 + ERROR_NEGATIVE_SEEK syscall.Errno = 131 + ERROR_SEEK_ON_DEVICE syscall.Errno = 132 + ERROR_IS_JOIN_TARGET syscall.Errno = 133 + ERROR_IS_JOINED syscall.Errno = 134 + ERROR_IS_SUBSTED syscall.Errno = 135 + ERROR_NOT_JOINED syscall.Errno = 136 + ERROR_NOT_SUBSTED syscall.Errno = 137 + ERROR_JOIN_TO_JOIN syscall.Errno = 138 + ERROR_SUBST_TO_SUBST syscall.Errno = 139 + ERROR_JOIN_TO_SUBST syscall.Errno = 140 + ERROR_SUBST_TO_JOIN syscall.Errno = 141 + ERROR_BUSY_DRIVE syscall.Errno = 142 + ERROR_SAME_DRIVE syscall.Errno = 143 + ERROR_DIR_NOT_ROOT syscall.Errno = 144 + ERROR_DIR_NOT_EMPTY syscall.Errno = 145 + ERROR_IS_SUBST_PATH syscall.Errno = 146 + ERROR_IS_JOIN_PATH syscall.Errno = 147 + ERROR_PATH_BUSY syscall.Errno = 148 + ERROR_IS_SUBST_TARGET syscall.Errno = 149 + ERROR_SYSTEM_TRACE syscall.Errno = 150 + ERROR_INVALID_EVENT_COUNT syscall.Errno = 151 + ERROR_TOO_MANY_MUXWAITERS syscall.Errno = 152 + ERROR_INVALID_LIST_FORMAT syscall.Errno = 153 + ERROR_LABEL_TOO_LONG syscall.Errno = 154 + ERROR_TOO_MANY_TCBS syscall.Errno = 155 + ERROR_SIGNAL_REFUSED syscall.Errno = 156 + ERROR_DISCARDED syscall.Errno = 157 + ERROR_NOT_LOCKED syscall.Errno = 158 + ERROR_BAD_THREADID_ADDR syscall.Errno = 159 + ERROR_BAD_ARGUMENTS syscall.Errno = 160 + ERROR_BAD_PATHNAME syscall.Errno = 161 + ERROR_SIGNAL_PENDING syscall.Errno = 162 + ERROR_MAX_THRDS_REACHED syscall.Errno = 164 + ERROR_LOCK_FAILED syscall.Errno = 167 + ERROR_BUSY syscall.Errno = 170 + ERROR_DEVICE_SUPPORT_IN_PROGRESS syscall.Errno = 171 + ERROR_CANCEL_VIOLATION syscall.Errno = 173 + ERROR_ATOMIC_LOCKS_NOT_SUPPORTED syscall.Errno = 174 + ERROR_INVALID_SEGMENT_NUMBER syscall.Errno = 180 + ERROR_INVALID_ORDINAL syscall.Errno = 182 + ERROR_ALREADY_EXISTS syscall.Errno = 183 + ERROR_INVALID_FLAG_NUMBER syscall.Errno = 186 + ERROR_SEM_NOT_FOUND syscall.Errno = 187 + ERROR_INVALID_STARTING_CODESEG syscall.Errno = 188 + ERROR_INVALID_STACKSEG syscall.Errno = 189 + ERROR_INVALID_MODULETYPE syscall.Errno = 190 + ERROR_INVALID_EXE_SIGNATURE syscall.Errno = 191 + ERROR_EXE_MARKED_INVALID syscall.Errno = 192 + ERROR_BAD_EXE_FORMAT syscall.Errno = 193 + ERROR_ITERATED_DATA_EXCEEDS_64k syscall.Errno = 194 + ERROR_INVALID_MINALLOCSIZE syscall.Errno = 195 + ERROR_DYNLINK_FROM_INVALID_RING syscall.Errno = 196 + ERROR_IOPL_NOT_ENABLED syscall.Errno = 197 + ERROR_INVALID_SEGDPL syscall.Errno = 198 + ERROR_AUTODATASEG_EXCEEDS_64k syscall.Errno = 199 + ERROR_RING2SEG_MUST_BE_MOVABLE syscall.Errno = 200 + ERROR_RELOC_CHAIN_XEEDS_SEGLIM syscall.Errno = 201 + ERROR_INFLOOP_IN_RELOC_CHAIN syscall.Errno = 202 + ERROR_ENVVAR_NOT_FOUND syscall.Errno = 203 + ERROR_NO_SIGNAL_SENT syscall.Errno = 205 + ERROR_FILENAME_EXCED_RANGE syscall.Errno = 206 + ERROR_RING2_STACK_IN_USE syscall.Errno = 207 + ERROR_META_EXPANSION_TOO_LONG syscall.Errno = 208 + ERROR_INVALID_SIGNAL_NUMBER syscall.Errno = 209 + ERROR_THREAD_1_INACTIVE syscall.Errno = 210 + ERROR_LOCKED syscall.Errno = 212 + ERROR_TOO_MANY_MODULES syscall.Errno = 214 + ERROR_NESTING_NOT_ALLOWED syscall.Errno = 215 + ERROR_EXE_MACHINE_TYPE_MISMATCH syscall.Errno = 216 + ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY syscall.Errno = 217 + ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY syscall.Errno = 218 + ERROR_FILE_CHECKED_OUT syscall.Errno = 220 + ERROR_CHECKOUT_REQUIRED syscall.Errno = 221 + ERROR_BAD_FILE_TYPE syscall.Errno = 222 + ERROR_FILE_TOO_LARGE syscall.Errno = 223 + ERROR_FORMS_AUTH_REQUIRED syscall.Errno = 224 + ERROR_VIRUS_INFECTED syscall.Errno = 225 + ERROR_VIRUS_DELETED syscall.Errno = 226 + ERROR_PIPE_LOCAL syscall.Errno = 229 + ERROR_BAD_PIPE syscall.Errno = 230 + ERROR_PIPE_BUSY syscall.Errno = 231 + ERROR_NO_DATA syscall.Errno = 232 + ERROR_PIPE_NOT_CONNECTED syscall.Errno = 233 + ERROR_MORE_DATA syscall.Errno = 234 + ERROR_NO_WORK_DONE syscall.Errno = 235 + ERROR_VC_DISCONNECTED syscall.Errno = 240 + ERROR_INVALID_EA_NAME syscall.Errno = 254 + ERROR_EA_LIST_INCONSISTENT syscall.Errno = 255 + WAIT_TIMEOUT syscall.Errno = 258 + ERROR_NO_MORE_ITEMS syscall.Errno = 259 + ERROR_CANNOT_COPY syscall.Errno = 266 + ERROR_DIRECTORY syscall.Errno = 267 + ERROR_EAS_DIDNT_FIT syscall.Errno = 275 + ERROR_EA_FILE_CORRUPT syscall.Errno = 276 + ERROR_EA_TABLE_FULL syscall.Errno = 277 + ERROR_INVALID_EA_HANDLE syscall.Errno = 278 + ERROR_EAS_NOT_SUPPORTED syscall.Errno = 282 + ERROR_NOT_OWNER syscall.Errno = 288 + ERROR_TOO_MANY_POSTS syscall.Errno = 298 + ERROR_PARTIAL_COPY syscall.Errno = 299 + ERROR_OPLOCK_NOT_GRANTED syscall.Errno = 300 + ERROR_INVALID_OPLOCK_PROTOCOL syscall.Errno = 301 + ERROR_DISK_TOO_FRAGMENTED syscall.Errno = 302 + ERROR_DELETE_PENDING syscall.Errno = 303 + ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING syscall.Errno = 304 + ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME syscall.Errno = 305 + ERROR_SECURITY_STREAM_IS_INCONSISTENT syscall.Errno = 306 + ERROR_INVALID_LOCK_RANGE syscall.Errno = 307 + ERROR_IMAGE_SUBSYSTEM_NOT_PRESENT syscall.Errno = 308 + ERROR_NOTIFICATION_GUID_ALREADY_DEFINED syscall.Errno = 309 + ERROR_INVALID_EXCEPTION_HANDLER syscall.Errno = 310 + ERROR_DUPLICATE_PRIVILEGES syscall.Errno = 311 + ERROR_NO_RANGES_PROCESSED syscall.Errno = 312 + ERROR_NOT_ALLOWED_ON_SYSTEM_FILE syscall.Errno = 313 + ERROR_DISK_RESOURCES_EXHAUSTED syscall.Errno = 314 + ERROR_INVALID_TOKEN syscall.Errno = 315 + ERROR_DEVICE_FEATURE_NOT_SUPPORTED syscall.Errno = 316 + ERROR_MR_MID_NOT_FOUND syscall.Errno = 317 + ERROR_SCOPE_NOT_FOUND syscall.Errno = 318 + ERROR_UNDEFINED_SCOPE syscall.Errno = 319 + ERROR_INVALID_CAP syscall.Errno = 320 + ERROR_DEVICE_UNREACHABLE syscall.Errno = 321 + ERROR_DEVICE_NO_RESOURCES syscall.Errno = 322 + ERROR_DATA_CHECKSUM_ERROR syscall.Errno = 323 + ERROR_INTERMIXED_KERNEL_EA_OPERATION syscall.Errno = 324 + ERROR_FILE_LEVEL_TRIM_NOT_SUPPORTED syscall.Errno = 326 + ERROR_OFFSET_ALIGNMENT_VIOLATION syscall.Errno = 327 + ERROR_INVALID_FIELD_IN_PARAMETER_LIST syscall.Errno = 328 + ERROR_OPERATION_IN_PROGRESS syscall.Errno = 329 + ERROR_BAD_DEVICE_PATH syscall.Errno = 330 + ERROR_TOO_MANY_DESCRIPTORS syscall.Errno = 331 + ERROR_SCRUB_DATA_DISABLED syscall.Errno = 332 + ERROR_NOT_REDUNDANT_STORAGE syscall.Errno = 333 + ERROR_RESIDENT_FILE_NOT_SUPPORTED syscall.Errno = 334 + ERROR_COMPRESSED_FILE_NOT_SUPPORTED syscall.Errno = 335 + ERROR_DIRECTORY_NOT_SUPPORTED syscall.Errno = 336 + ERROR_NOT_READ_FROM_COPY syscall.Errno = 337 + ERROR_FT_WRITE_FAILURE syscall.Errno = 338 + ERROR_FT_DI_SCAN_REQUIRED syscall.Errno = 339 + ERROR_INVALID_KERNEL_INFO_VERSION syscall.Errno = 340 + ERROR_INVALID_PEP_INFO_VERSION syscall.Errno = 341 + ERROR_OBJECT_NOT_EXTERNALLY_BACKED syscall.Errno = 342 + ERROR_EXTERNAL_BACKING_PROVIDER_UNKNOWN syscall.Errno = 343 + ERROR_COMPRESSION_NOT_BENEFICIAL syscall.Errno = 344 + ERROR_STORAGE_TOPOLOGY_ID_MISMATCH syscall.Errno = 345 + ERROR_BLOCKED_BY_PARENTAL_CONTROLS syscall.Errno = 346 + ERROR_BLOCK_TOO_MANY_REFERENCES syscall.Errno = 347 + ERROR_MARKED_TO_DISALLOW_WRITES syscall.Errno = 348 + ERROR_ENCLAVE_FAILURE syscall.Errno = 349 + ERROR_FAIL_NOACTION_REBOOT syscall.Errno = 350 + ERROR_FAIL_SHUTDOWN syscall.Errno = 351 + ERROR_FAIL_RESTART syscall.Errno = 352 + ERROR_MAX_SESSIONS_REACHED syscall.Errno = 353 + ERROR_NETWORK_ACCESS_DENIED_EDP syscall.Errno = 354 + ERROR_DEVICE_HINT_NAME_BUFFER_TOO_SMALL syscall.Errno = 355 + ERROR_EDP_POLICY_DENIES_OPERATION syscall.Errno = 356 + ERROR_EDP_DPL_POLICY_CANT_BE_SATISFIED syscall.Errno = 357 + ERROR_CLOUD_FILE_SYNC_ROOT_METADATA_CORRUPT syscall.Errno = 358 + ERROR_DEVICE_IN_MAINTENANCE syscall.Errno = 359 + ERROR_NOT_SUPPORTED_ON_DAX syscall.Errno = 360 + ERROR_DAX_MAPPING_EXISTS syscall.Errno = 361 + ERROR_CLOUD_FILE_PROVIDER_NOT_RUNNING syscall.Errno = 362 + ERROR_CLOUD_FILE_METADATA_CORRUPT syscall.Errno = 363 + ERROR_CLOUD_FILE_METADATA_TOO_LARGE syscall.Errno = 364 + ERROR_CLOUD_FILE_PROPERTY_BLOB_TOO_LARGE syscall.Errno = 365 + ERROR_CLOUD_FILE_PROPERTY_BLOB_CHECKSUM_MISMATCH syscall.Errno = 366 + ERROR_CHILD_PROCESS_BLOCKED syscall.Errno = 367 + ERROR_STORAGE_LOST_DATA_PERSISTENCE syscall.Errno = 368 + ERROR_FILE_SYSTEM_VIRTUALIZATION_UNAVAILABLE syscall.Errno = 369 + ERROR_FILE_SYSTEM_VIRTUALIZATION_METADATA_CORRUPT syscall.Errno = 370 + ERROR_FILE_SYSTEM_VIRTUALIZATION_BUSY syscall.Errno = 371 + ERROR_FILE_SYSTEM_VIRTUALIZATION_PROVIDER_UNKNOWN syscall.Errno = 372 + ERROR_GDI_HANDLE_LEAK syscall.Errno = 373 + ERROR_CLOUD_FILE_TOO_MANY_PROPERTY_BLOBS syscall.Errno = 374 + ERROR_CLOUD_FILE_PROPERTY_VERSION_NOT_SUPPORTED syscall.Errno = 375 + ERROR_NOT_A_CLOUD_FILE syscall.Errno = 376 + ERROR_CLOUD_FILE_NOT_IN_SYNC syscall.Errno = 377 + ERROR_CLOUD_FILE_ALREADY_CONNECTED syscall.Errno = 378 + ERROR_CLOUD_FILE_NOT_SUPPORTED syscall.Errno = 379 + ERROR_CLOUD_FILE_INVALID_REQUEST syscall.Errno = 380 + ERROR_CLOUD_FILE_READ_ONLY_VOLUME syscall.Errno = 381 + ERROR_CLOUD_FILE_CONNECTED_PROVIDER_ONLY syscall.Errno = 382 + ERROR_CLOUD_FILE_VALIDATION_FAILED syscall.Errno = 383 + ERROR_SMB1_NOT_AVAILABLE syscall.Errno = 384 + ERROR_FILE_SYSTEM_VIRTUALIZATION_INVALID_OPERATION syscall.Errno = 385 + ERROR_CLOUD_FILE_AUTHENTICATION_FAILED syscall.Errno = 386 + ERROR_CLOUD_FILE_INSUFFICIENT_RESOURCES syscall.Errno = 387 + ERROR_CLOUD_FILE_NETWORK_UNAVAILABLE syscall.Errno = 388 + ERROR_CLOUD_FILE_UNSUCCESSFUL syscall.Errno = 389 + ERROR_CLOUD_FILE_NOT_UNDER_SYNC_ROOT syscall.Errno = 390 + ERROR_CLOUD_FILE_IN_USE syscall.Errno = 391 + ERROR_CLOUD_FILE_PINNED syscall.Errno = 392 + ERROR_CLOUD_FILE_REQUEST_ABORTED syscall.Errno = 393 + ERROR_CLOUD_FILE_PROPERTY_CORRUPT syscall.Errno = 394 + ERROR_CLOUD_FILE_ACCESS_DENIED syscall.Errno = 395 + ERROR_CLOUD_FILE_INCOMPATIBLE_HARDLINKS syscall.Errno = 396 + ERROR_CLOUD_FILE_PROPERTY_LOCK_CONFLICT syscall.Errno = 397 + ERROR_CLOUD_FILE_REQUEST_CANCELED syscall.Errno = 398 + ERROR_EXTERNAL_SYSKEY_NOT_SUPPORTED syscall.Errno = 399 + ERROR_THREAD_MODE_ALREADY_BACKGROUND syscall.Errno = 400 + ERROR_THREAD_MODE_NOT_BACKGROUND syscall.Errno = 401 + ERROR_PROCESS_MODE_ALREADY_BACKGROUND syscall.Errno = 402 + ERROR_PROCESS_MODE_NOT_BACKGROUND syscall.Errno = 403 + ERROR_CLOUD_FILE_PROVIDER_TERMINATED syscall.Errno = 404 + ERROR_NOT_A_CLOUD_SYNC_ROOT syscall.Errno = 405 + ERROR_FILE_PROTECTED_UNDER_DPL syscall.Errno = 406 + ERROR_VOLUME_NOT_CLUSTER_ALIGNED syscall.Errno = 407 + ERROR_NO_PHYSICALLY_ALIGNED_FREE_SPACE_FOUND syscall.Errno = 408 + ERROR_APPX_FILE_NOT_ENCRYPTED syscall.Errno = 409 + ERROR_RWRAW_ENCRYPTED_FILE_NOT_ENCRYPTED syscall.Errno = 410 + ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILEOFFSET syscall.Errno = 411 + ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILERANGE syscall.Errno = 412 + ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_PARAMETER syscall.Errno = 413 + ERROR_LINUX_SUBSYSTEM_NOT_PRESENT syscall.Errno = 414 + ERROR_FT_READ_FAILURE syscall.Errno = 415 + ERROR_STORAGE_RESERVE_ID_INVALID syscall.Errno = 416 + ERROR_STORAGE_RESERVE_DOES_NOT_EXIST syscall.Errno = 417 + ERROR_STORAGE_RESERVE_ALREADY_EXISTS syscall.Errno = 418 + ERROR_STORAGE_RESERVE_NOT_EMPTY syscall.Errno = 419 + ERROR_NOT_A_DAX_VOLUME syscall.Errno = 420 + ERROR_NOT_DAX_MAPPABLE syscall.Errno = 421 + ERROR_TIME_SENSITIVE_THREAD syscall.Errno = 422 + ERROR_DPL_NOT_SUPPORTED_FOR_USER syscall.Errno = 423 + ERROR_CASE_DIFFERING_NAMES_IN_DIR syscall.Errno = 424 + ERROR_FILE_NOT_SUPPORTED syscall.Errno = 425 + ERROR_CLOUD_FILE_REQUEST_TIMEOUT syscall.Errno = 426 + ERROR_NO_TASK_QUEUE syscall.Errno = 427 + ERROR_SRC_SRV_DLL_LOAD_FAILED syscall.Errno = 428 + ERROR_NOT_SUPPORTED_WITH_BTT syscall.Errno = 429 + ERROR_ENCRYPTION_DISABLED syscall.Errno = 430 + ERROR_ENCRYPTING_METADATA_DISALLOWED syscall.Errno = 431 + ERROR_CANT_CLEAR_ENCRYPTION_FLAG syscall.Errno = 432 + ERROR_NO_SUCH_DEVICE syscall.Errno = 433 + ERROR_CAPAUTHZ_NOT_DEVUNLOCKED syscall.Errno = 450 + ERROR_CAPAUTHZ_CHANGE_TYPE syscall.Errno = 451 + ERROR_CAPAUTHZ_NOT_PROVISIONED syscall.Errno = 452 + ERROR_CAPAUTHZ_NOT_AUTHORIZED syscall.Errno = 453 + ERROR_CAPAUTHZ_NO_POLICY syscall.Errno = 454 + ERROR_CAPAUTHZ_DB_CORRUPTED syscall.Errno = 455 + ERROR_CAPAUTHZ_SCCD_INVALID_CATALOG syscall.Errno = 456 + ERROR_CAPAUTHZ_SCCD_NO_AUTH_ENTITY syscall.Errno = 457 + ERROR_CAPAUTHZ_SCCD_PARSE_ERROR syscall.Errno = 458 + ERROR_CAPAUTHZ_SCCD_DEV_MODE_REQUIRED syscall.Errno = 459 + ERROR_CAPAUTHZ_SCCD_NO_CAPABILITY_MATCH syscall.Errno = 460 + ERROR_PNP_QUERY_REMOVE_DEVICE_TIMEOUT syscall.Errno = 480 + ERROR_PNP_QUERY_REMOVE_RELATED_DEVICE_TIMEOUT syscall.Errno = 481 + ERROR_PNP_QUERY_REMOVE_UNRELATED_DEVICE_TIMEOUT syscall.Errno = 482 + ERROR_DEVICE_HARDWARE_ERROR syscall.Errno = 483 + ERROR_INVALID_ADDRESS syscall.Errno = 487 + ERROR_VRF_CFG_ENABLED syscall.Errno = 1183 + ERROR_PARTITION_TERMINATING syscall.Errno = 1184 + ERROR_USER_PROFILE_LOAD syscall.Errno = 500 + ERROR_ARITHMETIC_OVERFLOW syscall.Errno = 534 + ERROR_PIPE_CONNECTED syscall.Errno = 535 + ERROR_PIPE_LISTENING syscall.Errno = 536 + ERROR_VERIFIER_STOP syscall.Errno = 537 + ERROR_ABIOS_ERROR syscall.Errno = 538 + ERROR_WX86_WARNING syscall.Errno = 539 + ERROR_WX86_ERROR syscall.Errno = 540 + ERROR_TIMER_NOT_CANCELED syscall.Errno = 541 + ERROR_UNWIND syscall.Errno = 542 + ERROR_BAD_STACK syscall.Errno = 543 + ERROR_INVALID_UNWIND_TARGET syscall.Errno = 544 + ERROR_INVALID_PORT_ATTRIBUTES syscall.Errno = 545 + ERROR_PORT_MESSAGE_TOO_LONG syscall.Errno = 546 + ERROR_INVALID_QUOTA_LOWER syscall.Errno = 547 + ERROR_DEVICE_ALREADY_ATTACHED syscall.Errno = 548 + ERROR_INSTRUCTION_MISALIGNMENT syscall.Errno = 549 + ERROR_PROFILING_NOT_STARTED syscall.Errno = 550 + ERROR_PROFILING_NOT_STOPPED syscall.Errno = 551 + ERROR_COULD_NOT_INTERPRET syscall.Errno = 552 + ERROR_PROFILING_AT_LIMIT syscall.Errno = 553 + ERROR_CANT_WAIT syscall.Errno = 554 + ERROR_CANT_TERMINATE_SELF syscall.Errno = 555 + ERROR_UNEXPECTED_MM_CREATE_ERR syscall.Errno = 556 + ERROR_UNEXPECTED_MM_MAP_ERROR syscall.Errno = 557 + ERROR_UNEXPECTED_MM_EXTEND_ERR syscall.Errno = 558 + ERROR_BAD_FUNCTION_TABLE syscall.Errno = 559 + ERROR_NO_GUID_TRANSLATION syscall.Errno = 560 + ERROR_INVALID_LDT_SIZE syscall.Errno = 561 + ERROR_INVALID_LDT_OFFSET syscall.Errno = 563 + ERROR_INVALID_LDT_DESCRIPTOR syscall.Errno = 564 + ERROR_TOO_MANY_THREADS syscall.Errno = 565 + ERROR_THREAD_NOT_IN_PROCESS syscall.Errno = 566 + ERROR_PAGEFILE_QUOTA_EXCEEDED syscall.Errno = 567 + ERROR_LOGON_SERVER_CONFLICT syscall.Errno = 568 + ERROR_SYNCHRONIZATION_REQUIRED syscall.Errno = 569 + ERROR_NET_OPEN_FAILED syscall.Errno = 570 + ERROR_IO_PRIVILEGE_FAILED syscall.Errno = 571 + ERROR_CONTROL_C_EXIT syscall.Errno = 572 + ERROR_MISSING_SYSTEMFILE syscall.Errno = 573 + ERROR_UNHANDLED_EXCEPTION syscall.Errno = 574 + ERROR_APP_INIT_FAILURE syscall.Errno = 575 + ERROR_PAGEFILE_CREATE_FAILED syscall.Errno = 576 + ERROR_INVALID_IMAGE_HASH syscall.Errno = 577 + ERROR_NO_PAGEFILE syscall.Errno = 578 + ERROR_ILLEGAL_FLOAT_CONTEXT syscall.Errno = 579 + ERROR_NO_EVENT_PAIR syscall.Errno = 580 + ERROR_DOMAIN_CTRLR_CONFIG_ERROR syscall.Errno = 581 + ERROR_ILLEGAL_CHARACTER syscall.Errno = 582 + ERROR_UNDEFINED_CHARACTER syscall.Errno = 583 + ERROR_FLOPPY_VOLUME syscall.Errno = 584 + ERROR_BIOS_FAILED_TO_CONNECT_INTERRUPT syscall.Errno = 585 + ERROR_BACKUP_CONTROLLER syscall.Errno = 586 + ERROR_MUTANT_LIMIT_EXCEEDED syscall.Errno = 587 + ERROR_FS_DRIVER_REQUIRED syscall.Errno = 588 + ERROR_CANNOT_LOAD_REGISTRY_FILE syscall.Errno = 589 + ERROR_DEBUG_ATTACH_FAILED syscall.Errno = 590 + ERROR_SYSTEM_PROCESS_TERMINATED syscall.Errno = 591 + ERROR_DATA_NOT_ACCEPTED syscall.Errno = 592 + ERROR_VDM_HARD_ERROR syscall.Errno = 593 + ERROR_DRIVER_CANCEL_TIMEOUT syscall.Errno = 594 + ERROR_REPLY_MESSAGE_MISMATCH syscall.Errno = 595 + ERROR_LOST_WRITEBEHIND_DATA syscall.Errno = 596 + ERROR_CLIENT_SERVER_PARAMETERS_INVALID syscall.Errno = 597 + ERROR_NOT_TINY_STREAM syscall.Errno = 598 + ERROR_STACK_OVERFLOW_READ syscall.Errno = 599 + ERROR_CONVERT_TO_LARGE syscall.Errno = 600 + ERROR_FOUND_OUT_OF_SCOPE syscall.Errno = 601 + ERROR_ALLOCATE_BUCKET syscall.Errno = 602 + ERROR_MARSHALL_OVERFLOW syscall.Errno = 603 + ERROR_INVALID_VARIANT syscall.Errno = 604 + ERROR_BAD_COMPRESSION_BUFFER syscall.Errno = 605 + ERROR_AUDIT_FAILED syscall.Errno = 606 + ERROR_TIMER_RESOLUTION_NOT_SET syscall.Errno = 607 + ERROR_INSUFFICIENT_LOGON_INFO syscall.Errno = 608 + ERROR_BAD_DLL_ENTRYPOINT syscall.Errno = 609 + ERROR_BAD_SERVICE_ENTRYPOINT syscall.Errno = 610 + ERROR_IP_ADDRESS_CONFLICT1 syscall.Errno = 611 + ERROR_IP_ADDRESS_CONFLICT2 syscall.Errno = 612 + ERROR_REGISTRY_QUOTA_LIMIT syscall.Errno = 613 + ERROR_NO_CALLBACK_ACTIVE syscall.Errno = 614 + ERROR_PWD_TOO_SHORT syscall.Errno = 615 + ERROR_PWD_TOO_RECENT syscall.Errno = 616 + ERROR_PWD_HISTORY_CONFLICT syscall.Errno = 617 + ERROR_UNSUPPORTED_COMPRESSION syscall.Errno = 618 + ERROR_INVALID_HW_PROFILE syscall.Errno = 619 + ERROR_INVALID_PLUGPLAY_DEVICE_PATH syscall.Errno = 620 + ERROR_QUOTA_LIST_INCONSISTENT syscall.Errno = 621 + ERROR_EVALUATION_EXPIRATION syscall.Errno = 622 + ERROR_ILLEGAL_DLL_RELOCATION syscall.Errno = 623 + ERROR_DLL_INIT_FAILED_LOGOFF syscall.Errno = 624 + ERROR_VALIDATE_CONTINUE syscall.Errno = 625 + ERROR_NO_MORE_MATCHES syscall.Errno = 626 + ERROR_RANGE_LIST_CONFLICT syscall.Errno = 627 + ERROR_SERVER_SID_MISMATCH syscall.Errno = 628 + ERROR_CANT_ENABLE_DENY_ONLY syscall.Errno = 629 + ERROR_FLOAT_MULTIPLE_FAULTS syscall.Errno = 630 + ERROR_FLOAT_MULTIPLE_TRAPS syscall.Errno = 631 + ERROR_NOINTERFACE syscall.Errno = 632 + ERROR_DRIVER_FAILED_SLEEP syscall.Errno = 633 + ERROR_CORRUPT_SYSTEM_FILE syscall.Errno = 634 + ERROR_COMMITMENT_MINIMUM syscall.Errno = 635 + ERROR_PNP_RESTART_ENUMERATION syscall.Errno = 636 + ERROR_SYSTEM_IMAGE_BAD_SIGNATURE syscall.Errno = 637 + ERROR_PNP_REBOOT_REQUIRED syscall.Errno = 638 + ERROR_INSUFFICIENT_POWER syscall.Errno = 639 + ERROR_MULTIPLE_FAULT_VIOLATION syscall.Errno = 640 + ERROR_SYSTEM_SHUTDOWN syscall.Errno = 641 + ERROR_PORT_NOT_SET syscall.Errno = 642 + ERROR_DS_VERSION_CHECK_FAILURE syscall.Errno = 643 + ERROR_RANGE_NOT_FOUND syscall.Errno = 644 + ERROR_NOT_SAFE_MODE_DRIVER syscall.Errno = 646 + ERROR_FAILED_DRIVER_ENTRY syscall.Errno = 647 + ERROR_DEVICE_ENUMERATION_ERROR syscall.Errno = 648 + ERROR_MOUNT_POINT_NOT_RESOLVED syscall.Errno = 649 + ERROR_INVALID_DEVICE_OBJECT_PARAMETER syscall.Errno = 650 + ERROR_MCA_OCCURED syscall.Errno = 651 + ERROR_DRIVER_DATABASE_ERROR syscall.Errno = 652 + ERROR_SYSTEM_HIVE_TOO_LARGE syscall.Errno = 653 + ERROR_DRIVER_FAILED_PRIOR_UNLOAD syscall.Errno = 654 + ERROR_VOLSNAP_PREPARE_HIBERNATE syscall.Errno = 655 + ERROR_HIBERNATION_FAILURE syscall.Errno = 656 + ERROR_PWD_TOO_LONG syscall.Errno = 657 + ERROR_FILE_SYSTEM_LIMITATION syscall.Errno = 665 + ERROR_ASSERTION_FAILURE syscall.Errno = 668 + ERROR_ACPI_ERROR syscall.Errno = 669 + ERROR_WOW_ASSERTION syscall.Errno = 670 + ERROR_PNP_BAD_MPS_TABLE syscall.Errno = 671 + ERROR_PNP_TRANSLATION_FAILED syscall.Errno = 672 + ERROR_PNP_IRQ_TRANSLATION_FAILED syscall.Errno = 673 + ERROR_PNP_INVALID_ID syscall.Errno = 674 + ERROR_WAKE_SYSTEM_DEBUGGER syscall.Errno = 675 + ERROR_HANDLES_CLOSED syscall.Errno = 676 + ERROR_EXTRANEOUS_INFORMATION syscall.Errno = 677 + ERROR_RXACT_COMMIT_NECESSARY syscall.Errno = 678 + ERROR_MEDIA_CHECK syscall.Errno = 679 + ERROR_GUID_SUBSTITUTION_MADE syscall.Errno = 680 + ERROR_STOPPED_ON_SYMLINK syscall.Errno = 681 + ERROR_LONGJUMP syscall.Errno = 682 + ERROR_PLUGPLAY_QUERY_VETOED syscall.Errno = 683 + ERROR_UNWIND_CONSOLIDATE syscall.Errno = 684 + ERROR_REGISTRY_HIVE_RECOVERED syscall.Errno = 685 + ERROR_DLL_MIGHT_BE_INSECURE syscall.Errno = 686 + ERROR_DLL_MIGHT_BE_INCOMPATIBLE syscall.Errno = 687 + ERROR_DBG_EXCEPTION_NOT_HANDLED syscall.Errno = 688 + ERROR_DBG_REPLY_LATER syscall.Errno = 689 + ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE syscall.Errno = 690 + ERROR_DBG_TERMINATE_THREAD syscall.Errno = 691 + ERROR_DBG_TERMINATE_PROCESS syscall.Errno = 692 + ERROR_DBG_CONTROL_C syscall.Errno = 693 + ERROR_DBG_PRINTEXCEPTION_C syscall.Errno = 694 + ERROR_DBG_RIPEXCEPTION syscall.Errno = 695 + ERROR_DBG_CONTROL_BREAK syscall.Errno = 696 + ERROR_DBG_COMMAND_EXCEPTION syscall.Errno = 697 + ERROR_OBJECT_NAME_EXISTS syscall.Errno = 698 + ERROR_THREAD_WAS_SUSPENDED syscall.Errno = 699 + ERROR_IMAGE_NOT_AT_BASE syscall.Errno = 700 + ERROR_RXACT_STATE_CREATED syscall.Errno = 701 + ERROR_SEGMENT_NOTIFICATION syscall.Errno = 702 + ERROR_BAD_CURRENT_DIRECTORY syscall.Errno = 703 + ERROR_FT_READ_RECOVERY_FROM_BACKUP syscall.Errno = 704 + ERROR_FT_WRITE_RECOVERY syscall.Errno = 705 + ERROR_IMAGE_MACHINE_TYPE_MISMATCH syscall.Errno = 706 + ERROR_RECEIVE_PARTIAL syscall.Errno = 707 + ERROR_RECEIVE_EXPEDITED syscall.Errno = 708 + ERROR_RECEIVE_PARTIAL_EXPEDITED syscall.Errno = 709 + ERROR_EVENT_DONE syscall.Errno = 710 + ERROR_EVENT_PENDING syscall.Errno = 711 + ERROR_CHECKING_FILE_SYSTEM syscall.Errno = 712 + ERROR_FATAL_APP_EXIT syscall.Errno = 713 + ERROR_PREDEFINED_HANDLE syscall.Errno = 714 + ERROR_WAS_UNLOCKED syscall.Errno = 715 + ERROR_SERVICE_NOTIFICATION syscall.Errno = 716 + ERROR_WAS_LOCKED syscall.Errno = 717 + ERROR_LOG_HARD_ERROR syscall.Errno = 718 + ERROR_ALREADY_WIN32 syscall.Errno = 719 + ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE syscall.Errno = 720 + ERROR_NO_YIELD_PERFORMED syscall.Errno = 721 + ERROR_TIMER_RESUME_IGNORED syscall.Errno = 722 + ERROR_ARBITRATION_UNHANDLED syscall.Errno = 723 + ERROR_CARDBUS_NOT_SUPPORTED syscall.Errno = 724 + ERROR_MP_PROCESSOR_MISMATCH syscall.Errno = 725 + ERROR_HIBERNATED syscall.Errno = 726 + ERROR_RESUME_HIBERNATION syscall.Errno = 727 + ERROR_FIRMWARE_UPDATED syscall.Errno = 728 + ERROR_DRIVERS_LEAKING_LOCKED_PAGES syscall.Errno = 729 + ERROR_WAKE_SYSTEM syscall.Errno = 730 + ERROR_WAIT_1 syscall.Errno = 731 + ERROR_WAIT_2 syscall.Errno = 732 + ERROR_WAIT_3 syscall.Errno = 733 + ERROR_WAIT_63 syscall.Errno = 734 + ERROR_ABANDONED_WAIT_0 syscall.Errno = 735 + ERROR_ABANDONED_WAIT_63 syscall.Errno = 736 + ERROR_USER_APC syscall.Errno = 737 + ERROR_KERNEL_APC syscall.Errno = 738 + ERROR_ALERTED syscall.Errno = 739 + ERROR_ELEVATION_REQUIRED syscall.Errno = 740 + ERROR_REPARSE syscall.Errno = 741 + ERROR_OPLOCK_BREAK_IN_PROGRESS syscall.Errno = 742 + ERROR_VOLUME_MOUNTED syscall.Errno = 743 + ERROR_RXACT_COMMITTED syscall.Errno = 744 + ERROR_NOTIFY_CLEANUP syscall.Errno = 745 + ERROR_PRIMARY_TRANSPORT_CONNECT_FAILED syscall.Errno = 746 + ERROR_PAGE_FAULT_TRANSITION syscall.Errno = 747 + ERROR_PAGE_FAULT_DEMAND_ZERO syscall.Errno = 748 + ERROR_PAGE_FAULT_COPY_ON_WRITE syscall.Errno = 749 + ERROR_PAGE_FAULT_GUARD_PAGE syscall.Errno = 750 + ERROR_PAGE_FAULT_PAGING_FILE syscall.Errno = 751 + ERROR_CACHE_PAGE_LOCKED syscall.Errno = 752 + ERROR_CRASH_DUMP syscall.Errno = 753 + ERROR_BUFFER_ALL_ZEROS syscall.Errno = 754 + ERROR_REPARSE_OBJECT syscall.Errno = 755 + ERROR_RESOURCE_REQUIREMENTS_CHANGED syscall.Errno = 756 + ERROR_TRANSLATION_COMPLETE syscall.Errno = 757 + ERROR_NOTHING_TO_TERMINATE syscall.Errno = 758 + ERROR_PROCESS_NOT_IN_JOB syscall.Errno = 759 + ERROR_PROCESS_IN_JOB syscall.Errno = 760 + ERROR_VOLSNAP_HIBERNATE_READY syscall.Errno = 761 + ERROR_FSFILTER_OP_COMPLETED_SUCCESSFULLY syscall.Errno = 762 + ERROR_INTERRUPT_VECTOR_ALREADY_CONNECTED syscall.Errno = 763 + ERROR_INTERRUPT_STILL_CONNECTED syscall.Errno = 764 + ERROR_WAIT_FOR_OPLOCK syscall.Errno = 765 + ERROR_DBG_EXCEPTION_HANDLED syscall.Errno = 766 + ERROR_DBG_CONTINUE syscall.Errno = 767 + ERROR_CALLBACK_POP_STACK syscall.Errno = 768 + ERROR_COMPRESSION_DISABLED syscall.Errno = 769 + ERROR_CANTFETCHBACKWARDS syscall.Errno = 770 + ERROR_CANTSCROLLBACKWARDS syscall.Errno = 771 + ERROR_ROWSNOTRELEASED syscall.Errno = 772 + ERROR_BAD_ACCESSOR_FLAGS syscall.Errno = 773 + ERROR_ERRORS_ENCOUNTERED syscall.Errno = 774 + ERROR_NOT_CAPABLE syscall.Errno = 775 + ERROR_REQUEST_OUT_OF_SEQUENCE syscall.Errno = 776 + ERROR_VERSION_PARSE_ERROR syscall.Errno = 777 + ERROR_BADSTARTPOSITION syscall.Errno = 778 + ERROR_MEMORY_HARDWARE syscall.Errno = 779 + ERROR_DISK_REPAIR_DISABLED syscall.Errno = 780 + ERROR_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE syscall.Errno = 781 + ERROR_SYSTEM_POWERSTATE_TRANSITION syscall.Errno = 782 + ERROR_SYSTEM_POWERSTATE_COMPLEX_TRANSITION syscall.Errno = 783 + ERROR_MCA_EXCEPTION syscall.Errno = 784 + ERROR_ACCESS_AUDIT_BY_POLICY syscall.Errno = 785 + ERROR_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY syscall.Errno = 786 + ERROR_ABANDON_HIBERFILE syscall.Errno = 787 + ERROR_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED syscall.Errno = 788 + ERROR_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR syscall.Errno = 789 + ERROR_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR syscall.Errno = 790 + ERROR_BAD_MCFG_TABLE syscall.Errno = 791 + ERROR_DISK_REPAIR_REDIRECTED syscall.Errno = 792 + ERROR_DISK_REPAIR_UNSUCCESSFUL syscall.Errno = 793 + ERROR_CORRUPT_LOG_OVERFULL syscall.Errno = 794 + ERROR_CORRUPT_LOG_CORRUPTED syscall.Errno = 795 + ERROR_CORRUPT_LOG_UNAVAILABLE syscall.Errno = 796 + ERROR_CORRUPT_LOG_DELETED_FULL syscall.Errno = 797 + ERROR_CORRUPT_LOG_CLEARED syscall.Errno = 798 + ERROR_ORPHAN_NAME_EXHAUSTED syscall.Errno = 799 + ERROR_OPLOCK_SWITCHED_TO_NEW_HANDLE syscall.Errno = 800 + ERROR_CANNOT_GRANT_REQUESTED_OPLOCK syscall.Errno = 801 + ERROR_CANNOT_BREAK_OPLOCK syscall.Errno = 802 + ERROR_OPLOCK_HANDLE_CLOSED syscall.Errno = 803 + ERROR_NO_ACE_CONDITION syscall.Errno = 804 + ERROR_INVALID_ACE_CONDITION syscall.Errno = 805 + ERROR_FILE_HANDLE_REVOKED syscall.Errno = 806 + ERROR_IMAGE_AT_DIFFERENT_BASE syscall.Errno = 807 + ERROR_ENCRYPTED_IO_NOT_POSSIBLE syscall.Errno = 808 + ERROR_FILE_METADATA_OPTIMIZATION_IN_PROGRESS syscall.Errno = 809 + ERROR_QUOTA_ACTIVITY syscall.Errno = 810 + ERROR_HANDLE_REVOKED syscall.Errno = 811 + ERROR_CALLBACK_INVOKE_INLINE syscall.Errno = 812 + ERROR_CPU_SET_INVALID syscall.Errno = 813 + ERROR_ENCLAVE_NOT_TERMINATED syscall.Errno = 814 + ERROR_ENCLAVE_VIOLATION syscall.Errno = 815 + ERROR_EA_ACCESS_DENIED syscall.Errno = 994 + ERROR_OPERATION_ABORTED syscall.Errno = 995 + ERROR_IO_INCOMPLETE syscall.Errno = 996 + ERROR_IO_PENDING syscall.Errno = 997 + ERROR_NOACCESS syscall.Errno = 998 + ERROR_SWAPERROR syscall.Errno = 999 + ERROR_STACK_OVERFLOW syscall.Errno = 1001 + ERROR_INVALID_MESSAGE syscall.Errno = 1002 + ERROR_CAN_NOT_COMPLETE syscall.Errno = 1003 + ERROR_INVALID_FLAGS syscall.Errno = 1004 + ERROR_UNRECOGNIZED_VOLUME syscall.Errno = 1005 + ERROR_FILE_INVALID syscall.Errno = 1006 + ERROR_FULLSCREEN_MODE syscall.Errno = 1007 + ERROR_NO_TOKEN syscall.Errno = 1008 + ERROR_BADDB syscall.Errno = 1009 + ERROR_BADKEY syscall.Errno = 1010 + ERROR_CANTOPEN syscall.Errno = 1011 + ERROR_CANTREAD syscall.Errno = 1012 + ERROR_CANTWRITE syscall.Errno = 1013 + ERROR_REGISTRY_RECOVERED syscall.Errno = 1014 + ERROR_REGISTRY_CORRUPT syscall.Errno = 1015 + ERROR_REGISTRY_IO_FAILED syscall.Errno = 1016 + ERROR_NOT_REGISTRY_FILE syscall.Errno = 1017 + ERROR_KEY_DELETED syscall.Errno = 1018 + ERROR_NO_LOG_SPACE syscall.Errno = 1019 + ERROR_KEY_HAS_CHILDREN syscall.Errno = 1020 + ERROR_CHILD_MUST_BE_VOLATILE syscall.Errno = 1021 + ERROR_NOTIFY_ENUM_DIR syscall.Errno = 1022 + ERROR_DEPENDENT_SERVICES_RUNNING syscall.Errno = 1051 + ERROR_INVALID_SERVICE_CONTROL syscall.Errno = 1052 + ERROR_SERVICE_REQUEST_TIMEOUT syscall.Errno = 1053 + ERROR_SERVICE_NO_THREAD syscall.Errno = 1054 + ERROR_SERVICE_DATABASE_LOCKED syscall.Errno = 1055 + ERROR_SERVICE_ALREADY_RUNNING syscall.Errno = 1056 + ERROR_INVALID_SERVICE_ACCOUNT syscall.Errno = 1057 + ERROR_SERVICE_DISABLED syscall.Errno = 1058 + ERROR_CIRCULAR_DEPENDENCY syscall.Errno = 1059 + ERROR_SERVICE_DOES_NOT_EXIST syscall.Errno = 1060 + ERROR_SERVICE_CANNOT_ACCEPT_CTRL syscall.Errno = 1061 + ERROR_SERVICE_NOT_ACTIVE syscall.Errno = 1062 + ERROR_FAILED_SERVICE_CONTROLLER_CONNECT syscall.Errno = 1063 + ERROR_EXCEPTION_IN_SERVICE syscall.Errno = 1064 + ERROR_DATABASE_DOES_NOT_EXIST syscall.Errno = 1065 + ERROR_SERVICE_SPECIFIC_ERROR syscall.Errno = 1066 + ERROR_PROCESS_ABORTED syscall.Errno = 1067 + ERROR_SERVICE_DEPENDENCY_FAIL syscall.Errno = 1068 + ERROR_SERVICE_LOGON_FAILED syscall.Errno = 1069 + ERROR_SERVICE_START_HANG syscall.Errno = 1070 + ERROR_INVALID_SERVICE_LOCK syscall.Errno = 1071 + ERROR_SERVICE_MARKED_FOR_DELETE syscall.Errno = 1072 + ERROR_SERVICE_EXISTS syscall.Errno = 1073 + ERROR_ALREADY_RUNNING_LKG syscall.Errno = 1074 + ERROR_SERVICE_DEPENDENCY_DELETED syscall.Errno = 1075 + ERROR_BOOT_ALREADY_ACCEPTED syscall.Errno = 1076 + ERROR_SERVICE_NEVER_STARTED syscall.Errno = 1077 + ERROR_DUPLICATE_SERVICE_NAME syscall.Errno = 1078 + ERROR_DIFFERENT_SERVICE_ACCOUNT syscall.Errno = 1079 + ERROR_CANNOT_DETECT_DRIVER_FAILURE syscall.Errno = 1080 + ERROR_CANNOT_DETECT_PROCESS_ABORT syscall.Errno = 1081 + ERROR_NO_RECOVERY_PROGRAM syscall.Errno = 1082 + ERROR_SERVICE_NOT_IN_EXE syscall.Errno = 1083 + ERROR_NOT_SAFEBOOT_SERVICE syscall.Errno = 1084 + ERROR_END_OF_MEDIA syscall.Errno = 1100 + ERROR_FILEMARK_DETECTED syscall.Errno = 1101 + ERROR_BEGINNING_OF_MEDIA syscall.Errno = 1102 + ERROR_SETMARK_DETECTED syscall.Errno = 1103 + ERROR_NO_DATA_DETECTED syscall.Errno = 1104 + ERROR_PARTITION_FAILURE syscall.Errno = 1105 + ERROR_INVALID_BLOCK_LENGTH syscall.Errno = 1106 + ERROR_DEVICE_NOT_PARTITIONED syscall.Errno = 1107 + ERROR_UNABLE_TO_LOCK_MEDIA syscall.Errno = 1108 + ERROR_UNABLE_TO_UNLOAD_MEDIA syscall.Errno = 1109 + ERROR_MEDIA_CHANGED syscall.Errno = 1110 + ERROR_BUS_RESET syscall.Errno = 1111 + ERROR_NO_MEDIA_IN_DRIVE syscall.Errno = 1112 + ERROR_NO_UNICODE_TRANSLATION syscall.Errno = 1113 + ERROR_DLL_INIT_FAILED syscall.Errno = 1114 + ERROR_SHUTDOWN_IN_PROGRESS syscall.Errno = 1115 + ERROR_NO_SHUTDOWN_IN_PROGRESS syscall.Errno = 1116 + ERROR_IO_DEVICE syscall.Errno = 1117 + ERROR_SERIAL_NO_DEVICE syscall.Errno = 1118 + ERROR_IRQ_BUSY syscall.Errno = 1119 + ERROR_MORE_WRITES syscall.Errno = 1120 + ERROR_COUNTER_TIMEOUT syscall.Errno = 1121 + ERROR_FLOPPY_ID_MARK_NOT_FOUND syscall.Errno = 1122 + ERROR_FLOPPY_WRONG_CYLINDER syscall.Errno = 1123 + ERROR_FLOPPY_UNKNOWN_ERROR syscall.Errno = 1124 + ERROR_FLOPPY_BAD_REGISTERS syscall.Errno = 1125 + ERROR_DISK_RECALIBRATE_FAILED syscall.Errno = 1126 + ERROR_DISK_OPERATION_FAILED syscall.Errno = 1127 + ERROR_DISK_RESET_FAILED syscall.Errno = 1128 + ERROR_EOM_OVERFLOW syscall.Errno = 1129 + ERROR_NOT_ENOUGH_SERVER_MEMORY syscall.Errno = 1130 + ERROR_POSSIBLE_DEADLOCK syscall.Errno = 1131 + ERROR_MAPPED_ALIGNMENT syscall.Errno = 1132 + ERROR_SET_POWER_STATE_VETOED syscall.Errno = 1140 + ERROR_SET_POWER_STATE_FAILED syscall.Errno = 1141 + ERROR_TOO_MANY_LINKS syscall.Errno = 1142 + ERROR_OLD_WIN_VERSION syscall.Errno = 1150 + ERROR_APP_WRONG_OS syscall.Errno = 1151 + ERROR_SINGLE_INSTANCE_APP syscall.Errno = 1152 + ERROR_RMODE_APP syscall.Errno = 1153 + ERROR_INVALID_DLL syscall.Errno = 1154 + ERROR_NO_ASSOCIATION syscall.Errno = 1155 + ERROR_DDE_FAIL syscall.Errno = 1156 + ERROR_DLL_NOT_FOUND syscall.Errno = 1157 + ERROR_NO_MORE_USER_HANDLES syscall.Errno = 1158 + ERROR_MESSAGE_SYNC_ONLY syscall.Errno = 1159 + ERROR_SOURCE_ELEMENT_EMPTY syscall.Errno = 1160 + ERROR_DESTINATION_ELEMENT_FULL syscall.Errno = 1161 + ERROR_ILLEGAL_ELEMENT_ADDRESS syscall.Errno = 1162 + ERROR_MAGAZINE_NOT_PRESENT syscall.Errno = 1163 + ERROR_DEVICE_REINITIALIZATION_NEEDED syscall.Errno = 1164 + ERROR_DEVICE_REQUIRES_CLEANING syscall.Errno = 1165 + ERROR_DEVICE_DOOR_OPEN syscall.Errno = 1166 + ERROR_DEVICE_NOT_CONNECTED syscall.Errno = 1167 + ERROR_NOT_FOUND syscall.Errno = 1168 + ERROR_NO_MATCH syscall.Errno = 1169 + ERROR_SET_NOT_FOUND syscall.Errno = 1170 + ERROR_POINT_NOT_FOUND syscall.Errno = 1171 + ERROR_NO_TRACKING_SERVICE syscall.Errno = 1172 + ERROR_NO_VOLUME_ID syscall.Errno = 1173 + ERROR_UNABLE_TO_REMOVE_REPLACED syscall.Errno = 1175 + ERROR_UNABLE_TO_MOVE_REPLACEMENT syscall.Errno = 1176 + ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 syscall.Errno = 1177 + ERROR_JOURNAL_DELETE_IN_PROGRESS syscall.Errno = 1178 + ERROR_JOURNAL_NOT_ACTIVE syscall.Errno = 1179 + ERROR_POTENTIAL_FILE_FOUND syscall.Errno = 1180 + ERROR_JOURNAL_ENTRY_DELETED syscall.Errno = 1181 + ERROR_SHUTDOWN_IS_SCHEDULED syscall.Errno = 1190 + ERROR_SHUTDOWN_USERS_LOGGED_ON syscall.Errno = 1191 + ERROR_BAD_DEVICE syscall.Errno = 1200 + ERROR_CONNECTION_UNAVAIL syscall.Errno = 1201 + ERROR_DEVICE_ALREADY_REMEMBERED syscall.Errno = 1202 + ERROR_NO_NET_OR_BAD_PATH syscall.Errno = 1203 + ERROR_BAD_PROVIDER syscall.Errno = 1204 + ERROR_CANNOT_OPEN_PROFILE syscall.Errno = 1205 + ERROR_BAD_PROFILE syscall.Errno = 1206 + ERROR_NOT_CONTAINER syscall.Errno = 1207 + ERROR_EXTENDED_ERROR syscall.Errno = 1208 + ERROR_INVALID_GROUPNAME syscall.Errno = 1209 + ERROR_INVALID_COMPUTERNAME syscall.Errno = 1210 + ERROR_INVALID_EVENTNAME syscall.Errno = 1211 + ERROR_INVALID_DOMAINNAME syscall.Errno = 1212 + ERROR_INVALID_SERVICENAME syscall.Errno = 1213 + ERROR_INVALID_NETNAME syscall.Errno = 1214 + ERROR_INVALID_SHARENAME syscall.Errno = 1215 + ERROR_INVALID_PASSWORDNAME syscall.Errno = 1216 + ERROR_INVALID_MESSAGENAME syscall.Errno = 1217 + ERROR_INVALID_MESSAGEDEST syscall.Errno = 1218 + ERROR_SESSION_CREDENTIAL_CONFLICT syscall.Errno = 1219 + ERROR_REMOTE_SESSION_LIMIT_EXCEEDED syscall.Errno = 1220 + ERROR_DUP_DOMAINNAME syscall.Errno = 1221 + ERROR_NO_NETWORK syscall.Errno = 1222 + ERROR_CANCELLED syscall.Errno = 1223 + ERROR_USER_MAPPED_FILE syscall.Errno = 1224 + ERROR_CONNECTION_REFUSED syscall.Errno = 1225 + ERROR_GRACEFUL_DISCONNECT syscall.Errno = 1226 + ERROR_ADDRESS_ALREADY_ASSOCIATED syscall.Errno = 1227 + ERROR_ADDRESS_NOT_ASSOCIATED syscall.Errno = 1228 + ERROR_CONNECTION_INVALID syscall.Errno = 1229 + ERROR_CONNECTION_ACTIVE syscall.Errno = 1230 + ERROR_NETWORK_UNREACHABLE syscall.Errno = 1231 + ERROR_HOST_UNREACHABLE syscall.Errno = 1232 + ERROR_PROTOCOL_UNREACHABLE syscall.Errno = 1233 + ERROR_PORT_UNREACHABLE syscall.Errno = 1234 + ERROR_REQUEST_ABORTED syscall.Errno = 1235 + ERROR_CONNECTION_ABORTED syscall.Errno = 1236 + ERROR_RETRY syscall.Errno = 1237 + ERROR_CONNECTION_COUNT_LIMIT syscall.Errno = 1238 + ERROR_LOGIN_TIME_RESTRICTION syscall.Errno = 1239 + ERROR_LOGIN_WKSTA_RESTRICTION syscall.Errno = 1240 + ERROR_INCORRECT_ADDRESS syscall.Errno = 1241 + ERROR_ALREADY_REGISTERED syscall.Errno = 1242 + ERROR_SERVICE_NOT_FOUND syscall.Errno = 1243 + ERROR_NOT_AUTHENTICATED syscall.Errno = 1244 + ERROR_NOT_LOGGED_ON syscall.Errno = 1245 + ERROR_CONTINUE syscall.Errno = 1246 + ERROR_ALREADY_INITIALIZED syscall.Errno = 1247 + ERROR_NO_MORE_DEVICES syscall.Errno = 1248 + ERROR_NO_SUCH_SITE syscall.Errno = 1249 + ERROR_DOMAIN_CONTROLLER_EXISTS syscall.Errno = 1250 + ERROR_ONLY_IF_CONNECTED syscall.Errno = 1251 + ERROR_OVERRIDE_NOCHANGES syscall.Errno = 1252 + ERROR_BAD_USER_PROFILE syscall.Errno = 1253 + ERROR_NOT_SUPPORTED_ON_SBS syscall.Errno = 1254 + ERROR_SERVER_SHUTDOWN_IN_PROGRESS syscall.Errno = 1255 + ERROR_HOST_DOWN syscall.Errno = 1256 + ERROR_NON_ACCOUNT_SID syscall.Errno = 1257 + ERROR_NON_DOMAIN_SID syscall.Errno = 1258 + ERROR_APPHELP_BLOCK syscall.Errno = 1259 + ERROR_ACCESS_DISABLED_BY_POLICY syscall.Errno = 1260 + ERROR_REG_NAT_CONSUMPTION syscall.Errno = 1261 + ERROR_CSCSHARE_OFFLINE syscall.Errno = 1262 + ERROR_PKINIT_FAILURE syscall.Errno = 1263 + ERROR_SMARTCARD_SUBSYSTEM_FAILURE syscall.Errno = 1264 + ERROR_DOWNGRADE_DETECTED syscall.Errno = 1265 + ERROR_MACHINE_LOCKED syscall.Errno = 1271 + ERROR_SMB_GUEST_LOGON_BLOCKED syscall.Errno = 1272 + ERROR_CALLBACK_SUPPLIED_INVALID_DATA syscall.Errno = 1273 + ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED syscall.Errno = 1274 + ERROR_DRIVER_BLOCKED syscall.Errno = 1275 + ERROR_INVALID_IMPORT_OF_NON_DLL syscall.Errno = 1276 + ERROR_ACCESS_DISABLED_WEBBLADE syscall.Errno = 1277 + ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER syscall.Errno = 1278 + ERROR_RECOVERY_FAILURE syscall.Errno = 1279 + ERROR_ALREADY_FIBER syscall.Errno = 1280 + ERROR_ALREADY_THREAD syscall.Errno = 1281 + ERROR_STACK_BUFFER_OVERRUN syscall.Errno = 1282 + ERROR_PARAMETER_QUOTA_EXCEEDED syscall.Errno = 1283 + ERROR_DEBUGGER_INACTIVE syscall.Errno = 1284 + ERROR_DELAY_LOAD_FAILED syscall.Errno = 1285 + ERROR_VDM_DISALLOWED syscall.Errno = 1286 + ERROR_UNIDENTIFIED_ERROR syscall.Errno = 1287 + ERROR_INVALID_CRUNTIME_PARAMETER syscall.Errno = 1288 + ERROR_BEYOND_VDL syscall.Errno = 1289 + ERROR_INCOMPATIBLE_SERVICE_SID_TYPE syscall.Errno = 1290 + ERROR_DRIVER_PROCESS_TERMINATED syscall.Errno = 1291 + ERROR_IMPLEMENTATION_LIMIT syscall.Errno = 1292 + ERROR_PROCESS_IS_PROTECTED syscall.Errno = 1293 + ERROR_SERVICE_NOTIFY_CLIENT_LAGGING syscall.Errno = 1294 + ERROR_DISK_QUOTA_EXCEEDED syscall.Errno = 1295 + ERROR_CONTENT_BLOCKED syscall.Errno = 1296 + ERROR_INCOMPATIBLE_SERVICE_PRIVILEGE syscall.Errno = 1297 + ERROR_APP_HANG syscall.Errno = 1298 + ERROR_INVALID_LABEL syscall.Errno = 1299 + ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300 + ERROR_SOME_NOT_MAPPED syscall.Errno = 1301 + ERROR_NO_QUOTAS_FOR_ACCOUNT syscall.Errno = 1302 + ERROR_LOCAL_USER_SESSION_KEY syscall.Errno = 1303 + ERROR_NULL_LM_PASSWORD syscall.Errno = 1304 + ERROR_UNKNOWN_REVISION syscall.Errno = 1305 + ERROR_REVISION_MISMATCH syscall.Errno = 1306 + ERROR_INVALID_OWNER syscall.Errno = 1307 + ERROR_INVALID_PRIMARY_GROUP syscall.Errno = 1308 + ERROR_NO_IMPERSONATION_TOKEN syscall.Errno = 1309 + ERROR_CANT_DISABLE_MANDATORY syscall.Errno = 1310 + ERROR_NO_LOGON_SERVERS syscall.Errno = 1311 + ERROR_NO_SUCH_LOGON_SESSION syscall.Errno = 1312 + ERROR_NO_SUCH_PRIVILEGE syscall.Errno = 1313 + ERROR_PRIVILEGE_NOT_HELD syscall.Errno = 1314 + ERROR_INVALID_ACCOUNT_NAME syscall.Errno = 1315 + ERROR_USER_EXISTS syscall.Errno = 1316 + ERROR_NO_SUCH_USER syscall.Errno = 1317 + ERROR_GROUP_EXISTS syscall.Errno = 1318 + ERROR_NO_SUCH_GROUP syscall.Errno = 1319 + ERROR_MEMBER_IN_GROUP syscall.Errno = 1320 + ERROR_MEMBER_NOT_IN_GROUP syscall.Errno = 1321 + ERROR_LAST_ADMIN syscall.Errno = 1322 + ERROR_WRONG_PASSWORD syscall.Errno = 1323 + ERROR_ILL_FORMED_PASSWORD syscall.Errno = 1324 + ERROR_PASSWORD_RESTRICTION syscall.Errno = 1325 + ERROR_LOGON_FAILURE syscall.Errno = 1326 + ERROR_ACCOUNT_RESTRICTION syscall.Errno = 1327 + ERROR_INVALID_LOGON_HOURS syscall.Errno = 1328 + ERROR_INVALID_WORKSTATION syscall.Errno = 1329 + ERROR_PASSWORD_EXPIRED syscall.Errno = 1330 + ERROR_ACCOUNT_DISABLED syscall.Errno = 1331 + ERROR_NONE_MAPPED syscall.Errno = 1332 + ERROR_TOO_MANY_LUIDS_REQUESTED syscall.Errno = 1333 + ERROR_LUIDS_EXHAUSTED syscall.Errno = 1334 + ERROR_INVALID_SUB_AUTHORITY syscall.Errno = 1335 + ERROR_INVALID_ACL syscall.Errno = 1336 + ERROR_INVALID_SID syscall.Errno = 1337 + ERROR_INVALID_SECURITY_DESCR syscall.Errno = 1338 + ERROR_BAD_INHERITANCE_ACL syscall.Errno = 1340 + ERROR_SERVER_DISABLED syscall.Errno = 1341 + ERROR_SERVER_NOT_DISABLED syscall.Errno = 1342 + ERROR_INVALID_ID_AUTHORITY syscall.Errno = 1343 + ERROR_ALLOTTED_SPACE_EXCEEDED syscall.Errno = 1344 + ERROR_INVALID_GROUP_ATTRIBUTES syscall.Errno = 1345 + ERROR_BAD_IMPERSONATION_LEVEL syscall.Errno = 1346 + ERROR_CANT_OPEN_ANONYMOUS syscall.Errno = 1347 + ERROR_BAD_VALIDATION_CLASS syscall.Errno = 1348 + ERROR_BAD_TOKEN_TYPE syscall.Errno = 1349 + ERROR_NO_SECURITY_ON_OBJECT syscall.Errno = 1350 + ERROR_CANT_ACCESS_DOMAIN_INFO syscall.Errno = 1351 + ERROR_INVALID_SERVER_STATE syscall.Errno = 1352 + ERROR_INVALID_DOMAIN_STATE syscall.Errno = 1353 + ERROR_INVALID_DOMAIN_ROLE syscall.Errno = 1354 + ERROR_NO_SUCH_DOMAIN syscall.Errno = 1355 + ERROR_DOMAIN_EXISTS syscall.Errno = 1356 + ERROR_DOMAIN_LIMIT_EXCEEDED syscall.Errno = 1357 + ERROR_INTERNAL_DB_CORRUPTION syscall.Errno = 1358 + ERROR_INTERNAL_ERROR syscall.Errno = 1359 + ERROR_GENERIC_NOT_MAPPED syscall.Errno = 1360 + ERROR_BAD_DESCRIPTOR_FORMAT syscall.Errno = 1361 + ERROR_NOT_LOGON_PROCESS syscall.Errno = 1362 + ERROR_LOGON_SESSION_EXISTS syscall.Errno = 1363 + ERROR_NO_SUCH_PACKAGE syscall.Errno = 1364 + ERROR_BAD_LOGON_SESSION_STATE syscall.Errno = 1365 + ERROR_LOGON_SESSION_COLLISION syscall.Errno = 1366 + ERROR_INVALID_LOGON_TYPE syscall.Errno = 1367 + ERROR_CANNOT_IMPERSONATE syscall.Errno = 1368 + ERROR_RXACT_INVALID_STATE syscall.Errno = 1369 + ERROR_RXACT_COMMIT_FAILURE syscall.Errno = 1370 + ERROR_SPECIAL_ACCOUNT syscall.Errno = 1371 + ERROR_SPECIAL_GROUP syscall.Errno = 1372 + ERROR_SPECIAL_USER syscall.Errno = 1373 + ERROR_MEMBERS_PRIMARY_GROUP syscall.Errno = 1374 + ERROR_TOKEN_ALREADY_IN_USE syscall.Errno = 1375 + ERROR_NO_SUCH_ALIAS syscall.Errno = 1376 + ERROR_MEMBER_NOT_IN_ALIAS syscall.Errno = 1377 + ERROR_MEMBER_IN_ALIAS syscall.Errno = 1378 + ERROR_ALIAS_EXISTS syscall.Errno = 1379 + ERROR_LOGON_NOT_GRANTED syscall.Errno = 1380 + ERROR_TOO_MANY_SECRETS syscall.Errno = 1381 + ERROR_SECRET_TOO_LONG syscall.Errno = 1382 + ERROR_INTERNAL_DB_ERROR syscall.Errno = 1383 + ERROR_TOO_MANY_CONTEXT_IDS syscall.Errno = 1384 + ERROR_LOGON_TYPE_NOT_GRANTED syscall.Errno = 1385 + ERROR_NT_CROSS_ENCRYPTION_REQUIRED syscall.Errno = 1386 + ERROR_NO_SUCH_MEMBER syscall.Errno = 1387 + ERROR_INVALID_MEMBER syscall.Errno = 1388 + ERROR_TOO_MANY_SIDS syscall.Errno = 1389 + ERROR_LM_CROSS_ENCRYPTION_REQUIRED syscall.Errno = 1390 + ERROR_NO_INHERITANCE syscall.Errno = 1391 + ERROR_FILE_CORRUPT syscall.Errno = 1392 + ERROR_DISK_CORRUPT syscall.Errno = 1393 + ERROR_NO_USER_SESSION_KEY syscall.Errno = 1394 + ERROR_LICENSE_QUOTA_EXCEEDED syscall.Errno = 1395 + ERROR_WRONG_TARGET_NAME syscall.Errno = 1396 + ERROR_MUTUAL_AUTH_FAILED syscall.Errno = 1397 + ERROR_TIME_SKEW syscall.Errno = 1398 + ERROR_CURRENT_DOMAIN_NOT_ALLOWED syscall.Errno = 1399 + ERROR_INVALID_WINDOW_HANDLE syscall.Errno = 1400 + ERROR_INVALID_MENU_HANDLE syscall.Errno = 1401 + ERROR_INVALID_CURSOR_HANDLE syscall.Errno = 1402 + ERROR_INVALID_ACCEL_HANDLE syscall.Errno = 1403 + ERROR_INVALID_HOOK_HANDLE syscall.Errno = 1404 + ERROR_INVALID_DWP_HANDLE syscall.Errno = 1405 + ERROR_TLW_WITH_WSCHILD syscall.Errno = 1406 + ERROR_CANNOT_FIND_WND_CLASS syscall.Errno = 1407 + ERROR_WINDOW_OF_OTHER_THREAD syscall.Errno = 1408 + ERROR_HOTKEY_ALREADY_REGISTERED syscall.Errno = 1409 + ERROR_CLASS_ALREADY_EXISTS syscall.Errno = 1410 + ERROR_CLASS_DOES_NOT_EXIST syscall.Errno = 1411 + ERROR_CLASS_HAS_WINDOWS syscall.Errno = 1412 + ERROR_INVALID_INDEX syscall.Errno = 1413 + ERROR_INVALID_ICON_HANDLE syscall.Errno = 1414 + ERROR_PRIVATE_DIALOG_INDEX syscall.Errno = 1415 + ERROR_LISTBOX_ID_NOT_FOUND syscall.Errno = 1416 + ERROR_NO_WILDCARD_CHARACTERS syscall.Errno = 1417 + ERROR_CLIPBOARD_NOT_OPEN syscall.Errno = 1418 + ERROR_HOTKEY_NOT_REGISTERED syscall.Errno = 1419 + ERROR_WINDOW_NOT_DIALOG syscall.Errno = 1420 + ERROR_CONTROL_ID_NOT_FOUND syscall.Errno = 1421 + ERROR_INVALID_COMBOBOX_MESSAGE syscall.Errno = 1422 + ERROR_WINDOW_NOT_COMBOBOX syscall.Errno = 1423 + ERROR_INVALID_EDIT_HEIGHT syscall.Errno = 1424 + ERROR_DC_NOT_FOUND syscall.Errno = 1425 + ERROR_INVALID_HOOK_FILTER syscall.Errno = 1426 + ERROR_INVALID_FILTER_PROC syscall.Errno = 1427 + ERROR_HOOK_NEEDS_HMOD syscall.Errno = 1428 + ERROR_GLOBAL_ONLY_HOOK syscall.Errno = 1429 + ERROR_JOURNAL_HOOK_SET syscall.Errno = 1430 + ERROR_HOOK_NOT_INSTALLED syscall.Errno = 1431 + ERROR_INVALID_LB_MESSAGE syscall.Errno = 1432 + ERROR_SETCOUNT_ON_BAD_LB syscall.Errno = 1433 + ERROR_LB_WITHOUT_TABSTOPS syscall.Errno = 1434 + ERROR_DESTROY_OBJECT_OF_OTHER_THREAD syscall.Errno = 1435 + ERROR_CHILD_WINDOW_MENU syscall.Errno = 1436 + ERROR_NO_SYSTEM_MENU syscall.Errno = 1437 + ERROR_INVALID_MSGBOX_STYLE syscall.Errno = 1438 + ERROR_INVALID_SPI_VALUE syscall.Errno = 1439 + ERROR_SCREEN_ALREADY_LOCKED syscall.Errno = 1440 + ERROR_HWNDS_HAVE_DIFF_PARENT syscall.Errno = 1441 + ERROR_NOT_CHILD_WINDOW syscall.Errno = 1442 + ERROR_INVALID_GW_COMMAND syscall.Errno = 1443 + ERROR_INVALID_THREAD_ID syscall.Errno = 1444 + ERROR_NON_MDICHILD_WINDOW syscall.Errno = 1445 + ERROR_POPUP_ALREADY_ACTIVE syscall.Errno = 1446 + ERROR_NO_SCROLLBARS syscall.Errno = 1447 + ERROR_INVALID_SCROLLBAR_RANGE syscall.Errno = 1448 + ERROR_INVALID_SHOWWIN_COMMAND syscall.Errno = 1449 + ERROR_NO_SYSTEM_RESOURCES syscall.Errno = 1450 + ERROR_NONPAGED_SYSTEM_RESOURCES syscall.Errno = 1451 + ERROR_PAGED_SYSTEM_RESOURCES syscall.Errno = 1452 + ERROR_WORKING_SET_QUOTA syscall.Errno = 1453 + ERROR_PAGEFILE_QUOTA syscall.Errno = 1454 + ERROR_COMMITMENT_LIMIT syscall.Errno = 1455 + ERROR_MENU_ITEM_NOT_FOUND syscall.Errno = 1456 + ERROR_INVALID_KEYBOARD_HANDLE syscall.Errno = 1457 + ERROR_HOOK_TYPE_NOT_ALLOWED syscall.Errno = 1458 + ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION syscall.Errno = 1459 + ERROR_TIMEOUT syscall.Errno = 1460 + ERROR_INVALID_MONITOR_HANDLE syscall.Errno = 1461 + ERROR_INCORRECT_SIZE syscall.Errno = 1462 + ERROR_SYMLINK_CLASS_DISABLED syscall.Errno = 1463 + ERROR_SYMLINK_NOT_SUPPORTED syscall.Errno = 1464 + ERROR_XML_PARSE_ERROR syscall.Errno = 1465 + ERROR_XMLDSIG_ERROR syscall.Errno = 1466 + ERROR_RESTART_APPLICATION syscall.Errno = 1467 + ERROR_WRONG_COMPARTMENT syscall.Errno = 1468 + ERROR_AUTHIP_FAILURE syscall.Errno = 1469 + ERROR_NO_NVRAM_RESOURCES syscall.Errno = 1470 + ERROR_NOT_GUI_PROCESS syscall.Errno = 1471 + ERROR_EVENTLOG_FILE_CORRUPT syscall.Errno = 1500 + ERROR_EVENTLOG_CANT_START syscall.Errno = 1501 + ERROR_LOG_FILE_FULL syscall.Errno = 1502 + ERROR_EVENTLOG_FILE_CHANGED syscall.Errno = 1503 + ERROR_CONTAINER_ASSIGNED syscall.Errno = 1504 + ERROR_JOB_NO_CONTAINER syscall.Errno = 1505 + ERROR_INVALID_TASK_NAME syscall.Errno = 1550 + ERROR_INVALID_TASK_INDEX syscall.Errno = 1551 + ERROR_THREAD_ALREADY_IN_TASK syscall.Errno = 1552 + ERROR_INSTALL_SERVICE_FAILURE syscall.Errno = 1601 + ERROR_INSTALL_USEREXIT syscall.Errno = 1602 + ERROR_INSTALL_FAILURE syscall.Errno = 1603 + ERROR_INSTALL_SUSPEND syscall.Errno = 1604 + ERROR_UNKNOWN_PRODUCT syscall.Errno = 1605 + ERROR_UNKNOWN_FEATURE syscall.Errno = 1606 + ERROR_UNKNOWN_COMPONENT syscall.Errno = 1607 + ERROR_UNKNOWN_PROPERTY syscall.Errno = 1608 + ERROR_INVALID_HANDLE_STATE syscall.Errno = 1609 + ERROR_BAD_CONFIGURATION syscall.Errno = 1610 + ERROR_INDEX_ABSENT syscall.Errno = 1611 + ERROR_INSTALL_SOURCE_ABSENT syscall.Errno = 1612 + ERROR_INSTALL_PACKAGE_VERSION syscall.Errno = 1613 + ERROR_PRODUCT_UNINSTALLED syscall.Errno = 1614 + ERROR_BAD_QUERY_SYNTAX syscall.Errno = 1615 + ERROR_INVALID_FIELD syscall.Errno = 1616 + ERROR_DEVICE_REMOVED syscall.Errno = 1617 + ERROR_INSTALL_ALREADY_RUNNING syscall.Errno = 1618 + ERROR_INSTALL_PACKAGE_OPEN_FAILED syscall.Errno = 1619 + ERROR_INSTALL_PACKAGE_INVALID syscall.Errno = 1620 + ERROR_INSTALL_UI_FAILURE syscall.Errno = 1621 + ERROR_INSTALL_LOG_FAILURE syscall.Errno = 1622 + ERROR_INSTALL_LANGUAGE_UNSUPPORTED syscall.Errno = 1623 + ERROR_INSTALL_TRANSFORM_FAILURE syscall.Errno = 1624 + ERROR_INSTALL_PACKAGE_REJECTED syscall.Errno = 1625 + ERROR_FUNCTION_NOT_CALLED syscall.Errno = 1626 + ERROR_FUNCTION_FAILED syscall.Errno = 1627 + ERROR_INVALID_TABLE syscall.Errno = 1628 + ERROR_DATATYPE_MISMATCH syscall.Errno = 1629 + ERROR_UNSUPPORTED_TYPE syscall.Errno = 1630 + ERROR_CREATE_FAILED syscall.Errno = 1631 + ERROR_INSTALL_TEMP_UNWRITABLE syscall.Errno = 1632 + ERROR_INSTALL_PLATFORM_UNSUPPORTED syscall.Errno = 1633 + ERROR_INSTALL_NOTUSED syscall.Errno = 1634 + ERROR_PATCH_PACKAGE_OPEN_FAILED syscall.Errno = 1635 + ERROR_PATCH_PACKAGE_INVALID syscall.Errno = 1636 + ERROR_PATCH_PACKAGE_UNSUPPORTED syscall.Errno = 1637 + ERROR_PRODUCT_VERSION syscall.Errno = 1638 + ERROR_INVALID_COMMAND_LINE syscall.Errno = 1639 + ERROR_INSTALL_REMOTE_DISALLOWED syscall.Errno = 1640 + ERROR_SUCCESS_REBOOT_INITIATED syscall.Errno = 1641 + ERROR_PATCH_TARGET_NOT_FOUND syscall.Errno = 1642 + ERROR_PATCH_PACKAGE_REJECTED syscall.Errno = 1643 + ERROR_INSTALL_TRANSFORM_REJECTED syscall.Errno = 1644 + ERROR_INSTALL_REMOTE_PROHIBITED syscall.Errno = 1645 + ERROR_PATCH_REMOVAL_UNSUPPORTED syscall.Errno = 1646 + ERROR_UNKNOWN_PATCH syscall.Errno = 1647 + ERROR_PATCH_NO_SEQUENCE syscall.Errno = 1648 + ERROR_PATCH_REMOVAL_DISALLOWED syscall.Errno = 1649 + ERROR_INVALID_PATCH_XML syscall.Errno = 1650 + ERROR_PATCH_MANAGED_ADVERTISED_PRODUCT syscall.Errno = 1651 + ERROR_INSTALL_SERVICE_SAFEBOOT syscall.Errno = 1652 + ERROR_FAIL_FAST_EXCEPTION syscall.Errno = 1653 + ERROR_INSTALL_REJECTED syscall.Errno = 1654 + ERROR_DYNAMIC_CODE_BLOCKED syscall.Errno = 1655 + ERROR_NOT_SAME_OBJECT syscall.Errno = 1656 + ERROR_STRICT_CFG_VIOLATION syscall.Errno = 1657 + ERROR_SET_CONTEXT_DENIED syscall.Errno = 1660 + ERROR_CROSS_PARTITION_VIOLATION syscall.Errno = 1661 + RPC_S_INVALID_STRING_BINDING syscall.Errno = 1700 + RPC_S_WRONG_KIND_OF_BINDING syscall.Errno = 1701 + RPC_S_INVALID_BINDING syscall.Errno = 1702 + RPC_S_PROTSEQ_NOT_SUPPORTED syscall.Errno = 1703 + RPC_S_INVALID_RPC_PROTSEQ syscall.Errno = 1704 + RPC_S_INVALID_STRING_UUID syscall.Errno = 1705 + RPC_S_INVALID_ENDPOINT_FORMAT syscall.Errno = 1706 + RPC_S_INVALID_NET_ADDR syscall.Errno = 1707 + RPC_S_NO_ENDPOINT_FOUND syscall.Errno = 1708 + RPC_S_INVALID_TIMEOUT syscall.Errno = 1709 + RPC_S_OBJECT_NOT_FOUND syscall.Errno = 1710 + RPC_S_ALREADY_REGISTERED syscall.Errno = 1711 + RPC_S_TYPE_ALREADY_REGISTERED syscall.Errno = 1712 + RPC_S_ALREADY_LISTENING syscall.Errno = 1713 + RPC_S_NO_PROTSEQS_REGISTERED syscall.Errno = 1714 + RPC_S_NOT_LISTENING syscall.Errno = 1715 + RPC_S_UNKNOWN_MGR_TYPE syscall.Errno = 1716 + RPC_S_UNKNOWN_IF syscall.Errno = 1717 + RPC_S_NO_BINDINGS syscall.Errno = 1718 + RPC_S_NO_PROTSEQS syscall.Errno = 1719 + RPC_S_CANT_CREATE_ENDPOINT syscall.Errno = 1720 + RPC_S_OUT_OF_RESOURCES syscall.Errno = 1721 + RPC_S_SERVER_UNAVAILABLE syscall.Errno = 1722 + RPC_S_SERVER_TOO_BUSY syscall.Errno = 1723 + RPC_S_INVALID_NETWORK_OPTIONS syscall.Errno = 1724 + RPC_S_NO_CALL_ACTIVE syscall.Errno = 1725 + RPC_S_CALL_FAILED syscall.Errno = 1726 + RPC_S_CALL_FAILED_DNE syscall.Errno = 1727 + RPC_S_PROTOCOL_ERROR syscall.Errno = 1728 + RPC_S_PROXY_ACCESS_DENIED syscall.Errno = 1729 + RPC_S_UNSUPPORTED_TRANS_SYN syscall.Errno = 1730 + RPC_S_UNSUPPORTED_TYPE syscall.Errno = 1732 + RPC_S_INVALID_TAG syscall.Errno = 1733 + RPC_S_INVALID_BOUND syscall.Errno = 1734 + RPC_S_NO_ENTRY_NAME syscall.Errno = 1735 + RPC_S_INVALID_NAME_SYNTAX syscall.Errno = 1736 + RPC_S_UNSUPPORTED_NAME_SYNTAX syscall.Errno = 1737 + RPC_S_UUID_NO_ADDRESS syscall.Errno = 1739 + RPC_S_DUPLICATE_ENDPOINT syscall.Errno = 1740 + RPC_S_UNKNOWN_AUTHN_TYPE syscall.Errno = 1741 + RPC_S_MAX_CALLS_TOO_SMALL syscall.Errno = 1742 + RPC_S_STRING_TOO_LONG syscall.Errno = 1743 + RPC_S_PROTSEQ_NOT_FOUND syscall.Errno = 1744 + RPC_S_PROCNUM_OUT_OF_RANGE syscall.Errno = 1745 + RPC_S_BINDING_HAS_NO_AUTH syscall.Errno = 1746 + RPC_S_UNKNOWN_AUTHN_SERVICE syscall.Errno = 1747 + RPC_S_UNKNOWN_AUTHN_LEVEL syscall.Errno = 1748 + RPC_S_INVALID_AUTH_IDENTITY syscall.Errno = 1749 + RPC_S_UNKNOWN_AUTHZ_SERVICE syscall.Errno = 1750 + EPT_S_INVALID_ENTRY syscall.Errno = 1751 + EPT_S_CANT_PERFORM_OP syscall.Errno = 1752 + EPT_S_NOT_REGISTERED syscall.Errno = 1753 + RPC_S_NOTHING_TO_EXPORT syscall.Errno = 1754 + RPC_S_INCOMPLETE_NAME syscall.Errno = 1755 + RPC_S_INVALID_VERS_OPTION syscall.Errno = 1756 + RPC_S_NO_MORE_MEMBERS syscall.Errno = 1757 + RPC_S_NOT_ALL_OBJS_UNEXPORTED syscall.Errno = 1758 + RPC_S_INTERFACE_NOT_FOUND syscall.Errno = 1759 + RPC_S_ENTRY_ALREADY_EXISTS syscall.Errno = 1760 + RPC_S_ENTRY_NOT_FOUND syscall.Errno = 1761 + RPC_S_NAME_SERVICE_UNAVAILABLE syscall.Errno = 1762 + RPC_S_INVALID_NAF_ID syscall.Errno = 1763 + RPC_S_CANNOT_SUPPORT syscall.Errno = 1764 + RPC_S_NO_CONTEXT_AVAILABLE syscall.Errno = 1765 + RPC_S_INTERNAL_ERROR syscall.Errno = 1766 + RPC_S_ZERO_DIVIDE syscall.Errno = 1767 + RPC_S_ADDRESS_ERROR syscall.Errno = 1768 + RPC_S_FP_DIV_ZERO syscall.Errno = 1769 + RPC_S_FP_UNDERFLOW syscall.Errno = 1770 + RPC_S_FP_OVERFLOW syscall.Errno = 1771 + RPC_X_NO_MORE_ENTRIES syscall.Errno = 1772 + RPC_X_SS_CHAR_TRANS_OPEN_FAIL syscall.Errno = 1773 + RPC_X_SS_CHAR_TRANS_SHORT_FILE syscall.Errno = 1774 + RPC_X_SS_IN_NULL_CONTEXT syscall.Errno = 1775 + RPC_X_SS_CONTEXT_DAMAGED syscall.Errno = 1777 + RPC_X_SS_HANDLES_MISMATCH syscall.Errno = 1778 + RPC_X_SS_CANNOT_GET_CALL_HANDLE syscall.Errno = 1779 + RPC_X_NULL_REF_POINTER syscall.Errno = 1780 + RPC_X_ENUM_VALUE_OUT_OF_RANGE syscall.Errno = 1781 + RPC_X_BYTE_COUNT_TOO_SMALL syscall.Errno = 1782 + RPC_X_BAD_STUB_DATA syscall.Errno = 1783 + ERROR_INVALID_USER_BUFFER syscall.Errno = 1784 + ERROR_UNRECOGNIZED_MEDIA syscall.Errno = 1785 + ERROR_NO_TRUST_LSA_SECRET syscall.Errno = 1786 + ERROR_NO_TRUST_SAM_ACCOUNT syscall.Errno = 1787 + ERROR_TRUSTED_DOMAIN_FAILURE syscall.Errno = 1788 + ERROR_TRUSTED_RELATIONSHIP_FAILURE syscall.Errno = 1789 + ERROR_TRUST_FAILURE syscall.Errno = 1790 + RPC_S_CALL_IN_PROGRESS syscall.Errno = 1791 + ERROR_NETLOGON_NOT_STARTED syscall.Errno = 1792 + ERROR_ACCOUNT_EXPIRED syscall.Errno = 1793 + ERROR_REDIRECTOR_HAS_OPEN_HANDLES syscall.Errno = 1794 + ERROR_PRINTER_DRIVER_ALREADY_INSTALLED syscall.Errno = 1795 + ERROR_UNKNOWN_PORT syscall.Errno = 1796 + ERROR_UNKNOWN_PRINTER_DRIVER syscall.Errno = 1797 + ERROR_UNKNOWN_PRINTPROCESSOR syscall.Errno = 1798 + ERROR_INVALID_SEPARATOR_FILE syscall.Errno = 1799 + ERROR_INVALID_PRIORITY syscall.Errno = 1800 + ERROR_INVALID_PRINTER_NAME syscall.Errno = 1801 + ERROR_PRINTER_ALREADY_EXISTS syscall.Errno = 1802 + ERROR_INVALID_PRINTER_COMMAND syscall.Errno = 1803 + ERROR_INVALID_DATATYPE syscall.Errno = 1804 + ERROR_INVALID_ENVIRONMENT syscall.Errno = 1805 + RPC_S_NO_MORE_BINDINGS syscall.Errno = 1806 + ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT syscall.Errno = 1807 + ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT syscall.Errno = 1808 + ERROR_NOLOGON_SERVER_TRUST_ACCOUNT syscall.Errno = 1809 + ERROR_DOMAIN_TRUST_INCONSISTENT syscall.Errno = 1810 + ERROR_SERVER_HAS_OPEN_HANDLES syscall.Errno = 1811 + ERROR_RESOURCE_DATA_NOT_FOUND syscall.Errno = 1812 + ERROR_RESOURCE_TYPE_NOT_FOUND syscall.Errno = 1813 + ERROR_RESOURCE_NAME_NOT_FOUND syscall.Errno = 1814 + ERROR_RESOURCE_LANG_NOT_FOUND syscall.Errno = 1815 + ERROR_NOT_ENOUGH_QUOTA syscall.Errno = 1816 + RPC_S_NO_INTERFACES syscall.Errno = 1817 + RPC_S_CALL_CANCELLED syscall.Errno = 1818 + RPC_S_BINDING_INCOMPLETE syscall.Errno = 1819 + RPC_S_COMM_FAILURE syscall.Errno = 1820 + RPC_S_UNSUPPORTED_AUTHN_LEVEL syscall.Errno = 1821 + RPC_S_NO_PRINC_NAME syscall.Errno = 1822 + RPC_S_NOT_RPC_ERROR syscall.Errno = 1823 + RPC_S_UUID_LOCAL_ONLY syscall.Errno = 1824 + RPC_S_SEC_PKG_ERROR syscall.Errno = 1825 + RPC_S_NOT_CANCELLED syscall.Errno = 1826 + RPC_X_INVALID_ES_ACTION syscall.Errno = 1827 + RPC_X_WRONG_ES_VERSION syscall.Errno = 1828 + RPC_X_WRONG_STUB_VERSION syscall.Errno = 1829 + RPC_X_INVALID_PIPE_OBJECT syscall.Errno = 1830 + RPC_X_WRONG_PIPE_ORDER syscall.Errno = 1831 + RPC_X_WRONG_PIPE_VERSION syscall.Errno = 1832 + RPC_S_COOKIE_AUTH_FAILED syscall.Errno = 1833 + RPC_S_DO_NOT_DISTURB syscall.Errno = 1834 + RPC_S_SYSTEM_HANDLE_COUNT_EXCEEDED syscall.Errno = 1835 + RPC_S_SYSTEM_HANDLE_TYPE_MISMATCH syscall.Errno = 1836 + RPC_S_GROUP_MEMBER_NOT_FOUND syscall.Errno = 1898 + EPT_S_CANT_CREATE syscall.Errno = 1899 + RPC_S_INVALID_OBJECT syscall.Errno = 1900 + ERROR_INVALID_TIME syscall.Errno = 1901 + ERROR_INVALID_FORM_NAME syscall.Errno = 1902 + ERROR_INVALID_FORM_SIZE syscall.Errno = 1903 + ERROR_ALREADY_WAITING syscall.Errno = 1904 + ERROR_PRINTER_DELETED syscall.Errno = 1905 + ERROR_INVALID_PRINTER_STATE syscall.Errno = 1906 + ERROR_PASSWORD_MUST_CHANGE syscall.Errno = 1907 + ERROR_DOMAIN_CONTROLLER_NOT_FOUND syscall.Errno = 1908 + ERROR_ACCOUNT_LOCKED_OUT syscall.Errno = 1909 + OR_INVALID_OXID syscall.Errno = 1910 + OR_INVALID_OID syscall.Errno = 1911 + OR_INVALID_SET syscall.Errno = 1912 + RPC_S_SEND_INCOMPLETE syscall.Errno = 1913 + RPC_S_INVALID_ASYNC_HANDLE syscall.Errno = 1914 + RPC_S_INVALID_ASYNC_CALL syscall.Errno = 1915 + RPC_X_PIPE_CLOSED syscall.Errno = 1916 + RPC_X_PIPE_DISCIPLINE_ERROR syscall.Errno = 1917 + RPC_X_PIPE_EMPTY syscall.Errno = 1918 + ERROR_NO_SITENAME syscall.Errno = 1919 + ERROR_CANT_ACCESS_FILE syscall.Errno = 1920 + ERROR_CANT_RESOLVE_FILENAME syscall.Errno = 1921 + RPC_S_ENTRY_TYPE_MISMATCH syscall.Errno = 1922 + RPC_S_NOT_ALL_OBJS_EXPORTED syscall.Errno = 1923 + RPC_S_INTERFACE_NOT_EXPORTED syscall.Errno = 1924 + RPC_S_PROFILE_NOT_ADDED syscall.Errno = 1925 + RPC_S_PRF_ELT_NOT_ADDED syscall.Errno = 1926 + RPC_S_PRF_ELT_NOT_REMOVED syscall.Errno = 1927 + RPC_S_GRP_ELT_NOT_ADDED syscall.Errno = 1928 + RPC_S_GRP_ELT_NOT_REMOVED syscall.Errno = 1929 + ERROR_KM_DRIVER_BLOCKED syscall.Errno = 1930 + ERROR_CONTEXT_EXPIRED syscall.Errno = 1931 + ERROR_PER_USER_TRUST_QUOTA_EXCEEDED syscall.Errno = 1932 + ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED syscall.Errno = 1933 + ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED syscall.Errno = 1934 + ERROR_AUTHENTICATION_FIREWALL_FAILED syscall.Errno = 1935 + ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED syscall.Errno = 1936 + ERROR_NTLM_BLOCKED syscall.Errno = 1937 + ERROR_PASSWORD_CHANGE_REQUIRED syscall.Errno = 1938 + ERROR_LOST_MODE_LOGON_RESTRICTION syscall.Errno = 1939 + ERROR_INVALID_PIXEL_FORMAT syscall.Errno = 2000 + ERROR_BAD_DRIVER syscall.Errno = 2001 + ERROR_INVALID_WINDOW_STYLE syscall.Errno = 2002 + ERROR_METAFILE_NOT_SUPPORTED syscall.Errno = 2003 + ERROR_TRANSFORM_NOT_SUPPORTED syscall.Errno = 2004 + ERROR_CLIPPING_NOT_SUPPORTED syscall.Errno = 2005 + ERROR_INVALID_CMM syscall.Errno = 2010 + ERROR_INVALID_PROFILE syscall.Errno = 2011 + ERROR_TAG_NOT_FOUND syscall.Errno = 2012 + ERROR_TAG_NOT_PRESENT syscall.Errno = 2013 + ERROR_DUPLICATE_TAG syscall.Errno = 2014 + ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE syscall.Errno = 2015 + ERROR_PROFILE_NOT_FOUND syscall.Errno = 2016 + ERROR_INVALID_COLORSPACE syscall.Errno = 2017 + ERROR_ICM_NOT_ENABLED syscall.Errno = 2018 + ERROR_DELETING_ICM_XFORM syscall.Errno = 2019 + ERROR_INVALID_TRANSFORM syscall.Errno = 2020 + ERROR_COLORSPACE_MISMATCH syscall.Errno = 2021 + ERROR_INVALID_COLORINDEX syscall.Errno = 2022 + ERROR_PROFILE_DOES_NOT_MATCH_DEVICE syscall.Errno = 2023 + ERROR_CONNECTED_OTHER_PASSWORD syscall.Errno = 2108 + ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT syscall.Errno = 2109 + ERROR_BAD_USERNAME syscall.Errno = 2202 + ERROR_NOT_CONNECTED syscall.Errno = 2250 + ERROR_OPEN_FILES syscall.Errno = 2401 + ERROR_ACTIVE_CONNECTIONS syscall.Errno = 2402 + ERROR_DEVICE_IN_USE syscall.Errno = 2404 + ERROR_UNKNOWN_PRINT_MONITOR syscall.Errno = 3000 + ERROR_PRINTER_DRIVER_IN_USE syscall.Errno = 3001 + ERROR_SPOOL_FILE_NOT_FOUND syscall.Errno = 3002 + ERROR_SPL_NO_STARTDOC syscall.Errno = 3003 + ERROR_SPL_NO_ADDJOB syscall.Errno = 3004 + ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED syscall.Errno = 3005 + ERROR_PRINT_MONITOR_ALREADY_INSTALLED syscall.Errno = 3006 + ERROR_INVALID_PRINT_MONITOR syscall.Errno = 3007 + ERROR_PRINT_MONITOR_IN_USE syscall.Errno = 3008 + ERROR_PRINTER_HAS_JOBS_QUEUED syscall.Errno = 3009 + ERROR_SUCCESS_REBOOT_REQUIRED syscall.Errno = 3010 + ERROR_SUCCESS_RESTART_REQUIRED syscall.Errno = 3011 + ERROR_PRINTER_NOT_FOUND syscall.Errno = 3012 + ERROR_PRINTER_DRIVER_WARNED syscall.Errno = 3013 + ERROR_PRINTER_DRIVER_BLOCKED syscall.Errno = 3014 + ERROR_PRINTER_DRIVER_PACKAGE_IN_USE syscall.Errno = 3015 + ERROR_CORE_DRIVER_PACKAGE_NOT_FOUND syscall.Errno = 3016 + ERROR_FAIL_REBOOT_REQUIRED syscall.Errno = 3017 + ERROR_FAIL_REBOOT_INITIATED syscall.Errno = 3018 + ERROR_PRINTER_DRIVER_DOWNLOAD_NEEDED syscall.Errno = 3019 + ERROR_PRINT_JOB_RESTART_REQUIRED syscall.Errno = 3020 + ERROR_INVALID_PRINTER_DRIVER_MANIFEST syscall.Errno = 3021 + ERROR_PRINTER_NOT_SHAREABLE syscall.Errno = 3022 + ERROR_REQUEST_PAUSED syscall.Errno = 3050 + ERROR_APPEXEC_CONDITION_NOT_SATISFIED syscall.Errno = 3060 + ERROR_APPEXEC_HANDLE_INVALIDATED syscall.Errno = 3061 + ERROR_APPEXEC_INVALID_HOST_GENERATION syscall.Errno = 3062 + ERROR_APPEXEC_UNEXPECTED_PROCESS_REGISTRATION syscall.Errno = 3063 + ERROR_APPEXEC_INVALID_HOST_STATE syscall.Errno = 3064 + ERROR_APPEXEC_NO_DONOR syscall.Errno = 3065 + ERROR_APPEXEC_HOST_ID_MISMATCH syscall.Errno = 3066 + ERROR_APPEXEC_UNKNOWN_USER syscall.Errno = 3067 + ERROR_IO_REISSUE_AS_CACHED syscall.Errno = 3950 + ERROR_WINS_INTERNAL syscall.Errno = 4000 + ERROR_CAN_NOT_DEL_LOCAL_WINS syscall.Errno = 4001 + ERROR_STATIC_INIT syscall.Errno = 4002 + ERROR_INC_BACKUP syscall.Errno = 4003 + ERROR_FULL_BACKUP syscall.Errno = 4004 + ERROR_REC_NON_EXISTENT syscall.Errno = 4005 + ERROR_RPL_NOT_ALLOWED syscall.Errno = 4006 + PEERDIST_ERROR_CONTENTINFO_VERSION_UNSUPPORTED syscall.Errno = 4050 + PEERDIST_ERROR_CANNOT_PARSE_CONTENTINFO syscall.Errno = 4051 + PEERDIST_ERROR_MISSING_DATA syscall.Errno = 4052 + PEERDIST_ERROR_NO_MORE syscall.Errno = 4053 + PEERDIST_ERROR_NOT_INITIALIZED syscall.Errno = 4054 + PEERDIST_ERROR_ALREADY_INITIALIZED syscall.Errno = 4055 + PEERDIST_ERROR_SHUTDOWN_IN_PROGRESS syscall.Errno = 4056 + PEERDIST_ERROR_INVALIDATED syscall.Errno = 4057 + PEERDIST_ERROR_ALREADY_EXISTS syscall.Errno = 4058 + PEERDIST_ERROR_OPERATION_NOTFOUND syscall.Errno = 4059 + PEERDIST_ERROR_ALREADY_COMPLETED syscall.Errno = 4060 + PEERDIST_ERROR_OUT_OF_BOUNDS syscall.Errno = 4061 + PEERDIST_ERROR_VERSION_UNSUPPORTED syscall.Errno = 4062 + PEERDIST_ERROR_INVALID_CONFIGURATION syscall.Errno = 4063 + PEERDIST_ERROR_NOT_LICENSED syscall.Errno = 4064 + PEERDIST_ERROR_SERVICE_UNAVAILABLE syscall.Errno = 4065 + PEERDIST_ERROR_TRUST_FAILURE syscall.Errno = 4066 + ERROR_DHCP_ADDRESS_CONFLICT syscall.Errno = 4100 + ERROR_WMI_GUID_NOT_FOUND syscall.Errno = 4200 + ERROR_WMI_INSTANCE_NOT_FOUND syscall.Errno = 4201 + ERROR_WMI_ITEMID_NOT_FOUND syscall.Errno = 4202 + ERROR_WMI_TRY_AGAIN syscall.Errno = 4203 + ERROR_WMI_DP_NOT_FOUND syscall.Errno = 4204 + ERROR_WMI_UNRESOLVED_INSTANCE_REF syscall.Errno = 4205 + ERROR_WMI_ALREADY_ENABLED syscall.Errno = 4206 + ERROR_WMI_GUID_DISCONNECTED syscall.Errno = 4207 + ERROR_WMI_SERVER_UNAVAILABLE syscall.Errno = 4208 + ERROR_WMI_DP_FAILED syscall.Errno = 4209 + ERROR_WMI_INVALID_MOF syscall.Errno = 4210 + ERROR_WMI_INVALID_REGINFO syscall.Errno = 4211 + ERROR_WMI_ALREADY_DISABLED syscall.Errno = 4212 + ERROR_WMI_READ_ONLY syscall.Errno = 4213 + ERROR_WMI_SET_FAILURE syscall.Errno = 4214 + ERROR_NOT_APPCONTAINER syscall.Errno = 4250 + ERROR_APPCONTAINER_REQUIRED syscall.Errno = 4251 + ERROR_NOT_SUPPORTED_IN_APPCONTAINER syscall.Errno = 4252 + ERROR_INVALID_PACKAGE_SID_LENGTH syscall.Errno = 4253 + ERROR_INVALID_MEDIA syscall.Errno = 4300 + ERROR_INVALID_LIBRARY syscall.Errno = 4301 + ERROR_INVALID_MEDIA_POOL syscall.Errno = 4302 + ERROR_DRIVE_MEDIA_MISMATCH syscall.Errno = 4303 + ERROR_MEDIA_OFFLINE syscall.Errno = 4304 + ERROR_LIBRARY_OFFLINE syscall.Errno = 4305 + ERROR_EMPTY syscall.Errno = 4306 + ERROR_NOT_EMPTY syscall.Errno = 4307 + ERROR_MEDIA_UNAVAILABLE syscall.Errno = 4308 + ERROR_RESOURCE_DISABLED syscall.Errno = 4309 + ERROR_INVALID_CLEANER syscall.Errno = 4310 + ERROR_UNABLE_TO_CLEAN syscall.Errno = 4311 + ERROR_OBJECT_NOT_FOUND syscall.Errno = 4312 + ERROR_DATABASE_FAILURE syscall.Errno = 4313 + ERROR_DATABASE_FULL syscall.Errno = 4314 + ERROR_MEDIA_INCOMPATIBLE syscall.Errno = 4315 + ERROR_RESOURCE_NOT_PRESENT syscall.Errno = 4316 + ERROR_INVALID_OPERATION syscall.Errno = 4317 + ERROR_MEDIA_NOT_AVAILABLE syscall.Errno = 4318 + ERROR_DEVICE_NOT_AVAILABLE syscall.Errno = 4319 + ERROR_REQUEST_REFUSED syscall.Errno = 4320 + ERROR_INVALID_DRIVE_OBJECT syscall.Errno = 4321 + ERROR_LIBRARY_FULL syscall.Errno = 4322 + ERROR_MEDIUM_NOT_ACCESSIBLE syscall.Errno = 4323 + ERROR_UNABLE_TO_LOAD_MEDIUM syscall.Errno = 4324 + ERROR_UNABLE_TO_INVENTORY_DRIVE syscall.Errno = 4325 + ERROR_UNABLE_TO_INVENTORY_SLOT syscall.Errno = 4326 + ERROR_UNABLE_TO_INVENTORY_TRANSPORT syscall.Errno = 4327 + ERROR_TRANSPORT_FULL syscall.Errno = 4328 + ERROR_CONTROLLING_IEPORT syscall.Errno = 4329 + ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA syscall.Errno = 4330 + ERROR_CLEANER_SLOT_SET syscall.Errno = 4331 + ERROR_CLEANER_SLOT_NOT_SET syscall.Errno = 4332 + ERROR_CLEANER_CARTRIDGE_SPENT syscall.Errno = 4333 + ERROR_UNEXPECTED_OMID syscall.Errno = 4334 + ERROR_CANT_DELETE_LAST_ITEM syscall.Errno = 4335 + ERROR_MESSAGE_EXCEEDS_MAX_SIZE syscall.Errno = 4336 + ERROR_VOLUME_CONTAINS_SYS_FILES syscall.Errno = 4337 + ERROR_INDIGENOUS_TYPE syscall.Errno = 4338 + ERROR_NO_SUPPORTING_DRIVES syscall.Errno = 4339 + ERROR_CLEANER_CARTRIDGE_INSTALLED syscall.Errno = 4340 + ERROR_IEPORT_FULL syscall.Errno = 4341 + ERROR_FILE_OFFLINE syscall.Errno = 4350 + ERROR_REMOTE_STORAGE_NOT_ACTIVE syscall.Errno = 4351 + ERROR_REMOTE_STORAGE_MEDIA_ERROR syscall.Errno = 4352 + ERROR_NOT_A_REPARSE_POINT syscall.Errno = 4390 + ERROR_REPARSE_ATTRIBUTE_CONFLICT syscall.Errno = 4391 + ERROR_INVALID_REPARSE_DATA syscall.Errno = 4392 + ERROR_REPARSE_TAG_INVALID syscall.Errno = 4393 + ERROR_REPARSE_TAG_MISMATCH syscall.Errno = 4394 + ERROR_REPARSE_POINT_ENCOUNTERED syscall.Errno = 4395 + ERROR_APP_DATA_NOT_FOUND syscall.Errno = 4400 + ERROR_APP_DATA_EXPIRED syscall.Errno = 4401 + ERROR_APP_DATA_CORRUPT syscall.Errno = 4402 + ERROR_APP_DATA_LIMIT_EXCEEDED syscall.Errno = 4403 + ERROR_APP_DATA_REBOOT_REQUIRED syscall.Errno = 4404 + ERROR_SECUREBOOT_ROLLBACK_DETECTED syscall.Errno = 4420 + ERROR_SECUREBOOT_POLICY_VIOLATION syscall.Errno = 4421 + ERROR_SECUREBOOT_INVALID_POLICY syscall.Errno = 4422 + ERROR_SECUREBOOT_POLICY_PUBLISHER_NOT_FOUND syscall.Errno = 4423 + ERROR_SECUREBOOT_POLICY_NOT_SIGNED syscall.Errno = 4424 + ERROR_SECUREBOOT_NOT_ENABLED syscall.Errno = 4425 + ERROR_SECUREBOOT_FILE_REPLACED syscall.Errno = 4426 + ERROR_SECUREBOOT_POLICY_NOT_AUTHORIZED syscall.Errno = 4427 + ERROR_SECUREBOOT_POLICY_UNKNOWN syscall.Errno = 4428 + ERROR_SECUREBOOT_POLICY_MISSING_ANTIROLLBACKVERSION syscall.Errno = 4429 + ERROR_SECUREBOOT_PLATFORM_ID_MISMATCH syscall.Errno = 4430 + ERROR_SECUREBOOT_POLICY_ROLLBACK_DETECTED syscall.Errno = 4431 + ERROR_SECUREBOOT_POLICY_UPGRADE_MISMATCH syscall.Errno = 4432 + ERROR_SECUREBOOT_REQUIRED_POLICY_FILE_MISSING syscall.Errno = 4433 + ERROR_SECUREBOOT_NOT_BASE_POLICY syscall.Errno = 4434 + ERROR_SECUREBOOT_NOT_SUPPLEMENTAL_POLICY syscall.Errno = 4435 + ERROR_OFFLOAD_READ_FLT_NOT_SUPPORTED syscall.Errno = 4440 + ERROR_OFFLOAD_WRITE_FLT_NOT_SUPPORTED syscall.Errno = 4441 + ERROR_OFFLOAD_READ_FILE_NOT_SUPPORTED syscall.Errno = 4442 + ERROR_OFFLOAD_WRITE_FILE_NOT_SUPPORTED syscall.Errno = 4443 + ERROR_ALREADY_HAS_STREAM_ID syscall.Errno = 4444 + ERROR_SMR_GARBAGE_COLLECTION_REQUIRED syscall.Errno = 4445 + ERROR_WOF_WIM_HEADER_CORRUPT syscall.Errno = 4446 + ERROR_WOF_WIM_RESOURCE_TABLE_CORRUPT syscall.Errno = 4447 + ERROR_WOF_FILE_RESOURCE_TABLE_CORRUPT syscall.Errno = 4448 + ERROR_VOLUME_NOT_SIS_ENABLED syscall.Errno = 4500 + ERROR_SYSTEM_INTEGRITY_ROLLBACK_DETECTED syscall.Errno = 4550 + ERROR_SYSTEM_INTEGRITY_POLICY_VIOLATION syscall.Errno = 4551 + ERROR_SYSTEM_INTEGRITY_INVALID_POLICY syscall.Errno = 4552 + ERROR_SYSTEM_INTEGRITY_POLICY_NOT_SIGNED syscall.Errno = 4553 + ERROR_SYSTEM_INTEGRITY_TOO_MANY_POLICIES syscall.Errno = 4554 + ERROR_SYSTEM_INTEGRITY_SUPPLEMENTAL_POLICY_NOT_AUTHORIZED syscall.Errno = 4555 + ERROR_VSM_NOT_INITIALIZED syscall.Errno = 4560 + ERROR_VSM_DMA_PROTECTION_NOT_IN_USE syscall.Errno = 4561 + ERROR_PLATFORM_MANIFEST_NOT_AUTHORIZED syscall.Errno = 4570 + ERROR_PLATFORM_MANIFEST_INVALID syscall.Errno = 4571 + ERROR_PLATFORM_MANIFEST_FILE_NOT_AUTHORIZED syscall.Errno = 4572 + ERROR_PLATFORM_MANIFEST_CATALOG_NOT_AUTHORIZED syscall.Errno = 4573 + ERROR_PLATFORM_MANIFEST_BINARY_ID_NOT_FOUND syscall.Errno = 4574 + ERROR_PLATFORM_MANIFEST_NOT_ACTIVE syscall.Errno = 4575 + ERROR_PLATFORM_MANIFEST_NOT_SIGNED syscall.Errno = 4576 + ERROR_DEPENDENT_RESOURCE_EXISTS syscall.Errno = 5001 + ERROR_DEPENDENCY_NOT_FOUND syscall.Errno = 5002 + ERROR_DEPENDENCY_ALREADY_EXISTS syscall.Errno = 5003 + ERROR_RESOURCE_NOT_ONLINE syscall.Errno = 5004 + ERROR_HOST_NODE_NOT_AVAILABLE syscall.Errno = 5005 + ERROR_RESOURCE_NOT_AVAILABLE syscall.Errno = 5006 + ERROR_RESOURCE_NOT_FOUND syscall.Errno = 5007 + ERROR_SHUTDOWN_CLUSTER syscall.Errno = 5008 + ERROR_CANT_EVICT_ACTIVE_NODE syscall.Errno = 5009 + ERROR_OBJECT_ALREADY_EXISTS syscall.Errno = 5010 + ERROR_OBJECT_IN_LIST syscall.Errno = 5011 + ERROR_GROUP_NOT_AVAILABLE syscall.Errno = 5012 + ERROR_GROUP_NOT_FOUND syscall.Errno = 5013 + ERROR_GROUP_NOT_ONLINE syscall.Errno = 5014 + ERROR_HOST_NODE_NOT_RESOURCE_OWNER syscall.Errno = 5015 + ERROR_HOST_NODE_NOT_GROUP_OWNER syscall.Errno = 5016 + ERROR_RESMON_CREATE_FAILED syscall.Errno = 5017 + ERROR_RESMON_ONLINE_FAILED syscall.Errno = 5018 + ERROR_RESOURCE_ONLINE syscall.Errno = 5019 + ERROR_QUORUM_RESOURCE syscall.Errno = 5020 + ERROR_NOT_QUORUM_CAPABLE syscall.Errno = 5021 + ERROR_CLUSTER_SHUTTING_DOWN syscall.Errno = 5022 + ERROR_INVALID_STATE syscall.Errno = 5023 + ERROR_RESOURCE_PROPERTIES_STORED syscall.Errno = 5024 + ERROR_NOT_QUORUM_CLASS syscall.Errno = 5025 + ERROR_CORE_RESOURCE syscall.Errno = 5026 + ERROR_QUORUM_RESOURCE_ONLINE_FAILED syscall.Errno = 5027 + ERROR_QUORUMLOG_OPEN_FAILED syscall.Errno = 5028 + ERROR_CLUSTERLOG_CORRUPT syscall.Errno = 5029 + ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE syscall.Errno = 5030 + ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE syscall.Errno = 5031 + ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND syscall.Errno = 5032 + ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE syscall.Errno = 5033 + ERROR_QUORUM_OWNER_ALIVE syscall.Errno = 5034 + ERROR_NETWORK_NOT_AVAILABLE syscall.Errno = 5035 + ERROR_NODE_NOT_AVAILABLE syscall.Errno = 5036 + ERROR_ALL_NODES_NOT_AVAILABLE syscall.Errno = 5037 + ERROR_RESOURCE_FAILED syscall.Errno = 5038 + ERROR_CLUSTER_INVALID_NODE syscall.Errno = 5039 + ERROR_CLUSTER_NODE_EXISTS syscall.Errno = 5040 + ERROR_CLUSTER_JOIN_IN_PROGRESS syscall.Errno = 5041 + ERROR_CLUSTER_NODE_NOT_FOUND syscall.Errno = 5042 + ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND syscall.Errno = 5043 + ERROR_CLUSTER_NETWORK_EXISTS syscall.Errno = 5044 + ERROR_CLUSTER_NETWORK_NOT_FOUND syscall.Errno = 5045 + ERROR_CLUSTER_NETINTERFACE_EXISTS syscall.Errno = 5046 + ERROR_CLUSTER_NETINTERFACE_NOT_FOUND syscall.Errno = 5047 + ERROR_CLUSTER_INVALID_REQUEST syscall.Errno = 5048 + ERROR_CLUSTER_INVALID_NETWORK_PROVIDER syscall.Errno = 5049 + ERROR_CLUSTER_NODE_DOWN syscall.Errno = 5050 + ERROR_CLUSTER_NODE_UNREACHABLE syscall.Errno = 5051 + ERROR_CLUSTER_NODE_NOT_MEMBER syscall.Errno = 5052 + ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS syscall.Errno = 5053 + ERROR_CLUSTER_INVALID_NETWORK syscall.Errno = 5054 + ERROR_CLUSTER_NODE_UP syscall.Errno = 5056 + ERROR_CLUSTER_IPADDR_IN_USE syscall.Errno = 5057 + ERROR_CLUSTER_NODE_NOT_PAUSED syscall.Errno = 5058 + ERROR_CLUSTER_NO_SECURITY_CONTEXT syscall.Errno = 5059 + ERROR_CLUSTER_NETWORK_NOT_INTERNAL syscall.Errno = 5060 + ERROR_CLUSTER_NODE_ALREADY_UP syscall.Errno = 5061 + ERROR_CLUSTER_NODE_ALREADY_DOWN syscall.Errno = 5062 + ERROR_CLUSTER_NETWORK_ALREADY_ONLINE syscall.Errno = 5063 + ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE syscall.Errno = 5064 + ERROR_CLUSTER_NODE_ALREADY_MEMBER syscall.Errno = 5065 + ERROR_CLUSTER_LAST_INTERNAL_NETWORK syscall.Errno = 5066 + ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS syscall.Errno = 5067 + ERROR_INVALID_OPERATION_ON_QUORUM syscall.Errno = 5068 + ERROR_DEPENDENCY_NOT_ALLOWED syscall.Errno = 5069 + ERROR_CLUSTER_NODE_PAUSED syscall.Errno = 5070 + ERROR_NODE_CANT_HOST_RESOURCE syscall.Errno = 5071 + ERROR_CLUSTER_NODE_NOT_READY syscall.Errno = 5072 + ERROR_CLUSTER_NODE_SHUTTING_DOWN syscall.Errno = 5073 + ERROR_CLUSTER_JOIN_ABORTED syscall.Errno = 5074 + ERROR_CLUSTER_INCOMPATIBLE_VERSIONS syscall.Errno = 5075 + ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED syscall.Errno = 5076 + ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED syscall.Errno = 5077 + ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND syscall.Errno = 5078 + ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED syscall.Errno = 5079 + ERROR_CLUSTER_RESNAME_NOT_FOUND syscall.Errno = 5080 + ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED syscall.Errno = 5081 + ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST syscall.Errno = 5082 + ERROR_CLUSTER_DATABASE_SEQMISMATCH syscall.Errno = 5083 + ERROR_RESMON_INVALID_STATE syscall.Errno = 5084 + ERROR_CLUSTER_GUM_NOT_LOCKER syscall.Errno = 5085 + ERROR_QUORUM_DISK_NOT_FOUND syscall.Errno = 5086 + ERROR_DATABASE_BACKUP_CORRUPT syscall.Errno = 5087 + ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT syscall.Errno = 5088 + ERROR_RESOURCE_PROPERTY_UNCHANGEABLE syscall.Errno = 5089 + ERROR_NO_ADMIN_ACCESS_POINT syscall.Errno = 5090 + ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE syscall.Errno = 5890 + ERROR_CLUSTER_QUORUMLOG_NOT_FOUND syscall.Errno = 5891 + ERROR_CLUSTER_MEMBERSHIP_HALT syscall.Errno = 5892 + ERROR_CLUSTER_INSTANCE_ID_MISMATCH syscall.Errno = 5893 + ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP syscall.Errno = 5894 + ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH syscall.Errno = 5895 + ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP syscall.Errno = 5896 + ERROR_CLUSTER_PARAMETER_MISMATCH syscall.Errno = 5897 + ERROR_NODE_CANNOT_BE_CLUSTERED syscall.Errno = 5898 + ERROR_CLUSTER_WRONG_OS_VERSION syscall.Errno = 5899 + ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME syscall.Errno = 5900 + ERROR_CLUSCFG_ALREADY_COMMITTED syscall.Errno = 5901 + ERROR_CLUSCFG_ROLLBACK_FAILED syscall.Errno = 5902 + ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT syscall.Errno = 5903 + ERROR_CLUSTER_OLD_VERSION syscall.Errno = 5904 + ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME syscall.Errno = 5905 + ERROR_CLUSTER_NO_NET_ADAPTERS syscall.Errno = 5906 + ERROR_CLUSTER_POISONED syscall.Errno = 5907 + ERROR_CLUSTER_GROUP_MOVING syscall.Errno = 5908 + ERROR_CLUSTER_RESOURCE_TYPE_BUSY syscall.Errno = 5909 + ERROR_RESOURCE_CALL_TIMED_OUT syscall.Errno = 5910 + ERROR_INVALID_CLUSTER_IPV6_ADDRESS syscall.Errno = 5911 + ERROR_CLUSTER_INTERNAL_INVALID_FUNCTION syscall.Errno = 5912 + ERROR_CLUSTER_PARAMETER_OUT_OF_BOUNDS syscall.Errno = 5913 + ERROR_CLUSTER_PARTIAL_SEND syscall.Errno = 5914 + ERROR_CLUSTER_REGISTRY_INVALID_FUNCTION syscall.Errno = 5915 + ERROR_CLUSTER_INVALID_STRING_TERMINATION syscall.Errno = 5916 + ERROR_CLUSTER_INVALID_STRING_FORMAT syscall.Errno = 5917 + ERROR_CLUSTER_DATABASE_TRANSACTION_IN_PROGRESS syscall.Errno = 5918 + ERROR_CLUSTER_DATABASE_TRANSACTION_NOT_IN_PROGRESS syscall.Errno = 5919 + ERROR_CLUSTER_NULL_DATA syscall.Errno = 5920 + ERROR_CLUSTER_PARTIAL_READ syscall.Errno = 5921 + ERROR_CLUSTER_PARTIAL_WRITE syscall.Errno = 5922 + ERROR_CLUSTER_CANT_DESERIALIZE_DATA syscall.Errno = 5923 + ERROR_DEPENDENT_RESOURCE_PROPERTY_CONFLICT syscall.Errno = 5924 + ERROR_CLUSTER_NO_QUORUM syscall.Errno = 5925 + ERROR_CLUSTER_INVALID_IPV6_NETWORK syscall.Errno = 5926 + ERROR_CLUSTER_INVALID_IPV6_TUNNEL_NETWORK syscall.Errno = 5927 + ERROR_QUORUM_NOT_ALLOWED_IN_THIS_GROUP syscall.Errno = 5928 + ERROR_DEPENDENCY_TREE_TOO_COMPLEX syscall.Errno = 5929 + ERROR_EXCEPTION_IN_RESOURCE_CALL syscall.Errno = 5930 + ERROR_CLUSTER_RHS_FAILED_INITIALIZATION syscall.Errno = 5931 + ERROR_CLUSTER_NOT_INSTALLED syscall.Errno = 5932 + ERROR_CLUSTER_RESOURCES_MUST_BE_ONLINE_ON_THE_SAME_NODE syscall.Errno = 5933 + ERROR_CLUSTER_MAX_NODES_IN_CLUSTER syscall.Errno = 5934 + ERROR_CLUSTER_TOO_MANY_NODES syscall.Errno = 5935 + ERROR_CLUSTER_OBJECT_ALREADY_USED syscall.Errno = 5936 + ERROR_NONCORE_GROUPS_FOUND syscall.Errno = 5937 + ERROR_FILE_SHARE_RESOURCE_CONFLICT syscall.Errno = 5938 + ERROR_CLUSTER_EVICT_INVALID_REQUEST syscall.Errno = 5939 + ERROR_CLUSTER_SINGLETON_RESOURCE syscall.Errno = 5940 + ERROR_CLUSTER_GROUP_SINGLETON_RESOURCE syscall.Errno = 5941 + ERROR_CLUSTER_RESOURCE_PROVIDER_FAILED syscall.Errno = 5942 + ERROR_CLUSTER_RESOURCE_CONFIGURATION_ERROR syscall.Errno = 5943 + ERROR_CLUSTER_GROUP_BUSY syscall.Errno = 5944 + ERROR_CLUSTER_NOT_SHARED_VOLUME syscall.Errno = 5945 + ERROR_CLUSTER_INVALID_SECURITY_DESCRIPTOR syscall.Errno = 5946 + ERROR_CLUSTER_SHARED_VOLUMES_IN_USE syscall.Errno = 5947 + ERROR_CLUSTER_USE_SHARED_VOLUMES_API syscall.Errno = 5948 + ERROR_CLUSTER_BACKUP_IN_PROGRESS syscall.Errno = 5949 + ERROR_NON_CSV_PATH syscall.Errno = 5950 + ERROR_CSV_VOLUME_NOT_LOCAL syscall.Errno = 5951 + ERROR_CLUSTER_WATCHDOG_TERMINATING syscall.Errno = 5952 + ERROR_CLUSTER_RESOURCE_VETOED_MOVE_INCOMPATIBLE_NODES syscall.Errno = 5953 + ERROR_CLUSTER_INVALID_NODE_WEIGHT syscall.Errno = 5954 + ERROR_CLUSTER_RESOURCE_VETOED_CALL syscall.Errno = 5955 + ERROR_RESMON_SYSTEM_RESOURCES_LACKING syscall.Errno = 5956 + ERROR_CLUSTER_RESOURCE_VETOED_MOVE_NOT_ENOUGH_RESOURCES_ON_DESTINATION syscall.Errno = 5957 + ERROR_CLUSTER_RESOURCE_VETOED_MOVE_NOT_ENOUGH_RESOURCES_ON_SOURCE syscall.Errno = 5958 + ERROR_CLUSTER_GROUP_QUEUED syscall.Errno = 5959 + ERROR_CLUSTER_RESOURCE_LOCKED_STATUS syscall.Errno = 5960 + ERROR_CLUSTER_SHARED_VOLUME_FAILOVER_NOT_ALLOWED syscall.Errno = 5961 + ERROR_CLUSTER_NODE_DRAIN_IN_PROGRESS syscall.Errno = 5962 + ERROR_CLUSTER_DISK_NOT_CONNECTED syscall.Errno = 5963 + ERROR_DISK_NOT_CSV_CAPABLE syscall.Errno = 5964 + ERROR_RESOURCE_NOT_IN_AVAILABLE_STORAGE syscall.Errno = 5965 + ERROR_CLUSTER_SHARED_VOLUME_REDIRECTED syscall.Errno = 5966 + ERROR_CLUSTER_SHARED_VOLUME_NOT_REDIRECTED syscall.Errno = 5967 + ERROR_CLUSTER_CANNOT_RETURN_PROPERTIES syscall.Errno = 5968 + ERROR_CLUSTER_RESOURCE_CONTAINS_UNSUPPORTED_DIFF_AREA_FOR_SHARED_VOLUMES syscall.Errno = 5969 + ERROR_CLUSTER_RESOURCE_IS_IN_MAINTENANCE_MODE syscall.Errno = 5970 + ERROR_CLUSTER_AFFINITY_CONFLICT syscall.Errno = 5971 + ERROR_CLUSTER_RESOURCE_IS_REPLICA_VIRTUAL_MACHINE syscall.Errno = 5972 + ERROR_CLUSTER_UPGRADE_INCOMPATIBLE_VERSIONS syscall.Errno = 5973 + ERROR_CLUSTER_UPGRADE_FIX_QUORUM_NOT_SUPPORTED syscall.Errno = 5974 + ERROR_CLUSTER_UPGRADE_RESTART_REQUIRED syscall.Errno = 5975 + ERROR_CLUSTER_UPGRADE_IN_PROGRESS syscall.Errno = 5976 + ERROR_CLUSTER_UPGRADE_INCOMPLETE syscall.Errno = 5977 + ERROR_CLUSTER_NODE_IN_GRACE_PERIOD syscall.Errno = 5978 + ERROR_CLUSTER_CSV_IO_PAUSE_TIMEOUT syscall.Errno = 5979 + ERROR_NODE_NOT_ACTIVE_CLUSTER_MEMBER syscall.Errno = 5980 + ERROR_CLUSTER_RESOURCE_NOT_MONITORED syscall.Errno = 5981 + ERROR_CLUSTER_RESOURCE_DOES_NOT_SUPPORT_UNMONITORED syscall.Errno = 5982 + ERROR_CLUSTER_RESOURCE_IS_REPLICATED syscall.Errno = 5983 + ERROR_CLUSTER_NODE_ISOLATED syscall.Errno = 5984 + ERROR_CLUSTER_NODE_QUARANTINED syscall.Errno = 5985 + ERROR_CLUSTER_DATABASE_UPDATE_CONDITION_FAILED syscall.Errno = 5986 + ERROR_CLUSTER_SPACE_DEGRADED syscall.Errno = 5987 + ERROR_CLUSTER_TOKEN_DELEGATION_NOT_SUPPORTED syscall.Errno = 5988 + ERROR_CLUSTER_CSV_INVALID_HANDLE syscall.Errno = 5989 + ERROR_CLUSTER_CSV_SUPPORTED_ONLY_ON_COORDINATOR syscall.Errno = 5990 + ERROR_GROUPSET_NOT_AVAILABLE syscall.Errno = 5991 + ERROR_GROUPSET_NOT_FOUND syscall.Errno = 5992 + ERROR_GROUPSET_CANT_PROVIDE syscall.Errno = 5993 + ERROR_CLUSTER_FAULT_DOMAIN_PARENT_NOT_FOUND syscall.Errno = 5994 + ERROR_CLUSTER_FAULT_DOMAIN_INVALID_HIERARCHY syscall.Errno = 5995 + ERROR_CLUSTER_FAULT_DOMAIN_FAILED_S2D_VALIDATION syscall.Errno = 5996 + ERROR_CLUSTER_FAULT_DOMAIN_S2D_CONNECTIVITY_LOSS syscall.Errno = 5997 + ERROR_CLUSTER_INVALID_INFRASTRUCTURE_FILESERVER_NAME syscall.Errno = 5998 + ERROR_CLUSTERSET_MANAGEMENT_CLUSTER_UNREACHABLE syscall.Errno = 5999 + ERROR_ENCRYPTION_FAILED syscall.Errno = 6000 + ERROR_DECRYPTION_FAILED syscall.Errno = 6001 + ERROR_FILE_ENCRYPTED syscall.Errno = 6002 + ERROR_NO_RECOVERY_POLICY syscall.Errno = 6003 + ERROR_NO_EFS syscall.Errno = 6004 + ERROR_WRONG_EFS syscall.Errno = 6005 + ERROR_NO_USER_KEYS syscall.Errno = 6006 + ERROR_FILE_NOT_ENCRYPTED syscall.Errno = 6007 + ERROR_NOT_EXPORT_FORMAT syscall.Errno = 6008 + ERROR_FILE_READ_ONLY syscall.Errno = 6009 + ERROR_DIR_EFS_DISALLOWED syscall.Errno = 6010 + ERROR_EFS_SERVER_NOT_TRUSTED syscall.Errno = 6011 + ERROR_BAD_RECOVERY_POLICY syscall.Errno = 6012 + ERROR_EFS_ALG_BLOB_TOO_BIG syscall.Errno = 6013 + ERROR_VOLUME_NOT_SUPPORT_EFS syscall.Errno = 6014 + ERROR_EFS_DISABLED syscall.Errno = 6015 + ERROR_EFS_VERSION_NOT_SUPPORT syscall.Errno = 6016 + ERROR_CS_ENCRYPTION_INVALID_SERVER_RESPONSE syscall.Errno = 6017 + ERROR_CS_ENCRYPTION_UNSUPPORTED_SERVER syscall.Errno = 6018 + ERROR_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE syscall.Errno = 6019 + ERROR_CS_ENCRYPTION_NEW_ENCRYPTED_FILE syscall.Errno = 6020 + ERROR_CS_ENCRYPTION_FILE_NOT_CSE syscall.Errno = 6021 + ERROR_ENCRYPTION_POLICY_DENIES_OPERATION syscall.Errno = 6022 + ERROR_WIP_ENCRYPTION_FAILED syscall.Errno = 6023 + ERROR_NO_BROWSER_SERVERS_FOUND syscall.Errno = 6118 + SCHED_E_SERVICE_NOT_LOCALSYSTEM syscall.Errno = 6200 + ERROR_LOG_SECTOR_INVALID syscall.Errno = 6600 + ERROR_LOG_SECTOR_PARITY_INVALID syscall.Errno = 6601 + ERROR_LOG_SECTOR_REMAPPED syscall.Errno = 6602 + ERROR_LOG_BLOCK_INCOMPLETE syscall.Errno = 6603 + ERROR_LOG_INVALID_RANGE syscall.Errno = 6604 + ERROR_LOG_BLOCKS_EXHAUSTED syscall.Errno = 6605 + ERROR_LOG_READ_CONTEXT_INVALID syscall.Errno = 6606 + ERROR_LOG_RESTART_INVALID syscall.Errno = 6607 + ERROR_LOG_BLOCK_VERSION syscall.Errno = 6608 + ERROR_LOG_BLOCK_INVALID syscall.Errno = 6609 + ERROR_LOG_READ_MODE_INVALID syscall.Errno = 6610 + ERROR_LOG_NO_RESTART syscall.Errno = 6611 + ERROR_LOG_METADATA_CORRUPT syscall.Errno = 6612 + ERROR_LOG_METADATA_INVALID syscall.Errno = 6613 + ERROR_LOG_METADATA_INCONSISTENT syscall.Errno = 6614 + ERROR_LOG_RESERVATION_INVALID syscall.Errno = 6615 + ERROR_LOG_CANT_DELETE syscall.Errno = 6616 + ERROR_LOG_CONTAINER_LIMIT_EXCEEDED syscall.Errno = 6617 + ERROR_LOG_START_OF_LOG syscall.Errno = 6618 + ERROR_LOG_POLICY_ALREADY_INSTALLED syscall.Errno = 6619 + ERROR_LOG_POLICY_NOT_INSTALLED syscall.Errno = 6620 + ERROR_LOG_POLICY_INVALID syscall.Errno = 6621 + ERROR_LOG_POLICY_CONFLICT syscall.Errno = 6622 + ERROR_LOG_PINNED_ARCHIVE_TAIL syscall.Errno = 6623 + ERROR_LOG_RECORD_NONEXISTENT syscall.Errno = 6624 + ERROR_LOG_RECORDS_RESERVED_INVALID syscall.Errno = 6625 + ERROR_LOG_SPACE_RESERVED_INVALID syscall.Errno = 6626 + ERROR_LOG_TAIL_INVALID syscall.Errno = 6627 + ERROR_LOG_FULL syscall.Errno = 6628 + ERROR_COULD_NOT_RESIZE_LOG syscall.Errno = 6629 + ERROR_LOG_MULTIPLEXED syscall.Errno = 6630 + ERROR_LOG_DEDICATED syscall.Errno = 6631 + ERROR_LOG_ARCHIVE_NOT_IN_PROGRESS syscall.Errno = 6632 + ERROR_LOG_ARCHIVE_IN_PROGRESS syscall.Errno = 6633 + ERROR_LOG_EPHEMERAL syscall.Errno = 6634 + ERROR_LOG_NOT_ENOUGH_CONTAINERS syscall.Errno = 6635 + ERROR_LOG_CLIENT_ALREADY_REGISTERED syscall.Errno = 6636 + ERROR_LOG_CLIENT_NOT_REGISTERED syscall.Errno = 6637 + ERROR_LOG_FULL_HANDLER_IN_PROGRESS syscall.Errno = 6638 + ERROR_LOG_CONTAINER_READ_FAILED syscall.Errno = 6639 + ERROR_LOG_CONTAINER_WRITE_FAILED syscall.Errno = 6640 + ERROR_LOG_CONTAINER_OPEN_FAILED syscall.Errno = 6641 + ERROR_LOG_CONTAINER_STATE_INVALID syscall.Errno = 6642 + ERROR_LOG_STATE_INVALID syscall.Errno = 6643 + ERROR_LOG_PINNED syscall.Errno = 6644 + ERROR_LOG_METADATA_FLUSH_FAILED syscall.Errno = 6645 + ERROR_LOG_INCONSISTENT_SECURITY syscall.Errno = 6646 + ERROR_LOG_APPENDED_FLUSH_FAILED syscall.Errno = 6647 + ERROR_LOG_PINNED_RESERVATION syscall.Errno = 6648 + ERROR_INVALID_TRANSACTION syscall.Errno = 6700 + ERROR_TRANSACTION_NOT_ACTIVE syscall.Errno = 6701 + ERROR_TRANSACTION_REQUEST_NOT_VALID syscall.Errno = 6702 + ERROR_TRANSACTION_NOT_REQUESTED syscall.Errno = 6703 + ERROR_TRANSACTION_ALREADY_ABORTED syscall.Errno = 6704 + ERROR_TRANSACTION_ALREADY_COMMITTED syscall.Errno = 6705 + ERROR_TM_INITIALIZATION_FAILED syscall.Errno = 6706 + ERROR_RESOURCEMANAGER_READ_ONLY syscall.Errno = 6707 + ERROR_TRANSACTION_NOT_JOINED syscall.Errno = 6708 + ERROR_TRANSACTION_SUPERIOR_EXISTS syscall.Errno = 6709 + ERROR_CRM_PROTOCOL_ALREADY_EXISTS syscall.Errno = 6710 + ERROR_TRANSACTION_PROPAGATION_FAILED syscall.Errno = 6711 + ERROR_CRM_PROTOCOL_NOT_FOUND syscall.Errno = 6712 + ERROR_TRANSACTION_INVALID_MARSHALL_BUFFER syscall.Errno = 6713 + ERROR_CURRENT_TRANSACTION_NOT_VALID syscall.Errno = 6714 + ERROR_TRANSACTION_NOT_FOUND syscall.Errno = 6715 + ERROR_RESOURCEMANAGER_NOT_FOUND syscall.Errno = 6716 + ERROR_ENLISTMENT_NOT_FOUND syscall.Errno = 6717 + ERROR_TRANSACTIONMANAGER_NOT_FOUND syscall.Errno = 6718 + ERROR_TRANSACTIONMANAGER_NOT_ONLINE syscall.Errno = 6719 + ERROR_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION syscall.Errno = 6720 + ERROR_TRANSACTION_NOT_ROOT syscall.Errno = 6721 + ERROR_TRANSACTION_OBJECT_EXPIRED syscall.Errno = 6722 + ERROR_TRANSACTION_RESPONSE_NOT_ENLISTED syscall.Errno = 6723 + ERROR_TRANSACTION_RECORD_TOO_LONG syscall.Errno = 6724 + ERROR_IMPLICIT_TRANSACTION_NOT_SUPPORTED syscall.Errno = 6725 + ERROR_TRANSACTION_INTEGRITY_VIOLATED syscall.Errno = 6726 + ERROR_TRANSACTIONMANAGER_IDENTITY_MISMATCH syscall.Errno = 6727 + ERROR_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT syscall.Errno = 6728 + ERROR_TRANSACTION_MUST_WRITETHROUGH syscall.Errno = 6729 + ERROR_TRANSACTION_NO_SUPERIOR syscall.Errno = 6730 + ERROR_HEURISTIC_DAMAGE_POSSIBLE syscall.Errno = 6731 + ERROR_TRANSACTIONAL_CONFLICT syscall.Errno = 6800 + ERROR_RM_NOT_ACTIVE syscall.Errno = 6801 + ERROR_RM_METADATA_CORRUPT syscall.Errno = 6802 + ERROR_DIRECTORY_NOT_RM syscall.Errno = 6803 + ERROR_TRANSACTIONS_UNSUPPORTED_REMOTE syscall.Errno = 6805 + ERROR_LOG_RESIZE_INVALID_SIZE syscall.Errno = 6806 + ERROR_OBJECT_NO_LONGER_EXISTS syscall.Errno = 6807 + ERROR_STREAM_MINIVERSION_NOT_FOUND syscall.Errno = 6808 + ERROR_STREAM_MINIVERSION_NOT_VALID syscall.Errno = 6809 + ERROR_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION syscall.Errno = 6810 + ERROR_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT syscall.Errno = 6811 + ERROR_CANT_CREATE_MORE_STREAM_MINIVERSIONS syscall.Errno = 6812 + ERROR_REMOTE_FILE_VERSION_MISMATCH syscall.Errno = 6814 + ERROR_HANDLE_NO_LONGER_VALID syscall.Errno = 6815 + ERROR_NO_TXF_METADATA syscall.Errno = 6816 + ERROR_LOG_CORRUPTION_DETECTED syscall.Errno = 6817 + ERROR_CANT_RECOVER_WITH_HANDLE_OPEN syscall.Errno = 6818 + ERROR_RM_DISCONNECTED syscall.Errno = 6819 + ERROR_ENLISTMENT_NOT_SUPERIOR syscall.Errno = 6820 + ERROR_RECOVERY_NOT_NEEDED syscall.Errno = 6821 + ERROR_RM_ALREADY_STARTED syscall.Errno = 6822 + ERROR_FILE_IDENTITY_NOT_PERSISTENT syscall.Errno = 6823 + ERROR_CANT_BREAK_TRANSACTIONAL_DEPENDENCY syscall.Errno = 6824 + ERROR_CANT_CROSS_RM_BOUNDARY syscall.Errno = 6825 + ERROR_TXF_DIR_NOT_EMPTY syscall.Errno = 6826 + ERROR_INDOUBT_TRANSACTIONS_EXIST syscall.Errno = 6827 + ERROR_TM_VOLATILE syscall.Errno = 6828 + ERROR_ROLLBACK_TIMER_EXPIRED syscall.Errno = 6829 + ERROR_TXF_ATTRIBUTE_CORRUPT syscall.Errno = 6830 + ERROR_EFS_NOT_ALLOWED_IN_TRANSACTION syscall.Errno = 6831 + ERROR_TRANSACTIONAL_OPEN_NOT_ALLOWED syscall.Errno = 6832 + ERROR_LOG_GROWTH_FAILED syscall.Errno = 6833 + ERROR_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE syscall.Errno = 6834 + ERROR_TXF_METADATA_ALREADY_PRESENT syscall.Errno = 6835 + ERROR_TRANSACTION_SCOPE_CALLBACKS_NOT_SET syscall.Errno = 6836 + ERROR_TRANSACTION_REQUIRED_PROMOTION syscall.Errno = 6837 + ERROR_CANNOT_EXECUTE_FILE_IN_TRANSACTION syscall.Errno = 6838 + ERROR_TRANSACTIONS_NOT_FROZEN syscall.Errno = 6839 + ERROR_TRANSACTION_FREEZE_IN_PROGRESS syscall.Errno = 6840 + ERROR_NOT_SNAPSHOT_VOLUME syscall.Errno = 6841 + ERROR_NO_SAVEPOINT_WITH_OPEN_FILES syscall.Errno = 6842 + ERROR_DATA_LOST_REPAIR syscall.Errno = 6843 + ERROR_SPARSE_NOT_ALLOWED_IN_TRANSACTION syscall.Errno = 6844 + ERROR_TM_IDENTITY_MISMATCH syscall.Errno = 6845 + ERROR_FLOATED_SECTION syscall.Errno = 6846 + ERROR_CANNOT_ACCEPT_TRANSACTED_WORK syscall.Errno = 6847 + ERROR_CANNOT_ABORT_TRANSACTIONS syscall.Errno = 6848 + ERROR_BAD_CLUSTERS syscall.Errno = 6849 + ERROR_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION syscall.Errno = 6850 + ERROR_VOLUME_DIRTY syscall.Errno = 6851 + ERROR_NO_LINK_TRACKING_IN_TRANSACTION syscall.Errno = 6852 + ERROR_OPERATION_NOT_SUPPORTED_IN_TRANSACTION syscall.Errno = 6853 + ERROR_EXPIRED_HANDLE syscall.Errno = 6854 + ERROR_TRANSACTION_NOT_ENLISTED syscall.Errno = 6855 + ERROR_CTX_WINSTATION_NAME_INVALID syscall.Errno = 7001 + ERROR_CTX_INVALID_PD syscall.Errno = 7002 + ERROR_CTX_PD_NOT_FOUND syscall.Errno = 7003 + ERROR_CTX_WD_NOT_FOUND syscall.Errno = 7004 + ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY syscall.Errno = 7005 + ERROR_CTX_SERVICE_NAME_COLLISION syscall.Errno = 7006 + ERROR_CTX_CLOSE_PENDING syscall.Errno = 7007 + ERROR_CTX_NO_OUTBUF syscall.Errno = 7008 + ERROR_CTX_MODEM_INF_NOT_FOUND syscall.Errno = 7009 + ERROR_CTX_INVALID_MODEMNAME syscall.Errno = 7010 + ERROR_CTX_MODEM_RESPONSE_ERROR syscall.Errno = 7011 + ERROR_CTX_MODEM_RESPONSE_TIMEOUT syscall.Errno = 7012 + ERROR_CTX_MODEM_RESPONSE_NO_CARRIER syscall.Errno = 7013 + ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE syscall.Errno = 7014 + ERROR_CTX_MODEM_RESPONSE_BUSY syscall.Errno = 7015 + ERROR_CTX_MODEM_RESPONSE_VOICE syscall.Errno = 7016 + ERROR_CTX_TD_ERROR syscall.Errno = 7017 + ERROR_CTX_WINSTATION_NOT_FOUND syscall.Errno = 7022 + ERROR_CTX_WINSTATION_ALREADY_EXISTS syscall.Errno = 7023 + ERROR_CTX_WINSTATION_BUSY syscall.Errno = 7024 + ERROR_CTX_BAD_VIDEO_MODE syscall.Errno = 7025 + ERROR_CTX_GRAPHICS_INVALID syscall.Errno = 7035 + ERROR_CTX_LOGON_DISABLED syscall.Errno = 7037 + ERROR_CTX_NOT_CONSOLE syscall.Errno = 7038 + ERROR_CTX_CLIENT_QUERY_TIMEOUT syscall.Errno = 7040 + ERROR_CTX_CONSOLE_DISCONNECT syscall.Errno = 7041 + ERROR_CTX_CONSOLE_CONNECT syscall.Errno = 7042 + ERROR_CTX_SHADOW_DENIED syscall.Errno = 7044 + ERROR_CTX_WINSTATION_ACCESS_DENIED syscall.Errno = 7045 + ERROR_CTX_INVALID_WD syscall.Errno = 7049 + ERROR_CTX_SHADOW_INVALID syscall.Errno = 7050 + ERROR_CTX_SHADOW_DISABLED syscall.Errno = 7051 + ERROR_CTX_CLIENT_LICENSE_IN_USE syscall.Errno = 7052 + ERROR_CTX_CLIENT_LICENSE_NOT_SET syscall.Errno = 7053 + ERROR_CTX_LICENSE_NOT_AVAILABLE syscall.Errno = 7054 + ERROR_CTX_LICENSE_CLIENT_INVALID syscall.Errno = 7055 + ERROR_CTX_LICENSE_EXPIRED syscall.Errno = 7056 + ERROR_CTX_SHADOW_NOT_RUNNING syscall.Errno = 7057 + ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE syscall.Errno = 7058 + ERROR_ACTIVATION_COUNT_EXCEEDED syscall.Errno = 7059 + ERROR_CTX_WINSTATIONS_DISABLED syscall.Errno = 7060 + ERROR_CTX_ENCRYPTION_LEVEL_REQUIRED syscall.Errno = 7061 + ERROR_CTX_SESSION_IN_USE syscall.Errno = 7062 + ERROR_CTX_NO_FORCE_LOGOFF syscall.Errno = 7063 + ERROR_CTX_ACCOUNT_RESTRICTION syscall.Errno = 7064 + ERROR_RDP_PROTOCOL_ERROR syscall.Errno = 7065 + ERROR_CTX_CDM_CONNECT syscall.Errno = 7066 + ERROR_CTX_CDM_DISCONNECT syscall.Errno = 7067 + ERROR_CTX_SECURITY_LAYER_ERROR syscall.Errno = 7068 + ERROR_TS_INCOMPATIBLE_SESSIONS syscall.Errno = 7069 + ERROR_TS_VIDEO_SUBSYSTEM_ERROR syscall.Errno = 7070 + FRS_ERR_INVALID_API_SEQUENCE syscall.Errno = 8001 + FRS_ERR_STARTING_SERVICE syscall.Errno = 8002 + FRS_ERR_STOPPING_SERVICE syscall.Errno = 8003 + FRS_ERR_INTERNAL_API syscall.Errno = 8004 + FRS_ERR_INTERNAL syscall.Errno = 8005 + FRS_ERR_SERVICE_COMM syscall.Errno = 8006 + FRS_ERR_INSUFFICIENT_PRIV syscall.Errno = 8007 + FRS_ERR_AUTHENTICATION syscall.Errno = 8008 + FRS_ERR_PARENT_INSUFFICIENT_PRIV syscall.Errno = 8009 + FRS_ERR_PARENT_AUTHENTICATION syscall.Errno = 8010 + FRS_ERR_CHILD_TO_PARENT_COMM syscall.Errno = 8011 + FRS_ERR_PARENT_TO_CHILD_COMM syscall.Errno = 8012 + FRS_ERR_SYSVOL_POPULATE syscall.Errno = 8013 + FRS_ERR_SYSVOL_POPULATE_TIMEOUT syscall.Errno = 8014 + FRS_ERR_SYSVOL_IS_BUSY syscall.Errno = 8015 + FRS_ERR_SYSVOL_DEMOTE syscall.Errno = 8016 + FRS_ERR_INVALID_SERVICE_PARAMETER syscall.Errno = 8017 + DS_S_SUCCESS = ERROR_SUCCESS + ERROR_DS_NOT_INSTALLED syscall.Errno = 8200 + ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY syscall.Errno = 8201 + ERROR_DS_NO_ATTRIBUTE_OR_VALUE syscall.Errno = 8202 + ERROR_DS_INVALID_ATTRIBUTE_SYNTAX syscall.Errno = 8203 + ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED syscall.Errno = 8204 + ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS syscall.Errno = 8205 + ERROR_DS_BUSY syscall.Errno = 8206 + ERROR_DS_UNAVAILABLE syscall.Errno = 8207 + ERROR_DS_NO_RIDS_ALLOCATED syscall.Errno = 8208 + ERROR_DS_NO_MORE_RIDS syscall.Errno = 8209 + ERROR_DS_INCORRECT_ROLE_OWNER syscall.Errno = 8210 + ERROR_DS_RIDMGR_INIT_ERROR syscall.Errno = 8211 + ERROR_DS_OBJ_CLASS_VIOLATION syscall.Errno = 8212 + ERROR_DS_CANT_ON_NON_LEAF syscall.Errno = 8213 + ERROR_DS_CANT_ON_RDN syscall.Errno = 8214 + ERROR_DS_CANT_MOD_OBJ_CLASS syscall.Errno = 8215 + ERROR_DS_CROSS_DOM_MOVE_ERROR syscall.Errno = 8216 + ERROR_DS_GC_NOT_AVAILABLE syscall.Errno = 8217 + ERROR_SHARED_POLICY syscall.Errno = 8218 + ERROR_POLICY_OBJECT_NOT_FOUND syscall.Errno = 8219 + ERROR_POLICY_ONLY_IN_DS syscall.Errno = 8220 + ERROR_PROMOTION_ACTIVE syscall.Errno = 8221 + ERROR_NO_PROMOTION_ACTIVE syscall.Errno = 8222 + ERROR_DS_OPERATIONS_ERROR syscall.Errno = 8224 + ERROR_DS_PROTOCOL_ERROR syscall.Errno = 8225 + ERROR_DS_TIMELIMIT_EXCEEDED syscall.Errno = 8226 + ERROR_DS_SIZELIMIT_EXCEEDED syscall.Errno = 8227 + ERROR_DS_ADMIN_LIMIT_EXCEEDED syscall.Errno = 8228 + ERROR_DS_COMPARE_FALSE syscall.Errno = 8229 + ERROR_DS_COMPARE_TRUE syscall.Errno = 8230 + ERROR_DS_AUTH_METHOD_NOT_SUPPORTED syscall.Errno = 8231 + ERROR_DS_STRONG_AUTH_REQUIRED syscall.Errno = 8232 + ERROR_DS_INAPPROPRIATE_AUTH syscall.Errno = 8233 + ERROR_DS_AUTH_UNKNOWN syscall.Errno = 8234 + ERROR_DS_REFERRAL syscall.Errno = 8235 + ERROR_DS_UNAVAILABLE_CRIT_EXTENSION syscall.Errno = 8236 + ERROR_DS_CONFIDENTIALITY_REQUIRED syscall.Errno = 8237 + ERROR_DS_INAPPROPRIATE_MATCHING syscall.Errno = 8238 + ERROR_DS_CONSTRAINT_VIOLATION syscall.Errno = 8239 + ERROR_DS_NO_SUCH_OBJECT syscall.Errno = 8240 + ERROR_DS_ALIAS_PROBLEM syscall.Errno = 8241 + ERROR_DS_INVALID_DN_SYNTAX syscall.Errno = 8242 + ERROR_DS_IS_LEAF syscall.Errno = 8243 + ERROR_DS_ALIAS_DEREF_PROBLEM syscall.Errno = 8244 + ERROR_DS_UNWILLING_TO_PERFORM syscall.Errno = 8245 + ERROR_DS_LOOP_DETECT syscall.Errno = 8246 + ERROR_DS_NAMING_VIOLATION syscall.Errno = 8247 + ERROR_DS_OBJECT_RESULTS_TOO_LARGE syscall.Errno = 8248 + ERROR_DS_AFFECTS_MULTIPLE_DSAS syscall.Errno = 8249 + ERROR_DS_SERVER_DOWN syscall.Errno = 8250 + ERROR_DS_LOCAL_ERROR syscall.Errno = 8251 + ERROR_DS_ENCODING_ERROR syscall.Errno = 8252 + ERROR_DS_DECODING_ERROR syscall.Errno = 8253 + ERROR_DS_FILTER_UNKNOWN syscall.Errno = 8254 + ERROR_DS_PARAM_ERROR syscall.Errno = 8255 + ERROR_DS_NOT_SUPPORTED syscall.Errno = 8256 + ERROR_DS_NO_RESULTS_RETURNED syscall.Errno = 8257 + ERROR_DS_CONTROL_NOT_FOUND syscall.Errno = 8258 + ERROR_DS_CLIENT_LOOP syscall.Errno = 8259 + ERROR_DS_REFERRAL_LIMIT_EXCEEDED syscall.Errno = 8260 + ERROR_DS_SORT_CONTROL_MISSING syscall.Errno = 8261 + ERROR_DS_OFFSET_RANGE_ERROR syscall.Errno = 8262 + ERROR_DS_RIDMGR_DISABLED syscall.Errno = 8263 + ERROR_DS_ROOT_MUST_BE_NC syscall.Errno = 8301 + ERROR_DS_ADD_REPLICA_INHIBITED syscall.Errno = 8302 + ERROR_DS_ATT_NOT_DEF_IN_SCHEMA syscall.Errno = 8303 + ERROR_DS_MAX_OBJ_SIZE_EXCEEDED syscall.Errno = 8304 + ERROR_DS_OBJ_STRING_NAME_EXISTS syscall.Errno = 8305 + ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA syscall.Errno = 8306 + ERROR_DS_RDN_DOESNT_MATCH_SCHEMA syscall.Errno = 8307 + ERROR_DS_NO_REQUESTED_ATTS_FOUND syscall.Errno = 8308 + ERROR_DS_USER_BUFFER_TO_SMALL syscall.Errno = 8309 + ERROR_DS_ATT_IS_NOT_ON_OBJ syscall.Errno = 8310 + ERROR_DS_ILLEGAL_MOD_OPERATION syscall.Errno = 8311 + ERROR_DS_OBJ_TOO_LARGE syscall.Errno = 8312 + ERROR_DS_BAD_INSTANCE_TYPE syscall.Errno = 8313 + ERROR_DS_MASTERDSA_REQUIRED syscall.Errno = 8314 + ERROR_DS_OBJECT_CLASS_REQUIRED syscall.Errno = 8315 + ERROR_DS_MISSING_REQUIRED_ATT syscall.Errno = 8316 + ERROR_DS_ATT_NOT_DEF_FOR_CLASS syscall.Errno = 8317 + ERROR_DS_ATT_ALREADY_EXISTS syscall.Errno = 8318 + ERROR_DS_CANT_ADD_ATT_VALUES syscall.Errno = 8320 + ERROR_DS_SINGLE_VALUE_CONSTRAINT syscall.Errno = 8321 + ERROR_DS_RANGE_CONSTRAINT syscall.Errno = 8322 + ERROR_DS_ATT_VAL_ALREADY_EXISTS syscall.Errno = 8323 + ERROR_DS_CANT_REM_MISSING_ATT syscall.Errno = 8324 + ERROR_DS_CANT_REM_MISSING_ATT_VAL syscall.Errno = 8325 + ERROR_DS_ROOT_CANT_BE_SUBREF syscall.Errno = 8326 + ERROR_DS_NO_CHAINING syscall.Errno = 8327 + ERROR_DS_NO_CHAINED_EVAL syscall.Errno = 8328 + ERROR_DS_NO_PARENT_OBJECT syscall.Errno = 8329 + ERROR_DS_PARENT_IS_AN_ALIAS syscall.Errno = 8330 + ERROR_DS_CANT_MIX_MASTER_AND_REPS syscall.Errno = 8331 + ERROR_DS_CHILDREN_EXIST syscall.Errno = 8332 + ERROR_DS_OBJ_NOT_FOUND syscall.Errno = 8333 + ERROR_DS_ALIASED_OBJ_MISSING syscall.Errno = 8334 + ERROR_DS_BAD_NAME_SYNTAX syscall.Errno = 8335 + ERROR_DS_ALIAS_POINTS_TO_ALIAS syscall.Errno = 8336 + ERROR_DS_CANT_DEREF_ALIAS syscall.Errno = 8337 + ERROR_DS_OUT_OF_SCOPE syscall.Errno = 8338 + ERROR_DS_OBJECT_BEING_REMOVED syscall.Errno = 8339 + ERROR_DS_CANT_DELETE_DSA_OBJ syscall.Errno = 8340 + ERROR_DS_GENERIC_ERROR syscall.Errno = 8341 + ERROR_DS_DSA_MUST_BE_INT_MASTER syscall.Errno = 8342 + ERROR_DS_CLASS_NOT_DSA syscall.Errno = 8343 + ERROR_DS_INSUFF_ACCESS_RIGHTS syscall.Errno = 8344 + ERROR_DS_ILLEGAL_SUPERIOR syscall.Errno = 8345 + ERROR_DS_ATTRIBUTE_OWNED_BY_SAM syscall.Errno = 8346 + ERROR_DS_NAME_TOO_MANY_PARTS syscall.Errno = 8347 + ERROR_DS_NAME_TOO_LONG syscall.Errno = 8348 + ERROR_DS_NAME_VALUE_TOO_LONG syscall.Errno = 8349 + ERROR_DS_NAME_UNPARSEABLE syscall.Errno = 8350 + ERROR_DS_NAME_TYPE_UNKNOWN syscall.Errno = 8351 + ERROR_DS_NOT_AN_OBJECT syscall.Errno = 8352 + ERROR_DS_SEC_DESC_TOO_SHORT syscall.Errno = 8353 + ERROR_DS_SEC_DESC_INVALID syscall.Errno = 8354 + ERROR_DS_NO_DELETED_NAME syscall.Errno = 8355 + ERROR_DS_SUBREF_MUST_HAVE_PARENT syscall.Errno = 8356 + ERROR_DS_NCNAME_MUST_BE_NC syscall.Errno = 8357 + ERROR_DS_CANT_ADD_SYSTEM_ONLY syscall.Errno = 8358 + ERROR_DS_CLASS_MUST_BE_CONCRETE syscall.Errno = 8359 + ERROR_DS_INVALID_DMD syscall.Errno = 8360 + ERROR_DS_OBJ_GUID_EXISTS syscall.Errno = 8361 + ERROR_DS_NOT_ON_BACKLINK syscall.Errno = 8362 + ERROR_DS_NO_CROSSREF_FOR_NC syscall.Errno = 8363 + ERROR_DS_SHUTTING_DOWN syscall.Errno = 8364 + ERROR_DS_UNKNOWN_OPERATION syscall.Errno = 8365 + ERROR_DS_INVALID_ROLE_OWNER syscall.Errno = 8366 + ERROR_DS_COULDNT_CONTACT_FSMO syscall.Errno = 8367 + ERROR_DS_CROSS_NC_DN_RENAME syscall.Errno = 8368 + ERROR_DS_CANT_MOD_SYSTEM_ONLY syscall.Errno = 8369 + ERROR_DS_REPLICATOR_ONLY syscall.Errno = 8370 + ERROR_DS_OBJ_CLASS_NOT_DEFINED syscall.Errno = 8371 + ERROR_DS_OBJ_CLASS_NOT_SUBCLASS syscall.Errno = 8372 + ERROR_DS_NAME_REFERENCE_INVALID syscall.Errno = 8373 + ERROR_DS_CROSS_REF_EXISTS syscall.Errno = 8374 + ERROR_DS_CANT_DEL_MASTER_CROSSREF syscall.Errno = 8375 + ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD syscall.Errno = 8376 + ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX syscall.Errno = 8377 + ERROR_DS_DUP_RDN syscall.Errno = 8378 + ERROR_DS_DUP_OID syscall.Errno = 8379 + ERROR_DS_DUP_MAPI_ID syscall.Errno = 8380 + ERROR_DS_DUP_SCHEMA_ID_GUID syscall.Errno = 8381 + ERROR_DS_DUP_LDAP_DISPLAY_NAME syscall.Errno = 8382 + ERROR_DS_SEMANTIC_ATT_TEST syscall.Errno = 8383 + ERROR_DS_SYNTAX_MISMATCH syscall.Errno = 8384 + ERROR_DS_EXISTS_IN_MUST_HAVE syscall.Errno = 8385 + ERROR_DS_EXISTS_IN_MAY_HAVE syscall.Errno = 8386 + ERROR_DS_NONEXISTENT_MAY_HAVE syscall.Errno = 8387 + ERROR_DS_NONEXISTENT_MUST_HAVE syscall.Errno = 8388 + ERROR_DS_AUX_CLS_TEST_FAIL syscall.Errno = 8389 + ERROR_DS_NONEXISTENT_POSS_SUP syscall.Errno = 8390 + ERROR_DS_SUB_CLS_TEST_FAIL syscall.Errno = 8391 + ERROR_DS_BAD_RDN_ATT_ID_SYNTAX syscall.Errno = 8392 + ERROR_DS_EXISTS_IN_AUX_CLS syscall.Errno = 8393 + ERROR_DS_EXISTS_IN_SUB_CLS syscall.Errno = 8394 + ERROR_DS_EXISTS_IN_POSS_SUP syscall.Errno = 8395 + ERROR_DS_RECALCSCHEMA_FAILED syscall.Errno = 8396 + ERROR_DS_TREE_DELETE_NOT_FINISHED syscall.Errno = 8397 + ERROR_DS_CANT_DELETE syscall.Errno = 8398 + ERROR_DS_ATT_SCHEMA_REQ_ID syscall.Errno = 8399 + ERROR_DS_BAD_ATT_SCHEMA_SYNTAX syscall.Errno = 8400 + ERROR_DS_CANT_CACHE_ATT syscall.Errno = 8401 + ERROR_DS_CANT_CACHE_CLASS syscall.Errno = 8402 + ERROR_DS_CANT_REMOVE_ATT_CACHE syscall.Errno = 8403 + ERROR_DS_CANT_REMOVE_CLASS_CACHE syscall.Errno = 8404 + ERROR_DS_CANT_RETRIEVE_DN syscall.Errno = 8405 + ERROR_DS_MISSING_SUPREF syscall.Errno = 8406 + ERROR_DS_CANT_RETRIEVE_INSTANCE syscall.Errno = 8407 + ERROR_DS_CODE_INCONSISTENCY syscall.Errno = 8408 + ERROR_DS_DATABASE_ERROR syscall.Errno = 8409 + ERROR_DS_GOVERNSID_MISSING syscall.Errno = 8410 + ERROR_DS_MISSING_EXPECTED_ATT syscall.Errno = 8411 + ERROR_DS_NCNAME_MISSING_CR_REF syscall.Errno = 8412 + ERROR_DS_SECURITY_CHECKING_ERROR syscall.Errno = 8413 + ERROR_DS_SCHEMA_NOT_LOADED syscall.Errno = 8414 + ERROR_DS_SCHEMA_ALLOC_FAILED syscall.Errno = 8415 + ERROR_DS_ATT_SCHEMA_REQ_SYNTAX syscall.Errno = 8416 + ERROR_DS_GCVERIFY_ERROR syscall.Errno = 8417 + ERROR_DS_DRA_SCHEMA_MISMATCH syscall.Errno = 8418 + ERROR_DS_CANT_FIND_DSA_OBJ syscall.Errno = 8419 + ERROR_DS_CANT_FIND_EXPECTED_NC syscall.Errno = 8420 + ERROR_DS_CANT_FIND_NC_IN_CACHE syscall.Errno = 8421 + ERROR_DS_CANT_RETRIEVE_CHILD syscall.Errno = 8422 + ERROR_DS_SECURITY_ILLEGAL_MODIFY syscall.Errno = 8423 + ERROR_DS_CANT_REPLACE_HIDDEN_REC syscall.Errno = 8424 + ERROR_DS_BAD_HIERARCHY_FILE syscall.Errno = 8425 + ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED syscall.Errno = 8426 + ERROR_DS_CONFIG_PARAM_MISSING syscall.Errno = 8427 + ERROR_DS_COUNTING_AB_INDICES_FAILED syscall.Errno = 8428 + ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED syscall.Errno = 8429 + ERROR_DS_INTERNAL_FAILURE syscall.Errno = 8430 + ERROR_DS_UNKNOWN_ERROR syscall.Errno = 8431 + ERROR_DS_ROOT_REQUIRES_CLASS_TOP syscall.Errno = 8432 + ERROR_DS_REFUSING_FSMO_ROLES syscall.Errno = 8433 + ERROR_DS_MISSING_FSMO_SETTINGS syscall.Errno = 8434 + ERROR_DS_UNABLE_TO_SURRENDER_ROLES syscall.Errno = 8435 + ERROR_DS_DRA_GENERIC syscall.Errno = 8436 + ERROR_DS_DRA_INVALID_PARAMETER syscall.Errno = 8437 + ERROR_DS_DRA_BUSY syscall.Errno = 8438 + ERROR_DS_DRA_BAD_DN syscall.Errno = 8439 + ERROR_DS_DRA_BAD_NC syscall.Errno = 8440 + ERROR_DS_DRA_DN_EXISTS syscall.Errno = 8441 + ERROR_DS_DRA_INTERNAL_ERROR syscall.Errno = 8442 + ERROR_DS_DRA_INCONSISTENT_DIT syscall.Errno = 8443 + ERROR_DS_DRA_CONNECTION_FAILED syscall.Errno = 8444 + ERROR_DS_DRA_BAD_INSTANCE_TYPE syscall.Errno = 8445 + ERROR_DS_DRA_OUT_OF_MEM syscall.Errno = 8446 + ERROR_DS_DRA_MAIL_PROBLEM syscall.Errno = 8447 + ERROR_DS_DRA_REF_ALREADY_EXISTS syscall.Errno = 8448 + ERROR_DS_DRA_REF_NOT_FOUND syscall.Errno = 8449 + ERROR_DS_DRA_OBJ_IS_REP_SOURCE syscall.Errno = 8450 + ERROR_DS_DRA_DB_ERROR syscall.Errno = 8451 + ERROR_DS_DRA_NO_REPLICA syscall.Errno = 8452 + ERROR_DS_DRA_ACCESS_DENIED syscall.Errno = 8453 + ERROR_DS_DRA_NOT_SUPPORTED syscall.Errno = 8454 + ERROR_DS_DRA_RPC_CANCELLED syscall.Errno = 8455 + ERROR_DS_DRA_SOURCE_DISABLED syscall.Errno = 8456 + ERROR_DS_DRA_SINK_DISABLED syscall.Errno = 8457 + ERROR_DS_DRA_NAME_COLLISION syscall.Errno = 8458 + ERROR_DS_DRA_SOURCE_REINSTALLED syscall.Errno = 8459 + ERROR_DS_DRA_MISSING_PARENT syscall.Errno = 8460 + ERROR_DS_DRA_PREEMPTED syscall.Errno = 8461 + ERROR_DS_DRA_ABANDON_SYNC syscall.Errno = 8462 + ERROR_DS_DRA_SHUTDOWN syscall.Errno = 8463 + ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET syscall.Errno = 8464 + ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA syscall.Errno = 8465 + ERROR_DS_DRA_EXTN_CONNECTION_FAILED syscall.Errno = 8466 + ERROR_DS_INSTALL_SCHEMA_MISMATCH syscall.Errno = 8467 + ERROR_DS_DUP_LINK_ID syscall.Errno = 8468 + ERROR_DS_NAME_ERROR_RESOLVING syscall.Errno = 8469 + ERROR_DS_NAME_ERROR_NOT_FOUND syscall.Errno = 8470 + ERROR_DS_NAME_ERROR_NOT_UNIQUE syscall.Errno = 8471 + ERROR_DS_NAME_ERROR_NO_MAPPING syscall.Errno = 8472 + ERROR_DS_NAME_ERROR_DOMAIN_ONLY syscall.Errno = 8473 + ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING syscall.Errno = 8474 + ERROR_DS_CONSTRUCTED_ATT_MOD syscall.Errno = 8475 + ERROR_DS_WRONG_OM_OBJ_CLASS syscall.Errno = 8476 + ERROR_DS_DRA_REPL_PENDING syscall.Errno = 8477 + ERROR_DS_DS_REQUIRED syscall.Errno = 8478 + ERROR_DS_INVALID_LDAP_DISPLAY_NAME syscall.Errno = 8479 + ERROR_DS_NON_BASE_SEARCH syscall.Errno = 8480 + ERROR_DS_CANT_RETRIEVE_ATTS syscall.Errno = 8481 + ERROR_DS_BACKLINK_WITHOUT_LINK syscall.Errno = 8482 + ERROR_DS_EPOCH_MISMATCH syscall.Errno = 8483 + ERROR_DS_SRC_NAME_MISMATCH syscall.Errno = 8484 + ERROR_DS_SRC_AND_DST_NC_IDENTICAL syscall.Errno = 8485 + ERROR_DS_DST_NC_MISMATCH syscall.Errno = 8486 + ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC syscall.Errno = 8487 + ERROR_DS_SRC_GUID_MISMATCH syscall.Errno = 8488 + ERROR_DS_CANT_MOVE_DELETED_OBJECT syscall.Errno = 8489 + ERROR_DS_PDC_OPERATION_IN_PROGRESS syscall.Errno = 8490 + ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD syscall.Errno = 8491 + ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION syscall.Errno = 8492 + ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS syscall.Errno = 8493 + ERROR_DS_NC_MUST_HAVE_NC_PARENT syscall.Errno = 8494 + ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE syscall.Errno = 8495 + ERROR_DS_DST_DOMAIN_NOT_NATIVE syscall.Errno = 8496 + ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER syscall.Errno = 8497 + ERROR_DS_CANT_MOVE_ACCOUNT_GROUP syscall.Errno = 8498 + ERROR_DS_CANT_MOVE_RESOURCE_GROUP syscall.Errno = 8499 + ERROR_DS_INVALID_SEARCH_FLAG syscall.Errno = 8500 + ERROR_DS_NO_TREE_DELETE_ABOVE_NC syscall.Errno = 8501 + ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE syscall.Errno = 8502 + ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE syscall.Errno = 8503 + ERROR_DS_SAM_INIT_FAILURE syscall.Errno = 8504 + ERROR_DS_SENSITIVE_GROUP_VIOLATION syscall.Errno = 8505 + ERROR_DS_CANT_MOD_PRIMARYGROUPID syscall.Errno = 8506 + ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD syscall.Errno = 8507 + ERROR_DS_NONSAFE_SCHEMA_CHANGE syscall.Errno = 8508 + ERROR_DS_SCHEMA_UPDATE_DISALLOWED syscall.Errno = 8509 + ERROR_DS_CANT_CREATE_UNDER_SCHEMA syscall.Errno = 8510 + ERROR_DS_INSTALL_NO_SRC_SCH_VERSION syscall.Errno = 8511 + ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE syscall.Errno = 8512 + ERROR_DS_INVALID_GROUP_TYPE syscall.Errno = 8513 + ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN syscall.Errno = 8514 + ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN syscall.Errno = 8515 + ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER syscall.Errno = 8516 + ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER syscall.Errno = 8517 + ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER syscall.Errno = 8518 + ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER syscall.Errno = 8519 + ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER syscall.Errno = 8520 + ERROR_DS_HAVE_PRIMARY_MEMBERS syscall.Errno = 8521 + ERROR_DS_STRING_SD_CONVERSION_FAILED syscall.Errno = 8522 + ERROR_DS_NAMING_MASTER_GC syscall.Errno = 8523 + ERROR_DS_DNS_LOOKUP_FAILURE syscall.Errno = 8524 + ERROR_DS_COULDNT_UPDATE_SPNS syscall.Errno = 8525 + ERROR_DS_CANT_RETRIEVE_SD syscall.Errno = 8526 + ERROR_DS_KEY_NOT_UNIQUE syscall.Errno = 8527 + ERROR_DS_WRONG_LINKED_ATT_SYNTAX syscall.Errno = 8528 + ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD syscall.Errno = 8529 + ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY syscall.Errno = 8530 + ERROR_DS_CANT_START syscall.Errno = 8531 + ERROR_DS_INIT_FAILURE syscall.Errno = 8532 + ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION syscall.Errno = 8533 + ERROR_DS_SOURCE_DOMAIN_IN_FOREST syscall.Errno = 8534 + ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST syscall.Errno = 8535 + ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED syscall.Errno = 8536 + ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN syscall.Errno = 8537 + ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER syscall.Errno = 8538 + ERROR_DS_SRC_SID_EXISTS_IN_FOREST syscall.Errno = 8539 + ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH syscall.Errno = 8540 + ERROR_SAM_INIT_FAILURE syscall.Errno = 8541 + ERROR_DS_DRA_SCHEMA_INFO_SHIP syscall.Errno = 8542 + ERROR_DS_DRA_SCHEMA_CONFLICT syscall.Errno = 8543 + ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT syscall.Errno = 8544 + ERROR_DS_DRA_OBJ_NC_MISMATCH syscall.Errno = 8545 + ERROR_DS_NC_STILL_HAS_DSAS syscall.Errno = 8546 + ERROR_DS_GC_REQUIRED syscall.Errno = 8547 + ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY syscall.Errno = 8548 + ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS syscall.Errno = 8549 + ERROR_DS_CANT_ADD_TO_GC syscall.Errno = 8550 + ERROR_DS_NO_CHECKPOINT_WITH_PDC syscall.Errno = 8551 + ERROR_DS_SOURCE_AUDITING_NOT_ENABLED syscall.Errno = 8552 + ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC syscall.Errno = 8553 + ERROR_DS_INVALID_NAME_FOR_SPN syscall.Errno = 8554 + ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS syscall.Errno = 8555 + ERROR_DS_UNICODEPWD_NOT_IN_QUOTES syscall.Errno = 8556 + ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED syscall.Errno = 8557 + ERROR_DS_MUST_BE_RUN_ON_DST_DC syscall.Errno = 8558 + ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER syscall.Errno = 8559 + ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ syscall.Errno = 8560 + ERROR_DS_INIT_FAILURE_CONSOLE syscall.Errno = 8561 + ERROR_DS_SAM_INIT_FAILURE_CONSOLE syscall.Errno = 8562 + ERROR_DS_FOREST_VERSION_TOO_HIGH syscall.Errno = 8563 + ERROR_DS_DOMAIN_VERSION_TOO_HIGH syscall.Errno = 8564 + ERROR_DS_FOREST_VERSION_TOO_LOW syscall.Errno = 8565 + ERROR_DS_DOMAIN_VERSION_TOO_LOW syscall.Errno = 8566 + ERROR_DS_INCOMPATIBLE_VERSION syscall.Errno = 8567 + ERROR_DS_LOW_DSA_VERSION syscall.Errno = 8568 + ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN syscall.Errno = 8569 + ERROR_DS_NOT_SUPPORTED_SORT_ORDER syscall.Errno = 8570 + ERROR_DS_NAME_NOT_UNIQUE syscall.Errno = 8571 + ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4 syscall.Errno = 8572 + ERROR_DS_OUT_OF_VERSION_STORE syscall.Errno = 8573 + ERROR_DS_INCOMPATIBLE_CONTROLS_USED syscall.Errno = 8574 + ERROR_DS_NO_REF_DOMAIN syscall.Errno = 8575 + ERROR_DS_RESERVED_LINK_ID syscall.Errno = 8576 + ERROR_DS_LINK_ID_NOT_AVAILABLE syscall.Errno = 8577 + ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER syscall.Errno = 8578 + ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE syscall.Errno = 8579 + ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC syscall.Errno = 8580 + ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG syscall.Errno = 8581 + ERROR_DS_MODIFYDN_WRONG_GRANDPARENT syscall.Errno = 8582 + ERROR_DS_NAME_ERROR_TRUST_REFERRAL syscall.Errno = 8583 + ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER syscall.Errno = 8584 + ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD syscall.Errno = 8585 + ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2 syscall.Errno = 8586 + ERROR_DS_THREAD_LIMIT_EXCEEDED syscall.Errno = 8587 + ERROR_DS_NOT_CLOSEST syscall.Errno = 8588 + ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF syscall.Errno = 8589 + ERROR_DS_SINGLE_USER_MODE_FAILED syscall.Errno = 8590 + ERROR_DS_NTDSCRIPT_SYNTAX_ERROR syscall.Errno = 8591 + ERROR_DS_NTDSCRIPT_PROCESS_ERROR syscall.Errno = 8592 + ERROR_DS_DIFFERENT_REPL_EPOCHS syscall.Errno = 8593 + ERROR_DS_DRS_EXTENSIONS_CHANGED syscall.Errno = 8594 + ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR syscall.Errno = 8595 + ERROR_DS_NO_MSDS_INTID syscall.Errno = 8596 + ERROR_DS_DUP_MSDS_INTID syscall.Errno = 8597 + ERROR_DS_EXISTS_IN_RDNATTID syscall.Errno = 8598 + ERROR_DS_AUTHORIZATION_FAILED syscall.Errno = 8599 + ERROR_DS_INVALID_SCRIPT syscall.Errno = 8600 + ERROR_DS_REMOTE_CROSSREF_OP_FAILED syscall.Errno = 8601 + ERROR_DS_CROSS_REF_BUSY syscall.Errno = 8602 + ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN syscall.Errno = 8603 + ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC syscall.Errno = 8604 + ERROR_DS_DUPLICATE_ID_FOUND syscall.Errno = 8605 + ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT syscall.Errno = 8606 + ERROR_DS_GROUP_CONVERSION_ERROR syscall.Errno = 8607 + ERROR_DS_CANT_MOVE_APP_BASIC_GROUP syscall.Errno = 8608 + ERROR_DS_CANT_MOVE_APP_QUERY_GROUP syscall.Errno = 8609 + ERROR_DS_ROLE_NOT_VERIFIED syscall.Errno = 8610 + ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL syscall.Errno = 8611 + ERROR_DS_DOMAIN_RENAME_IN_PROGRESS syscall.Errno = 8612 + ERROR_DS_EXISTING_AD_CHILD_NC syscall.Errno = 8613 + ERROR_DS_REPL_LIFETIME_EXCEEDED syscall.Errno = 8614 + ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER syscall.Errno = 8615 + ERROR_DS_LDAP_SEND_QUEUE_FULL syscall.Errno = 8616 + ERROR_DS_DRA_OUT_SCHEDULE_WINDOW syscall.Errno = 8617 + ERROR_DS_POLICY_NOT_KNOWN syscall.Errno = 8618 + ERROR_NO_SITE_SETTINGS_OBJECT syscall.Errno = 8619 + ERROR_NO_SECRETS syscall.Errno = 8620 + ERROR_NO_WRITABLE_DC_FOUND syscall.Errno = 8621 + ERROR_DS_NO_SERVER_OBJECT syscall.Errno = 8622 + ERROR_DS_NO_NTDSA_OBJECT syscall.Errno = 8623 + ERROR_DS_NON_ASQ_SEARCH syscall.Errno = 8624 + ERROR_DS_AUDIT_FAILURE syscall.Errno = 8625 + ERROR_DS_INVALID_SEARCH_FLAG_SUBTREE syscall.Errno = 8626 + ERROR_DS_INVALID_SEARCH_FLAG_TUPLE syscall.Errno = 8627 + ERROR_DS_HIERARCHY_TABLE_TOO_DEEP syscall.Errno = 8628 + ERROR_DS_DRA_CORRUPT_UTD_VECTOR syscall.Errno = 8629 + ERROR_DS_DRA_SECRETS_DENIED syscall.Errno = 8630 + ERROR_DS_RESERVED_MAPI_ID syscall.Errno = 8631 + ERROR_DS_MAPI_ID_NOT_AVAILABLE syscall.Errno = 8632 + ERROR_DS_DRA_MISSING_KRBTGT_SECRET syscall.Errno = 8633 + ERROR_DS_DOMAIN_NAME_EXISTS_IN_FOREST syscall.Errno = 8634 + ERROR_DS_FLAT_NAME_EXISTS_IN_FOREST syscall.Errno = 8635 + ERROR_INVALID_USER_PRINCIPAL_NAME syscall.Errno = 8636 + ERROR_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS syscall.Errno = 8637 + ERROR_DS_OID_NOT_FOUND syscall.Errno = 8638 + ERROR_DS_DRA_RECYCLED_TARGET syscall.Errno = 8639 + ERROR_DS_DISALLOWED_NC_REDIRECT syscall.Errno = 8640 + ERROR_DS_HIGH_ADLDS_FFL syscall.Errno = 8641 + ERROR_DS_HIGH_DSA_VERSION syscall.Errno = 8642 + ERROR_DS_LOW_ADLDS_FFL syscall.Errno = 8643 + ERROR_DOMAIN_SID_SAME_AS_LOCAL_WORKSTATION syscall.Errno = 8644 + ERROR_DS_UNDELETE_SAM_VALIDATION_FAILED syscall.Errno = 8645 + ERROR_INCORRECT_ACCOUNT_TYPE syscall.Errno = 8646 + ERROR_DS_SPN_VALUE_NOT_UNIQUE_IN_FOREST syscall.Errno = 8647 + ERROR_DS_UPN_VALUE_NOT_UNIQUE_IN_FOREST syscall.Errno = 8648 + ERROR_DS_MISSING_FOREST_TRUST syscall.Errno = 8649 + ERROR_DS_VALUE_KEY_NOT_UNIQUE syscall.Errno = 8650 + DNS_ERROR_RESPONSE_CODES_BASE syscall.Errno = 9000 + DNS_ERROR_RCODE_NO_ERROR = ERROR_SUCCESS + DNS_ERROR_MASK syscall.Errno = 0x00002328 + DNS_ERROR_RCODE_FORMAT_ERROR syscall.Errno = 9001 + DNS_ERROR_RCODE_SERVER_FAILURE syscall.Errno = 9002 + DNS_ERROR_RCODE_NAME_ERROR syscall.Errno = 9003 + DNS_ERROR_RCODE_NOT_IMPLEMENTED syscall.Errno = 9004 + DNS_ERROR_RCODE_REFUSED syscall.Errno = 9005 + DNS_ERROR_RCODE_YXDOMAIN syscall.Errno = 9006 + DNS_ERROR_RCODE_YXRRSET syscall.Errno = 9007 + DNS_ERROR_RCODE_NXRRSET syscall.Errno = 9008 + DNS_ERROR_RCODE_NOTAUTH syscall.Errno = 9009 + DNS_ERROR_RCODE_NOTZONE syscall.Errno = 9010 + DNS_ERROR_RCODE_BADSIG syscall.Errno = 9016 + DNS_ERROR_RCODE_BADKEY syscall.Errno = 9017 + DNS_ERROR_RCODE_BADTIME syscall.Errno = 9018 + DNS_ERROR_RCODE_LAST = DNS_ERROR_RCODE_BADTIME + DNS_ERROR_DNSSEC_BASE syscall.Errno = 9100 + DNS_ERROR_KEYMASTER_REQUIRED syscall.Errno = 9101 + DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE syscall.Errno = 9102 + DNS_ERROR_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1 syscall.Errno = 9103 + DNS_ERROR_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS syscall.Errno = 9104 + DNS_ERROR_UNSUPPORTED_ALGORITHM syscall.Errno = 9105 + DNS_ERROR_INVALID_KEY_SIZE syscall.Errno = 9106 + DNS_ERROR_SIGNING_KEY_NOT_ACCESSIBLE syscall.Errno = 9107 + DNS_ERROR_KSP_DOES_NOT_SUPPORT_PROTECTION syscall.Errno = 9108 + DNS_ERROR_UNEXPECTED_DATA_PROTECTION_ERROR syscall.Errno = 9109 + DNS_ERROR_UNEXPECTED_CNG_ERROR syscall.Errno = 9110 + DNS_ERROR_UNKNOWN_SIGNING_PARAMETER_VERSION syscall.Errno = 9111 + DNS_ERROR_KSP_NOT_ACCESSIBLE syscall.Errno = 9112 + DNS_ERROR_TOO_MANY_SKDS syscall.Errno = 9113 + DNS_ERROR_INVALID_ROLLOVER_PERIOD syscall.Errno = 9114 + DNS_ERROR_INVALID_INITIAL_ROLLOVER_OFFSET syscall.Errno = 9115 + DNS_ERROR_ROLLOVER_IN_PROGRESS syscall.Errno = 9116 + DNS_ERROR_STANDBY_KEY_NOT_PRESENT syscall.Errno = 9117 + DNS_ERROR_NOT_ALLOWED_ON_ZSK syscall.Errno = 9118 + DNS_ERROR_NOT_ALLOWED_ON_ACTIVE_SKD syscall.Errno = 9119 + DNS_ERROR_ROLLOVER_ALREADY_QUEUED syscall.Errno = 9120 + DNS_ERROR_NOT_ALLOWED_ON_UNSIGNED_ZONE syscall.Errno = 9121 + DNS_ERROR_BAD_KEYMASTER syscall.Errno = 9122 + DNS_ERROR_INVALID_SIGNATURE_VALIDITY_PERIOD syscall.Errno = 9123 + DNS_ERROR_INVALID_NSEC3_ITERATION_COUNT syscall.Errno = 9124 + DNS_ERROR_DNSSEC_IS_DISABLED syscall.Errno = 9125 + DNS_ERROR_INVALID_XML syscall.Errno = 9126 + DNS_ERROR_NO_VALID_TRUST_ANCHORS syscall.Errno = 9127 + DNS_ERROR_ROLLOVER_NOT_POKEABLE syscall.Errno = 9128 + DNS_ERROR_NSEC3_NAME_COLLISION syscall.Errno = 9129 + DNS_ERROR_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1 syscall.Errno = 9130 + DNS_ERROR_PACKET_FMT_BASE syscall.Errno = 9500 + DNS_INFO_NO_RECORDS syscall.Errno = 9501 + DNS_ERROR_BAD_PACKET syscall.Errno = 9502 + DNS_ERROR_NO_PACKET syscall.Errno = 9503 + DNS_ERROR_RCODE syscall.Errno = 9504 + DNS_ERROR_UNSECURE_PACKET syscall.Errno = 9505 + DNS_STATUS_PACKET_UNSECURE = DNS_ERROR_UNSECURE_PACKET + DNS_REQUEST_PENDING syscall.Errno = 9506 + DNS_ERROR_NO_MEMORY = ERROR_OUTOFMEMORY + DNS_ERROR_INVALID_NAME = ERROR_INVALID_NAME + DNS_ERROR_INVALID_DATA = ERROR_INVALID_DATA + DNS_ERROR_GENERAL_API_BASE syscall.Errno = 9550 + DNS_ERROR_INVALID_TYPE syscall.Errno = 9551 + DNS_ERROR_INVALID_IP_ADDRESS syscall.Errno = 9552 + DNS_ERROR_INVALID_PROPERTY syscall.Errno = 9553 + DNS_ERROR_TRY_AGAIN_LATER syscall.Errno = 9554 + DNS_ERROR_NOT_UNIQUE syscall.Errno = 9555 + DNS_ERROR_NON_RFC_NAME syscall.Errno = 9556 + DNS_STATUS_FQDN syscall.Errno = 9557 + DNS_STATUS_DOTTED_NAME syscall.Errno = 9558 + DNS_STATUS_SINGLE_PART_NAME syscall.Errno = 9559 + DNS_ERROR_INVALID_NAME_CHAR syscall.Errno = 9560 + DNS_ERROR_NUMERIC_NAME syscall.Errno = 9561 + DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER syscall.Errno = 9562 + DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION syscall.Errno = 9563 + DNS_ERROR_CANNOT_FIND_ROOT_HINTS syscall.Errno = 9564 + DNS_ERROR_INCONSISTENT_ROOT_HINTS syscall.Errno = 9565 + DNS_ERROR_DWORD_VALUE_TOO_SMALL syscall.Errno = 9566 + DNS_ERROR_DWORD_VALUE_TOO_LARGE syscall.Errno = 9567 + DNS_ERROR_BACKGROUND_LOADING syscall.Errno = 9568 + DNS_ERROR_NOT_ALLOWED_ON_RODC syscall.Errno = 9569 + DNS_ERROR_NOT_ALLOWED_UNDER_DNAME syscall.Errno = 9570 + DNS_ERROR_DELEGATION_REQUIRED syscall.Errno = 9571 + DNS_ERROR_INVALID_POLICY_TABLE syscall.Errno = 9572 + DNS_ERROR_ADDRESS_REQUIRED syscall.Errno = 9573 + DNS_ERROR_ZONE_BASE syscall.Errno = 9600 + DNS_ERROR_ZONE_DOES_NOT_EXIST syscall.Errno = 9601 + DNS_ERROR_NO_ZONE_INFO syscall.Errno = 9602 + DNS_ERROR_INVALID_ZONE_OPERATION syscall.Errno = 9603 + DNS_ERROR_ZONE_CONFIGURATION_ERROR syscall.Errno = 9604 + DNS_ERROR_ZONE_HAS_NO_SOA_RECORD syscall.Errno = 9605 + DNS_ERROR_ZONE_HAS_NO_NS_RECORDS syscall.Errno = 9606 + DNS_ERROR_ZONE_LOCKED syscall.Errno = 9607 + DNS_ERROR_ZONE_CREATION_FAILED syscall.Errno = 9608 + DNS_ERROR_ZONE_ALREADY_EXISTS syscall.Errno = 9609 + DNS_ERROR_AUTOZONE_ALREADY_EXISTS syscall.Errno = 9610 + DNS_ERROR_INVALID_ZONE_TYPE syscall.Errno = 9611 + DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP syscall.Errno = 9612 + DNS_ERROR_ZONE_NOT_SECONDARY syscall.Errno = 9613 + DNS_ERROR_NEED_SECONDARY_ADDRESSES syscall.Errno = 9614 + DNS_ERROR_WINS_INIT_FAILED syscall.Errno = 9615 + DNS_ERROR_NEED_WINS_SERVERS syscall.Errno = 9616 + DNS_ERROR_NBSTAT_INIT_FAILED syscall.Errno = 9617 + DNS_ERROR_SOA_DELETE_INVALID syscall.Errno = 9618 + DNS_ERROR_FORWARDER_ALREADY_EXISTS syscall.Errno = 9619 + DNS_ERROR_ZONE_REQUIRES_MASTER_IP syscall.Errno = 9620 + DNS_ERROR_ZONE_IS_SHUTDOWN syscall.Errno = 9621 + DNS_ERROR_ZONE_LOCKED_FOR_SIGNING syscall.Errno = 9622 + DNS_ERROR_DATAFILE_BASE syscall.Errno = 9650 + DNS_ERROR_PRIMARY_REQUIRES_DATAFILE syscall.Errno = 9651 + DNS_ERROR_INVALID_DATAFILE_NAME syscall.Errno = 9652 + DNS_ERROR_DATAFILE_OPEN_FAILURE syscall.Errno = 9653 + DNS_ERROR_FILE_WRITEBACK_FAILED syscall.Errno = 9654 + DNS_ERROR_DATAFILE_PARSING syscall.Errno = 9655 + DNS_ERROR_DATABASE_BASE syscall.Errno = 9700 + DNS_ERROR_RECORD_DOES_NOT_EXIST syscall.Errno = 9701 + DNS_ERROR_RECORD_FORMAT syscall.Errno = 9702 + DNS_ERROR_NODE_CREATION_FAILED syscall.Errno = 9703 + DNS_ERROR_UNKNOWN_RECORD_TYPE syscall.Errno = 9704 + DNS_ERROR_RECORD_TIMED_OUT syscall.Errno = 9705 + DNS_ERROR_NAME_NOT_IN_ZONE syscall.Errno = 9706 + DNS_ERROR_CNAME_LOOP syscall.Errno = 9707 + DNS_ERROR_NODE_IS_CNAME syscall.Errno = 9708 + DNS_ERROR_CNAME_COLLISION syscall.Errno = 9709 + DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT syscall.Errno = 9710 + DNS_ERROR_RECORD_ALREADY_EXISTS syscall.Errno = 9711 + DNS_ERROR_SECONDARY_DATA syscall.Errno = 9712 + DNS_ERROR_NO_CREATE_CACHE_DATA syscall.Errno = 9713 + DNS_ERROR_NAME_DOES_NOT_EXIST syscall.Errno = 9714 + DNS_WARNING_PTR_CREATE_FAILED syscall.Errno = 9715 + DNS_WARNING_DOMAIN_UNDELETED syscall.Errno = 9716 + DNS_ERROR_DS_UNAVAILABLE syscall.Errno = 9717 + DNS_ERROR_DS_ZONE_ALREADY_EXISTS syscall.Errno = 9718 + DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE syscall.Errno = 9719 + DNS_ERROR_NODE_IS_DNAME syscall.Errno = 9720 + DNS_ERROR_DNAME_COLLISION syscall.Errno = 9721 + DNS_ERROR_ALIAS_LOOP syscall.Errno = 9722 + DNS_ERROR_OPERATION_BASE syscall.Errno = 9750 + DNS_INFO_AXFR_COMPLETE syscall.Errno = 9751 + DNS_ERROR_AXFR syscall.Errno = 9752 + DNS_INFO_ADDED_LOCAL_WINS syscall.Errno = 9753 + DNS_ERROR_SECURE_BASE syscall.Errno = 9800 + DNS_STATUS_CONTINUE_NEEDED syscall.Errno = 9801 + DNS_ERROR_SETUP_BASE syscall.Errno = 9850 + DNS_ERROR_NO_TCPIP syscall.Errno = 9851 + DNS_ERROR_NO_DNS_SERVERS syscall.Errno = 9852 + DNS_ERROR_DP_BASE syscall.Errno = 9900 + DNS_ERROR_DP_DOES_NOT_EXIST syscall.Errno = 9901 + DNS_ERROR_DP_ALREADY_EXISTS syscall.Errno = 9902 + DNS_ERROR_DP_NOT_ENLISTED syscall.Errno = 9903 + DNS_ERROR_DP_ALREADY_ENLISTED syscall.Errno = 9904 + DNS_ERROR_DP_NOT_AVAILABLE syscall.Errno = 9905 + DNS_ERROR_DP_FSMO_ERROR syscall.Errno = 9906 + DNS_ERROR_RRL_NOT_ENABLED syscall.Errno = 9911 + DNS_ERROR_RRL_INVALID_WINDOW_SIZE syscall.Errno = 9912 + DNS_ERROR_RRL_INVALID_IPV4_PREFIX syscall.Errno = 9913 + DNS_ERROR_RRL_INVALID_IPV6_PREFIX syscall.Errno = 9914 + DNS_ERROR_RRL_INVALID_TC_RATE syscall.Errno = 9915 + DNS_ERROR_RRL_INVALID_LEAK_RATE syscall.Errno = 9916 + DNS_ERROR_RRL_LEAK_RATE_LESSTHAN_TC_RATE syscall.Errno = 9917 + DNS_ERROR_VIRTUALIZATION_INSTANCE_ALREADY_EXISTS syscall.Errno = 9921 + DNS_ERROR_VIRTUALIZATION_INSTANCE_DOES_NOT_EXIST syscall.Errno = 9922 + DNS_ERROR_VIRTUALIZATION_TREE_LOCKED syscall.Errno = 9923 + DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME syscall.Errno = 9924 + DNS_ERROR_DEFAULT_VIRTUALIZATION_INSTANCE syscall.Errno = 9925 + DNS_ERROR_ZONESCOPE_ALREADY_EXISTS syscall.Errno = 9951 + DNS_ERROR_ZONESCOPE_DOES_NOT_EXIST syscall.Errno = 9952 + DNS_ERROR_DEFAULT_ZONESCOPE syscall.Errno = 9953 + DNS_ERROR_INVALID_ZONESCOPE_NAME syscall.Errno = 9954 + DNS_ERROR_NOT_ALLOWED_WITH_ZONESCOPES syscall.Errno = 9955 + DNS_ERROR_LOAD_ZONESCOPE_FAILED syscall.Errno = 9956 + DNS_ERROR_ZONESCOPE_FILE_WRITEBACK_FAILED syscall.Errno = 9957 + DNS_ERROR_INVALID_SCOPE_NAME syscall.Errno = 9958 + DNS_ERROR_SCOPE_DOES_NOT_EXIST syscall.Errno = 9959 + DNS_ERROR_DEFAULT_SCOPE syscall.Errno = 9960 + DNS_ERROR_INVALID_SCOPE_OPERATION syscall.Errno = 9961 + DNS_ERROR_SCOPE_LOCKED syscall.Errno = 9962 + DNS_ERROR_SCOPE_ALREADY_EXISTS syscall.Errno = 9963 + DNS_ERROR_POLICY_ALREADY_EXISTS syscall.Errno = 9971 + DNS_ERROR_POLICY_DOES_NOT_EXIST syscall.Errno = 9972 + DNS_ERROR_POLICY_INVALID_CRITERIA syscall.Errno = 9973 + DNS_ERROR_POLICY_INVALID_SETTINGS syscall.Errno = 9974 + DNS_ERROR_CLIENT_SUBNET_IS_ACCESSED syscall.Errno = 9975 + DNS_ERROR_CLIENT_SUBNET_DOES_NOT_EXIST syscall.Errno = 9976 + DNS_ERROR_CLIENT_SUBNET_ALREADY_EXISTS syscall.Errno = 9977 + DNS_ERROR_SUBNET_DOES_NOT_EXIST syscall.Errno = 9978 + DNS_ERROR_SUBNET_ALREADY_EXISTS syscall.Errno = 9979 + DNS_ERROR_POLICY_LOCKED syscall.Errno = 9980 + DNS_ERROR_POLICY_INVALID_WEIGHT syscall.Errno = 9981 + DNS_ERROR_POLICY_INVALID_NAME syscall.Errno = 9982 + DNS_ERROR_POLICY_MISSING_CRITERIA syscall.Errno = 9983 + DNS_ERROR_INVALID_CLIENT_SUBNET_NAME syscall.Errno = 9984 + DNS_ERROR_POLICY_PROCESSING_ORDER_INVALID syscall.Errno = 9985 + DNS_ERROR_POLICY_SCOPE_MISSING syscall.Errno = 9986 + DNS_ERROR_POLICY_SCOPE_NOT_ALLOWED syscall.Errno = 9987 + DNS_ERROR_SERVERSCOPE_IS_REFERENCED syscall.Errno = 9988 + DNS_ERROR_ZONESCOPE_IS_REFERENCED syscall.Errno = 9989 + DNS_ERROR_POLICY_INVALID_CRITERIA_CLIENT_SUBNET syscall.Errno = 9990 + DNS_ERROR_POLICY_INVALID_CRITERIA_TRANSPORT_PROTOCOL syscall.Errno = 9991 + DNS_ERROR_POLICY_INVALID_CRITERIA_NETWORK_PROTOCOL syscall.Errno = 9992 + DNS_ERROR_POLICY_INVALID_CRITERIA_INTERFACE syscall.Errno = 9993 + DNS_ERROR_POLICY_INVALID_CRITERIA_FQDN syscall.Errno = 9994 + DNS_ERROR_POLICY_INVALID_CRITERIA_QUERY_TYPE syscall.Errno = 9995 + DNS_ERROR_POLICY_INVALID_CRITERIA_TIME_OF_DAY syscall.Errno = 9996 + WSABASEERR syscall.Errno = 10000 + WSAEINTR syscall.Errno = 10004 + WSAEBADF syscall.Errno = 10009 + WSAEACCES syscall.Errno = 10013 + WSAEFAULT syscall.Errno = 10014 + WSAEINVAL syscall.Errno = 10022 + WSAEMFILE syscall.Errno = 10024 + WSAEWOULDBLOCK syscall.Errno = 10035 + WSAEINPROGRESS syscall.Errno = 10036 + WSAEALREADY syscall.Errno = 10037 + WSAENOTSOCK syscall.Errno = 10038 + WSAEDESTADDRREQ syscall.Errno = 10039 + WSAEMSGSIZE syscall.Errno = 10040 + WSAEPROTOTYPE syscall.Errno = 10041 + WSAENOPROTOOPT syscall.Errno = 10042 + WSAEPROTONOSUPPORT syscall.Errno = 10043 + WSAESOCKTNOSUPPORT syscall.Errno = 10044 + WSAEOPNOTSUPP syscall.Errno = 10045 + WSAEPFNOSUPPORT syscall.Errno = 10046 + WSAEAFNOSUPPORT syscall.Errno = 10047 + WSAEADDRINUSE syscall.Errno = 10048 + WSAEADDRNOTAVAIL syscall.Errno = 10049 + WSAENETDOWN syscall.Errno = 10050 + WSAENETUNREACH syscall.Errno = 10051 + WSAENETRESET syscall.Errno = 10052 + WSAECONNABORTED syscall.Errno = 10053 + WSAECONNRESET syscall.Errno = 10054 + WSAENOBUFS syscall.Errno = 10055 + WSAEISCONN syscall.Errno = 10056 + WSAENOTCONN syscall.Errno = 10057 + WSAESHUTDOWN syscall.Errno = 10058 + WSAETOOMANYREFS syscall.Errno = 10059 + WSAETIMEDOUT syscall.Errno = 10060 + WSAECONNREFUSED syscall.Errno = 10061 + WSAELOOP syscall.Errno = 10062 + WSAENAMETOOLONG syscall.Errno = 10063 + WSAEHOSTDOWN syscall.Errno = 10064 + WSAEHOSTUNREACH syscall.Errno = 10065 + WSAENOTEMPTY syscall.Errno = 10066 + WSAEPROCLIM syscall.Errno = 10067 + WSAEUSERS syscall.Errno = 10068 + WSAEDQUOT syscall.Errno = 10069 + WSAESTALE syscall.Errno = 10070 + WSAEREMOTE syscall.Errno = 10071 + WSASYSNOTREADY syscall.Errno = 10091 + WSAVERNOTSUPPORTED syscall.Errno = 10092 + WSANOTINITIALISED syscall.Errno = 10093 + WSAEDISCON syscall.Errno = 10101 + WSAENOMORE syscall.Errno = 10102 + WSAECANCELLED syscall.Errno = 10103 + WSAEINVALIDPROCTABLE syscall.Errno = 10104 + WSAEINVALIDPROVIDER syscall.Errno = 10105 + WSAEPROVIDERFAILEDINIT syscall.Errno = 10106 + WSASYSCALLFAILURE syscall.Errno = 10107 + WSASERVICE_NOT_FOUND syscall.Errno = 10108 + WSATYPE_NOT_FOUND syscall.Errno = 10109 + WSA_E_NO_MORE syscall.Errno = 10110 + WSA_E_CANCELLED syscall.Errno = 10111 + WSAEREFUSED syscall.Errno = 10112 + WSAHOST_NOT_FOUND syscall.Errno = 11001 + WSATRY_AGAIN syscall.Errno = 11002 + WSANO_RECOVERY syscall.Errno = 11003 + WSANO_DATA syscall.Errno = 11004 + WSA_QOS_RECEIVERS syscall.Errno = 11005 + WSA_QOS_SENDERS syscall.Errno = 11006 + WSA_QOS_NO_SENDERS syscall.Errno = 11007 + WSA_QOS_NO_RECEIVERS syscall.Errno = 11008 + WSA_QOS_REQUEST_CONFIRMED syscall.Errno = 11009 + WSA_QOS_ADMISSION_FAILURE syscall.Errno = 11010 + WSA_QOS_POLICY_FAILURE syscall.Errno = 11011 + WSA_QOS_BAD_STYLE syscall.Errno = 11012 + WSA_QOS_BAD_OBJECT syscall.Errno = 11013 + WSA_QOS_TRAFFIC_CTRL_ERROR syscall.Errno = 11014 + WSA_QOS_GENERIC_ERROR syscall.Errno = 11015 + WSA_QOS_ESERVICETYPE syscall.Errno = 11016 + WSA_QOS_EFLOWSPEC syscall.Errno = 11017 + WSA_QOS_EPROVSPECBUF syscall.Errno = 11018 + WSA_QOS_EFILTERSTYLE syscall.Errno = 11019 + WSA_QOS_EFILTERTYPE syscall.Errno = 11020 + WSA_QOS_EFILTERCOUNT syscall.Errno = 11021 + WSA_QOS_EOBJLENGTH syscall.Errno = 11022 + WSA_QOS_EFLOWCOUNT syscall.Errno = 11023 + WSA_QOS_EUNKOWNPSOBJ syscall.Errno = 11024 + WSA_QOS_EPOLICYOBJ syscall.Errno = 11025 + WSA_QOS_EFLOWDESC syscall.Errno = 11026 + WSA_QOS_EPSFLOWSPEC syscall.Errno = 11027 + WSA_QOS_EPSFILTERSPEC syscall.Errno = 11028 + WSA_QOS_ESDMODEOBJ syscall.Errno = 11029 + WSA_QOS_ESHAPERATEOBJ syscall.Errno = 11030 + WSA_QOS_RESERVED_PETYPE syscall.Errno = 11031 + WSA_SECURE_HOST_NOT_FOUND syscall.Errno = 11032 + WSA_IPSEC_NAME_POLICY_ERROR syscall.Errno = 11033 + ERROR_IPSEC_QM_POLICY_EXISTS syscall.Errno = 13000 + ERROR_IPSEC_QM_POLICY_NOT_FOUND syscall.Errno = 13001 + ERROR_IPSEC_QM_POLICY_IN_USE syscall.Errno = 13002 + ERROR_IPSEC_MM_POLICY_EXISTS syscall.Errno = 13003 + ERROR_IPSEC_MM_POLICY_NOT_FOUND syscall.Errno = 13004 + ERROR_IPSEC_MM_POLICY_IN_USE syscall.Errno = 13005 + ERROR_IPSEC_MM_FILTER_EXISTS syscall.Errno = 13006 + ERROR_IPSEC_MM_FILTER_NOT_FOUND syscall.Errno = 13007 + ERROR_IPSEC_TRANSPORT_FILTER_EXISTS syscall.Errno = 13008 + ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND syscall.Errno = 13009 + ERROR_IPSEC_MM_AUTH_EXISTS syscall.Errno = 13010 + ERROR_IPSEC_MM_AUTH_NOT_FOUND syscall.Errno = 13011 + ERROR_IPSEC_MM_AUTH_IN_USE syscall.Errno = 13012 + ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND syscall.Errno = 13013 + ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND syscall.Errno = 13014 + ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND syscall.Errno = 13015 + ERROR_IPSEC_TUNNEL_FILTER_EXISTS syscall.Errno = 13016 + ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND syscall.Errno = 13017 + ERROR_IPSEC_MM_FILTER_PENDING_DELETION syscall.Errno = 13018 + ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION syscall.Errno = 13019 + ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION syscall.Errno = 13020 + ERROR_IPSEC_MM_POLICY_PENDING_DELETION syscall.Errno = 13021 + ERROR_IPSEC_MM_AUTH_PENDING_DELETION syscall.Errno = 13022 + ERROR_IPSEC_QM_POLICY_PENDING_DELETION syscall.Errno = 13023 + WARNING_IPSEC_MM_POLICY_PRUNED syscall.Errno = 13024 + WARNING_IPSEC_QM_POLICY_PRUNED syscall.Errno = 13025 + ERROR_IPSEC_IKE_NEG_STATUS_BEGIN syscall.Errno = 13800 + ERROR_IPSEC_IKE_AUTH_FAIL syscall.Errno = 13801 + ERROR_IPSEC_IKE_ATTRIB_FAIL syscall.Errno = 13802 + ERROR_IPSEC_IKE_NEGOTIATION_PENDING syscall.Errno = 13803 + ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR syscall.Errno = 13804 + ERROR_IPSEC_IKE_TIMED_OUT syscall.Errno = 13805 + ERROR_IPSEC_IKE_NO_CERT syscall.Errno = 13806 + ERROR_IPSEC_IKE_SA_DELETED syscall.Errno = 13807 + ERROR_IPSEC_IKE_SA_REAPED syscall.Errno = 13808 + ERROR_IPSEC_IKE_MM_ACQUIRE_DROP syscall.Errno = 13809 + ERROR_IPSEC_IKE_QM_ACQUIRE_DROP syscall.Errno = 13810 + ERROR_IPSEC_IKE_QUEUE_DROP_MM syscall.Errno = 13811 + ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM syscall.Errno = 13812 + ERROR_IPSEC_IKE_DROP_NO_RESPONSE syscall.Errno = 13813 + ERROR_IPSEC_IKE_MM_DELAY_DROP syscall.Errno = 13814 + ERROR_IPSEC_IKE_QM_DELAY_DROP syscall.Errno = 13815 + ERROR_IPSEC_IKE_ERROR syscall.Errno = 13816 + ERROR_IPSEC_IKE_CRL_FAILED syscall.Errno = 13817 + ERROR_IPSEC_IKE_INVALID_KEY_USAGE syscall.Errno = 13818 + ERROR_IPSEC_IKE_INVALID_CERT_TYPE syscall.Errno = 13819 + ERROR_IPSEC_IKE_NO_PRIVATE_KEY syscall.Errno = 13820 + ERROR_IPSEC_IKE_SIMULTANEOUS_REKEY syscall.Errno = 13821 + ERROR_IPSEC_IKE_DH_FAIL syscall.Errno = 13822 + ERROR_IPSEC_IKE_CRITICAL_PAYLOAD_NOT_RECOGNIZED syscall.Errno = 13823 + ERROR_IPSEC_IKE_INVALID_HEADER syscall.Errno = 13824 + ERROR_IPSEC_IKE_NO_POLICY syscall.Errno = 13825 + ERROR_IPSEC_IKE_INVALID_SIGNATURE syscall.Errno = 13826 + ERROR_IPSEC_IKE_KERBEROS_ERROR syscall.Errno = 13827 + ERROR_IPSEC_IKE_NO_PUBLIC_KEY syscall.Errno = 13828 + ERROR_IPSEC_IKE_PROCESS_ERR syscall.Errno = 13829 + ERROR_IPSEC_IKE_PROCESS_ERR_SA syscall.Errno = 13830 + ERROR_IPSEC_IKE_PROCESS_ERR_PROP syscall.Errno = 13831 + ERROR_IPSEC_IKE_PROCESS_ERR_TRANS syscall.Errno = 13832 + ERROR_IPSEC_IKE_PROCESS_ERR_KE syscall.Errno = 13833 + ERROR_IPSEC_IKE_PROCESS_ERR_ID syscall.Errno = 13834 + ERROR_IPSEC_IKE_PROCESS_ERR_CERT syscall.Errno = 13835 + ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ syscall.Errno = 13836 + ERROR_IPSEC_IKE_PROCESS_ERR_HASH syscall.Errno = 13837 + ERROR_IPSEC_IKE_PROCESS_ERR_SIG syscall.Errno = 13838 + ERROR_IPSEC_IKE_PROCESS_ERR_NONCE syscall.Errno = 13839 + ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY syscall.Errno = 13840 + ERROR_IPSEC_IKE_PROCESS_ERR_DELETE syscall.Errno = 13841 + ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR syscall.Errno = 13842 + ERROR_IPSEC_IKE_INVALID_PAYLOAD syscall.Errno = 13843 + ERROR_IPSEC_IKE_LOAD_SOFT_SA syscall.Errno = 13844 + ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN syscall.Errno = 13845 + ERROR_IPSEC_IKE_INVALID_COOKIE syscall.Errno = 13846 + ERROR_IPSEC_IKE_NO_PEER_CERT syscall.Errno = 13847 + ERROR_IPSEC_IKE_PEER_CRL_FAILED syscall.Errno = 13848 + ERROR_IPSEC_IKE_POLICY_CHANGE syscall.Errno = 13849 + ERROR_IPSEC_IKE_NO_MM_POLICY syscall.Errno = 13850 + ERROR_IPSEC_IKE_NOTCBPRIV syscall.Errno = 13851 + ERROR_IPSEC_IKE_SECLOADFAIL syscall.Errno = 13852 + ERROR_IPSEC_IKE_FAILSSPINIT syscall.Errno = 13853 + ERROR_IPSEC_IKE_FAILQUERYSSP syscall.Errno = 13854 + ERROR_IPSEC_IKE_SRVACQFAIL syscall.Errno = 13855 + ERROR_IPSEC_IKE_SRVQUERYCRED syscall.Errno = 13856 + ERROR_IPSEC_IKE_GETSPIFAIL syscall.Errno = 13857 + ERROR_IPSEC_IKE_INVALID_FILTER syscall.Errno = 13858 + ERROR_IPSEC_IKE_OUT_OF_MEMORY syscall.Errno = 13859 + ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED syscall.Errno = 13860 + ERROR_IPSEC_IKE_INVALID_POLICY syscall.Errno = 13861 + ERROR_IPSEC_IKE_UNKNOWN_DOI syscall.Errno = 13862 + ERROR_IPSEC_IKE_INVALID_SITUATION syscall.Errno = 13863 + ERROR_IPSEC_IKE_DH_FAILURE syscall.Errno = 13864 + ERROR_IPSEC_IKE_INVALID_GROUP syscall.Errno = 13865 + ERROR_IPSEC_IKE_ENCRYPT syscall.Errno = 13866 + ERROR_IPSEC_IKE_DECRYPT syscall.Errno = 13867 + ERROR_IPSEC_IKE_POLICY_MATCH syscall.Errno = 13868 + ERROR_IPSEC_IKE_UNSUPPORTED_ID syscall.Errno = 13869 + ERROR_IPSEC_IKE_INVALID_HASH syscall.Errno = 13870 + ERROR_IPSEC_IKE_INVALID_HASH_ALG syscall.Errno = 13871 + ERROR_IPSEC_IKE_INVALID_HASH_SIZE syscall.Errno = 13872 + ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG syscall.Errno = 13873 + ERROR_IPSEC_IKE_INVALID_AUTH_ALG syscall.Errno = 13874 + ERROR_IPSEC_IKE_INVALID_SIG syscall.Errno = 13875 + ERROR_IPSEC_IKE_LOAD_FAILED syscall.Errno = 13876 + ERROR_IPSEC_IKE_RPC_DELETE syscall.Errno = 13877 + ERROR_IPSEC_IKE_BENIGN_REINIT syscall.Errno = 13878 + ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY syscall.Errno = 13879 + ERROR_IPSEC_IKE_INVALID_MAJOR_VERSION syscall.Errno = 13880 + ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN syscall.Errno = 13881 + ERROR_IPSEC_IKE_MM_LIMIT syscall.Errno = 13882 + ERROR_IPSEC_IKE_NEGOTIATION_DISABLED syscall.Errno = 13883 + ERROR_IPSEC_IKE_QM_LIMIT syscall.Errno = 13884 + ERROR_IPSEC_IKE_MM_EXPIRED syscall.Errno = 13885 + ERROR_IPSEC_IKE_PEER_MM_ASSUMED_INVALID syscall.Errno = 13886 + ERROR_IPSEC_IKE_CERT_CHAIN_POLICY_MISMATCH syscall.Errno = 13887 + ERROR_IPSEC_IKE_UNEXPECTED_MESSAGE_ID syscall.Errno = 13888 + ERROR_IPSEC_IKE_INVALID_AUTH_PAYLOAD syscall.Errno = 13889 + ERROR_IPSEC_IKE_DOS_COOKIE_SENT syscall.Errno = 13890 + ERROR_IPSEC_IKE_SHUTTING_DOWN syscall.Errno = 13891 + ERROR_IPSEC_IKE_CGA_AUTH_FAILED syscall.Errno = 13892 + ERROR_IPSEC_IKE_PROCESS_ERR_NATOA syscall.Errno = 13893 + ERROR_IPSEC_IKE_INVALID_MM_FOR_QM syscall.Errno = 13894 + ERROR_IPSEC_IKE_QM_EXPIRED syscall.Errno = 13895 + ERROR_IPSEC_IKE_TOO_MANY_FILTERS syscall.Errno = 13896 + ERROR_IPSEC_IKE_NEG_STATUS_END syscall.Errno = 13897 + ERROR_IPSEC_IKE_KILL_DUMMY_NAP_TUNNEL syscall.Errno = 13898 + ERROR_IPSEC_IKE_INNER_IP_ASSIGNMENT_FAILURE syscall.Errno = 13899 + ERROR_IPSEC_IKE_REQUIRE_CP_PAYLOAD_MISSING syscall.Errno = 13900 + ERROR_IPSEC_KEY_MODULE_IMPERSONATION_NEGOTIATION_PENDING syscall.Errno = 13901 + ERROR_IPSEC_IKE_COEXISTENCE_SUPPRESS syscall.Errno = 13902 + ERROR_IPSEC_IKE_RATELIMIT_DROP syscall.Errno = 13903 + ERROR_IPSEC_IKE_PEER_DOESNT_SUPPORT_MOBIKE syscall.Errno = 13904 + ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE syscall.Errno = 13905 + ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_FAILURE syscall.Errno = 13906 + ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE_WITH_OPTIONAL_RETRY syscall.Errno = 13907 + ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_AND_CERTMAP_FAILURE syscall.Errno = 13908 + ERROR_IPSEC_IKE_NEG_STATUS_EXTENDED_END syscall.Errno = 13909 + ERROR_IPSEC_BAD_SPI syscall.Errno = 13910 + ERROR_IPSEC_SA_LIFETIME_EXPIRED syscall.Errno = 13911 + ERROR_IPSEC_WRONG_SA syscall.Errno = 13912 + ERROR_IPSEC_REPLAY_CHECK_FAILED syscall.Errno = 13913 + ERROR_IPSEC_INVALID_PACKET syscall.Errno = 13914 + ERROR_IPSEC_INTEGRITY_CHECK_FAILED syscall.Errno = 13915 + ERROR_IPSEC_CLEAR_TEXT_DROP syscall.Errno = 13916 + ERROR_IPSEC_AUTH_FIREWALL_DROP syscall.Errno = 13917 + ERROR_IPSEC_THROTTLE_DROP syscall.Errno = 13918 + ERROR_IPSEC_DOSP_BLOCK syscall.Errno = 13925 + ERROR_IPSEC_DOSP_RECEIVED_MULTICAST syscall.Errno = 13926 + ERROR_IPSEC_DOSP_INVALID_PACKET syscall.Errno = 13927 + ERROR_IPSEC_DOSP_STATE_LOOKUP_FAILED syscall.Errno = 13928 + ERROR_IPSEC_DOSP_MAX_ENTRIES syscall.Errno = 13929 + ERROR_IPSEC_DOSP_KEYMOD_NOT_ALLOWED syscall.Errno = 13930 + ERROR_IPSEC_DOSP_NOT_INSTALLED syscall.Errno = 13931 + ERROR_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES syscall.Errno = 13932 + ERROR_SXS_SECTION_NOT_FOUND syscall.Errno = 14000 + ERROR_SXS_CANT_GEN_ACTCTX syscall.Errno = 14001 + ERROR_SXS_INVALID_ACTCTXDATA_FORMAT syscall.Errno = 14002 + ERROR_SXS_ASSEMBLY_NOT_FOUND syscall.Errno = 14003 + ERROR_SXS_MANIFEST_FORMAT_ERROR syscall.Errno = 14004 + ERROR_SXS_MANIFEST_PARSE_ERROR syscall.Errno = 14005 + ERROR_SXS_ACTIVATION_CONTEXT_DISABLED syscall.Errno = 14006 + ERROR_SXS_KEY_NOT_FOUND syscall.Errno = 14007 + ERROR_SXS_VERSION_CONFLICT syscall.Errno = 14008 + ERROR_SXS_WRONG_SECTION_TYPE syscall.Errno = 14009 + ERROR_SXS_THREAD_QUERIES_DISABLED syscall.Errno = 14010 + ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET syscall.Errno = 14011 + ERROR_SXS_UNKNOWN_ENCODING_GROUP syscall.Errno = 14012 + ERROR_SXS_UNKNOWN_ENCODING syscall.Errno = 14013 + ERROR_SXS_INVALID_XML_NAMESPACE_URI syscall.Errno = 14014 + ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED syscall.Errno = 14015 + ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED syscall.Errno = 14016 + ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE syscall.Errno = 14017 + ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE syscall.Errno = 14018 + ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE syscall.Errno = 14019 + ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT syscall.Errno = 14020 + ERROR_SXS_DUPLICATE_DLL_NAME syscall.Errno = 14021 + ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME syscall.Errno = 14022 + ERROR_SXS_DUPLICATE_CLSID syscall.Errno = 14023 + ERROR_SXS_DUPLICATE_IID syscall.Errno = 14024 + ERROR_SXS_DUPLICATE_TLBID syscall.Errno = 14025 + ERROR_SXS_DUPLICATE_PROGID syscall.Errno = 14026 + ERROR_SXS_DUPLICATE_ASSEMBLY_NAME syscall.Errno = 14027 + ERROR_SXS_FILE_HASH_MISMATCH syscall.Errno = 14028 + ERROR_SXS_POLICY_PARSE_ERROR syscall.Errno = 14029 + ERROR_SXS_XML_E_MISSINGQUOTE syscall.Errno = 14030 + ERROR_SXS_XML_E_COMMENTSYNTAX syscall.Errno = 14031 + ERROR_SXS_XML_E_BADSTARTNAMECHAR syscall.Errno = 14032 + ERROR_SXS_XML_E_BADNAMECHAR syscall.Errno = 14033 + ERROR_SXS_XML_E_BADCHARINSTRING syscall.Errno = 14034 + ERROR_SXS_XML_E_XMLDECLSYNTAX syscall.Errno = 14035 + ERROR_SXS_XML_E_BADCHARDATA syscall.Errno = 14036 + ERROR_SXS_XML_E_MISSINGWHITESPACE syscall.Errno = 14037 + ERROR_SXS_XML_E_EXPECTINGTAGEND syscall.Errno = 14038 + ERROR_SXS_XML_E_MISSINGSEMICOLON syscall.Errno = 14039 + ERROR_SXS_XML_E_UNBALANCEDPAREN syscall.Errno = 14040 + ERROR_SXS_XML_E_INTERNALERROR syscall.Errno = 14041 + ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE syscall.Errno = 14042 + ERROR_SXS_XML_E_INCOMPLETE_ENCODING syscall.Errno = 14043 + ERROR_SXS_XML_E_MISSING_PAREN syscall.Errno = 14044 + ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE syscall.Errno = 14045 + ERROR_SXS_XML_E_MULTIPLE_COLONS syscall.Errno = 14046 + ERROR_SXS_XML_E_INVALID_DECIMAL syscall.Errno = 14047 + ERROR_SXS_XML_E_INVALID_HEXIDECIMAL syscall.Errno = 14048 + ERROR_SXS_XML_E_INVALID_UNICODE syscall.Errno = 14049 + ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK syscall.Errno = 14050 + ERROR_SXS_XML_E_UNEXPECTEDENDTAG syscall.Errno = 14051 + ERROR_SXS_XML_E_UNCLOSEDTAG syscall.Errno = 14052 + ERROR_SXS_XML_E_DUPLICATEATTRIBUTE syscall.Errno = 14053 + ERROR_SXS_XML_E_MULTIPLEROOTS syscall.Errno = 14054 + ERROR_SXS_XML_E_INVALIDATROOTLEVEL syscall.Errno = 14055 + ERROR_SXS_XML_E_BADXMLDECL syscall.Errno = 14056 + ERROR_SXS_XML_E_MISSINGROOT syscall.Errno = 14057 + ERROR_SXS_XML_E_UNEXPECTEDEOF syscall.Errno = 14058 + ERROR_SXS_XML_E_BADPEREFINSUBSET syscall.Errno = 14059 + ERROR_SXS_XML_E_UNCLOSEDSTARTTAG syscall.Errno = 14060 + ERROR_SXS_XML_E_UNCLOSEDENDTAG syscall.Errno = 14061 + ERROR_SXS_XML_E_UNCLOSEDSTRING syscall.Errno = 14062 + ERROR_SXS_XML_E_UNCLOSEDCOMMENT syscall.Errno = 14063 + ERROR_SXS_XML_E_UNCLOSEDDECL syscall.Errno = 14064 + ERROR_SXS_XML_E_UNCLOSEDCDATA syscall.Errno = 14065 + ERROR_SXS_XML_E_RESERVEDNAMESPACE syscall.Errno = 14066 + ERROR_SXS_XML_E_INVALIDENCODING syscall.Errno = 14067 + ERROR_SXS_XML_E_INVALIDSWITCH syscall.Errno = 14068 + ERROR_SXS_XML_E_BADXMLCASE syscall.Errno = 14069 + ERROR_SXS_XML_E_INVALID_STANDALONE syscall.Errno = 14070 + ERROR_SXS_XML_E_UNEXPECTED_STANDALONE syscall.Errno = 14071 + ERROR_SXS_XML_E_INVALID_VERSION syscall.Errno = 14072 + ERROR_SXS_XML_E_MISSINGEQUALS syscall.Errno = 14073 + ERROR_SXS_PROTECTION_RECOVERY_FAILED syscall.Errno = 14074 + ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT syscall.Errno = 14075 + ERROR_SXS_PROTECTION_CATALOG_NOT_VALID syscall.Errno = 14076 + ERROR_SXS_UNTRANSLATABLE_HRESULT syscall.Errno = 14077 + ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING syscall.Errno = 14078 + ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE syscall.Errno = 14079 + ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME syscall.Errno = 14080 + ERROR_SXS_ASSEMBLY_MISSING syscall.Errno = 14081 + ERROR_SXS_CORRUPT_ACTIVATION_STACK syscall.Errno = 14082 + ERROR_SXS_CORRUPTION syscall.Errno = 14083 + ERROR_SXS_EARLY_DEACTIVATION syscall.Errno = 14084 + ERROR_SXS_INVALID_DEACTIVATION syscall.Errno = 14085 + ERROR_SXS_MULTIPLE_DEACTIVATION syscall.Errno = 14086 + ERROR_SXS_PROCESS_TERMINATION_REQUESTED syscall.Errno = 14087 + ERROR_SXS_RELEASE_ACTIVATION_CONTEXT syscall.Errno = 14088 + ERROR_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY syscall.Errno = 14089 + ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE syscall.Errno = 14090 + ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME syscall.Errno = 14091 + ERROR_SXS_IDENTITY_DUPLICATE_ATTRIBUTE syscall.Errno = 14092 + ERROR_SXS_IDENTITY_PARSE_ERROR syscall.Errno = 14093 + ERROR_MALFORMED_SUBSTITUTION_STRING syscall.Errno = 14094 + ERROR_SXS_INCORRECT_PUBLIC_KEY_TOKEN syscall.Errno = 14095 + ERROR_UNMAPPED_SUBSTITUTION_STRING syscall.Errno = 14096 + ERROR_SXS_ASSEMBLY_NOT_LOCKED syscall.Errno = 14097 + ERROR_SXS_COMPONENT_STORE_CORRUPT syscall.Errno = 14098 + ERROR_ADVANCED_INSTALLER_FAILED syscall.Errno = 14099 + ERROR_XML_ENCODING_MISMATCH syscall.Errno = 14100 + ERROR_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT syscall.Errno = 14101 + ERROR_SXS_IDENTITIES_DIFFERENT syscall.Errno = 14102 + ERROR_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT syscall.Errno = 14103 + ERROR_SXS_FILE_NOT_PART_OF_ASSEMBLY syscall.Errno = 14104 + ERROR_SXS_MANIFEST_TOO_BIG syscall.Errno = 14105 + ERROR_SXS_SETTING_NOT_REGISTERED syscall.Errno = 14106 + ERROR_SXS_TRANSACTION_CLOSURE_INCOMPLETE syscall.Errno = 14107 + ERROR_SMI_PRIMITIVE_INSTALLER_FAILED syscall.Errno = 14108 + ERROR_GENERIC_COMMAND_FAILED syscall.Errno = 14109 + ERROR_SXS_FILE_HASH_MISSING syscall.Errno = 14110 + ERROR_SXS_DUPLICATE_ACTIVATABLE_CLASS syscall.Errno = 14111 + ERROR_EVT_INVALID_CHANNEL_PATH syscall.Errno = 15000 + ERROR_EVT_INVALID_QUERY syscall.Errno = 15001 + ERROR_EVT_PUBLISHER_METADATA_NOT_FOUND syscall.Errno = 15002 + ERROR_EVT_EVENT_TEMPLATE_NOT_FOUND syscall.Errno = 15003 + ERROR_EVT_INVALID_PUBLISHER_NAME syscall.Errno = 15004 + ERROR_EVT_INVALID_EVENT_DATA syscall.Errno = 15005 + ERROR_EVT_CHANNEL_NOT_FOUND syscall.Errno = 15007 + ERROR_EVT_MALFORMED_XML_TEXT syscall.Errno = 15008 + ERROR_EVT_SUBSCRIPTION_TO_DIRECT_CHANNEL syscall.Errno = 15009 + ERROR_EVT_CONFIGURATION_ERROR syscall.Errno = 15010 + ERROR_EVT_QUERY_RESULT_STALE syscall.Errno = 15011 + ERROR_EVT_QUERY_RESULT_INVALID_POSITION syscall.Errno = 15012 + ERROR_EVT_NON_VALIDATING_MSXML syscall.Errno = 15013 + ERROR_EVT_FILTER_ALREADYSCOPED syscall.Errno = 15014 + ERROR_EVT_FILTER_NOTELTSET syscall.Errno = 15015 + ERROR_EVT_FILTER_INVARG syscall.Errno = 15016 + ERROR_EVT_FILTER_INVTEST syscall.Errno = 15017 + ERROR_EVT_FILTER_INVTYPE syscall.Errno = 15018 + ERROR_EVT_FILTER_PARSEERR syscall.Errno = 15019 + ERROR_EVT_FILTER_UNSUPPORTEDOP syscall.Errno = 15020 + ERROR_EVT_FILTER_UNEXPECTEDTOKEN syscall.Errno = 15021 + ERROR_EVT_INVALID_OPERATION_OVER_ENABLED_DIRECT_CHANNEL syscall.Errno = 15022 + ERROR_EVT_INVALID_CHANNEL_PROPERTY_VALUE syscall.Errno = 15023 + ERROR_EVT_INVALID_PUBLISHER_PROPERTY_VALUE syscall.Errno = 15024 + ERROR_EVT_CHANNEL_CANNOT_ACTIVATE syscall.Errno = 15025 + ERROR_EVT_FILTER_TOO_COMPLEX syscall.Errno = 15026 + ERROR_EVT_MESSAGE_NOT_FOUND syscall.Errno = 15027 + ERROR_EVT_MESSAGE_ID_NOT_FOUND syscall.Errno = 15028 + ERROR_EVT_UNRESOLVED_VALUE_INSERT syscall.Errno = 15029 + ERROR_EVT_UNRESOLVED_PARAMETER_INSERT syscall.Errno = 15030 + ERROR_EVT_MAX_INSERTS_REACHED syscall.Errno = 15031 + ERROR_EVT_EVENT_DEFINITION_NOT_FOUND syscall.Errno = 15032 + ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND syscall.Errno = 15033 + ERROR_EVT_VERSION_TOO_OLD syscall.Errno = 15034 + ERROR_EVT_VERSION_TOO_NEW syscall.Errno = 15035 + ERROR_EVT_CANNOT_OPEN_CHANNEL_OF_QUERY syscall.Errno = 15036 + ERROR_EVT_PUBLISHER_DISABLED syscall.Errno = 15037 + ERROR_EVT_FILTER_OUT_OF_RANGE syscall.Errno = 15038 + ERROR_EC_SUBSCRIPTION_CANNOT_ACTIVATE syscall.Errno = 15080 + ERROR_EC_LOG_DISABLED syscall.Errno = 15081 + ERROR_EC_CIRCULAR_FORWARDING syscall.Errno = 15082 + ERROR_EC_CREDSTORE_FULL syscall.Errno = 15083 + ERROR_EC_CRED_NOT_FOUND syscall.Errno = 15084 + ERROR_EC_NO_ACTIVE_CHANNEL syscall.Errno = 15085 + ERROR_MUI_FILE_NOT_FOUND syscall.Errno = 15100 + ERROR_MUI_INVALID_FILE syscall.Errno = 15101 + ERROR_MUI_INVALID_RC_CONFIG syscall.Errno = 15102 + ERROR_MUI_INVALID_LOCALE_NAME syscall.Errno = 15103 + ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME syscall.Errno = 15104 + ERROR_MUI_FILE_NOT_LOADED syscall.Errno = 15105 + ERROR_RESOURCE_ENUM_USER_STOP syscall.Errno = 15106 + ERROR_MUI_INTLSETTINGS_UILANG_NOT_INSTALLED syscall.Errno = 15107 + ERROR_MUI_INTLSETTINGS_INVALID_LOCALE_NAME syscall.Errno = 15108 + ERROR_MRM_RUNTIME_NO_DEFAULT_OR_NEUTRAL_RESOURCE syscall.Errno = 15110 + ERROR_MRM_INVALID_PRICONFIG syscall.Errno = 15111 + ERROR_MRM_INVALID_FILE_TYPE syscall.Errno = 15112 + ERROR_MRM_UNKNOWN_QUALIFIER syscall.Errno = 15113 + ERROR_MRM_INVALID_QUALIFIER_VALUE syscall.Errno = 15114 + ERROR_MRM_NO_CANDIDATE syscall.Errno = 15115 + ERROR_MRM_NO_MATCH_OR_DEFAULT_CANDIDATE syscall.Errno = 15116 + ERROR_MRM_RESOURCE_TYPE_MISMATCH syscall.Errno = 15117 + ERROR_MRM_DUPLICATE_MAP_NAME syscall.Errno = 15118 + ERROR_MRM_DUPLICATE_ENTRY syscall.Errno = 15119 + ERROR_MRM_INVALID_RESOURCE_IDENTIFIER syscall.Errno = 15120 + ERROR_MRM_FILEPATH_TOO_LONG syscall.Errno = 15121 + ERROR_MRM_UNSUPPORTED_DIRECTORY_TYPE syscall.Errno = 15122 + ERROR_MRM_INVALID_PRI_FILE syscall.Errno = 15126 + ERROR_MRM_NAMED_RESOURCE_NOT_FOUND syscall.Errno = 15127 + ERROR_MRM_MAP_NOT_FOUND syscall.Errno = 15135 + ERROR_MRM_UNSUPPORTED_PROFILE_TYPE syscall.Errno = 15136 + ERROR_MRM_INVALID_QUALIFIER_OPERATOR syscall.Errno = 15137 + ERROR_MRM_INDETERMINATE_QUALIFIER_VALUE syscall.Errno = 15138 + ERROR_MRM_AUTOMERGE_ENABLED syscall.Errno = 15139 + ERROR_MRM_TOO_MANY_RESOURCES syscall.Errno = 15140 + ERROR_MRM_UNSUPPORTED_FILE_TYPE_FOR_MERGE syscall.Errno = 15141 + ERROR_MRM_UNSUPPORTED_FILE_TYPE_FOR_LOAD_UNLOAD_PRI_FILE syscall.Errno = 15142 + ERROR_MRM_NO_CURRENT_VIEW_ON_THREAD syscall.Errno = 15143 + ERROR_DIFFERENT_PROFILE_RESOURCE_MANAGER_EXIST syscall.Errno = 15144 + ERROR_OPERATION_NOT_ALLOWED_FROM_SYSTEM_COMPONENT syscall.Errno = 15145 + ERROR_MRM_DIRECT_REF_TO_NON_DEFAULT_RESOURCE syscall.Errno = 15146 + ERROR_MRM_GENERATION_COUNT_MISMATCH syscall.Errno = 15147 + ERROR_PRI_MERGE_VERSION_MISMATCH syscall.Errno = 15148 + ERROR_PRI_MERGE_MISSING_SCHEMA syscall.Errno = 15149 + ERROR_PRI_MERGE_LOAD_FILE_FAILED syscall.Errno = 15150 + ERROR_PRI_MERGE_ADD_FILE_FAILED syscall.Errno = 15151 + ERROR_PRI_MERGE_WRITE_FILE_FAILED syscall.Errno = 15152 + ERROR_PRI_MERGE_MULTIPLE_PACKAGE_FAMILIES_NOT_ALLOWED syscall.Errno = 15153 + ERROR_PRI_MERGE_MULTIPLE_MAIN_PACKAGES_NOT_ALLOWED syscall.Errno = 15154 + ERROR_PRI_MERGE_BUNDLE_PACKAGES_NOT_ALLOWED syscall.Errno = 15155 + ERROR_PRI_MERGE_MAIN_PACKAGE_REQUIRED syscall.Errno = 15156 + ERROR_PRI_MERGE_RESOURCE_PACKAGE_REQUIRED syscall.Errno = 15157 + ERROR_PRI_MERGE_INVALID_FILE_NAME syscall.Errno = 15158 + ERROR_MRM_PACKAGE_NOT_FOUND syscall.Errno = 15159 + ERROR_MRM_MISSING_DEFAULT_LANGUAGE syscall.Errno = 15160 + ERROR_MCA_INVALID_CAPABILITIES_STRING syscall.Errno = 15200 + ERROR_MCA_INVALID_VCP_VERSION syscall.Errno = 15201 + ERROR_MCA_MONITOR_VIOLATES_MCCS_SPECIFICATION syscall.Errno = 15202 + ERROR_MCA_MCCS_VERSION_MISMATCH syscall.Errno = 15203 + ERROR_MCA_UNSUPPORTED_MCCS_VERSION syscall.Errno = 15204 + ERROR_MCA_INTERNAL_ERROR syscall.Errno = 15205 + ERROR_MCA_INVALID_TECHNOLOGY_TYPE_RETURNED syscall.Errno = 15206 + ERROR_MCA_UNSUPPORTED_COLOR_TEMPERATURE syscall.Errno = 15207 + ERROR_AMBIGUOUS_SYSTEM_DEVICE syscall.Errno = 15250 + ERROR_SYSTEM_DEVICE_NOT_FOUND syscall.Errno = 15299 + ERROR_HASH_NOT_SUPPORTED syscall.Errno = 15300 + ERROR_HASH_NOT_PRESENT syscall.Errno = 15301 + ERROR_SECONDARY_IC_PROVIDER_NOT_REGISTERED syscall.Errno = 15321 + ERROR_GPIO_CLIENT_INFORMATION_INVALID syscall.Errno = 15322 + ERROR_GPIO_VERSION_NOT_SUPPORTED syscall.Errno = 15323 + ERROR_GPIO_INVALID_REGISTRATION_PACKET syscall.Errno = 15324 + ERROR_GPIO_OPERATION_DENIED syscall.Errno = 15325 + ERROR_GPIO_INCOMPATIBLE_CONNECT_MODE syscall.Errno = 15326 + ERROR_GPIO_INTERRUPT_ALREADY_UNMASKED syscall.Errno = 15327 + ERROR_CANNOT_SWITCH_RUNLEVEL syscall.Errno = 15400 + ERROR_INVALID_RUNLEVEL_SETTING syscall.Errno = 15401 + ERROR_RUNLEVEL_SWITCH_TIMEOUT syscall.Errno = 15402 + ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT syscall.Errno = 15403 + ERROR_RUNLEVEL_SWITCH_IN_PROGRESS syscall.Errno = 15404 + ERROR_SERVICES_FAILED_AUTOSTART syscall.Errno = 15405 + ERROR_COM_TASK_STOP_PENDING syscall.Errno = 15501 + ERROR_INSTALL_OPEN_PACKAGE_FAILED syscall.Errno = 15600 + ERROR_INSTALL_PACKAGE_NOT_FOUND syscall.Errno = 15601 + ERROR_INSTALL_INVALID_PACKAGE syscall.Errno = 15602 + ERROR_INSTALL_RESOLVE_DEPENDENCY_FAILED syscall.Errno = 15603 + ERROR_INSTALL_OUT_OF_DISK_SPACE syscall.Errno = 15604 + ERROR_INSTALL_NETWORK_FAILURE syscall.Errno = 15605 + ERROR_INSTALL_REGISTRATION_FAILURE syscall.Errno = 15606 + ERROR_INSTALL_DEREGISTRATION_FAILURE syscall.Errno = 15607 + ERROR_INSTALL_CANCEL syscall.Errno = 15608 + ERROR_INSTALL_FAILED syscall.Errno = 15609 + ERROR_REMOVE_FAILED syscall.Errno = 15610 + ERROR_PACKAGE_ALREADY_EXISTS syscall.Errno = 15611 + ERROR_NEEDS_REMEDIATION syscall.Errno = 15612 + ERROR_INSTALL_PREREQUISITE_FAILED syscall.Errno = 15613 + ERROR_PACKAGE_REPOSITORY_CORRUPTED syscall.Errno = 15614 + ERROR_INSTALL_POLICY_FAILURE syscall.Errno = 15615 + ERROR_PACKAGE_UPDATING syscall.Errno = 15616 + ERROR_DEPLOYMENT_BLOCKED_BY_POLICY syscall.Errno = 15617 + ERROR_PACKAGES_IN_USE syscall.Errno = 15618 + ERROR_RECOVERY_FILE_CORRUPT syscall.Errno = 15619 + ERROR_INVALID_STAGED_SIGNATURE syscall.Errno = 15620 + ERROR_DELETING_EXISTING_APPLICATIONDATA_STORE_FAILED syscall.Errno = 15621 + ERROR_INSTALL_PACKAGE_DOWNGRADE syscall.Errno = 15622 + ERROR_SYSTEM_NEEDS_REMEDIATION syscall.Errno = 15623 + ERROR_APPX_INTEGRITY_FAILURE_CLR_NGEN syscall.Errno = 15624 + ERROR_RESILIENCY_FILE_CORRUPT syscall.Errno = 15625 + ERROR_INSTALL_FIREWALL_SERVICE_NOT_RUNNING syscall.Errno = 15626 + ERROR_PACKAGE_MOVE_FAILED syscall.Errno = 15627 + ERROR_INSTALL_VOLUME_NOT_EMPTY syscall.Errno = 15628 + ERROR_INSTALL_VOLUME_OFFLINE syscall.Errno = 15629 + ERROR_INSTALL_VOLUME_CORRUPT syscall.Errno = 15630 + ERROR_NEEDS_REGISTRATION syscall.Errno = 15631 + ERROR_INSTALL_WRONG_PROCESSOR_ARCHITECTURE syscall.Errno = 15632 + ERROR_DEV_SIDELOAD_LIMIT_EXCEEDED syscall.Errno = 15633 + ERROR_INSTALL_OPTIONAL_PACKAGE_REQUIRES_MAIN_PACKAGE syscall.Errno = 15634 + ERROR_PACKAGE_NOT_SUPPORTED_ON_FILESYSTEM syscall.Errno = 15635 + ERROR_PACKAGE_MOVE_BLOCKED_BY_STREAMING syscall.Errno = 15636 + ERROR_INSTALL_OPTIONAL_PACKAGE_APPLICATIONID_NOT_UNIQUE syscall.Errno = 15637 + ERROR_PACKAGE_STAGING_ONHOLD syscall.Errno = 15638 + ERROR_INSTALL_INVALID_RELATED_SET_UPDATE syscall.Errno = 15639 + ERROR_INSTALL_OPTIONAL_PACKAGE_REQUIRES_MAIN_PACKAGE_FULLTRUST_CAPABILITY syscall.Errno = 15640 + ERROR_DEPLOYMENT_BLOCKED_BY_USER_LOG_OFF syscall.Errno = 15641 + ERROR_PROVISION_OPTIONAL_PACKAGE_REQUIRES_MAIN_PACKAGE_PROVISIONED syscall.Errno = 15642 + ERROR_PACKAGES_REPUTATION_CHECK_FAILED syscall.Errno = 15643 + ERROR_PACKAGES_REPUTATION_CHECK_TIMEDOUT syscall.Errno = 15644 + ERROR_DEPLOYMENT_OPTION_NOT_SUPPORTED syscall.Errno = 15645 + ERROR_APPINSTALLER_ACTIVATION_BLOCKED syscall.Errno = 15646 + ERROR_REGISTRATION_FROM_REMOTE_DRIVE_NOT_SUPPORTED syscall.Errno = 15647 + ERROR_APPX_RAW_DATA_WRITE_FAILED syscall.Errno = 15648 + ERROR_DEPLOYMENT_BLOCKED_BY_VOLUME_POLICY_PACKAGE syscall.Errno = 15649 + ERROR_DEPLOYMENT_BLOCKED_BY_VOLUME_POLICY_MACHINE syscall.Errno = 15650 + ERROR_DEPLOYMENT_BLOCKED_BY_PROFILE_POLICY syscall.Errno = 15651 + ERROR_DEPLOYMENT_FAILED_CONFLICTING_MUTABLE_PACKAGE_DIRECTORY syscall.Errno = 15652 + ERROR_SINGLETON_RESOURCE_INSTALLED_IN_ACTIVE_USER syscall.Errno = 15653 + ERROR_DIFFERENT_VERSION_OF_PACKAGED_SERVICE_INSTALLED syscall.Errno = 15654 + ERROR_SERVICE_EXISTS_AS_NON_PACKAGED_SERVICE syscall.Errno = 15655 + ERROR_PACKAGED_SERVICE_REQUIRES_ADMIN_PRIVILEGES syscall.Errno = 15656 + APPMODEL_ERROR_NO_PACKAGE syscall.Errno = 15700 + APPMODEL_ERROR_PACKAGE_RUNTIME_CORRUPT syscall.Errno = 15701 + APPMODEL_ERROR_PACKAGE_IDENTITY_CORRUPT syscall.Errno = 15702 + APPMODEL_ERROR_NO_APPLICATION syscall.Errno = 15703 + APPMODEL_ERROR_DYNAMIC_PROPERTY_READ_FAILED syscall.Errno = 15704 + APPMODEL_ERROR_DYNAMIC_PROPERTY_INVALID syscall.Errno = 15705 + APPMODEL_ERROR_PACKAGE_NOT_AVAILABLE syscall.Errno = 15706 + APPMODEL_ERROR_NO_MUTABLE_DIRECTORY syscall.Errno = 15707 + ERROR_STATE_LOAD_STORE_FAILED syscall.Errno = 15800 + ERROR_STATE_GET_VERSION_FAILED syscall.Errno = 15801 + ERROR_STATE_SET_VERSION_FAILED syscall.Errno = 15802 + ERROR_STATE_STRUCTURED_RESET_FAILED syscall.Errno = 15803 + ERROR_STATE_OPEN_CONTAINER_FAILED syscall.Errno = 15804 + ERROR_STATE_CREATE_CONTAINER_FAILED syscall.Errno = 15805 + ERROR_STATE_DELETE_CONTAINER_FAILED syscall.Errno = 15806 + ERROR_STATE_READ_SETTING_FAILED syscall.Errno = 15807 + ERROR_STATE_WRITE_SETTING_FAILED syscall.Errno = 15808 + ERROR_STATE_DELETE_SETTING_FAILED syscall.Errno = 15809 + ERROR_STATE_QUERY_SETTING_FAILED syscall.Errno = 15810 + ERROR_STATE_READ_COMPOSITE_SETTING_FAILED syscall.Errno = 15811 + ERROR_STATE_WRITE_COMPOSITE_SETTING_FAILED syscall.Errno = 15812 + ERROR_STATE_ENUMERATE_CONTAINER_FAILED syscall.Errno = 15813 + ERROR_STATE_ENUMERATE_SETTINGS_FAILED syscall.Errno = 15814 + ERROR_STATE_COMPOSITE_SETTING_VALUE_SIZE_LIMIT_EXCEEDED syscall.Errno = 15815 + ERROR_STATE_SETTING_VALUE_SIZE_LIMIT_EXCEEDED syscall.Errno = 15816 + ERROR_STATE_SETTING_NAME_SIZE_LIMIT_EXCEEDED syscall.Errno = 15817 + ERROR_STATE_CONTAINER_NAME_SIZE_LIMIT_EXCEEDED syscall.Errno = 15818 + ERROR_API_UNAVAILABLE syscall.Errno = 15841 + STORE_ERROR_UNLICENSED syscall.Errno = 15861 + STORE_ERROR_UNLICENSED_USER syscall.Errno = 15862 + STORE_ERROR_PENDING_COM_TRANSACTION syscall.Errno = 15863 + STORE_ERROR_LICENSE_REVOKED syscall.Errno = 15864 + SEVERITY_SUCCESS syscall.Errno = 0 + SEVERITY_ERROR syscall.Errno = 1 + FACILITY_NT_BIT = 0x10000000 + E_NOT_SET = ERROR_NOT_FOUND + E_NOT_VALID_STATE = ERROR_INVALID_STATE + E_NOT_SUFFICIENT_BUFFER = ERROR_INSUFFICIENT_BUFFER + E_TIME_SENSITIVE_THREAD = ERROR_TIME_SENSITIVE_THREAD + E_NO_TASK_QUEUE = ERROR_NO_TASK_QUEUE + NOERROR syscall.Errno = 0 + E_UNEXPECTED Handle = 0x8000FFFF + E_NOTIMPL Handle = 0x80004001 + E_OUTOFMEMORY Handle = 0x8007000E + E_INVALIDARG Handle = 0x80070057 + E_NOINTERFACE Handle = 0x80004002 + E_POINTER Handle = 0x80004003 + E_HANDLE Handle = 0x80070006 + E_ABORT Handle = 0x80004004 + E_FAIL Handle = 0x80004005 + E_ACCESSDENIED Handle = 0x80070005 + E_PENDING Handle = 0x8000000A + E_BOUNDS Handle = 0x8000000B + E_CHANGED_STATE Handle = 0x8000000C + E_ILLEGAL_STATE_CHANGE Handle = 0x8000000D + E_ILLEGAL_METHOD_CALL Handle = 0x8000000E + RO_E_METADATA_NAME_NOT_FOUND Handle = 0x8000000F + RO_E_METADATA_NAME_IS_NAMESPACE Handle = 0x80000010 + RO_E_METADATA_INVALID_TYPE_FORMAT Handle = 0x80000011 + RO_E_INVALID_METADATA_FILE Handle = 0x80000012 + RO_E_CLOSED Handle = 0x80000013 + RO_E_EXCLUSIVE_WRITE Handle = 0x80000014 + RO_E_CHANGE_NOTIFICATION_IN_PROGRESS Handle = 0x80000015 + RO_E_ERROR_STRING_NOT_FOUND Handle = 0x80000016 + E_STRING_NOT_NULL_TERMINATED Handle = 0x80000017 + E_ILLEGAL_DELEGATE_ASSIGNMENT Handle = 0x80000018 + E_ASYNC_OPERATION_NOT_STARTED Handle = 0x80000019 + E_APPLICATION_EXITING Handle = 0x8000001A + E_APPLICATION_VIEW_EXITING Handle = 0x8000001B + RO_E_MUST_BE_AGILE Handle = 0x8000001C + RO_E_UNSUPPORTED_FROM_MTA Handle = 0x8000001D + RO_E_COMMITTED Handle = 0x8000001E + RO_E_BLOCKED_CROSS_ASTA_CALL Handle = 0x8000001F + RO_E_CANNOT_ACTIVATE_FULL_TRUST_SERVER Handle = 0x80000020 + RO_E_CANNOT_ACTIVATE_UNIVERSAL_APPLICATION_SERVER Handle = 0x80000021 + CO_E_INIT_TLS Handle = 0x80004006 + CO_E_INIT_SHARED_ALLOCATOR Handle = 0x80004007 + CO_E_INIT_MEMORY_ALLOCATOR Handle = 0x80004008 + CO_E_INIT_CLASS_CACHE Handle = 0x80004009 + CO_E_INIT_RPC_CHANNEL Handle = 0x8000400A + CO_E_INIT_TLS_SET_CHANNEL_CONTROL Handle = 0x8000400B + CO_E_INIT_TLS_CHANNEL_CONTROL Handle = 0x8000400C + CO_E_INIT_UNACCEPTED_USER_ALLOCATOR Handle = 0x8000400D + CO_E_INIT_SCM_MUTEX_EXISTS Handle = 0x8000400E + CO_E_INIT_SCM_FILE_MAPPING_EXISTS Handle = 0x8000400F + CO_E_INIT_SCM_MAP_VIEW_OF_FILE Handle = 0x80004010 + CO_E_INIT_SCM_EXEC_FAILURE Handle = 0x80004011 + CO_E_INIT_ONLY_SINGLE_THREADED Handle = 0x80004012 + CO_E_CANT_REMOTE Handle = 0x80004013 + CO_E_BAD_SERVER_NAME Handle = 0x80004014 + CO_E_WRONG_SERVER_IDENTITY Handle = 0x80004015 + CO_E_OLE1DDE_DISABLED Handle = 0x80004016 + CO_E_RUNAS_SYNTAX Handle = 0x80004017 + CO_E_CREATEPROCESS_FAILURE Handle = 0x80004018 + CO_E_RUNAS_CREATEPROCESS_FAILURE Handle = 0x80004019 + CO_E_RUNAS_LOGON_FAILURE Handle = 0x8000401A + CO_E_LAUNCH_PERMSSION_DENIED Handle = 0x8000401B + CO_E_START_SERVICE_FAILURE Handle = 0x8000401C + CO_E_REMOTE_COMMUNICATION_FAILURE Handle = 0x8000401D + CO_E_SERVER_START_TIMEOUT Handle = 0x8000401E + CO_E_CLSREG_INCONSISTENT Handle = 0x8000401F + CO_E_IIDREG_INCONSISTENT Handle = 0x80004020 + CO_E_NOT_SUPPORTED Handle = 0x80004021 + CO_E_RELOAD_DLL Handle = 0x80004022 + CO_E_MSI_ERROR Handle = 0x80004023 + CO_E_ATTEMPT_TO_CREATE_OUTSIDE_CLIENT_CONTEXT Handle = 0x80004024 + CO_E_SERVER_PAUSED Handle = 0x80004025 + CO_E_SERVER_NOT_PAUSED Handle = 0x80004026 + CO_E_CLASS_DISABLED Handle = 0x80004027 + CO_E_CLRNOTAVAILABLE Handle = 0x80004028 + CO_E_ASYNC_WORK_REJECTED Handle = 0x80004029 + CO_E_SERVER_INIT_TIMEOUT Handle = 0x8000402A + CO_E_NO_SECCTX_IN_ACTIVATE Handle = 0x8000402B + CO_E_TRACKER_CONFIG Handle = 0x80004030 + CO_E_THREADPOOL_CONFIG Handle = 0x80004031 + CO_E_SXS_CONFIG Handle = 0x80004032 + CO_E_MALFORMED_SPN Handle = 0x80004033 + CO_E_UNREVOKED_REGISTRATION_ON_APARTMENT_SHUTDOWN Handle = 0x80004034 + CO_E_PREMATURE_STUB_RUNDOWN Handle = 0x80004035 + S_OK Handle = 0 + S_FALSE Handle = 1 + OLE_E_FIRST Handle = 0x80040000 + OLE_E_LAST Handle = 0x800400FF + OLE_S_FIRST Handle = 0x00040000 + OLE_S_LAST Handle = 0x000400FF + OLE_E_OLEVERB Handle = 0x80040000 + OLE_E_ADVF Handle = 0x80040001 + OLE_E_ENUM_NOMORE Handle = 0x80040002 + OLE_E_ADVISENOTSUPPORTED Handle = 0x80040003 + OLE_E_NOCONNECTION Handle = 0x80040004 + OLE_E_NOTRUNNING Handle = 0x80040005 + OLE_E_NOCACHE Handle = 0x80040006 + OLE_E_BLANK Handle = 0x80040007 + OLE_E_CLASSDIFF Handle = 0x80040008 + OLE_E_CANT_GETMONIKER Handle = 0x80040009 + OLE_E_CANT_BINDTOSOURCE Handle = 0x8004000A + OLE_E_STATIC Handle = 0x8004000B + OLE_E_PROMPTSAVECANCELLED Handle = 0x8004000C + OLE_E_INVALIDRECT Handle = 0x8004000D + OLE_E_WRONGCOMPOBJ Handle = 0x8004000E + OLE_E_INVALIDHWND Handle = 0x8004000F + OLE_E_NOT_INPLACEACTIVE Handle = 0x80040010 + OLE_E_CANTCONVERT Handle = 0x80040011 + OLE_E_NOSTORAGE Handle = 0x80040012 + DV_E_FORMATETC Handle = 0x80040064 + DV_E_DVTARGETDEVICE Handle = 0x80040065 + DV_E_STGMEDIUM Handle = 0x80040066 + DV_E_STATDATA Handle = 0x80040067 + DV_E_LINDEX Handle = 0x80040068 + DV_E_TYMED Handle = 0x80040069 + DV_E_CLIPFORMAT Handle = 0x8004006A + DV_E_DVASPECT Handle = 0x8004006B + DV_E_DVTARGETDEVICE_SIZE Handle = 0x8004006C + DV_E_NOIVIEWOBJECT Handle = 0x8004006D + DRAGDROP_E_FIRST syscall.Errno = 0x80040100 + DRAGDROP_E_LAST syscall.Errno = 0x8004010F + DRAGDROP_S_FIRST syscall.Errno = 0x00040100 + DRAGDROP_S_LAST syscall.Errno = 0x0004010F + DRAGDROP_E_NOTREGISTERED Handle = 0x80040100 + DRAGDROP_E_ALREADYREGISTERED Handle = 0x80040101 + DRAGDROP_E_INVALIDHWND Handle = 0x80040102 + DRAGDROP_E_CONCURRENT_DRAG_ATTEMPTED Handle = 0x80040103 + CLASSFACTORY_E_FIRST syscall.Errno = 0x80040110 + CLASSFACTORY_E_LAST syscall.Errno = 0x8004011F + CLASSFACTORY_S_FIRST syscall.Errno = 0x00040110 + CLASSFACTORY_S_LAST syscall.Errno = 0x0004011F + CLASS_E_NOAGGREGATION Handle = 0x80040110 + CLASS_E_CLASSNOTAVAILABLE Handle = 0x80040111 + CLASS_E_NOTLICENSED Handle = 0x80040112 + MARSHAL_E_FIRST syscall.Errno = 0x80040120 + MARSHAL_E_LAST syscall.Errno = 0x8004012F + MARSHAL_S_FIRST syscall.Errno = 0x00040120 + MARSHAL_S_LAST syscall.Errno = 0x0004012F + DATA_E_FIRST syscall.Errno = 0x80040130 + DATA_E_LAST syscall.Errno = 0x8004013F + DATA_S_FIRST syscall.Errno = 0x00040130 + DATA_S_LAST syscall.Errno = 0x0004013F + VIEW_E_FIRST syscall.Errno = 0x80040140 + VIEW_E_LAST syscall.Errno = 0x8004014F + VIEW_S_FIRST syscall.Errno = 0x00040140 + VIEW_S_LAST syscall.Errno = 0x0004014F + VIEW_E_DRAW Handle = 0x80040140 + REGDB_E_FIRST syscall.Errno = 0x80040150 + REGDB_E_LAST syscall.Errno = 0x8004015F + REGDB_S_FIRST syscall.Errno = 0x00040150 + REGDB_S_LAST syscall.Errno = 0x0004015F + REGDB_E_READREGDB Handle = 0x80040150 + REGDB_E_WRITEREGDB Handle = 0x80040151 + REGDB_E_KEYMISSING Handle = 0x80040152 + REGDB_E_INVALIDVALUE Handle = 0x80040153 + REGDB_E_CLASSNOTREG Handle = 0x80040154 + REGDB_E_IIDNOTREG Handle = 0x80040155 + REGDB_E_BADTHREADINGMODEL Handle = 0x80040156 + REGDB_E_PACKAGEPOLICYVIOLATION Handle = 0x80040157 + CAT_E_FIRST syscall.Errno = 0x80040160 + CAT_E_LAST syscall.Errno = 0x80040161 + CAT_E_CATIDNOEXIST Handle = 0x80040160 + CAT_E_NODESCRIPTION Handle = 0x80040161 + CS_E_FIRST syscall.Errno = 0x80040164 + CS_E_LAST syscall.Errno = 0x8004016F + CS_E_PACKAGE_NOTFOUND Handle = 0x80040164 + CS_E_NOT_DELETABLE Handle = 0x80040165 + CS_E_CLASS_NOTFOUND Handle = 0x80040166 + CS_E_INVALID_VERSION Handle = 0x80040167 + CS_E_NO_CLASSSTORE Handle = 0x80040168 + CS_E_OBJECT_NOTFOUND Handle = 0x80040169 + CS_E_OBJECT_ALREADY_EXISTS Handle = 0x8004016A + CS_E_INVALID_PATH Handle = 0x8004016B + CS_E_NETWORK_ERROR Handle = 0x8004016C + CS_E_ADMIN_LIMIT_EXCEEDED Handle = 0x8004016D + CS_E_SCHEMA_MISMATCH Handle = 0x8004016E + CS_E_INTERNAL_ERROR Handle = 0x8004016F + CACHE_E_FIRST syscall.Errno = 0x80040170 + CACHE_E_LAST syscall.Errno = 0x8004017F + CACHE_S_FIRST syscall.Errno = 0x00040170 + CACHE_S_LAST syscall.Errno = 0x0004017F + CACHE_E_NOCACHE_UPDATED Handle = 0x80040170 + OLEOBJ_E_FIRST syscall.Errno = 0x80040180 + OLEOBJ_E_LAST syscall.Errno = 0x8004018F + OLEOBJ_S_FIRST syscall.Errno = 0x00040180 + OLEOBJ_S_LAST syscall.Errno = 0x0004018F + OLEOBJ_E_NOVERBS Handle = 0x80040180 + OLEOBJ_E_INVALIDVERB Handle = 0x80040181 + CLIENTSITE_E_FIRST syscall.Errno = 0x80040190 + CLIENTSITE_E_LAST syscall.Errno = 0x8004019F + CLIENTSITE_S_FIRST syscall.Errno = 0x00040190 + CLIENTSITE_S_LAST syscall.Errno = 0x0004019F + INPLACE_E_NOTUNDOABLE Handle = 0x800401A0 + INPLACE_E_NOTOOLSPACE Handle = 0x800401A1 + INPLACE_E_FIRST syscall.Errno = 0x800401A0 + INPLACE_E_LAST syscall.Errno = 0x800401AF + INPLACE_S_FIRST syscall.Errno = 0x000401A0 + INPLACE_S_LAST syscall.Errno = 0x000401AF + ENUM_E_FIRST syscall.Errno = 0x800401B0 + ENUM_E_LAST syscall.Errno = 0x800401BF + ENUM_S_FIRST syscall.Errno = 0x000401B0 + ENUM_S_LAST syscall.Errno = 0x000401BF + CONVERT10_E_FIRST syscall.Errno = 0x800401C0 + CONVERT10_E_LAST syscall.Errno = 0x800401CF + CONVERT10_S_FIRST syscall.Errno = 0x000401C0 + CONVERT10_S_LAST syscall.Errno = 0x000401CF + CONVERT10_E_OLESTREAM_GET Handle = 0x800401C0 + CONVERT10_E_OLESTREAM_PUT Handle = 0x800401C1 + CONVERT10_E_OLESTREAM_FMT Handle = 0x800401C2 + CONVERT10_E_OLESTREAM_BITMAP_TO_DIB Handle = 0x800401C3 + CONVERT10_E_STG_FMT Handle = 0x800401C4 + CONVERT10_E_STG_NO_STD_STREAM Handle = 0x800401C5 + CONVERT10_E_STG_DIB_TO_BITMAP Handle = 0x800401C6 + CLIPBRD_E_FIRST syscall.Errno = 0x800401D0 + CLIPBRD_E_LAST syscall.Errno = 0x800401DF + CLIPBRD_S_FIRST syscall.Errno = 0x000401D0 + CLIPBRD_S_LAST syscall.Errno = 0x000401DF + CLIPBRD_E_CANT_OPEN Handle = 0x800401D0 + CLIPBRD_E_CANT_EMPTY Handle = 0x800401D1 + CLIPBRD_E_CANT_SET Handle = 0x800401D2 + CLIPBRD_E_BAD_DATA Handle = 0x800401D3 + CLIPBRD_E_CANT_CLOSE Handle = 0x800401D4 + MK_E_FIRST syscall.Errno = 0x800401E0 + MK_E_LAST syscall.Errno = 0x800401EF + MK_S_FIRST syscall.Errno = 0x000401E0 + MK_S_LAST syscall.Errno = 0x000401EF + MK_E_CONNECTMANUALLY Handle = 0x800401E0 + MK_E_EXCEEDEDDEADLINE Handle = 0x800401E1 + MK_E_NEEDGENERIC Handle = 0x800401E2 + MK_E_UNAVAILABLE Handle = 0x800401E3 + MK_E_SYNTAX Handle = 0x800401E4 + MK_E_NOOBJECT Handle = 0x800401E5 + MK_E_INVALIDEXTENSION Handle = 0x800401E6 + MK_E_INTERMEDIATEINTERFACENOTSUPPORTED Handle = 0x800401E7 + MK_E_NOTBINDABLE Handle = 0x800401E8 + MK_E_NOTBOUND Handle = 0x800401E9 + MK_E_CANTOPENFILE Handle = 0x800401EA + MK_E_MUSTBOTHERUSER Handle = 0x800401EB + MK_E_NOINVERSE Handle = 0x800401EC + MK_E_NOSTORAGE Handle = 0x800401ED + MK_E_NOPREFIX Handle = 0x800401EE + MK_E_ENUMERATION_FAILED Handle = 0x800401EF + CO_E_FIRST syscall.Errno = 0x800401F0 + CO_E_LAST syscall.Errno = 0x800401FF + CO_S_FIRST syscall.Errno = 0x000401F0 + CO_S_LAST syscall.Errno = 0x000401FF + CO_E_NOTINITIALIZED Handle = 0x800401F0 + CO_E_ALREADYINITIALIZED Handle = 0x800401F1 + CO_E_CANTDETERMINECLASS Handle = 0x800401F2 + CO_E_CLASSSTRING Handle = 0x800401F3 + CO_E_IIDSTRING Handle = 0x800401F4 + CO_E_APPNOTFOUND Handle = 0x800401F5 + CO_E_APPSINGLEUSE Handle = 0x800401F6 + CO_E_ERRORINAPP Handle = 0x800401F7 + CO_E_DLLNOTFOUND Handle = 0x800401F8 + CO_E_ERRORINDLL Handle = 0x800401F9 + CO_E_WRONGOSFORAPP Handle = 0x800401FA + CO_E_OBJNOTREG Handle = 0x800401FB + CO_E_OBJISREG Handle = 0x800401FC + CO_E_OBJNOTCONNECTED Handle = 0x800401FD + CO_E_APPDIDNTREG Handle = 0x800401FE + CO_E_RELEASED Handle = 0x800401FF + EVENT_E_FIRST syscall.Errno = 0x80040200 + EVENT_E_LAST syscall.Errno = 0x8004021F + EVENT_S_FIRST syscall.Errno = 0x00040200 + EVENT_S_LAST syscall.Errno = 0x0004021F + EVENT_S_SOME_SUBSCRIBERS_FAILED Handle = 0x00040200 + EVENT_E_ALL_SUBSCRIBERS_FAILED Handle = 0x80040201 + EVENT_S_NOSUBSCRIBERS Handle = 0x00040202 + EVENT_E_QUERYSYNTAX Handle = 0x80040203 + EVENT_E_QUERYFIELD Handle = 0x80040204 + EVENT_E_INTERNALEXCEPTION Handle = 0x80040205 + EVENT_E_INTERNALERROR Handle = 0x80040206 + EVENT_E_INVALID_PER_USER_SID Handle = 0x80040207 + EVENT_E_USER_EXCEPTION Handle = 0x80040208 + EVENT_E_TOO_MANY_METHODS Handle = 0x80040209 + EVENT_E_MISSING_EVENTCLASS Handle = 0x8004020A + EVENT_E_NOT_ALL_REMOVED Handle = 0x8004020B + EVENT_E_COMPLUS_NOT_INSTALLED Handle = 0x8004020C + EVENT_E_CANT_MODIFY_OR_DELETE_UNCONFIGURED_OBJECT Handle = 0x8004020D + EVENT_E_CANT_MODIFY_OR_DELETE_CONFIGURED_OBJECT Handle = 0x8004020E + EVENT_E_INVALID_EVENT_CLASS_PARTITION Handle = 0x8004020F + EVENT_E_PER_USER_SID_NOT_LOGGED_ON Handle = 0x80040210 + TPC_E_INVALID_PROPERTY Handle = 0x80040241 + TPC_E_NO_DEFAULT_TABLET Handle = 0x80040212 + TPC_E_UNKNOWN_PROPERTY Handle = 0x8004021B + TPC_E_INVALID_INPUT_RECT Handle = 0x80040219 + TPC_E_INVALID_STROKE Handle = 0x80040222 + TPC_E_INITIALIZE_FAIL Handle = 0x80040223 + TPC_E_NOT_RELEVANT Handle = 0x80040232 + TPC_E_INVALID_PACKET_DESCRIPTION Handle = 0x80040233 + TPC_E_RECOGNIZER_NOT_REGISTERED Handle = 0x80040235 + TPC_E_INVALID_RIGHTS Handle = 0x80040236 + TPC_E_OUT_OF_ORDER_CALL Handle = 0x80040237 + TPC_E_QUEUE_FULL Handle = 0x80040238 + TPC_E_INVALID_CONFIGURATION Handle = 0x80040239 + TPC_E_INVALID_DATA_FROM_RECOGNIZER Handle = 0x8004023A + TPC_S_TRUNCATED Handle = 0x00040252 + TPC_S_INTERRUPTED Handle = 0x00040253 + TPC_S_NO_DATA_TO_PROCESS Handle = 0x00040254 + XACT_E_FIRST syscall.Errno = 0x8004D000 + XACT_E_LAST syscall.Errno = 0x8004D02B + XACT_S_FIRST syscall.Errno = 0x0004D000 + XACT_S_LAST syscall.Errno = 0x0004D010 + XACT_E_ALREADYOTHERSINGLEPHASE Handle = 0x8004D000 + XACT_E_CANTRETAIN Handle = 0x8004D001 + XACT_E_COMMITFAILED Handle = 0x8004D002 + XACT_E_COMMITPREVENTED Handle = 0x8004D003 + XACT_E_HEURISTICABORT Handle = 0x8004D004 + XACT_E_HEURISTICCOMMIT Handle = 0x8004D005 + XACT_E_HEURISTICDAMAGE Handle = 0x8004D006 + XACT_E_HEURISTICDANGER Handle = 0x8004D007 + XACT_E_ISOLATIONLEVEL Handle = 0x8004D008 + XACT_E_NOASYNC Handle = 0x8004D009 + XACT_E_NOENLIST Handle = 0x8004D00A + XACT_E_NOISORETAIN Handle = 0x8004D00B + XACT_E_NORESOURCE Handle = 0x8004D00C + XACT_E_NOTCURRENT Handle = 0x8004D00D + XACT_E_NOTRANSACTION Handle = 0x8004D00E + XACT_E_NOTSUPPORTED Handle = 0x8004D00F + XACT_E_UNKNOWNRMGRID Handle = 0x8004D010 + XACT_E_WRONGSTATE Handle = 0x8004D011 + XACT_E_WRONGUOW Handle = 0x8004D012 + XACT_E_XTIONEXISTS Handle = 0x8004D013 + XACT_E_NOIMPORTOBJECT Handle = 0x8004D014 + XACT_E_INVALIDCOOKIE Handle = 0x8004D015 + XACT_E_INDOUBT Handle = 0x8004D016 + XACT_E_NOTIMEOUT Handle = 0x8004D017 + XACT_E_ALREADYINPROGRESS Handle = 0x8004D018 + XACT_E_ABORTED Handle = 0x8004D019 + XACT_E_LOGFULL Handle = 0x8004D01A + XACT_E_TMNOTAVAILABLE Handle = 0x8004D01B + XACT_E_CONNECTION_DOWN Handle = 0x8004D01C + XACT_E_CONNECTION_DENIED Handle = 0x8004D01D + XACT_E_REENLISTTIMEOUT Handle = 0x8004D01E + XACT_E_TIP_CONNECT_FAILED Handle = 0x8004D01F + XACT_E_TIP_PROTOCOL_ERROR Handle = 0x8004D020 + XACT_E_TIP_PULL_FAILED Handle = 0x8004D021 + XACT_E_DEST_TMNOTAVAILABLE Handle = 0x8004D022 + XACT_E_TIP_DISABLED Handle = 0x8004D023 + XACT_E_NETWORK_TX_DISABLED Handle = 0x8004D024 + XACT_E_PARTNER_NETWORK_TX_DISABLED Handle = 0x8004D025 + XACT_E_XA_TX_DISABLED Handle = 0x8004D026 + XACT_E_UNABLE_TO_READ_DTC_CONFIG Handle = 0x8004D027 + XACT_E_UNABLE_TO_LOAD_DTC_PROXY Handle = 0x8004D028 + XACT_E_ABORTING Handle = 0x8004D029 + XACT_E_PUSH_COMM_FAILURE Handle = 0x8004D02A + XACT_E_PULL_COMM_FAILURE Handle = 0x8004D02B + XACT_E_LU_TX_DISABLED Handle = 0x8004D02C + XACT_E_CLERKNOTFOUND Handle = 0x8004D080 + XACT_E_CLERKEXISTS Handle = 0x8004D081 + XACT_E_RECOVERYINPROGRESS Handle = 0x8004D082 + XACT_E_TRANSACTIONCLOSED Handle = 0x8004D083 + XACT_E_INVALIDLSN Handle = 0x8004D084 + XACT_E_REPLAYREQUEST Handle = 0x8004D085 + XACT_S_ASYNC Handle = 0x0004D000 + XACT_S_DEFECT Handle = 0x0004D001 + XACT_S_READONLY Handle = 0x0004D002 + XACT_S_SOMENORETAIN Handle = 0x0004D003 + XACT_S_OKINFORM Handle = 0x0004D004 + XACT_S_MADECHANGESCONTENT Handle = 0x0004D005 + XACT_S_MADECHANGESINFORM Handle = 0x0004D006 + XACT_S_ALLNORETAIN Handle = 0x0004D007 + XACT_S_ABORTING Handle = 0x0004D008 + XACT_S_SINGLEPHASE Handle = 0x0004D009 + XACT_S_LOCALLY_OK Handle = 0x0004D00A + XACT_S_LASTRESOURCEMANAGER Handle = 0x0004D010 + CONTEXT_E_FIRST syscall.Errno = 0x8004E000 + CONTEXT_E_LAST syscall.Errno = 0x8004E02F + CONTEXT_S_FIRST syscall.Errno = 0x0004E000 + CONTEXT_S_LAST syscall.Errno = 0x0004E02F + CONTEXT_E_ABORTED Handle = 0x8004E002 + CONTEXT_E_ABORTING Handle = 0x8004E003 + CONTEXT_E_NOCONTEXT Handle = 0x8004E004 + CONTEXT_E_WOULD_DEADLOCK Handle = 0x8004E005 + CONTEXT_E_SYNCH_TIMEOUT Handle = 0x8004E006 + CONTEXT_E_OLDREF Handle = 0x8004E007 + CONTEXT_E_ROLENOTFOUND Handle = 0x8004E00C + CONTEXT_E_TMNOTAVAILABLE Handle = 0x8004E00F + CO_E_ACTIVATIONFAILED Handle = 0x8004E021 + CO_E_ACTIVATIONFAILED_EVENTLOGGED Handle = 0x8004E022 + CO_E_ACTIVATIONFAILED_CATALOGERROR Handle = 0x8004E023 + CO_E_ACTIVATIONFAILED_TIMEOUT Handle = 0x8004E024 + CO_E_INITIALIZATIONFAILED Handle = 0x8004E025 + CONTEXT_E_NOJIT Handle = 0x8004E026 + CONTEXT_E_NOTRANSACTION Handle = 0x8004E027 + CO_E_THREADINGMODEL_CHANGED Handle = 0x8004E028 + CO_E_NOIISINTRINSICS Handle = 0x8004E029 + CO_E_NOCOOKIES Handle = 0x8004E02A + CO_E_DBERROR Handle = 0x8004E02B + CO_E_NOTPOOLED Handle = 0x8004E02C + CO_E_NOTCONSTRUCTED Handle = 0x8004E02D + CO_E_NOSYNCHRONIZATION Handle = 0x8004E02E + CO_E_ISOLEVELMISMATCH Handle = 0x8004E02F + CO_E_CALL_OUT_OF_TX_SCOPE_NOT_ALLOWED Handle = 0x8004E030 + CO_E_EXIT_TRANSACTION_SCOPE_NOT_CALLED Handle = 0x8004E031 + OLE_S_USEREG Handle = 0x00040000 + OLE_S_STATIC Handle = 0x00040001 + OLE_S_MAC_CLIPFORMAT Handle = 0x00040002 + DRAGDROP_S_DROP Handle = 0x00040100 + DRAGDROP_S_CANCEL Handle = 0x00040101 + DRAGDROP_S_USEDEFAULTCURSORS Handle = 0x00040102 + DATA_S_SAMEFORMATETC Handle = 0x00040130 + VIEW_S_ALREADY_FROZEN Handle = 0x00040140 + CACHE_S_FORMATETC_NOTSUPPORTED Handle = 0x00040170 + CACHE_S_SAMECACHE Handle = 0x00040171 + CACHE_S_SOMECACHES_NOTUPDATED Handle = 0x00040172 + OLEOBJ_S_INVALIDVERB Handle = 0x00040180 + OLEOBJ_S_CANNOT_DOVERB_NOW Handle = 0x00040181 + OLEOBJ_S_INVALIDHWND Handle = 0x00040182 + INPLACE_S_TRUNCATED Handle = 0x000401A0 + CONVERT10_S_NO_PRESENTATION Handle = 0x000401C0 + MK_S_REDUCED_TO_SELF Handle = 0x000401E2 + MK_S_ME Handle = 0x000401E4 + MK_S_HIM Handle = 0x000401E5 + MK_S_US Handle = 0x000401E6 + MK_S_MONIKERALREADYREGISTERED Handle = 0x000401E7 + SCHED_S_TASK_READY Handle = 0x00041300 + SCHED_S_TASK_RUNNING Handle = 0x00041301 + SCHED_S_TASK_DISABLED Handle = 0x00041302 + SCHED_S_TASK_HAS_NOT_RUN Handle = 0x00041303 + SCHED_S_TASK_NO_MORE_RUNS Handle = 0x00041304 + SCHED_S_TASK_NOT_SCHEDULED Handle = 0x00041305 + SCHED_S_TASK_TERMINATED Handle = 0x00041306 + SCHED_S_TASK_NO_VALID_TRIGGERS Handle = 0x00041307 + SCHED_S_EVENT_TRIGGER Handle = 0x00041308 + SCHED_E_TRIGGER_NOT_FOUND Handle = 0x80041309 + SCHED_E_TASK_NOT_READY Handle = 0x8004130A + SCHED_E_TASK_NOT_RUNNING Handle = 0x8004130B + SCHED_E_SERVICE_NOT_INSTALLED Handle = 0x8004130C + SCHED_E_CANNOT_OPEN_TASK Handle = 0x8004130D + SCHED_E_INVALID_TASK Handle = 0x8004130E + SCHED_E_ACCOUNT_INFORMATION_NOT_SET Handle = 0x8004130F + SCHED_E_ACCOUNT_NAME_NOT_FOUND Handle = 0x80041310 + SCHED_E_ACCOUNT_DBASE_CORRUPT Handle = 0x80041311 + SCHED_E_NO_SECURITY_SERVICES Handle = 0x80041312 + SCHED_E_UNKNOWN_OBJECT_VERSION Handle = 0x80041313 + SCHED_E_UNSUPPORTED_ACCOUNT_OPTION Handle = 0x80041314 + SCHED_E_SERVICE_NOT_RUNNING Handle = 0x80041315 + SCHED_E_UNEXPECTEDNODE Handle = 0x80041316 + SCHED_E_NAMESPACE Handle = 0x80041317 + SCHED_E_INVALIDVALUE Handle = 0x80041318 + SCHED_E_MISSINGNODE Handle = 0x80041319 + SCHED_E_MALFORMEDXML Handle = 0x8004131A + SCHED_S_SOME_TRIGGERS_FAILED Handle = 0x0004131B + SCHED_S_BATCH_LOGON_PROBLEM Handle = 0x0004131C + SCHED_E_TOO_MANY_NODES Handle = 0x8004131D + SCHED_E_PAST_END_BOUNDARY Handle = 0x8004131E + SCHED_E_ALREADY_RUNNING Handle = 0x8004131F + SCHED_E_USER_NOT_LOGGED_ON Handle = 0x80041320 + SCHED_E_INVALID_TASK_HASH Handle = 0x80041321 + SCHED_E_SERVICE_NOT_AVAILABLE Handle = 0x80041322 + SCHED_E_SERVICE_TOO_BUSY Handle = 0x80041323 + SCHED_E_TASK_ATTEMPTED Handle = 0x80041324 + SCHED_S_TASK_QUEUED Handle = 0x00041325 + SCHED_E_TASK_DISABLED Handle = 0x80041326 + SCHED_E_TASK_NOT_V1_COMPAT Handle = 0x80041327 + SCHED_E_START_ON_DEMAND Handle = 0x80041328 + SCHED_E_TASK_NOT_UBPM_COMPAT Handle = 0x80041329 + SCHED_E_DEPRECATED_FEATURE_USED Handle = 0x80041330 + CO_E_CLASS_CREATE_FAILED Handle = 0x80080001 + CO_E_SCM_ERROR Handle = 0x80080002 + CO_E_SCM_RPC_FAILURE Handle = 0x80080003 + CO_E_BAD_PATH Handle = 0x80080004 + CO_E_SERVER_EXEC_FAILURE Handle = 0x80080005 + CO_E_OBJSRV_RPC_FAILURE Handle = 0x80080006 + MK_E_NO_NORMALIZED Handle = 0x80080007 + CO_E_SERVER_STOPPING Handle = 0x80080008 + MEM_E_INVALID_ROOT Handle = 0x80080009 + MEM_E_INVALID_LINK Handle = 0x80080010 + MEM_E_INVALID_SIZE Handle = 0x80080011 + CO_S_NOTALLINTERFACES Handle = 0x00080012 + CO_S_MACHINENAMENOTFOUND Handle = 0x00080013 + CO_E_MISSING_DISPLAYNAME Handle = 0x80080015 + CO_E_RUNAS_VALUE_MUST_BE_AAA Handle = 0x80080016 + CO_E_ELEVATION_DISABLED Handle = 0x80080017 + APPX_E_PACKAGING_INTERNAL Handle = 0x80080200 + APPX_E_INTERLEAVING_NOT_ALLOWED Handle = 0x80080201 + APPX_E_RELATIONSHIPS_NOT_ALLOWED Handle = 0x80080202 + APPX_E_MISSING_REQUIRED_FILE Handle = 0x80080203 + APPX_E_INVALID_MANIFEST Handle = 0x80080204 + APPX_E_INVALID_BLOCKMAP Handle = 0x80080205 + APPX_E_CORRUPT_CONTENT Handle = 0x80080206 + APPX_E_BLOCK_HASH_INVALID Handle = 0x80080207 + APPX_E_REQUESTED_RANGE_TOO_LARGE Handle = 0x80080208 + APPX_E_INVALID_SIP_CLIENT_DATA Handle = 0x80080209 + APPX_E_INVALID_KEY_INFO Handle = 0x8008020A + APPX_E_INVALID_CONTENTGROUPMAP Handle = 0x8008020B + APPX_E_INVALID_APPINSTALLER Handle = 0x8008020C + APPX_E_DELTA_BASELINE_VERSION_MISMATCH Handle = 0x8008020D + APPX_E_DELTA_PACKAGE_MISSING_FILE Handle = 0x8008020E + APPX_E_INVALID_DELTA_PACKAGE Handle = 0x8008020F + APPX_E_DELTA_APPENDED_PACKAGE_NOT_ALLOWED Handle = 0x80080210 + APPX_E_INVALID_PACKAGING_LAYOUT Handle = 0x80080211 + APPX_E_INVALID_PACKAGESIGNCONFIG Handle = 0x80080212 + APPX_E_RESOURCESPRI_NOT_ALLOWED Handle = 0x80080213 + APPX_E_FILE_COMPRESSION_MISMATCH Handle = 0x80080214 + APPX_E_INVALID_PAYLOAD_PACKAGE_EXTENSION Handle = 0x80080215 + APPX_E_INVALID_ENCRYPTION_EXCLUSION_FILE_LIST Handle = 0x80080216 + BT_E_SPURIOUS_ACTIVATION Handle = 0x80080300 + DISP_E_UNKNOWNINTERFACE Handle = 0x80020001 + DISP_E_MEMBERNOTFOUND Handle = 0x80020003 + DISP_E_PARAMNOTFOUND Handle = 0x80020004 + DISP_E_TYPEMISMATCH Handle = 0x80020005 + DISP_E_UNKNOWNNAME Handle = 0x80020006 + DISP_E_NONAMEDARGS Handle = 0x80020007 + DISP_E_BADVARTYPE Handle = 0x80020008 + DISP_E_EXCEPTION Handle = 0x80020009 + DISP_E_OVERFLOW Handle = 0x8002000A + DISP_E_BADINDEX Handle = 0x8002000B + DISP_E_UNKNOWNLCID Handle = 0x8002000C + DISP_E_ARRAYISLOCKED Handle = 0x8002000D + DISP_E_BADPARAMCOUNT Handle = 0x8002000E + DISP_E_PARAMNOTOPTIONAL Handle = 0x8002000F + DISP_E_BADCALLEE Handle = 0x80020010 + DISP_E_NOTACOLLECTION Handle = 0x80020011 + DISP_E_DIVBYZERO Handle = 0x80020012 + DISP_E_BUFFERTOOSMALL Handle = 0x80020013 + TYPE_E_BUFFERTOOSMALL Handle = 0x80028016 + TYPE_E_FIELDNOTFOUND Handle = 0x80028017 + TYPE_E_INVDATAREAD Handle = 0x80028018 + TYPE_E_UNSUPFORMAT Handle = 0x80028019 + TYPE_E_REGISTRYACCESS Handle = 0x8002801C + TYPE_E_LIBNOTREGISTERED Handle = 0x8002801D + TYPE_E_UNDEFINEDTYPE Handle = 0x80028027 + TYPE_E_QUALIFIEDNAMEDISALLOWED Handle = 0x80028028 + TYPE_E_INVALIDSTATE Handle = 0x80028029 + TYPE_E_WRONGTYPEKIND Handle = 0x8002802A + TYPE_E_ELEMENTNOTFOUND Handle = 0x8002802B + TYPE_E_AMBIGUOUSNAME Handle = 0x8002802C + TYPE_E_NAMECONFLICT Handle = 0x8002802D + TYPE_E_UNKNOWNLCID Handle = 0x8002802E + TYPE_E_DLLFUNCTIONNOTFOUND Handle = 0x8002802F + TYPE_E_BADMODULEKIND Handle = 0x800288BD + TYPE_E_SIZETOOBIG Handle = 0x800288C5 + TYPE_E_DUPLICATEID Handle = 0x800288C6 + TYPE_E_INVALIDID Handle = 0x800288CF + TYPE_E_TYPEMISMATCH Handle = 0x80028CA0 + TYPE_E_OUTOFBOUNDS Handle = 0x80028CA1 + TYPE_E_IOERROR Handle = 0x80028CA2 + TYPE_E_CANTCREATETMPFILE Handle = 0x80028CA3 + TYPE_E_CANTLOADLIBRARY Handle = 0x80029C4A + TYPE_E_INCONSISTENTPROPFUNCS Handle = 0x80029C83 + TYPE_E_CIRCULARTYPE Handle = 0x80029C84 + STG_E_INVALIDFUNCTION Handle = 0x80030001 + STG_E_FILENOTFOUND Handle = 0x80030002 + STG_E_PATHNOTFOUND Handle = 0x80030003 + STG_E_TOOMANYOPENFILES Handle = 0x80030004 + STG_E_ACCESSDENIED Handle = 0x80030005 + STG_E_INVALIDHANDLE Handle = 0x80030006 + STG_E_INSUFFICIENTMEMORY Handle = 0x80030008 + STG_E_INVALIDPOINTER Handle = 0x80030009 + STG_E_NOMOREFILES Handle = 0x80030012 + STG_E_DISKISWRITEPROTECTED Handle = 0x80030013 + STG_E_SEEKERROR Handle = 0x80030019 + STG_E_WRITEFAULT Handle = 0x8003001D + STG_E_READFAULT Handle = 0x8003001E + STG_E_SHAREVIOLATION Handle = 0x80030020 + STG_E_LOCKVIOLATION Handle = 0x80030021 + STG_E_FILEALREADYEXISTS Handle = 0x80030050 + STG_E_INVALIDPARAMETER Handle = 0x80030057 + STG_E_MEDIUMFULL Handle = 0x80030070 + STG_E_PROPSETMISMATCHED Handle = 0x800300F0 + STG_E_ABNORMALAPIEXIT Handle = 0x800300FA + STG_E_INVALIDHEADER Handle = 0x800300FB + STG_E_INVALIDNAME Handle = 0x800300FC + STG_E_UNKNOWN Handle = 0x800300FD + STG_E_UNIMPLEMENTEDFUNCTION Handle = 0x800300FE + STG_E_INVALIDFLAG Handle = 0x800300FF + STG_E_INUSE Handle = 0x80030100 + STG_E_NOTCURRENT Handle = 0x80030101 + STG_E_REVERTED Handle = 0x80030102 + STG_E_CANTSAVE Handle = 0x80030103 + STG_E_OLDFORMAT Handle = 0x80030104 + STG_E_OLDDLL Handle = 0x80030105 + STG_E_SHAREREQUIRED Handle = 0x80030106 + STG_E_NOTFILEBASEDSTORAGE Handle = 0x80030107 + STG_E_EXTANTMARSHALLINGS Handle = 0x80030108 + STG_E_DOCFILECORRUPT Handle = 0x80030109 + STG_E_BADBASEADDRESS Handle = 0x80030110 + STG_E_DOCFILETOOLARGE Handle = 0x80030111 + STG_E_NOTSIMPLEFORMAT Handle = 0x80030112 + STG_E_INCOMPLETE Handle = 0x80030201 + STG_E_TERMINATED Handle = 0x80030202 + STG_S_CONVERTED Handle = 0x00030200 + STG_S_BLOCK Handle = 0x00030201 + STG_S_RETRYNOW Handle = 0x00030202 + STG_S_MONITORING Handle = 0x00030203 + STG_S_MULTIPLEOPENS Handle = 0x00030204 + STG_S_CONSOLIDATIONFAILED Handle = 0x00030205 + STG_S_CANNOTCONSOLIDATE Handle = 0x00030206 + STG_S_POWER_CYCLE_REQUIRED Handle = 0x00030207 + STG_E_FIRMWARE_SLOT_INVALID Handle = 0x80030208 + STG_E_FIRMWARE_IMAGE_INVALID Handle = 0x80030209 + STG_E_DEVICE_UNRESPONSIVE Handle = 0x8003020A + STG_E_STATUS_COPY_PROTECTION_FAILURE Handle = 0x80030305 + STG_E_CSS_AUTHENTICATION_FAILURE Handle = 0x80030306 + STG_E_CSS_KEY_NOT_PRESENT Handle = 0x80030307 + STG_E_CSS_KEY_NOT_ESTABLISHED Handle = 0x80030308 + STG_E_CSS_SCRAMBLED_SECTOR Handle = 0x80030309 + STG_E_CSS_REGION_MISMATCH Handle = 0x8003030A + STG_E_RESETS_EXHAUSTED Handle = 0x8003030B + RPC_E_CALL_REJECTED Handle = 0x80010001 + RPC_E_CALL_CANCELED Handle = 0x80010002 + RPC_E_CANTPOST_INSENDCALL Handle = 0x80010003 + RPC_E_CANTCALLOUT_INASYNCCALL Handle = 0x80010004 + RPC_E_CANTCALLOUT_INEXTERNALCALL Handle = 0x80010005 + RPC_E_CONNECTION_TERMINATED Handle = 0x80010006 + RPC_E_SERVER_DIED Handle = 0x80010007 + RPC_E_CLIENT_DIED Handle = 0x80010008 + RPC_E_INVALID_DATAPACKET Handle = 0x80010009 + RPC_E_CANTTRANSMIT_CALL Handle = 0x8001000A + RPC_E_CLIENT_CANTMARSHAL_DATA Handle = 0x8001000B + RPC_E_CLIENT_CANTUNMARSHAL_DATA Handle = 0x8001000C + RPC_E_SERVER_CANTMARSHAL_DATA Handle = 0x8001000D + RPC_E_SERVER_CANTUNMARSHAL_DATA Handle = 0x8001000E + RPC_E_INVALID_DATA Handle = 0x8001000F + RPC_E_INVALID_PARAMETER Handle = 0x80010010 + RPC_E_CANTCALLOUT_AGAIN Handle = 0x80010011 + RPC_E_SERVER_DIED_DNE Handle = 0x80010012 + RPC_E_SYS_CALL_FAILED Handle = 0x80010100 + RPC_E_OUT_OF_RESOURCES Handle = 0x80010101 + RPC_E_ATTEMPTED_MULTITHREAD Handle = 0x80010102 + RPC_E_NOT_REGISTERED Handle = 0x80010103 + RPC_E_FAULT Handle = 0x80010104 + RPC_E_SERVERFAULT Handle = 0x80010105 + RPC_E_CHANGED_MODE Handle = 0x80010106 + RPC_E_INVALIDMETHOD Handle = 0x80010107 + RPC_E_DISCONNECTED Handle = 0x80010108 + RPC_E_RETRY Handle = 0x80010109 + RPC_E_SERVERCALL_RETRYLATER Handle = 0x8001010A + RPC_E_SERVERCALL_REJECTED Handle = 0x8001010B + RPC_E_INVALID_CALLDATA Handle = 0x8001010C + RPC_E_CANTCALLOUT_ININPUTSYNCCALL Handle = 0x8001010D + RPC_E_WRONG_THREAD Handle = 0x8001010E + RPC_E_THREAD_NOT_INIT Handle = 0x8001010F + RPC_E_VERSION_MISMATCH Handle = 0x80010110 + RPC_E_INVALID_HEADER Handle = 0x80010111 + RPC_E_INVALID_EXTENSION Handle = 0x80010112 + RPC_E_INVALID_IPID Handle = 0x80010113 + RPC_E_INVALID_OBJECT Handle = 0x80010114 + RPC_S_CALLPENDING Handle = 0x80010115 + RPC_S_WAITONTIMER Handle = 0x80010116 + RPC_E_CALL_COMPLETE Handle = 0x80010117 + RPC_E_UNSECURE_CALL Handle = 0x80010118 + RPC_E_TOO_LATE Handle = 0x80010119 + RPC_E_NO_GOOD_SECURITY_PACKAGES Handle = 0x8001011A + RPC_E_ACCESS_DENIED Handle = 0x8001011B + RPC_E_REMOTE_DISABLED Handle = 0x8001011C + RPC_E_INVALID_OBJREF Handle = 0x8001011D + RPC_E_NO_CONTEXT Handle = 0x8001011E + RPC_E_TIMEOUT Handle = 0x8001011F + RPC_E_NO_SYNC Handle = 0x80010120 + RPC_E_FULLSIC_REQUIRED Handle = 0x80010121 + RPC_E_INVALID_STD_NAME Handle = 0x80010122 + CO_E_FAILEDTOIMPERSONATE Handle = 0x80010123 + CO_E_FAILEDTOGETSECCTX Handle = 0x80010124 + CO_E_FAILEDTOOPENTHREADTOKEN Handle = 0x80010125 + CO_E_FAILEDTOGETTOKENINFO Handle = 0x80010126 + CO_E_TRUSTEEDOESNTMATCHCLIENT Handle = 0x80010127 + CO_E_FAILEDTOQUERYCLIENTBLANKET Handle = 0x80010128 + CO_E_FAILEDTOSETDACL Handle = 0x80010129 + CO_E_ACCESSCHECKFAILED Handle = 0x8001012A + CO_E_NETACCESSAPIFAILED Handle = 0x8001012B + CO_E_WRONGTRUSTEENAMESYNTAX Handle = 0x8001012C + CO_E_INVALIDSID Handle = 0x8001012D + CO_E_CONVERSIONFAILED Handle = 0x8001012E + CO_E_NOMATCHINGSIDFOUND Handle = 0x8001012F + CO_E_LOOKUPACCSIDFAILED Handle = 0x80010130 + CO_E_NOMATCHINGNAMEFOUND Handle = 0x80010131 + CO_E_LOOKUPACCNAMEFAILED Handle = 0x80010132 + CO_E_SETSERLHNDLFAILED Handle = 0x80010133 + CO_E_FAILEDTOGETWINDIR Handle = 0x80010134 + CO_E_PATHTOOLONG Handle = 0x80010135 + CO_E_FAILEDTOGENUUID Handle = 0x80010136 + CO_E_FAILEDTOCREATEFILE Handle = 0x80010137 + CO_E_FAILEDTOCLOSEHANDLE Handle = 0x80010138 + CO_E_EXCEEDSYSACLLIMIT Handle = 0x80010139 + CO_E_ACESINWRONGORDER Handle = 0x8001013A + CO_E_INCOMPATIBLESTREAMVERSION Handle = 0x8001013B + CO_E_FAILEDTOOPENPROCESSTOKEN Handle = 0x8001013C + CO_E_DECODEFAILED Handle = 0x8001013D + CO_E_ACNOTINITIALIZED Handle = 0x8001013F + CO_E_CANCEL_DISABLED Handle = 0x80010140 + RPC_E_UNEXPECTED Handle = 0x8001FFFF + ERROR_AUDITING_DISABLED Handle = 0xC0090001 + ERROR_ALL_SIDS_FILTERED Handle = 0xC0090002 + ERROR_BIZRULES_NOT_ENABLED Handle = 0xC0090003 + NTE_BAD_UID Handle = 0x80090001 + NTE_BAD_HASH Handle = 0x80090002 + NTE_BAD_KEY Handle = 0x80090003 + NTE_BAD_LEN Handle = 0x80090004 + NTE_BAD_DATA Handle = 0x80090005 + NTE_BAD_SIGNATURE Handle = 0x80090006 + NTE_BAD_VER Handle = 0x80090007 + NTE_BAD_ALGID Handle = 0x80090008 + NTE_BAD_FLAGS Handle = 0x80090009 + NTE_BAD_TYPE Handle = 0x8009000A + NTE_BAD_KEY_STATE Handle = 0x8009000B + NTE_BAD_HASH_STATE Handle = 0x8009000C + NTE_NO_KEY Handle = 0x8009000D + NTE_NO_MEMORY Handle = 0x8009000E + NTE_EXISTS Handle = 0x8009000F + NTE_PERM Handle = 0x80090010 + NTE_NOT_FOUND Handle = 0x80090011 + NTE_DOUBLE_ENCRYPT Handle = 0x80090012 + NTE_BAD_PROVIDER Handle = 0x80090013 + NTE_BAD_PROV_TYPE Handle = 0x80090014 + NTE_BAD_PUBLIC_KEY Handle = 0x80090015 + NTE_BAD_KEYSET Handle = 0x80090016 + NTE_PROV_TYPE_NOT_DEF Handle = 0x80090017 + NTE_PROV_TYPE_ENTRY_BAD Handle = 0x80090018 + NTE_KEYSET_NOT_DEF Handle = 0x80090019 + NTE_KEYSET_ENTRY_BAD Handle = 0x8009001A + NTE_PROV_TYPE_NO_MATCH Handle = 0x8009001B + NTE_SIGNATURE_FILE_BAD Handle = 0x8009001C + NTE_PROVIDER_DLL_FAIL Handle = 0x8009001D + NTE_PROV_DLL_NOT_FOUND Handle = 0x8009001E + NTE_BAD_KEYSET_PARAM Handle = 0x8009001F + NTE_FAIL Handle = 0x80090020 + NTE_SYS_ERR Handle = 0x80090021 + NTE_SILENT_CONTEXT Handle = 0x80090022 + NTE_TOKEN_KEYSET_STORAGE_FULL Handle = 0x80090023 + NTE_TEMPORARY_PROFILE Handle = 0x80090024 + NTE_FIXEDPARAMETER Handle = 0x80090025 + NTE_INVALID_HANDLE Handle = 0x80090026 + NTE_INVALID_PARAMETER Handle = 0x80090027 + NTE_BUFFER_TOO_SMALL Handle = 0x80090028 + NTE_NOT_SUPPORTED Handle = 0x80090029 + NTE_NO_MORE_ITEMS Handle = 0x8009002A + NTE_BUFFERS_OVERLAP Handle = 0x8009002B + NTE_DECRYPTION_FAILURE Handle = 0x8009002C + NTE_INTERNAL_ERROR Handle = 0x8009002D + NTE_UI_REQUIRED Handle = 0x8009002E + NTE_HMAC_NOT_SUPPORTED Handle = 0x8009002F + NTE_DEVICE_NOT_READY Handle = 0x80090030 + NTE_AUTHENTICATION_IGNORED Handle = 0x80090031 + NTE_VALIDATION_FAILED Handle = 0x80090032 + NTE_INCORRECT_PASSWORD Handle = 0x80090033 + NTE_ENCRYPTION_FAILURE Handle = 0x80090034 + NTE_DEVICE_NOT_FOUND Handle = 0x80090035 + NTE_USER_CANCELLED Handle = 0x80090036 + NTE_PASSWORD_CHANGE_REQUIRED Handle = 0x80090037 + NTE_NOT_ACTIVE_CONSOLE Handle = 0x80090038 + SEC_E_INSUFFICIENT_MEMORY Handle = 0x80090300 + SEC_E_INVALID_HANDLE Handle = 0x80090301 + SEC_E_UNSUPPORTED_FUNCTION Handle = 0x80090302 + SEC_E_TARGET_UNKNOWN Handle = 0x80090303 + SEC_E_INTERNAL_ERROR Handle = 0x80090304 + SEC_E_SECPKG_NOT_FOUND Handle = 0x80090305 + SEC_E_NOT_OWNER Handle = 0x80090306 + SEC_E_CANNOT_INSTALL Handle = 0x80090307 + SEC_E_INVALID_TOKEN Handle = 0x80090308 + SEC_E_CANNOT_PACK Handle = 0x80090309 + SEC_E_QOP_NOT_SUPPORTED Handle = 0x8009030A + SEC_E_NO_IMPERSONATION Handle = 0x8009030B + SEC_E_LOGON_DENIED Handle = 0x8009030C + SEC_E_UNKNOWN_CREDENTIALS Handle = 0x8009030D + SEC_E_NO_CREDENTIALS Handle = 0x8009030E + SEC_E_MESSAGE_ALTERED Handle = 0x8009030F + SEC_E_OUT_OF_SEQUENCE Handle = 0x80090310 + SEC_E_NO_AUTHENTICATING_AUTHORITY Handle = 0x80090311 + SEC_I_CONTINUE_NEEDED Handle = 0x00090312 + SEC_I_COMPLETE_NEEDED Handle = 0x00090313 + SEC_I_COMPLETE_AND_CONTINUE Handle = 0x00090314 + SEC_I_LOCAL_LOGON Handle = 0x00090315 + SEC_I_GENERIC_EXTENSION_RECEIVED Handle = 0x00090316 + SEC_E_BAD_PKGID Handle = 0x80090316 + SEC_E_CONTEXT_EXPIRED Handle = 0x80090317 + SEC_I_CONTEXT_EXPIRED Handle = 0x00090317 + SEC_E_INCOMPLETE_MESSAGE Handle = 0x80090318 + SEC_E_INCOMPLETE_CREDENTIALS Handle = 0x80090320 + SEC_E_BUFFER_TOO_SMALL Handle = 0x80090321 + SEC_I_INCOMPLETE_CREDENTIALS Handle = 0x00090320 + SEC_I_RENEGOTIATE Handle = 0x00090321 + SEC_E_WRONG_PRINCIPAL Handle = 0x80090322 + SEC_I_NO_LSA_CONTEXT Handle = 0x00090323 + SEC_E_TIME_SKEW Handle = 0x80090324 + SEC_E_UNTRUSTED_ROOT Handle = 0x80090325 + SEC_E_ILLEGAL_MESSAGE Handle = 0x80090326 + SEC_E_CERT_UNKNOWN Handle = 0x80090327 + SEC_E_CERT_EXPIRED Handle = 0x80090328 + SEC_E_ENCRYPT_FAILURE Handle = 0x80090329 + SEC_E_DECRYPT_FAILURE Handle = 0x80090330 + SEC_E_ALGORITHM_MISMATCH Handle = 0x80090331 + SEC_E_SECURITY_QOS_FAILED Handle = 0x80090332 + SEC_E_UNFINISHED_CONTEXT_DELETED Handle = 0x80090333 + SEC_E_NO_TGT_REPLY Handle = 0x80090334 + SEC_E_NO_IP_ADDRESSES Handle = 0x80090335 + SEC_E_WRONG_CREDENTIAL_HANDLE Handle = 0x80090336 + SEC_E_CRYPTO_SYSTEM_INVALID Handle = 0x80090337 + SEC_E_MAX_REFERRALS_EXCEEDED Handle = 0x80090338 + SEC_E_MUST_BE_KDC Handle = 0x80090339 + SEC_E_STRONG_CRYPTO_NOT_SUPPORTED Handle = 0x8009033A + SEC_E_TOO_MANY_PRINCIPALS Handle = 0x8009033B + SEC_E_NO_PA_DATA Handle = 0x8009033C + SEC_E_PKINIT_NAME_MISMATCH Handle = 0x8009033D + SEC_E_SMARTCARD_LOGON_REQUIRED Handle = 0x8009033E + SEC_E_SHUTDOWN_IN_PROGRESS Handle = 0x8009033F + SEC_E_KDC_INVALID_REQUEST Handle = 0x80090340 + SEC_E_KDC_UNABLE_TO_REFER Handle = 0x80090341 + SEC_E_KDC_UNKNOWN_ETYPE Handle = 0x80090342 + SEC_E_UNSUPPORTED_PREAUTH Handle = 0x80090343 + SEC_E_DELEGATION_REQUIRED Handle = 0x80090345 + SEC_E_BAD_BINDINGS Handle = 0x80090346 + SEC_E_MULTIPLE_ACCOUNTS Handle = 0x80090347 + SEC_E_NO_KERB_KEY Handle = 0x80090348 + SEC_E_CERT_WRONG_USAGE Handle = 0x80090349 + SEC_E_DOWNGRADE_DETECTED Handle = 0x80090350 + SEC_E_SMARTCARD_CERT_REVOKED Handle = 0x80090351 + SEC_E_ISSUING_CA_UNTRUSTED Handle = 0x80090352 + SEC_E_REVOCATION_OFFLINE_C Handle = 0x80090353 + SEC_E_PKINIT_CLIENT_FAILURE Handle = 0x80090354 + SEC_E_SMARTCARD_CERT_EXPIRED Handle = 0x80090355 + SEC_E_NO_S4U_PROT_SUPPORT Handle = 0x80090356 + SEC_E_CROSSREALM_DELEGATION_FAILURE Handle = 0x80090357 + SEC_E_REVOCATION_OFFLINE_KDC Handle = 0x80090358 + SEC_E_ISSUING_CA_UNTRUSTED_KDC Handle = 0x80090359 + SEC_E_KDC_CERT_EXPIRED Handle = 0x8009035A + SEC_E_KDC_CERT_REVOKED Handle = 0x8009035B + SEC_I_SIGNATURE_NEEDED Handle = 0x0009035C + SEC_E_INVALID_PARAMETER Handle = 0x8009035D + SEC_E_DELEGATION_POLICY Handle = 0x8009035E + SEC_E_POLICY_NLTM_ONLY Handle = 0x8009035F + SEC_I_NO_RENEGOTIATION Handle = 0x00090360 + SEC_E_NO_CONTEXT Handle = 0x80090361 + SEC_E_PKU2U_CERT_FAILURE Handle = 0x80090362 + SEC_E_MUTUAL_AUTH_FAILED Handle = 0x80090363 + SEC_I_MESSAGE_FRAGMENT Handle = 0x00090364 + SEC_E_ONLY_HTTPS_ALLOWED Handle = 0x80090365 + SEC_I_CONTINUE_NEEDED_MESSAGE_OK Handle = 0x00090366 + SEC_E_APPLICATION_PROTOCOL_MISMATCH Handle = 0x80090367 + SEC_I_ASYNC_CALL_PENDING Handle = 0x00090368 + SEC_E_INVALID_UPN_NAME Handle = 0x80090369 + SEC_E_EXT_BUFFER_TOO_SMALL Handle = 0x8009036A + SEC_E_INSUFFICIENT_BUFFERS Handle = 0x8009036B + SEC_E_NO_SPM = SEC_E_INTERNAL_ERROR + SEC_E_NOT_SUPPORTED = SEC_E_UNSUPPORTED_FUNCTION + CRYPT_E_MSG_ERROR Handle = 0x80091001 + CRYPT_E_UNKNOWN_ALGO Handle = 0x80091002 + CRYPT_E_OID_FORMAT Handle = 0x80091003 + CRYPT_E_INVALID_MSG_TYPE Handle = 0x80091004 + CRYPT_E_UNEXPECTED_ENCODING Handle = 0x80091005 + CRYPT_E_AUTH_ATTR_MISSING Handle = 0x80091006 + CRYPT_E_HASH_VALUE Handle = 0x80091007 + CRYPT_E_INVALID_INDEX Handle = 0x80091008 + CRYPT_E_ALREADY_DECRYPTED Handle = 0x80091009 + CRYPT_E_NOT_DECRYPTED Handle = 0x8009100A + CRYPT_E_RECIPIENT_NOT_FOUND Handle = 0x8009100B + CRYPT_E_CONTROL_TYPE Handle = 0x8009100C + CRYPT_E_ISSUER_SERIALNUMBER Handle = 0x8009100D + CRYPT_E_SIGNER_NOT_FOUND Handle = 0x8009100E + CRYPT_E_ATTRIBUTES_MISSING Handle = 0x8009100F + CRYPT_E_STREAM_MSG_NOT_READY Handle = 0x80091010 + CRYPT_E_STREAM_INSUFFICIENT_DATA Handle = 0x80091011 + CRYPT_I_NEW_PROTECTION_REQUIRED Handle = 0x00091012 + CRYPT_E_BAD_LEN Handle = 0x80092001 + CRYPT_E_BAD_ENCODE Handle = 0x80092002 + CRYPT_E_FILE_ERROR Handle = 0x80092003 + CRYPT_E_NOT_FOUND Handle = 0x80092004 + CRYPT_E_EXISTS Handle = 0x80092005 + CRYPT_E_NO_PROVIDER Handle = 0x80092006 + CRYPT_E_SELF_SIGNED Handle = 0x80092007 + CRYPT_E_DELETED_PREV Handle = 0x80092008 + CRYPT_E_NO_MATCH Handle = 0x80092009 + CRYPT_E_UNEXPECTED_MSG_TYPE Handle = 0x8009200A + CRYPT_E_NO_KEY_PROPERTY Handle = 0x8009200B + CRYPT_E_NO_DECRYPT_CERT Handle = 0x8009200C + CRYPT_E_BAD_MSG Handle = 0x8009200D + CRYPT_E_NO_SIGNER Handle = 0x8009200E + CRYPT_E_PENDING_CLOSE Handle = 0x8009200F + CRYPT_E_REVOKED Handle = 0x80092010 + CRYPT_E_NO_REVOCATION_DLL Handle = 0x80092011 + CRYPT_E_NO_REVOCATION_CHECK Handle = 0x80092012 + CRYPT_E_REVOCATION_OFFLINE Handle = 0x80092013 + CRYPT_E_NOT_IN_REVOCATION_DATABASE Handle = 0x80092014 + CRYPT_E_INVALID_NUMERIC_STRING Handle = 0x80092020 + CRYPT_E_INVALID_PRINTABLE_STRING Handle = 0x80092021 + CRYPT_E_INVALID_IA5_STRING Handle = 0x80092022 + CRYPT_E_INVALID_X500_STRING Handle = 0x80092023 + CRYPT_E_NOT_CHAR_STRING Handle = 0x80092024 + CRYPT_E_FILERESIZED Handle = 0x80092025 + CRYPT_E_SECURITY_SETTINGS Handle = 0x80092026 + CRYPT_E_NO_VERIFY_USAGE_DLL Handle = 0x80092027 + CRYPT_E_NO_VERIFY_USAGE_CHECK Handle = 0x80092028 + CRYPT_E_VERIFY_USAGE_OFFLINE Handle = 0x80092029 + CRYPT_E_NOT_IN_CTL Handle = 0x8009202A + CRYPT_E_NO_TRUSTED_SIGNER Handle = 0x8009202B + CRYPT_E_MISSING_PUBKEY_PARA Handle = 0x8009202C + CRYPT_E_OBJECT_LOCATOR_OBJECT_NOT_FOUND Handle = 0x8009202D + CRYPT_E_OSS_ERROR Handle = 0x80093000 + OSS_MORE_BUF Handle = 0x80093001 + OSS_NEGATIVE_UINTEGER Handle = 0x80093002 + OSS_PDU_RANGE Handle = 0x80093003 + OSS_MORE_INPUT Handle = 0x80093004 + OSS_DATA_ERROR Handle = 0x80093005 + OSS_BAD_ARG Handle = 0x80093006 + OSS_BAD_VERSION Handle = 0x80093007 + OSS_OUT_MEMORY Handle = 0x80093008 + OSS_PDU_MISMATCH Handle = 0x80093009 + OSS_LIMITED Handle = 0x8009300A + OSS_BAD_PTR Handle = 0x8009300B + OSS_BAD_TIME Handle = 0x8009300C + OSS_INDEFINITE_NOT_SUPPORTED Handle = 0x8009300D + OSS_MEM_ERROR Handle = 0x8009300E + OSS_BAD_TABLE Handle = 0x8009300F + OSS_TOO_LONG Handle = 0x80093010 + OSS_CONSTRAINT_VIOLATED Handle = 0x80093011 + OSS_FATAL_ERROR Handle = 0x80093012 + OSS_ACCESS_SERIALIZATION_ERROR Handle = 0x80093013 + OSS_NULL_TBL Handle = 0x80093014 + OSS_NULL_FCN Handle = 0x80093015 + OSS_BAD_ENCRULES Handle = 0x80093016 + OSS_UNAVAIL_ENCRULES Handle = 0x80093017 + OSS_CANT_OPEN_TRACE_WINDOW Handle = 0x80093018 + OSS_UNIMPLEMENTED Handle = 0x80093019 + OSS_OID_DLL_NOT_LINKED Handle = 0x8009301A + OSS_CANT_OPEN_TRACE_FILE Handle = 0x8009301B + OSS_TRACE_FILE_ALREADY_OPEN Handle = 0x8009301C + OSS_TABLE_MISMATCH Handle = 0x8009301D + OSS_TYPE_NOT_SUPPORTED Handle = 0x8009301E + OSS_REAL_DLL_NOT_LINKED Handle = 0x8009301F + OSS_REAL_CODE_NOT_LINKED Handle = 0x80093020 + OSS_OUT_OF_RANGE Handle = 0x80093021 + OSS_COPIER_DLL_NOT_LINKED Handle = 0x80093022 + OSS_CONSTRAINT_DLL_NOT_LINKED Handle = 0x80093023 + OSS_COMPARATOR_DLL_NOT_LINKED Handle = 0x80093024 + OSS_COMPARATOR_CODE_NOT_LINKED Handle = 0x80093025 + OSS_MEM_MGR_DLL_NOT_LINKED Handle = 0x80093026 + OSS_PDV_DLL_NOT_LINKED Handle = 0x80093027 + OSS_PDV_CODE_NOT_LINKED Handle = 0x80093028 + OSS_API_DLL_NOT_LINKED Handle = 0x80093029 + OSS_BERDER_DLL_NOT_LINKED Handle = 0x8009302A + OSS_PER_DLL_NOT_LINKED Handle = 0x8009302B + OSS_OPEN_TYPE_ERROR Handle = 0x8009302C + OSS_MUTEX_NOT_CREATED Handle = 0x8009302D + OSS_CANT_CLOSE_TRACE_FILE Handle = 0x8009302E + CRYPT_E_ASN1_ERROR Handle = 0x80093100 + CRYPT_E_ASN1_INTERNAL Handle = 0x80093101 + CRYPT_E_ASN1_EOD Handle = 0x80093102 + CRYPT_E_ASN1_CORRUPT Handle = 0x80093103 + CRYPT_E_ASN1_LARGE Handle = 0x80093104 + CRYPT_E_ASN1_CONSTRAINT Handle = 0x80093105 + CRYPT_E_ASN1_MEMORY Handle = 0x80093106 + CRYPT_E_ASN1_OVERFLOW Handle = 0x80093107 + CRYPT_E_ASN1_BADPDU Handle = 0x80093108 + CRYPT_E_ASN1_BADARGS Handle = 0x80093109 + CRYPT_E_ASN1_BADREAL Handle = 0x8009310A + CRYPT_E_ASN1_BADTAG Handle = 0x8009310B + CRYPT_E_ASN1_CHOICE Handle = 0x8009310C + CRYPT_E_ASN1_RULE Handle = 0x8009310D + CRYPT_E_ASN1_UTF8 Handle = 0x8009310E + CRYPT_E_ASN1_PDU_TYPE Handle = 0x80093133 + CRYPT_E_ASN1_NYI Handle = 0x80093134 + CRYPT_E_ASN1_EXTENDED Handle = 0x80093201 + CRYPT_E_ASN1_NOEOD Handle = 0x80093202 + CERTSRV_E_BAD_REQUESTSUBJECT Handle = 0x80094001 + CERTSRV_E_NO_REQUEST Handle = 0x80094002 + CERTSRV_E_BAD_REQUESTSTATUS Handle = 0x80094003 + CERTSRV_E_PROPERTY_EMPTY Handle = 0x80094004 + CERTSRV_E_INVALID_CA_CERTIFICATE Handle = 0x80094005 + CERTSRV_E_SERVER_SUSPENDED Handle = 0x80094006 + CERTSRV_E_ENCODING_LENGTH Handle = 0x80094007 + CERTSRV_E_ROLECONFLICT Handle = 0x80094008 + CERTSRV_E_RESTRICTEDOFFICER Handle = 0x80094009 + CERTSRV_E_KEY_ARCHIVAL_NOT_CONFIGURED Handle = 0x8009400A + CERTSRV_E_NO_VALID_KRA Handle = 0x8009400B + CERTSRV_E_BAD_REQUEST_KEY_ARCHIVAL Handle = 0x8009400C + CERTSRV_E_NO_CAADMIN_DEFINED Handle = 0x8009400D + CERTSRV_E_BAD_RENEWAL_CERT_ATTRIBUTE Handle = 0x8009400E + CERTSRV_E_NO_DB_SESSIONS Handle = 0x8009400F + CERTSRV_E_ALIGNMENT_FAULT Handle = 0x80094010 + CERTSRV_E_ENROLL_DENIED Handle = 0x80094011 + CERTSRV_E_TEMPLATE_DENIED Handle = 0x80094012 + CERTSRV_E_DOWNLEVEL_DC_SSL_OR_UPGRADE Handle = 0x80094013 + CERTSRV_E_ADMIN_DENIED_REQUEST Handle = 0x80094014 + CERTSRV_E_NO_POLICY_SERVER Handle = 0x80094015 + CERTSRV_E_WEAK_SIGNATURE_OR_KEY Handle = 0x80094016 + CERTSRV_E_KEY_ATTESTATION_NOT_SUPPORTED Handle = 0x80094017 + CERTSRV_E_ENCRYPTION_CERT_REQUIRED Handle = 0x80094018 + CERTSRV_E_UNSUPPORTED_CERT_TYPE Handle = 0x80094800 + CERTSRV_E_NO_CERT_TYPE Handle = 0x80094801 + CERTSRV_E_TEMPLATE_CONFLICT Handle = 0x80094802 + CERTSRV_E_SUBJECT_ALT_NAME_REQUIRED Handle = 0x80094803 + CERTSRV_E_ARCHIVED_KEY_REQUIRED Handle = 0x80094804 + CERTSRV_E_SMIME_REQUIRED Handle = 0x80094805 + CERTSRV_E_BAD_RENEWAL_SUBJECT Handle = 0x80094806 + CERTSRV_E_BAD_TEMPLATE_VERSION Handle = 0x80094807 + CERTSRV_E_TEMPLATE_POLICY_REQUIRED Handle = 0x80094808 + CERTSRV_E_SIGNATURE_POLICY_REQUIRED Handle = 0x80094809 + CERTSRV_E_SIGNATURE_COUNT Handle = 0x8009480A + CERTSRV_E_SIGNATURE_REJECTED Handle = 0x8009480B + CERTSRV_E_ISSUANCE_POLICY_REQUIRED Handle = 0x8009480C + CERTSRV_E_SUBJECT_UPN_REQUIRED Handle = 0x8009480D + CERTSRV_E_SUBJECT_DIRECTORY_GUID_REQUIRED Handle = 0x8009480E + CERTSRV_E_SUBJECT_DNS_REQUIRED Handle = 0x8009480F + CERTSRV_E_ARCHIVED_KEY_UNEXPECTED Handle = 0x80094810 + CERTSRV_E_KEY_LENGTH Handle = 0x80094811 + CERTSRV_E_SUBJECT_EMAIL_REQUIRED Handle = 0x80094812 + CERTSRV_E_UNKNOWN_CERT_TYPE Handle = 0x80094813 + CERTSRV_E_CERT_TYPE_OVERLAP Handle = 0x80094814 + CERTSRV_E_TOO_MANY_SIGNATURES Handle = 0x80094815 + CERTSRV_E_RENEWAL_BAD_PUBLIC_KEY Handle = 0x80094816 + CERTSRV_E_INVALID_EK Handle = 0x80094817 + CERTSRV_E_INVALID_IDBINDING Handle = 0x80094818 + CERTSRV_E_INVALID_ATTESTATION Handle = 0x80094819 + CERTSRV_E_KEY_ATTESTATION Handle = 0x8009481A + CERTSRV_E_CORRUPT_KEY_ATTESTATION Handle = 0x8009481B + CERTSRV_E_EXPIRED_CHALLENGE Handle = 0x8009481C + CERTSRV_E_INVALID_RESPONSE Handle = 0x8009481D + CERTSRV_E_INVALID_REQUESTID Handle = 0x8009481E + CERTSRV_E_REQUEST_PRECERTIFICATE_MISMATCH Handle = 0x8009481F + CERTSRV_E_PENDING_CLIENT_RESPONSE Handle = 0x80094820 + XENROLL_E_KEY_NOT_EXPORTABLE Handle = 0x80095000 + XENROLL_E_CANNOT_ADD_ROOT_CERT Handle = 0x80095001 + XENROLL_E_RESPONSE_KA_HASH_NOT_FOUND Handle = 0x80095002 + XENROLL_E_RESPONSE_UNEXPECTED_KA_HASH Handle = 0x80095003 + XENROLL_E_RESPONSE_KA_HASH_MISMATCH Handle = 0x80095004 + XENROLL_E_KEYSPEC_SMIME_MISMATCH Handle = 0x80095005 + TRUST_E_SYSTEM_ERROR Handle = 0x80096001 + TRUST_E_NO_SIGNER_CERT Handle = 0x80096002 + TRUST_E_COUNTER_SIGNER Handle = 0x80096003 + TRUST_E_CERT_SIGNATURE Handle = 0x80096004 + TRUST_E_TIME_STAMP Handle = 0x80096005 + TRUST_E_BAD_DIGEST Handle = 0x80096010 + TRUST_E_MALFORMED_SIGNATURE Handle = 0x80096011 + TRUST_E_BASIC_CONSTRAINTS Handle = 0x80096019 + TRUST_E_FINANCIAL_CRITERIA Handle = 0x8009601E + MSSIPOTF_E_OUTOFMEMRANGE Handle = 0x80097001 + MSSIPOTF_E_CANTGETOBJECT Handle = 0x80097002 + MSSIPOTF_E_NOHEADTABLE Handle = 0x80097003 + MSSIPOTF_E_BAD_MAGICNUMBER Handle = 0x80097004 + MSSIPOTF_E_BAD_OFFSET_TABLE Handle = 0x80097005 + MSSIPOTF_E_TABLE_TAGORDER Handle = 0x80097006 + MSSIPOTF_E_TABLE_LONGWORD Handle = 0x80097007 + MSSIPOTF_E_BAD_FIRST_TABLE_PLACEMENT Handle = 0x80097008 + MSSIPOTF_E_TABLES_OVERLAP Handle = 0x80097009 + MSSIPOTF_E_TABLE_PADBYTES Handle = 0x8009700A + MSSIPOTF_E_FILETOOSMALL Handle = 0x8009700B + MSSIPOTF_E_TABLE_CHECKSUM Handle = 0x8009700C + MSSIPOTF_E_FILE_CHECKSUM Handle = 0x8009700D + MSSIPOTF_E_FAILED_POLICY Handle = 0x80097010 + MSSIPOTF_E_FAILED_HINTS_CHECK Handle = 0x80097011 + MSSIPOTF_E_NOT_OPENTYPE Handle = 0x80097012 + MSSIPOTF_E_FILE Handle = 0x80097013 + MSSIPOTF_E_CRYPT Handle = 0x80097014 + MSSIPOTF_E_BADVERSION Handle = 0x80097015 + MSSIPOTF_E_DSIG_STRUCTURE Handle = 0x80097016 + MSSIPOTF_E_PCONST_CHECK Handle = 0x80097017 + MSSIPOTF_E_STRUCTURE Handle = 0x80097018 + ERROR_CRED_REQUIRES_CONFIRMATION Handle = 0x80097019 + NTE_OP_OK syscall.Errno = 0 + TRUST_E_PROVIDER_UNKNOWN Handle = 0x800B0001 + TRUST_E_ACTION_UNKNOWN Handle = 0x800B0002 + TRUST_E_SUBJECT_FORM_UNKNOWN Handle = 0x800B0003 + TRUST_E_SUBJECT_NOT_TRUSTED Handle = 0x800B0004 + DIGSIG_E_ENCODE Handle = 0x800B0005 + DIGSIG_E_DECODE Handle = 0x800B0006 + DIGSIG_E_EXTENSIBILITY Handle = 0x800B0007 + DIGSIG_E_CRYPTO Handle = 0x800B0008 + PERSIST_E_SIZEDEFINITE Handle = 0x800B0009 + PERSIST_E_SIZEINDEFINITE Handle = 0x800B000A + PERSIST_E_NOTSELFSIZING Handle = 0x800B000B + TRUST_E_NOSIGNATURE Handle = 0x800B0100 + CERT_E_EXPIRED Handle = 0x800B0101 + CERT_E_VALIDITYPERIODNESTING Handle = 0x800B0102 + CERT_E_ROLE Handle = 0x800B0103 + CERT_E_PATHLENCONST Handle = 0x800B0104 + CERT_E_CRITICAL Handle = 0x800B0105 + CERT_E_PURPOSE Handle = 0x800B0106 + CERT_E_ISSUERCHAINING Handle = 0x800B0107 + CERT_E_MALFORMED Handle = 0x800B0108 + CERT_E_UNTRUSTEDROOT Handle = 0x800B0109 + CERT_E_CHAINING Handle = 0x800B010A + TRUST_E_FAIL Handle = 0x800B010B + CERT_E_REVOKED Handle = 0x800B010C + CERT_E_UNTRUSTEDTESTROOT Handle = 0x800B010D + CERT_E_REVOCATION_FAILURE Handle = 0x800B010E + CERT_E_CN_NO_MATCH Handle = 0x800B010F + CERT_E_WRONG_USAGE Handle = 0x800B0110 + TRUST_E_EXPLICIT_DISTRUST Handle = 0x800B0111 + CERT_E_UNTRUSTEDCA Handle = 0x800B0112 + CERT_E_INVALID_POLICY Handle = 0x800B0113 + CERT_E_INVALID_NAME Handle = 0x800B0114 + SPAPI_E_EXPECTED_SECTION_NAME Handle = 0x800F0000 + SPAPI_E_BAD_SECTION_NAME_LINE Handle = 0x800F0001 + SPAPI_E_SECTION_NAME_TOO_LONG Handle = 0x800F0002 + SPAPI_E_GENERAL_SYNTAX Handle = 0x800F0003 + SPAPI_E_WRONG_INF_STYLE Handle = 0x800F0100 + SPAPI_E_SECTION_NOT_FOUND Handle = 0x800F0101 + SPAPI_E_LINE_NOT_FOUND Handle = 0x800F0102 + SPAPI_E_NO_BACKUP Handle = 0x800F0103 + SPAPI_E_NO_ASSOCIATED_CLASS Handle = 0x800F0200 + SPAPI_E_CLASS_MISMATCH Handle = 0x800F0201 + SPAPI_E_DUPLICATE_FOUND Handle = 0x800F0202 + SPAPI_E_NO_DRIVER_SELECTED Handle = 0x800F0203 + SPAPI_E_KEY_DOES_NOT_EXIST Handle = 0x800F0204 + SPAPI_E_INVALID_DEVINST_NAME Handle = 0x800F0205 + SPAPI_E_INVALID_CLASS Handle = 0x800F0206 + SPAPI_E_DEVINST_ALREADY_EXISTS Handle = 0x800F0207 + SPAPI_E_DEVINFO_NOT_REGISTERED Handle = 0x800F0208 + SPAPI_E_INVALID_REG_PROPERTY Handle = 0x800F0209 + SPAPI_E_NO_INF Handle = 0x800F020A + SPAPI_E_NO_SUCH_DEVINST Handle = 0x800F020B + SPAPI_E_CANT_LOAD_CLASS_ICON Handle = 0x800F020C + SPAPI_E_INVALID_CLASS_INSTALLER Handle = 0x800F020D + SPAPI_E_DI_DO_DEFAULT Handle = 0x800F020E + SPAPI_E_DI_NOFILECOPY Handle = 0x800F020F + SPAPI_E_INVALID_HWPROFILE Handle = 0x800F0210 + SPAPI_E_NO_DEVICE_SELECTED Handle = 0x800F0211 + SPAPI_E_DEVINFO_LIST_LOCKED Handle = 0x800F0212 + SPAPI_E_DEVINFO_DATA_LOCKED Handle = 0x800F0213 + SPAPI_E_DI_BAD_PATH Handle = 0x800F0214 + SPAPI_E_NO_CLASSINSTALL_PARAMS Handle = 0x800F0215 + SPAPI_E_FILEQUEUE_LOCKED Handle = 0x800F0216 + SPAPI_E_BAD_SERVICE_INSTALLSECT Handle = 0x800F0217 + SPAPI_E_NO_CLASS_DRIVER_LIST Handle = 0x800F0218 + SPAPI_E_NO_ASSOCIATED_SERVICE Handle = 0x800F0219 + SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE Handle = 0x800F021A + SPAPI_E_DEVICE_INTERFACE_ACTIVE Handle = 0x800F021B + SPAPI_E_DEVICE_INTERFACE_REMOVED Handle = 0x800F021C + SPAPI_E_BAD_INTERFACE_INSTALLSECT Handle = 0x800F021D + SPAPI_E_NO_SUCH_INTERFACE_CLASS Handle = 0x800F021E + SPAPI_E_INVALID_REFERENCE_STRING Handle = 0x800F021F + SPAPI_E_INVALID_MACHINENAME Handle = 0x800F0220 + SPAPI_E_REMOTE_COMM_FAILURE Handle = 0x800F0221 + SPAPI_E_MACHINE_UNAVAILABLE Handle = 0x800F0222 + SPAPI_E_NO_CONFIGMGR_SERVICES Handle = 0x800F0223 + SPAPI_E_INVALID_PROPPAGE_PROVIDER Handle = 0x800F0224 + SPAPI_E_NO_SUCH_DEVICE_INTERFACE Handle = 0x800F0225 + SPAPI_E_DI_POSTPROCESSING_REQUIRED Handle = 0x800F0226 + SPAPI_E_INVALID_COINSTALLER Handle = 0x800F0227 + SPAPI_E_NO_COMPAT_DRIVERS Handle = 0x800F0228 + SPAPI_E_NO_DEVICE_ICON Handle = 0x800F0229 + SPAPI_E_INVALID_INF_LOGCONFIG Handle = 0x800F022A + SPAPI_E_DI_DONT_INSTALL Handle = 0x800F022B + SPAPI_E_INVALID_FILTER_DRIVER Handle = 0x800F022C + SPAPI_E_NON_WINDOWS_NT_DRIVER Handle = 0x800F022D + SPAPI_E_NON_WINDOWS_DRIVER Handle = 0x800F022E + SPAPI_E_NO_CATALOG_FOR_OEM_INF Handle = 0x800F022F + SPAPI_E_DEVINSTALL_QUEUE_NONNATIVE Handle = 0x800F0230 + SPAPI_E_NOT_DISABLEABLE Handle = 0x800F0231 + SPAPI_E_CANT_REMOVE_DEVINST Handle = 0x800F0232 + SPAPI_E_INVALID_TARGET Handle = 0x800F0233 + SPAPI_E_DRIVER_NONNATIVE Handle = 0x800F0234 + SPAPI_E_IN_WOW64 Handle = 0x800F0235 + SPAPI_E_SET_SYSTEM_RESTORE_POINT Handle = 0x800F0236 + SPAPI_E_INCORRECTLY_COPIED_INF Handle = 0x800F0237 + SPAPI_E_SCE_DISABLED Handle = 0x800F0238 + SPAPI_E_UNKNOWN_EXCEPTION Handle = 0x800F0239 + SPAPI_E_PNP_REGISTRY_ERROR Handle = 0x800F023A + SPAPI_E_REMOTE_REQUEST_UNSUPPORTED Handle = 0x800F023B + SPAPI_E_NOT_AN_INSTALLED_OEM_INF Handle = 0x800F023C + SPAPI_E_INF_IN_USE_BY_DEVICES Handle = 0x800F023D + SPAPI_E_DI_FUNCTION_OBSOLETE Handle = 0x800F023E + SPAPI_E_NO_AUTHENTICODE_CATALOG Handle = 0x800F023F + SPAPI_E_AUTHENTICODE_DISALLOWED Handle = 0x800F0240 + SPAPI_E_AUTHENTICODE_TRUSTED_PUBLISHER Handle = 0x800F0241 + SPAPI_E_AUTHENTICODE_TRUST_NOT_ESTABLISHED Handle = 0x800F0242 + SPAPI_E_AUTHENTICODE_PUBLISHER_NOT_TRUSTED Handle = 0x800F0243 + SPAPI_E_SIGNATURE_OSATTRIBUTE_MISMATCH Handle = 0x800F0244 + SPAPI_E_ONLY_VALIDATE_VIA_AUTHENTICODE Handle = 0x800F0245 + SPAPI_E_DEVICE_INSTALLER_NOT_READY Handle = 0x800F0246 + SPAPI_E_DRIVER_STORE_ADD_FAILED Handle = 0x800F0247 + SPAPI_E_DEVICE_INSTALL_BLOCKED Handle = 0x800F0248 + SPAPI_E_DRIVER_INSTALL_BLOCKED Handle = 0x800F0249 + SPAPI_E_WRONG_INF_TYPE Handle = 0x800F024A + SPAPI_E_FILE_HASH_NOT_IN_CATALOG Handle = 0x800F024B + SPAPI_E_DRIVER_STORE_DELETE_FAILED Handle = 0x800F024C + SPAPI_E_UNRECOVERABLE_STACK_OVERFLOW Handle = 0x800F0300 + SPAPI_E_ERROR_NOT_INSTALLED Handle = 0x800F1000 + SCARD_S_SUCCESS = S_OK + SCARD_F_INTERNAL_ERROR Handle = 0x80100001 + SCARD_E_CANCELLED Handle = 0x80100002 + SCARD_E_INVALID_HANDLE Handle = 0x80100003 + SCARD_E_INVALID_PARAMETER Handle = 0x80100004 + SCARD_E_INVALID_TARGET Handle = 0x80100005 + SCARD_E_NO_MEMORY Handle = 0x80100006 + SCARD_F_WAITED_TOO_LONG Handle = 0x80100007 + SCARD_E_INSUFFICIENT_BUFFER Handle = 0x80100008 + SCARD_E_UNKNOWN_READER Handle = 0x80100009 + SCARD_E_TIMEOUT Handle = 0x8010000A + SCARD_E_SHARING_VIOLATION Handle = 0x8010000B + SCARD_E_NO_SMARTCARD Handle = 0x8010000C + SCARD_E_UNKNOWN_CARD Handle = 0x8010000D + SCARD_E_CANT_DISPOSE Handle = 0x8010000E + SCARD_E_PROTO_MISMATCH Handle = 0x8010000F + SCARD_E_NOT_READY Handle = 0x80100010 + SCARD_E_INVALID_VALUE Handle = 0x80100011 + SCARD_E_SYSTEM_CANCELLED Handle = 0x80100012 + SCARD_F_COMM_ERROR Handle = 0x80100013 + SCARD_F_UNKNOWN_ERROR Handle = 0x80100014 + SCARD_E_INVALID_ATR Handle = 0x80100015 + SCARD_E_NOT_TRANSACTED Handle = 0x80100016 + SCARD_E_READER_UNAVAILABLE Handle = 0x80100017 + SCARD_P_SHUTDOWN Handle = 0x80100018 + SCARD_E_PCI_TOO_SMALL Handle = 0x80100019 + SCARD_E_READER_UNSUPPORTED Handle = 0x8010001A + SCARD_E_DUPLICATE_READER Handle = 0x8010001B + SCARD_E_CARD_UNSUPPORTED Handle = 0x8010001C + SCARD_E_NO_SERVICE Handle = 0x8010001D + SCARD_E_SERVICE_STOPPED Handle = 0x8010001E + SCARD_E_UNEXPECTED Handle = 0x8010001F + SCARD_E_ICC_INSTALLATION Handle = 0x80100020 + SCARD_E_ICC_CREATEORDER Handle = 0x80100021 + SCARD_E_UNSUPPORTED_FEATURE Handle = 0x80100022 + SCARD_E_DIR_NOT_FOUND Handle = 0x80100023 + SCARD_E_FILE_NOT_FOUND Handle = 0x80100024 + SCARD_E_NO_DIR Handle = 0x80100025 + SCARD_E_NO_FILE Handle = 0x80100026 + SCARD_E_NO_ACCESS Handle = 0x80100027 + SCARD_E_WRITE_TOO_MANY Handle = 0x80100028 + SCARD_E_BAD_SEEK Handle = 0x80100029 + SCARD_E_INVALID_CHV Handle = 0x8010002A + SCARD_E_UNKNOWN_RES_MNG Handle = 0x8010002B + SCARD_E_NO_SUCH_CERTIFICATE Handle = 0x8010002C + SCARD_E_CERTIFICATE_UNAVAILABLE Handle = 0x8010002D + SCARD_E_NO_READERS_AVAILABLE Handle = 0x8010002E + SCARD_E_COMM_DATA_LOST Handle = 0x8010002F + SCARD_E_NO_KEY_CONTAINER Handle = 0x80100030 + SCARD_E_SERVER_TOO_BUSY Handle = 0x80100031 + SCARD_E_PIN_CACHE_EXPIRED Handle = 0x80100032 + SCARD_E_NO_PIN_CACHE Handle = 0x80100033 + SCARD_E_READ_ONLY_CARD Handle = 0x80100034 + SCARD_W_UNSUPPORTED_CARD Handle = 0x80100065 + SCARD_W_UNRESPONSIVE_CARD Handle = 0x80100066 + SCARD_W_UNPOWERED_CARD Handle = 0x80100067 + SCARD_W_RESET_CARD Handle = 0x80100068 + SCARD_W_REMOVED_CARD Handle = 0x80100069 + SCARD_W_SECURITY_VIOLATION Handle = 0x8010006A + SCARD_W_WRONG_CHV Handle = 0x8010006B + SCARD_W_CHV_BLOCKED Handle = 0x8010006C + SCARD_W_EOF Handle = 0x8010006D + SCARD_W_CANCELLED_BY_USER Handle = 0x8010006E + SCARD_W_CARD_NOT_AUTHENTICATED Handle = 0x8010006F + SCARD_W_CACHE_ITEM_NOT_FOUND Handle = 0x80100070 + SCARD_W_CACHE_ITEM_STALE Handle = 0x80100071 + SCARD_W_CACHE_ITEM_TOO_BIG Handle = 0x80100072 + COMADMIN_E_OBJECTERRORS Handle = 0x80110401 + COMADMIN_E_OBJECTINVALID Handle = 0x80110402 + COMADMIN_E_KEYMISSING Handle = 0x80110403 + COMADMIN_E_ALREADYINSTALLED Handle = 0x80110404 + COMADMIN_E_APP_FILE_WRITEFAIL Handle = 0x80110407 + COMADMIN_E_APP_FILE_READFAIL Handle = 0x80110408 + COMADMIN_E_APP_FILE_VERSION Handle = 0x80110409 + COMADMIN_E_BADPATH Handle = 0x8011040A + COMADMIN_E_APPLICATIONEXISTS Handle = 0x8011040B + COMADMIN_E_ROLEEXISTS Handle = 0x8011040C + COMADMIN_E_CANTCOPYFILE Handle = 0x8011040D + COMADMIN_E_NOUSER Handle = 0x8011040F + COMADMIN_E_INVALIDUSERIDS Handle = 0x80110410 + COMADMIN_E_NOREGISTRYCLSID Handle = 0x80110411 + COMADMIN_E_BADREGISTRYPROGID Handle = 0x80110412 + COMADMIN_E_AUTHENTICATIONLEVEL Handle = 0x80110413 + COMADMIN_E_USERPASSWDNOTVALID Handle = 0x80110414 + COMADMIN_E_CLSIDORIIDMISMATCH Handle = 0x80110418 + COMADMIN_E_REMOTEINTERFACE Handle = 0x80110419 + COMADMIN_E_DLLREGISTERSERVER Handle = 0x8011041A + COMADMIN_E_NOSERVERSHARE Handle = 0x8011041B + COMADMIN_E_DLLLOADFAILED Handle = 0x8011041D + COMADMIN_E_BADREGISTRYLIBID Handle = 0x8011041E + COMADMIN_E_APPDIRNOTFOUND Handle = 0x8011041F + COMADMIN_E_REGISTRARFAILED Handle = 0x80110423 + COMADMIN_E_COMPFILE_DOESNOTEXIST Handle = 0x80110424 + COMADMIN_E_COMPFILE_LOADDLLFAIL Handle = 0x80110425 + COMADMIN_E_COMPFILE_GETCLASSOBJ Handle = 0x80110426 + COMADMIN_E_COMPFILE_CLASSNOTAVAIL Handle = 0x80110427 + COMADMIN_E_COMPFILE_BADTLB Handle = 0x80110428 + COMADMIN_E_COMPFILE_NOTINSTALLABLE Handle = 0x80110429 + COMADMIN_E_NOTCHANGEABLE Handle = 0x8011042A + COMADMIN_E_NOTDELETEABLE Handle = 0x8011042B + COMADMIN_E_SESSION Handle = 0x8011042C + COMADMIN_E_COMP_MOVE_LOCKED Handle = 0x8011042D + COMADMIN_E_COMP_MOVE_BAD_DEST Handle = 0x8011042E + COMADMIN_E_REGISTERTLB Handle = 0x80110430 + COMADMIN_E_SYSTEMAPP Handle = 0x80110433 + COMADMIN_E_COMPFILE_NOREGISTRAR Handle = 0x80110434 + COMADMIN_E_COREQCOMPINSTALLED Handle = 0x80110435 + COMADMIN_E_SERVICENOTINSTALLED Handle = 0x80110436 + COMADMIN_E_PROPERTYSAVEFAILED Handle = 0x80110437 + COMADMIN_E_OBJECTEXISTS Handle = 0x80110438 + COMADMIN_E_COMPONENTEXISTS Handle = 0x80110439 + COMADMIN_E_REGFILE_CORRUPT Handle = 0x8011043B + COMADMIN_E_PROPERTY_OVERFLOW Handle = 0x8011043C + COMADMIN_E_NOTINREGISTRY Handle = 0x8011043E + COMADMIN_E_OBJECTNOTPOOLABLE Handle = 0x8011043F + COMADMIN_E_APPLID_MATCHES_CLSID Handle = 0x80110446 + COMADMIN_E_ROLE_DOES_NOT_EXIST Handle = 0x80110447 + COMADMIN_E_START_APP_NEEDS_COMPONENTS Handle = 0x80110448 + COMADMIN_E_REQUIRES_DIFFERENT_PLATFORM Handle = 0x80110449 + COMADMIN_E_CAN_NOT_EXPORT_APP_PROXY Handle = 0x8011044A + COMADMIN_E_CAN_NOT_START_APP Handle = 0x8011044B + COMADMIN_E_CAN_NOT_EXPORT_SYS_APP Handle = 0x8011044C + COMADMIN_E_CANT_SUBSCRIBE_TO_COMPONENT Handle = 0x8011044D + COMADMIN_E_EVENTCLASS_CANT_BE_SUBSCRIBER Handle = 0x8011044E + COMADMIN_E_LIB_APP_PROXY_INCOMPATIBLE Handle = 0x8011044F + COMADMIN_E_BASE_PARTITION_ONLY Handle = 0x80110450 + COMADMIN_E_START_APP_DISABLED Handle = 0x80110451 + COMADMIN_E_CAT_DUPLICATE_PARTITION_NAME Handle = 0x80110457 + COMADMIN_E_CAT_INVALID_PARTITION_NAME Handle = 0x80110458 + COMADMIN_E_CAT_PARTITION_IN_USE Handle = 0x80110459 + COMADMIN_E_FILE_PARTITION_DUPLICATE_FILES Handle = 0x8011045A + COMADMIN_E_CAT_IMPORTED_COMPONENTS_NOT_ALLOWED Handle = 0x8011045B + COMADMIN_E_AMBIGUOUS_APPLICATION_NAME Handle = 0x8011045C + COMADMIN_E_AMBIGUOUS_PARTITION_NAME Handle = 0x8011045D + COMADMIN_E_REGDB_NOTINITIALIZED Handle = 0x80110472 + COMADMIN_E_REGDB_NOTOPEN Handle = 0x80110473 + COMADMIN_E_REGDB_SYSTEMERR Handle = 0x80110474 + COMADMIN_E_REGDB_ALREADYRUNNING Handle = 0x80110475 + COMADMIN_E_MIG_VERSIONNOTSUPPORTED Handle = 0x80110480 + COMADMIN_E_MIG_SCHEMANOTFOUND Handle = 0x80110481 + COMADMIN_E_CAT_BITNESSMISMATCH Handle = 0x80110482 + COMADMIN_E_CAT_UNACCEPTABLEBITNESS Handle = 0x80110483 + COMADMIN_E_CAT_WRONGAPPBITNESS Handle = 0x80110484 + COMADMIN_E_CAT_PAUSE_RESUME_NOT_SUPPORTED Handle = 0x80110485 + COMADMIN_E_CAT_SERVERFAULT Handle = 0x80110486 + COMQC_E_APPLICATION_NOT_QUEUED Handle = 0x80110600 + COMQC_E_NO_QUEUEABLE_INTERFACES Handle = 0x80110601 + COMQC_E_QUEUING_SERVICE_NOT_AVAILABLE Handle = 0x80110602 + COMQC_E_NO_IPERSISTSTREAM Handle = 0x80110603 + COMQC_E_BAD_MESSAGE Handle = 0x80110604 + COMQC_E_UNAUTHENTICATED Handle = 0x80110605 + COMQC_E_UNTRUSTED_ENQUEUER Handle = 0x80110606 + MSDTC_E_DUPLICATE_RESOURCE Handle = 0x80110701 + COMADMIN_E_OBJECT_PARENT_MISSING Handle = 0x80110808 + COMADMIN_E_OBJECT_DOES_NOT_EXIST Handle = 0x80110809 + COMADMIN_E_APP_NOT_RUNNING Handle = 0x8011080A + COMADMIN_E_INVALID_PARTITION Handle = 0x8011080B + COMADMIN_E_SVCAPP_NOT_POOLABLE_OR_RECYCLABLE Handle = 0x8011080D + COMADMIN_E_USER_IN_SET Handle = 0x8011080E + COMADMIN_E_CANTRECYCLELIBRARYAPPS Handle = 0x8011080F + COMADMIN_E_CANTRECYCLESERVICEAPPS Handle = 0x80110811 + COMADMIN_E_PROCESSALREADYRECYCLED Handle = 0x80110812 + COMADMIN_E_PAUSEDPROCESSMAYNOTBERECYCLED Handle = 0x80110813 + COMADMIN_E_CANTMAKEINPROCSERVICE Handle = 0x80110814 + COMADMIN_E_PROGIDINUSEBYCLSID Handle = 0x80110815 + COMADMIN_E_DEFAULT_PARTITION_NOT_IN_SET Handle = 0x80110816 + COMADMIN_E_RECYCLEDPROCESSMAYNOTBEPAUSED Handle = 0x80110817 + COMADMIN_E_PARTITION_ACCESSDENIED Handle = 0x80110818 + COMADMIN_E_PARTITION_MSI_ONLY Handle = 0x80110819 + COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_1_0_FORMAT Handle = 0x8011081A + COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_NONBASE_PARTITIONS Handle = 0x8011081B + COMADMIN_E_COMP_MOVE_SOURCE Handle = 0x8011081C + COMADMIN_E_COMP_MOVE_DEST Handle = 0x8011081D + COMADMIN_E_COMP_MOVE_PRIVATE Handle = 0x8011081E + COMADMIN_E_BASEPARTITION_REQUIRED_IN_SET Handle = 0x8011081F + COMADMIN_E_CANNOT_ALIAS_EVENTCLASS Handle = 0x80110820 + COMADMIN_E_PRIVATE_ACCESSDENIED Handle = 0x80110821 + COMADMIN_E_SAFERINVALID Handle = 0x80110822 + COMADMIN_E_REGISTRY_ACCESSDENIED Handle = 0x80110823 + COMADMIN_E_PARTITIONS_DISABLED Handle = 0x80110824 + WER_S_REPORT_DEBUG Handle = 0x001B0000 + WER_S_REPORT_UPLOADED Handle = 0x001B0001 + WER_S_REPORT_QUEUED Handle = 0x001B0002 + WER_S_DISABLED Handle = 0x001B0003 + WER_S_SUSPENDED_UPLOAD Handle = 0x001B0004 + WER_S_DISABLED_QUEUE Handle = 0x001B0005 + WER_S_DISABLED_ARCHIVE Handle = 0x001B0006 + WER_S_REPORT_ASYNC Handle = 0x001B0007 + WER_S_IGNORE_ASSERT_INSTANCE Handle = 0x001B0008 + WER_S_IGNORE_ALL_ASSERTS Handle = 0x001B0009 + WER_S_ASSERT_CONTINUE Handle = 0x001B000A + WER_S_THROTTLED Handle = 0x001B000B + WER_S_REPORT_UPLOADED_CAB Handle = 0x001B000C + WER_E_CRASH_FAILURE Handle = 0x801B8000 + WER_E_CANCELED Handle = 0x801B8001 + WER_E_NETWORK_FAILURE Handle = 0x801B8002 + WER_E_NOT_INITIALIZED Handle = 0x801B8003 + WER_E_ALREADY_REPORTING Handle = 0x801B8004 + WER_E_DUMP_THROTTLED Handle = 0x801B8005 + WER_E_INSUFFICIENT_CONSENT Handle = 0x801B8006 + WER_E_TOO_HEAVY Handle = 0x801B8007 + ERROR_FLT_IO_COMPLETE Handle = 0x001F0001 + ERROR_FLT_NO_HANDLER_DEFINED Handle = 0x801F0001 + ERROR_FLT_CONTEXT_ALREADY_DEFINED Handle = 0x801F0002 + ERROR_FLT_INVALID_ASYNCHRONOUS_REQUEST Handle = 0x801F0003 + ERROR_FLT_DISALLOW_FAST_IO Handle = 0x801F0004 + ERROR_FLT_INVALID_NAME_REQUEST Handle = 0x801F0005 + ERROR_FLT_NOT_SAFE_TO_POST_OPERATION Handle = 0x801F0006 + ERROR_FLT_NOT_INITIALIZED Handle = 0x801F0007 + ERROR_FLT_FILTER_NOT_READY Handle = 0x801F0008 + ERROR_FLT_POST_OPERATION_CLEANUP Handle = 0x801F0009 + ERROR_FLT_INTERNAL_ERROR Handle = 0x801F000A + ERROR_FLT_DELETING_OBJECT Handle = 0x801F000B + ERROR_FLT_MUST_BE_NONPAGED_POOL Handle = 0x801F000C + ERROR_FLT_DUPLICATE_ENTRY Handle = 0x801F000D + ERROR_FLT_CBDQ_DISABLED Handle = 0x801F000E + ERROR_FLT_DO_NOT_ATTACH Handle = 0x801F000F + ERROR_FLT_DO_NOT_DETACH Handle = 0x801F0010 + ERROR_FLT_INSTANCE_ALTITUDE_COLLISION Handle = 0x801F0011 + ERROR_FLT_INSTANCE_NAME_COLLISION Handle = 0x801F0012 + ERROR_FLT_FILTER_NOT_FOUND Handle = 0x801F0013 + ERROR_FLT_VOLUME_NOT_FOUND Handle = 0x801F0014 + ERROR_FLT_INSTANCE_NOT_FOUND Handle = 0x801F0015 + ERROR_FLT_CONTEXT_ALLOCATION_NOT_FOUND Handle = 0x801F0016 + ERROR_FLT_INVALID_CONTEXT_REGISTRATION Handle = 0x801F0017 + ERROR_FLT_NAME_CACHE_MISS Handle = 0x801F0018 + ERROR_FLT_NO_DEVICE_OBJECT Handle = 0x801F0019 + ERROR_FLT_VOLUME_ALREADY_MOUNTED Handle = 0x801F001A + ERROR_FLT_ALREADY_ENLISTED Handle = 0x801F001B + ERROR_FLT_CONTEXT_ALREADY_LINKED Handle = 0x801F001C + ERROR_FLT_NO_WAITER_FOR_REPLY Handle = 0x801F0020 + ERROR_FLT_REGISTRATION_BUSY Handle = 0x801F0023 + ERROR_HUNG_DISPLAY_DRIVER_THREAD Handle = 0x80260001 + DWM_E_COMPOSITIONDISABLED Handle = 0x80263001 + DWM_E_REMOTING_NOT_SUPPORTED Handle = 0x80263002 + DWM_E_NO_REDIRECTION_SURFACE_AVAILABLE Handle = 0x80263003 + DWM_E_NOT_QUEUING_PRESENTS Handle = 0x80263004 + DWM_E_ADAPTER_NOT_FOUND Handle = 0x80263005 + DWM_S_GDI_REDIRECTION_SURFACE Handle = 0x00263005 + DWM_E_TEXTURE_TOO_LARGE Handle = 0x80263007 + DWM_S_GDI_REDIRECTION_SURFACE_BLT_VIA_GDI Handle = 0x00263008 + ERROR_MONITOR_NO_DESCRIPTOR Handle = 0x00261001 + ERROR_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT Handle = 0x00261002 + ERROR_MONITOR_INVALID_DESCRIPTOR_CHECKSUM Handle = 0xC0261003 + ERROR_MONITOR_INVALID_STANDARD_TIMING_BLOCK Handle = 0xC0261004 + ERROR_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED Handle = 0xC0261005 + ERROR_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK Handle = 0xC0261006 + ERROR_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK Handle = 0xC0261007 + ERROR_MONITOR_NO_MORE_DESCRIPTOR_DATA Handle = 0xC0261008 + ERROR_MONITOR_INVALID_DETAILED_TIMING_BLOCK Handle = 0xC0261009 + ERROR_MONITOR_INVALID_MANUFACTURE_DATE Handle = 0xC026100A + ERROR_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER Handle = 0xC0262000 + ERROR_GRAPHICS_INSUFFICIENT_DMA_BUFFER Handle = 0xC0262001 + ERROR_GRAPHICS_INVALID_DISPLAY_ADAPTER Handle = 0xC0262002 + ERROR_GRAPHICS_ADAPTER_WAS_RESET Handle = 0xC0262003 + ERROR_GRAPHICS_INVALID_DRIVER_MODEL Handle = 0xC0262004 + ERROR_GRAPHICS_PRESENT_MODE_CHANGED Handle = 0xC0262005 + ERROR_GRAPHICS_PRESENT_OCCLUDED Handle = 0xC0262006 + ERROR_GRAPHICS_PRESENT_DENIED Handle = 0xC0262007 + ERROR_GRAPHICS_CANNOTCOLORCONVERT Handle = 0xC0262008 + ERROR_GRAPHICS_DRIVER_MISMATCH Handle = 0xC0262009 + ERROR_GRAPHICS_PARTIAL_DATA_POPULATED Handle = 0x4026200A + ERROR_GRAPHICS_PRESENT_REDIRECTION_DISABLED Handle = 0xC026200B + ERROR_GRAPHICS_PRESENT_UNOCCLUDED Handle = 0xC026200C + ERROR_GRAPHICS_WINDOWDC_NOT_AVAILABLE Handle = 0xC026200D + ERROR_GRAPHICS_WINDOWLESS_PRESENT_DISABLED Handle = 0xC026200E + ERROR_GRAPHICS_PRESENT_INVALID_WINDOW Handle = 0xC026200F + ERROR_GRAPHICS_PRESENT_BUFFER_NOT_BOUND Handle = 0xC0262010 + ERROR_GRAPHICS_VAIL_STATE_CHANGED Handle = 0xC0262011 + ERROR_GRAPHICS_INDIRECT_DISPLAY_ABANDON_SWAPCHAIN Handle = 0xC0262012 + ERROR_GRAPHICS_INDIRECT_DISPLAY_DEVICE_STOPPED Handle = 0xC0262013 + ERROR_GRAPHICS_NO_VIDEO_MEMORY Handle = 0xC0262100 + ERROR_GRAPHICS_CANT_LOCK_MEMORY Handle = 0xC0262101 + ERROR_GRAPHICS_ALLOCATION_BUSY Handle = 0xC0262102 + ERROR_GRAPHICS_TOO_MANY_REFERENCES Handle = 0xC0262103 + ERROR_GRAPHICS_TRY_AGAIN_LATER Handle = 0xC0262104 + ERROR_GRAPHICS_TRY_AGAIN_NOW Handle = 0xC0262105 + ERROR_GRAPHICS_ALLOCATION_INVALID Handle = 0xC0262106 + ERROR_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE Handle = 0xC0262107 + ERROR_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED Handle = 0xC0262108 + ERROR_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION Handle = 0xC0262109 + ERROR_GRAPHICS_INVALID_ALLOCATION_USAGE Handle = 0xC0262110 + ERROR_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION Handle = 0xC0262111 + ERROR_GRAPHICS_ALLOCATION_CLOSED Handle = 0xC0262112 + ERROR_GRAPHICS_INVALID_ALLOCATION_INSTANCE Handle = 0xC0262113 + ERROR_GRAPHICS_INVALID_ALLOCATION_HANDLE Handle = 0xC0262114 + ERROR_GRAPHICS_WRONG_ALLOCATION_DEVICE Handle = 0xC0262115 + ERROR_GRAPHICS_ALLOCATION_CONTENT_LOST Handle = 0xC0262116 + ERROR_GRAPHICS_GPU_EXCEPTION_ON_DEVICE Handle = 0xC0262200 + ERROR_GRAPHICS_SKIP_ALLOCATION_PREPARATION Handle = 0x40262201 + ERROR_GRAPHICS_INVALID_VIDPN_TOPOLOGY Handle = 0xC0262300 + ERROR_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED Handle = 0xC0262301 + ERROR_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED Handle = 0xC0262302 + ERROR_GRAPHICS_INVALID_VIDPN Handle = 0xC0262303 + ERROR_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE Handle = 0xC0262304 + ERROR_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET Handle = 0xC0262305 + ERROR_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED Handle = 0xC0262306 + ERROR_GRAPHICS_MODE_NOT_PINNED Handle = 0x00262307 + ERROR_GRAPHICS_INVALID_VIDPN_SOURCEMODESET Handle = 0xC0262308 + ERROR_GRAPHICS_INVALID_VIDPN_TARGETMODESET Handle = 0xC0262309 + ERROR_GRAPHICS_INVALID_FREQUENCY Handle = 0xC026230A + ERROR_GRAPHICS_INVALID_ACTIVE_REGION Handle = 0xC026230B + ERROR_GRAPHICS_INVALID_TOTAL_REGION Handle = 0xC026230C + ERROR_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE Handle = 0xC0262310 + ERROR_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE Handle = 0xC0262311 + ERROR_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET Handle = 0xC0262312 + ERROR_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY Handle = 0xC0262313 + ERROR_GRAPHICS_MODE_ALREADY_IN_MODESET Handle = 0xC0262314 + ERROR_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET Handle = 0xC0262315 + ERROR_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET Handle = 0xC0262316 + ERROR_GRAPHICS_SOURCE_ALREADY_IN_SET Handle = 0xC0262317 + ERROR_GRAPHICS_TARGET_ALREADY_IN_SET Handle = 0xC0262318 + ERROR_GRAPHICS_INVALID_VIDPN_PRESENT_PATH Handle = 0xC0262319 + ERROR_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY Handle = 0xC026231A + ERROR_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET Handle = 0xC026231B + ERROR_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE Handle = 0xC026231C + ERROR_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET Handle = 0xC026231D + ERROR_GRAPHICS_NO_PREFERRED_MODE Handle = 0x0026231E + ERROR_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET Handle = 0xC026231F + ERROR_GRAPHICS_STALE_MODESET Handle = 0xC0262320 + ERROR_GRAPHICS_INVALID_MONITOR_SOURCEMODESET Handle = 0xC0262321 + ERROR_GRAPHICS_INVALID_MONITOR_SOURCE_MODE Handle = 0xC0262322 + ERROR_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN Handle = 0xC0262323 + ERROR_GRAPHICS_MODE_ID_MUST_BE_UNIQUE Handle = 0xC0262324 + ERROR_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION Handle = 0xC0262325 + ERROR_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES Handle = 0xC0262326 + ERROR_GRAPHICS_PATH_NOT_IN_TOPOLOGY Handle = 0xC0262327 + ERROR_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE Handle = 0xC0262328 + ERROR_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET Handle = 0xC0262329 + ERROR_GRAPHICS_INVALID_MONITORDESCRIPTORSET Handle = 0xC026232A + ERROR_GRAPHICS_INVALID_MONITORDESCRIPTOR Handle = 0xC026232B + ERROR_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET Handle = 0xC026232C + ERROR_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET Handle = 0xC026232D + ERROR_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE Handle = 0xC026232E + ERROR_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE Handle = 0xC026232F + ERROR_GRAPHICS_RESOURCES_NOT_RELATED Handle = 0xC0262330 + ERROR_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE Handle = 0xC0262331 + ERROR_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE Handle = 0xC0262332 + ERROR_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET Handle = 0xC0262333 + ERROR_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER Handle = 0xC0262334 + ERROR_GRAPHICS_NO_VIDPNMGR Handle = 0xC0262335 + ERROR_GRAPHICS_NO_ACTIVE_VIDPN Handle = 0xC0262336 + ERROR_GRAPHICS_STALE_VIDPN_TOPOLOGY Handle = 0xC0262337 + ERROR_GRAPHICS_MONITOR_NOT_CONNECTED Handle = 0xC0262338 + ERROR_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY Handle = 0xC0262339 + ERROR_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE Handle = 0xC026233A + ERROR_GRAPHICS_INVALID_VISIBLEREGION_SIZE Handle = 0xC026233B + ERROR_GRAPHICS_INVALID_STRIDE Handle = 0xC026233C + ERROR_GRAPHICS_INVALID_PIXELFORMAT Handle = 0xC026233D + ERROR_GRAPHICS_INVALID_COLORBASIS Handle = 0xC026233E + ERROR_GRAPHICS_INVALID_PIXELVALUEACCESSMODE Handle = 0xC026233F + ERROR_GRAPHICS_TARGET_NOT_IN_TOPOLOGY Handle = 0xC0262340 + ERROR_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT Handle = 0xC0262341 + ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE Handle = 0xC0262342 + ERROR_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN Handle = 0xC0262343 + ERROR_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL Handle = 0xC0262344 + ERROR_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION Handle = 0xC0262345 + ERROR_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED Handle = 0xC0262346 + ERROR_GRAPHICS_INVALID_GAMMA_RAMP Handle = 0xC0262347 + ERROR_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED Handle = 0xC0262348 + ERROR_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED Handle = 0xC0262349 + ERROR_GRAPHICS_MODE_NOT_IN_MODESET Handle = 0xC026234A + ERROR_GRAPHICS_DATASET_IS_EMPTY Handle = 0x0026234B + ERROR_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET Handle = 0x0026234C + ERROR_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON Handle = 0xC026234D + ERROR_GRAPHICS_INVALID_PATH_CONTENT_TYPE Handle = 0xC026234E + ERROR_GRAPHICS_INVALID_COPYPROTECTION_TYPE Handle = 0xC026234F + ERROR_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS Handle = 0xC0262350 + ERROR_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_PINNED Handle = 0x00262351 + ERROR_GRAPHICS_INVALID_SCANLINE_ORDERING Handle = 0xC0262352 + ERROR_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED Handle = 0xC0262353 + ERROR_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS Handle = 0xC0262354 + ERROR_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT Handle = 0xC0262355 + ERROR_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM Handle = 0xC0262356 + ERROR_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN Handle = 0xC0262357 + ERROR_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT Handle = 0xC0262358 + ERROR_GRAPHICS_MAX_NUM_PATHS_REACHED Handle = 0xC0262359 + ERROR_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION Handle = 0xC026235A + ERROR_GRAPHICS_INVALID_CLIENT_TYPE Handle = 0xC026235B + ERROR_GRAPHICS_CLIENTVIDPN_NOT_SET Handle = 0xC026235C + ERROR_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED Handle = 0xC0262400 + ERROR_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED Handle = 0xC0262401 + ERROR_GRAPHICS_UNKNOWN_CHILD_STATUS Handle = 0x4026242F + ERROR_GRAPHICS_NOT_A_LINKED_ADAPTER Handle = 0xC0262430 + ERROR_GRAPHICS_LEADLINK_NOT_ENUMERATED Handle = 0xC0262431 + ERROR_GRAPHICS_CHAINLINKS_NOT_ENUMERATED Handle = 0xC0262432 + ERROR_GRAPHICS_ADAPTER_CHAIN_NOT_READY Handle = 0xC0262433 + ERROR_GRAPHICS_CHAINLINKS_NOT_STARTED Handle = 0xC0262434 + ERROR_GRAPHICS_CHAINLINKS_NOT_POWERED_ON Handle = 0xC0262435 + ERROR_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE Handle = 0xC0262436 + ERROR_GRAPHICS_LEADLINK_START_DEFERRED Handle = 0x40262437 + ERROR_GRAPHICS_NOT_POST_DEVICE_DRIVER Handle = 0xC0262438 + ERROR_GRAPHICS_POLLING_TOO_FREQUENTLY Handle = 0x40262439 + ERROR_GRAPHICS_START_DEFERRED Handle = 0x4026243A + ERROR_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED Handle = 0xC026243B + ERROR_GRAPHICS_DEPENDABLE_CHILD_STATUS Handle = 0x4026243C + ERROR_GRAPHICS_OPM_NOT_SUPPORTED Handle = 0xC0262500 + ERROR_GRAPHICS_COPP_NOT_SUPPORTED Handle = 0xC0262501 + ERROR_GRAPHICS_UAB_NOT_SUPPORTED Handle = 0xC0262502 + ERROR_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS Handle = 0xC0262503 + ERROR_GRAPHICS_OPM_NO_VIDEO_OUTPUTS_EXIST Handle = 0xC0262505 + ERROR_GRAPHICS_OPM_INTERNAL_ERROR Handle = 0xC026250B + ERROR_GRAPHICS_OPM_INVALID_HANDLE Handle = 0xC026250C + ERROR_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH Handle = 0xC026250E + ERROR_GRAPHICS_OPM_SPANNING_MODE_ENABLED Handle = 0xC026250F + ERROR_GRAPHICS_OPM_THEATER_MODE_ENABLED Handle = 0xC0262510 + ERROR_GRAPHICS_PVP_HFS_FAILED Handle = 0xC0262511 + ERROR_GRAPHICS_OPM_INVALID_SRM Handle = 0xC0262512 + ERROR_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP Handle = 0xC0262513 + ERROR_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP Handle = 0xC0262514 + ERROR_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA Handle = 0xC0262515 + ERROR_GRAPHICS_OPM_HDCP_SRM_NEVER_SET Handle = 0xC0262516 + ERROR_GRAPHICS_OPM_RESOLUTION_TOO_HIGH Handle = 0xC0262517 + ERROR_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE Handle = 0xC0262518 + ERROR_GRAPHICS_OPM_VIDEO_OUTPUT_NO_LONGER_EXISTS Handle = 0xC026251A + ERROR_GRAPHICS_OPM_SESSION_TYPE_CHANGE_IN_PROGRESS Handle = 0xC026251B + ERROR_GRAPHICS_OPM_VIDEO_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS Handle = 0xC026251C + ERROR_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST Handle = 0xC026251D + ERROR_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR Handle = 0xC026251E + ERROR_GRAPHICS_OPM_VIDEO_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS Handle = 0xC026251F + ERROR_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED Handle = 0xC0262520 + ERROR_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST Handle = 0xC0262521 + ERROR_GRAPHICS_I2C_NOT_SUPPORTED Handle = 0xC0262580 + ERROR_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST Handle = 0xC0262581 + ERROR_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA Handle = 0xC0262582 + ERROR_GRAPHICS_I2C_ERROR_RECEIVING_DATA Handle = 0xC0262583 + ERROR_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED Handle = 0xC0262584 + ERROR_GRAPHICS_DDCCI_INVALID_DATA Handle = 0xC0262585 + ERROR_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE Handle = 0xC0262586 + ERROR_GRAPHICS_MCA_INVALID_CAPABILITIES_STRING Handle = 0xC0262587 + ERROR_GRAPHICS_MCA_INTERNAL_ERROR Handle = 0xC0262588 + ERROR_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND Handle = 0xC0262589 + ERROR_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH Handle = 0xC026258A + ERROR_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM Handle = 0xC026258B + ERROR_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE Handle = 0xC026258C + ERROR_GRAPHICS_MONITOR_NO_LONGER_EXISTS Handle = 0xC026258D + ERROR_GRAPHICS_DDCCI_CURRENT_CURRENT_VALUE_GREATER_THAN_MAXIMUM_VALUE Handle = 0xC02625D8 + ERROR_GRAPHICS_MCA_INVALID_VCP_VERSION Handle = 0xC02625D9 + ERROR_GRAPHICS_MCA_MONITOR_VIOLATES_MCCS_SPECIFICATION Handle = 0xC02625DA + ERROR_GRAPHICS_MCA_MCCS_VERSION_MISMATCH Handle = 0xC02625DB + ERROR_GRAPHICS_MCA_UNSUPPORTED_MCCS_VERSION Handle = 0xC02625DC + ERROR_GRAPHICS_MCA_INVALID_TECHNOLOGY_TYPE_RETURNED Handle = 0xC02625DE + ERROR_GRAPHICS_MCA_UNSUPPORTED_COLOR_TEMPERATURE Handle = 0xC02625DF + ERROR_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED Handle = 0xC02625E0 + ERROR_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME Handle = 0xC02625E1 + ERROR_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP Handle = 0xC02625E2 + ERROR_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED Handle = 0xC02625E3 + ERROR_GRAPHICS_INVALID_POINTER Handle = 0xC02625E4 + ERROR_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE Handle = 0xC02625E5 + ERROR_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL Handle = 0xC02625E6 + ERROR_GRAPHICS_INTERNAL_ERROR Handle = 0xC02625E7 + ERROR_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS Handle = 0xC02605E8 + NAP_E_INVALID_PACKET Handle = 0x80270001 + NAP_E_MISSING_SOH Handle = 0x80270002 + NAP_E_CONFLICTING_ID Handle = 0x80270003 + NAP_E_NO_CACHED_SOH Handle = 0x80270004 + NAP_E_STILL_BOUND Handle = 0x80270005 + NAP_E_NOT_REGISTERED Handle = 0x80270006 + NAP_E_NOT_INITIALIZED Handle = 0x80270007 + NAP_E_MISMATCHED_ID Handle = 0x80270008 + NAP_E_NOT_PENDING Handle = 0x80270009 + NAP_E_ID_NOT_FOUND Handle = 0x8027000A + NAP_E_MAXSIZE_TOO_SMALL Handle = 0x8027000B + NAP_E_SERVICE_NOT_RUNNING Handle = 0x8027000C + NAP_S_CERT_ALREADY_PRESENT Handle = 0x0027000D + NAP_E_ENTITY_DISABLED Handle = 0x8027000E + NAP_E_NETSH_GROUPPOLICY_ERROR Handle = 0x8027000F + NAP_E_TOO_MANY_CALLS Handle = 0x80270010 + NAP_E_SHV_CONFIG_EXISTED Handle = 0x80270011 + NAP_E_SHV_CONFIG_NOT_FOUND Handle = 0x80270012 + NAP_E_SHV_TIMEOUT Handle = 0x80270013 + TPM_E_ERROR_MASK Handle = 0x80280000 + TPM_E_AUTHFAIL Handle = 0x80280001 + TPM_E_BADINDEX Handle = 0x80280002 + TPM_E_BAD_PARAMETER Handle = 0x80280003 + TPM_E_AUDITFAILURE Handle = 0x80280004 + TPM_E_CLEAR_DISABLED Handle = 0x80280005 + TPM_E_DEACTIVATED Handle = 0x80280006 + TPM_E_DISABLED Handle = 0x80280007 + TPM_E_DISABLED_CMD Handle = 0x80280008 + TPM_E_FAIL Handle = 0x80280009 + TPM_E_BAD_ORDINAL Handle = 0x8028000A + TPM_E_INSTALL_DISABLED Handle = 0x8028000B + TPM_E_INVALID_KEYHANDLE Handle = 0x8028000C + TPM_E_KEYNOTFOUND Handle = 0x8028000D + TPM_E_INAPPROPRIATE_ENC Handle = 0x8028000E + TPM_E_MIGRATEFAIL Handle = 0x8028000F + TPM_E_INVALID_PCR_INFO Handle = 0x80280010 + TPM_E_NOSPACE Handle = 0x80280011 + TPM_E_NOSRK Handle = 0x80280012 + TPM_E_NOTSEALED_BLOB Handle = 0x80280013 + TPM_E_OWNER_SET Handle = 0x80280014 + TPM_E_RESOURCES Handle = 0x80280015 + TPM_E_SHORTRANDOM Handle = 0x80280016 + TPM_E_SIZE Handle = 0x80280017 + TPM_E_WRONGPCRVAL Handle = 0x80280018 + TPM_E_BAD_PARAM_SIZE Handle = 0x80280019 + TPM_E_SHA_THREAD Handle = 0x8028001A + TPM_E_SHA_ERROR Handle = 0x8028001B + TPM_E_FAILEDSELFTEST Handle = 0x8028001C + TPM_E_AUTH2FAIL Handle = 0x8028001D + TPM_E_BADTAG Handle = 0x8028001E + TPM_E_IOERROR Handle = 0x8028001F + TPM_E_ENCRYPT_ERROR Handle = 0x80280020 + TPM_E_DECRYPT_ERROR Handle = 0x80280021 + TPM_E_INVALID_AUTHHANDLE Handle = 0x80280022 + TPM_E_NO_ENDORSEMENT Handle = 0x80280023 + TPM_E_INVALID_KEYUSAGE Handle = 0x80280024 + TPM_E_WRONG_ENTITYTYPE Handle = 0x80280025 + TPM_E_INVALID_POSTINIT Handle = 0x80280026 + TPM_E_INAPPROPRIATE_SIG Handle = 0x80280027 + TPM_E_BAD_KEY_PROPERTY Handle = 0x80280028 + TPM_E_BAD_MIGRATION Handle = 0x80280029 + TPM_E_BAD_SCHEME Handle = 0x8028002A + TPM_E_BAD_DATASIZE Handle = 0x8028002B + TPM_E_BAD_MODE Handle = 0x8028002C + TPM_E_BAD_PRESENCE Handle = 0x8028002D + TPM_E_BAD_VERSION Handle = 0x8028002E + TPM_E_NO_WRAP_TRANSPORT Handle = 0x8028002F + TPM_E_AUDITFAIL_UNSUCCESSFUL Handle = 0x80280030 + TPM_E_AUDITFAIL_SUCCESSFUL Handle = 0x80280031 + TPM_E_NOTRESETABLE Handle = 0x80280032 + TPM_E_NOTLOCAL Handle = 0x80280033 + TPM_E_BAD_TYPE Handle = 0x80280034 + TPM_E_INVALID_RESOURCE Handle = 0x80280035 + TPM_E_NOTFIPS Handle = 0x80280036 + TPM_E_INVALID_FAMILY Handle = 0x80280037 + TPM_E_NO_NV_PERMISSION Handle = 0x80280038 + TPM_E_REQUIRES_SIGN Handle = 0x80280039 + TPM_E_KEY_NOTSUPPORTED Handle = 0x8028003A + TPM_E_AUTH_CONFLICT Handle = 0x8028003B + TPM_E_AREA_LOCKED Handle = 0x8028003C + TPM_E_BAD_LOCALITY Handle = 0x8028003D + TPM_E_READ_ONLY Handle = 0x8028003E + TPM_E_PER_NOWRITE Handle = 0x8028003F + TPM_E_FAMILYCOUNT Handle = 0x80280040 + TPM_E_WRITE_LOCKED Handle = 0x80280041 + TPM_E_BAD_ATTRIBUTES Handle = 0x80280042 + TPM_E_INVALID_STRUCTURE Handle = 0x80280043 + TPM_E_KEY_OWNER_CONTROL Handle = 0x80280044 + TPM_E_BAD_COUNTER Handle = 0x80280045 + TPM_E_NOT_FULLWRITE Handle = 0x80280046 + TPM_E_CONTEXT_GAP Handle = 0x80280047 + TPM_E_MAXNVWRITES Handle = 0x80280048 + TPM_E_NOOPERATOR Handle = 0x80280049 + TPM_E_RESOURCEMISSING Handle = 0x8028004A + TPM_E_DELEGATE_LOCK Handle = 0x8028004B + TPM_E_DELEGATE_FAMILY Handle = 0x8028004C + TPM_E_DELEGATE_ADMIN Handle = 0x8028004D + TPM_E_TRANSPORT_NOTEXCLUSIVE Handle = 0x8028004E + TPM_E_OWNER_CONTROL Handle = 0x8028004F + TPM_E_DAA_RESOURCES Handle = 0x80280050 + TPM_E_DAA_INPUT_DATA0 Handle = 0x80280051 + TPM_E_DAA_INPUT_DATA1 Handle = 0x80280052 + TPM_E_DAA_ISSUER_SETTINGS Handle = 0x80280053 + TPM_E_DAA_TPM_SETTINGS Handle = 0x80280054 + TPM_E_DAA_STAGE Handle = 0x80280055 + TPM_E_DAA_ISSUER_VALIDITY Handle = 0x80280056 + TPM_E_DAA_WRONG_W Handle = 0x80280057 + TPM_E_BAD_HANDLE Handle = 0x80280058 + TPM_E_BAD_DELEGATE Handle = 0x80280059 + TPM_E_BADCONTEXT Handle = 0x8028005A + TPM_E_TOOMANYCONTEXTS Handle = 0x8028005B + TPM_E_MA_TICKET_SIGNATURE Handle = 0x8028005C + TPM_E_MA_DESTINATION Handle = 0x8028005D + TPM_E_MA_SOURCE Handle = 0x8028005E + TPM_E_MA_AUTHORITY Handle = 0x8028005F + TPM_E_PERMANENTEK Handle = 0x80280061 + TPM_E_BAD_SIGNATURE Handle = 0x80280062 + TPM_E_NOCONTEXTSPACE Handle = 0x80280063 + TPM_20_E_ASYMMETRIC Handle = 0x80280081 + TPM_20_E_ATTRIBUTES Handle = 0x80280082 + TPM_20_E_HASH Handle = 0x80280083 + TPM_20_E_VALUE Handle = 0x80280084 + TPM_20_E_HIERARCHY Handle = 0x80280085 + TPM_20_E_KEY_SIZE Handle = 0x80280087 + TPM_20_E_MGF Handle = 0x80280088 + TPM_20_E_MODE Handle = 0x80280089 + TPM_20_E_TYPE Handle = 0x8028008A + TPM_20_E_HANDLE Handle = 0x8028008B + TPM_20_E_KDF Handle = 0x8028008C + TPM_20_E_RANGE Handle = 0x8028008D + TPM_20_E_AUTH_FAIL Handle = 0x8028008E + TPM_20_E_NONCE Handle = 0x8028008F + TPM_20_E_PP Handle = 0x80280090 + TPM_20_E_SCHEME Handle = 0x80280092 + TPM_20_E_SIZE Handle = 0x80280095 + TPM_20_E_SYMMETRIC Handle = 0x80280096 + TPM_20_E_TAG Handle = 0x80280097 + TPM_20_E_SELECTOR Handle = 0x80280098 + TPM_20_E_INSUFFICIENT Handle = 0x8028009A + TPM_20_E_SIGNATURE Handle = 0x8028009B + TPM_20_E_KEY Handle = 0x8028009C + TPM_20_E_POLICY_FAIL Handle = 0x8028009D + TPM_20_E_INTEGRITY Handle = 0x8028009F + TPM_20_E_TICKET Handle = 0x802800A0 + TPM_20_E_RESERVED_BITS Handle = 0x802800A1 + TPM_20_E_BAD_AUTH Handle = 0x802800A2 + TPM_20_E_EXPIRED Handle = 0x802800A3 + TPM_20_E_POLICY_CC Handle = 0x802800A4 + TPM_20_E_BINDING Handle = 0x802800A5 + TPM_20_E_CURVE Handle = 0x802800A6 + TPM_20_E_ECC_POINT Handle = 0x802800A7 + TPM_20_E_INITIALIZE Handle = 0x80280100 + TPM_20_E_FAILURE Handle = 0x80280101 + TPM_20_E_SEQUENCE Handle = 0x80280103 + TPM_20_E_PRIVATE Handle = 0x8028010B + TPM_20_E_HMAC Handle = 0x80280119 + TPM_20_E_DISABLED Handle = 0x80280120 + TPM_20_E_EXCLUSIVE Handle = 0x80280121 + TPM_20_E_ECC_CURVE Handle = 0x80280123 + TPM_20_E_AUTH_TYPE Handle = 0x80280124 + TPM_20_E_AUTH_MISSING Handle = 0x80280125 + TPM_20_E_POLICY Handle = 0x80280126 + TPM_20_E_PCR Handle = 0x80280127 + TPM_20_E_PCR_CHANGED Handle = 0x80280128 + TPM_20_E_UPGRADE Handle = 0x8028012D + TPM_20_E_TOO_MANY_CONTEXTS Handle = 0x8028012E + TPM_20_E_AUTH_UNAVAILABLE Handle = 0x8028012F + TPM_20_E_REBOOT Handle = 0x80280130 + TPM_20_E_UNBALANCED Handle = 0x80280131 + TPM_20_E_COMMAND_SIZE Handle = 0x80280142 + TPM_20_E_COMMAND_CODE Handle = 0x80280143 + TPM_20_E_AUTHSIZE Handle = 0x80280144 + TPM_20_E_AUTH_CONTEXT Handle = 0x80280145 + TPM_20_E_NV_RANGE Handle = 0x80280146 + TPM_20_E_NV_SIZE Handle = 0x80280147 + TPM_20_E_NV_LOCKED Handle = 0x80280148 + TPM_20_E_NV_AUTHORIZATION Handle = 0x80280149 + TPM_20_E_NV_UNINITIALIZED Handle = 0x8028014A + TPM_20_E_NV_SPACE Handle = 0x8028014B + TPM_20_E_NV_DEFINED Handle = 0x8028014C + TPM_20_E_BAD_CONTEXT Handle = 0x80280150 + TPM_20_E_CPHASH Handle = 0x80280151 + TPM_20_E_PARENT Handle = 0x80280152 + TPM_20_E_NEEDS_TEST Handle = 0x80280153 + TPM_20_E_NO_RESULT Handle = 0x80280154 + TPM_20_E_SENSITIVE Handle = 0x80280155 + TPM_E_COMMAND_BLOCKED Handle = 0x80280400 + TPM_E_INVALID_HANDLE Handle = 0x80280401 + TPM_E_DUPLICATE_VHANDLE Handle = 0x80280402 + TPM_E_EMBEDDED_COMMAND_BLOCKED Handle = 0x80280403 + TPM_E_EMBEDDED_COMMAND_UNSUPPORTED Handle = 0x80280404 + TPM_E_RETRY Handle = 0x80280800 + TPM_E_NEEDS_SELFTEST Handle = 0x80280801 + TPM_E_DOING_SELFTEST Handle = 0x80280802 + TPM_E_DEFEND_LOCK_RUNNING Handle = 0x80280803 + TPM_20_E_CONTEXT_GAP Handle = 0x80280901 + TPM_20_E_OBJECT_MEMORY Handle = 0x80280902 + TPM_20_E_SESSION_MEMORY Handle = 0x80280903 + TPM_20_E_MEMORY Handle = 0x80280904 + TPM_20_E_SESSION_HANDLES Handle = 0x80280905 + TPM_20_E_OBJECT_HANDLES Handle = 0x80280906 + TPM_20_E_LOCALITY Handle = 0x80280907 + TPM_20_E_YIELDED Handle = 0x80280908 + TPM_20_E_CANCELED Handle = 0x80280909 + TPM_20_E_TESTING Handle = 0x8028090A + TPM_20_E_NV_RATE Handle = 0x80280920 + TPM_20_E_LOCKOUT Handle = 0x80280921 + TPM_20_E_RETRY Handle = 0x80280922 + TPM_20_E_NV_UNAVAILABLE Handle = 0x80280923 + TBS_E_INTERNAL_ERROR Handle = 0x80284001 + TBS_E_BAD_PARAMETER Handle = 0x80284002 + TBS_E_INVALID_OUTPUT_POINTER Handle = 0x80284003 + TBS_E_INVALID_CONTEXT Handle = 0x80284004 + TBS_E_INSUFFICIENT_BUFFER Handle = 0x80284005 + TBS_E_IOERROR Handle = 0x80284006 + TBS_E_INVALID_CONTEXT_PARAM Handle = 0x80284007 + TBS_E_SERVICE_NOT_RUNNING Handle = 0x80284008 + TBS_E_TOO_MANY_TBS_CONTEXTS Handle = 0x80284009 + TBS_E_TOO_MANY_RESOURCES Handle = 0x8028400A + TBS_E_SERVICE_START_PENDING Handle = 0x8028400B + TBS_E_PPI_NOT_SUPPORTED Handle = 0x8028400C + TBS_E_COMMAND_CANCELED Handle = 0x8028400D + TBS_E_BUFFER_TOO_LARGE Handle = 0x8028400E + TBS_E_TPM_NOT_FOUND Handle = 0x8028400F + TBS_E_SERVICE_DISABLED Handle = 0x80284010 + TBS_E_NO_EVENT_LOG Handle = 0x80284011 + TBS_E_ACCESS_DENIED Handle = 0x80284012 + TBS_E_PROVISIONING_NOT_ALLOWED Handle = 0x80284013 + TBS_E_PPI_FUNCTION_UNSUPPORTED Handle = 0x80284014 + TBS_E_OWNERAUTH_NOT_FOUND Handle = 0x80284015 + TBS_E_PROVISIONING_INCOMPLETE Handle = 0x80284016 + TPMAPI_E_INVALID_STATE Handle = 0x80290100 + TPMAPI_E_NOT_ENOUGH_DATA Handle = 0x80290101 + TPMAPI_E_TOO_MUCH_DATA Handle = 0x80290102 + TPMAPI_E_INVALID_OUTPUT_POINTER Handle = 0x80290103 + TPMAPI_E_INVALID_PARAMETER Handle = 0x80290104 + TPMAPI_E_OUT_OF_MEMORY Handle = 0x80290105 + TPMAPI_E_BUFFER_TOO_SMALL Handle = 0x80290106 + TPMAPI_E_INTERNAL_ERROR Handle = 0x80290107 + TPMAPI_E_ACCESS_DENIED Handle = 0x80290108 + TPMAPI_E_AUTHORIZATION_FAILED Handle = 0x80290109 + TPMAPI_E_INVALID_CONTEXT_HANDLE Handle = 0x8029010A + TPMAPI_E_TBS_COMMUNICATION_ERROR Handle = 0x8029010B + TPMAPI_E_TPM_COMMAND_ERROR Handle = 0x8029010C + TPMAPI_E_MESSAGE_TOO_LARGE Handle = 0x8029010D + TPMAPI_E_INVALID_ENCODING Handle = 0x8029010E + TPMAPI_E_INVALID_KEY_SIZE Handle = 0x8029010F + TPMAPI_E_ENCRYPTION_FAILED Handle = 0x80290110 + TPMAPI_E_INVALID_KEY_PARAMS Handle = 0x80290111 + TPMAPI_E_INVALID_MIGRATION_AUTHORIZATION_BLOB Handle = 0x80290112 + TPMAPI_E_INVALID_PCR_INDEX Handle = 0x80290113 + TPMAPI_E_INVALID_DELEGATE_BLOB Handle = 0x80290114 + TPMAPI_E_INVALID_CONTEXT_PARAMS Handle = 0x80290115 + TPMAPI_E_INVALID_KEY_BLOB Handle = 0x80290116 + TPMAPI_E_INVALID_PCR_DATA Handle = 0x80290117 + TPMAPI_E_INVALID_OWNER_AUTH Handle = 0x80290118 + TPMAPI_E_FIPS_RNG_CHECK_FAILED Handle = 0x80290119 + TPMAPI_E_EMPTY_TCG_LOG Handle = 0x8029011A + TPMAPI_E_INVALID_TCG_LOG_ENTRY Handle = 0x8029011B + TPMAPI_E_TCG_SEPARATOR_ABSENT Handle = 0x8029011C + TPMAPI_E_TCG_INVALID_DIGEST_ENTRY Handle = 0x8029011D + TPMAPI_E_POLICY_DENIES_OPERATION Handle = 0x8029011E + TPMAPI_E_NV_BITS_NOT_DEFINED Handle = 0x8029011F + TPMAPI_E_NV_BITS_NOT_READY Handle = 0x80290120 + TPMAPI_E_SEALING_KEY_NOT_AVAILABLE Handle = 0x80290121 + TPMAPI_E_NO_AUTHORIZATION_CHAIN_FOUND Handle = 0x80290122 + TPMAPI_E_SVN_COUNTER_NOT_AVAILABLE Handle = 0x80290123 + TPMAPI_E_OWNER_AUTH_NOT_NULL Handle = 0x80290124 + TPMAPI_E_ENDORSEMENT_AUTH_NOT_NULL Handle = 0x80290125 + TPMAPI_E_AUTHORIZATION_REVOKED Handle = 0x80290126 + TPMAPI_E_MALFORMED_AUTHORIZATION_KEY Handle = 0x80290127 + TPMAPI_E_AUTHORIZING_KEY_NOT_SUPPORTED Handle = 0x80290128 + TPMAPI_E_INVALID_AUTHORIZATION_SIGNATURE Handle = 0x80290129 + TPMAPI_E_MALFORMED_AUTHORIZATION_POLICY Handle = 0x8029012A + TPMAPI_E_MALFORMED_AUTHORIZATION_OTHER Handle = 0x8029012B + TPMAPI_E_SEALING_KEY_CHANGED Handle = 0x8029012C + TBSIMP_E_BUFFER_TOO_SMALL Handle = 0x80290200 + TBSIMP_E_CLEANUP_FAILED Handle = 0x80290201 + TBSIMP_E_INVALID_CONTEXT_HANDLE Handle = 0x80290202 + TBSIMP_E_INVALID_CONTEXT_PARAM Handle = 0x80290203 + TBSIMP_E_TPM_ERROR Handle = 0x80290204 + TBSIMP_E_HASH_BAD_KEY Handle = 0x80290205 + TBSIMP_E_DUPLICATE_VHANDLE Handle = 0x80290206 + TBSIMP_E_INVALID_OUTPUT_POINTER Handle = 0x80290207 + TBSIMP_E_INVALID_PARAMETER Handle = 0x80290208 + TBSIMP_E_RPC_INIT_FAILED Handle = 0x80290209 + TBSIMP_E_SCHEDULER_NOT_RUNNING Handle = 0x8029020A + TBSIMP_E_COMMAND_CANCELED Handle = 0x8029020B + TBSIMP_E_OUT_OF_MEMORY Handle = 0x8029020C + TBSIMP_E_LIST_NO_MORE_ITEMS Handle = 0x8029020D + TBSIMP_E_LIST_NOT_FOUND Handle = 0x8029020E + TBSIMP_E_NOT_ENOUGH_SPACE Handle = 0x8029020F + TBSIMP_E_NOT_ENOUGH_TPM_CONTEXTS Handle = 0x80290210 + TBSIMP_E_COMMAND_FAILED Handle = 0x80290211 + TBSIMP_E_UNKNOWN_ORDINAL Handle = 0x80290212 + TBSIMP_E_RESOURCE_EXPIRED Handle = 0x80290213 + TBSIMP_E_INVALID_RESOURCE Handle = 0x80290214 + TBSIMP_E_NOTHING_TO_UNLOAD Handle = 0x80290215 + TBSIMP_E_HASH_TABLE_FULL Handle = 0x80290216 + TBSIMP_E_TOO_MANY_TBS_CONTEXTS Handle = 0x80290217 + TBSIMP_E_TOO_MANY_RESOURCES Handle = 0x80290218 + TBSIMP_E_PPI_NOT_SUPPORTED Handle = 0x80290219 + TBSIMP_E_TPM_INCOMPATIBLE Handle = 0x8029021A + TBSIMP_E_NO_EVENT_LOG Handle = 0x8029021B + TPM_E_PPI_ACPI_FAILURE Handle = 0x80290300 + TPM_E_PPI_USER_ABORT Handle = 0x80290301 + TPM_E_PPI_BIOS_FAILURE Handle = 0x80290302 + TPM_E_PPI_NOT_SUPPORTED Handle = 0x80290303 + TPM_E_PPI_BLOCKED_IN_BIOS Handle = 0x80290304 + TPM_E_PCP_ERROR_MASK Handle = 0x80290400 + TPM_E_PCP_DEVICE_NOT_READY Handle = 0x80290401 + TPM_E_PCP_INVALID_HANDLE Handle = 0x80290402 + TPM_E_PCP_INVALID_PARAMETER Handle = 0x80290403 + TPM_E_PCP_FLAG_NOT_SUPPORTED Handle = 0x80290404 + TPM_E_PCP_NOT_SUPPORTED Handle = 0x80290405 + TPM_E_PCP_BUFFER_TOO_SMALL Handle = 0x80290406 + TPM_E_PCP_INTERNAL_ERROR Handle = 0x80290407 + TPM_E_PCP_AUTHENTICATION_FAILED Handle = 0x80290408 + TPM_E_PCP_AUTHENTICATION_IGNORED Handle = 0x80290409 + TPM_E_PCP_POLICY_NOT_FOUND Handle = 0x8029040A + TPM_E_PCP_PROFILE_NOT_FOUND Handle = 0x8029040B + TPM_E_PCP_VALIDATION_FAILED Handle = 0x8029040C + TPM_E_PCP_WRONG_PARENT Handle = 0x8029040E + TPM_E_KEY_NOT_LOADED Handle = 0x8029040F + TPM_E_NO_KEY_CERTIFICATION Handle = 0x80290410 + TPM_E_KEY_NOT_FINALIZED Handle = 0x80290411 + TPM_E_ATTESTATION_CHALLENGE_NOT_SET Handle = 0x80290412 + TPM_E_NOT_PCR_BOUND Handle = 0x80290413 + TPM_E_KEY_ALREADY_FINALIZED Handle = 0x80290414 + TPM_E_KEY_USAGE_POLICY_NOT_SUPPORTED Handle = 0x80290415 + TPM_E_KEY_USAGE_POLICY_INVALID Handle = 0x80290416 + TPM_E_SOFT_KEY_ERROR Handle = 0x80290417 + TPM_E_KEY_NOT_AUTHENTICATED Handle = 0x80290418 + TPM_E_PCP_KEY_NOT_AIK Handle = 0x80290419 + TPM_E_KEY_NOT_SIGNING_KEY Handle = 0x8029041A + TPM_E_LOCKED_OUT Handle = 0x8029041B + TPM_E_CLAIM_TYPE_NOT_SUPPORTED Handle = 0x8029041C + TPM_E_VERSION_NOT_SUPPORTED Handle = 0x8029041D + TPM_E_BUFFER_LENGTH_MISMATCH Handle = 0x8029041E + TPM_E_PCP_IFX_RSA_KEY_CREATION_BLOCKED Handle = 0x8029041F + TPM_E_PCP_TICKET_MISSING Handle = 0x80290420 + TPM_E_PCP_RAW_POLICY_NOT_SUPPORTED Handle = 0x80290421 + TPM_E_PCP_KEY_HANDLE_INVALIDATED Handle = 0x80290422 + TPM_E_PCP_UNSUPPORTED_PSS_SALT Handle = 0x40290423 + TPM_E_ZERO_EXHAUST_ENABLED Handle = 0x80290500 + PLA_E_DCS_NOT_FOUND Handle = 0x80300002 + PLA_E_DCS_IN_USE Handle = 0x803000AA + PLA_E_TOO_MANY_FOLDERS Handle = 0x80300045 + PLA_E_NO_MIN_DISK Handle = 0x80300070 + PLA_E_DCS_ALREADY_EXISTS Handle = 0x803000B7 + PLA_S_PROPERTY_IGNORED Handle = 0x00300100 + PLA_E_PROPERTY_CONFLICT Handle = 0x80300101 + PLA_E_DCS_SINGLETON_REQUIRED Handle = 0x80300102 + PLA_E_CREDENTIALS_REQUIRED Handle = 0x80300103 + PLA_E_DCS_NOT_RUNNING Handle = 0x80300104 + PLA_E_CONFLICT_INCL_EXCL_API Handle = 0x80300105 + PLA_E_NETWORK_EXE_NOT_VALID Handle = 0x80300106 + PLA_E_EXE_ALREADY_CONFIGURED Handle = 0x80300107 + PLA_E_EXE_PATH_NOT_VALID Handle = 0x80300108 + PLA_E_DC_ALREADY_EXISTS Handle = 0x80300109 + PLA_E_DCS_START_WAIT_TIMEOUT Handle = 0x8030010A + PLA_E_DC_START_WAIT_TIMEOUT Handle = 0x8030010B + PLA_E_REPORT_WAIT_TIMEOUT Handle = 0x8030010C + PLA_E_NO_DUPLICATES Handle = 0x8030010D + PLA_E_EXE_FULL_PATH_REQUIRED Handle = 0x8030010E + PLA_E_INVALID_SESSION_NAME Handle = 0x8030010F + PLA_E_PLA_CHANNEL_NOT_ENABLED Handle = 0x80300110 + PLA_E_TASKSCHED_CHANNEL_NOT_ENABLED Handle = 0x80300111 + PLA_E_RULES_MANAGER_FAILED Handle = 0x80300112 + PLA_E_CABAPI_FAILURE Handle = 0x80300113 + FVE_E_LOCKED_VOLUME Handle = 0x80310000 + FVE_E_NOT_ENCRYPTED Handle = 0x80310001 + FVE_E_NO_TPM_BIOS Handle = 0x80310002 + FVE_E_NO_MBR_METRIC Handle = 0x80310003 + FVE_E_NO_BOOTSECTOR_METRIC Handle = 0x80310004 + FVE_E_NO_BOOTMGR_METRIC Handle = 0x80310005 + FVE_E_WRONG_BOOTMGR Handle = 0x80310006 + FVE_E_SECURE_KEY_REQUIRED Handle = 0x80310007 + FVE_E_NOT_ACTIVATED Handle = 0x80310008 + FVE_E_ACTION_NOT_ALLOWED Handle = 0x80310009 + FVE_E_AD_SCHEMA_NOT_INSTALLED Handle = 0x8031000A + FVE_E_AD_INVALID_DATATYPE Handle = 0x8031000B + FVE_E_AD_INVALID_DATASIZE Handle = 0x8031000C + FVE_E_AD_NO_VALUES Handle = 0x8031000D + FVE_E_AD_ATTR_NOT_SET Handle = 0x8031000E + FVE_E_AD_GUID_NOT_FOUND Handle = 0x8031000F + FVE_E_BAD_INFORMATION Handle = 0x80310010 + FVE_E_TOO_SMALL Handle = 0x80310011 + FVE_E_SYSTEM_VOLUME Handle = 0x80310012 + FVE_E_FAILED_WRONG_FS Handle = 0x80310013 + FVE_E_BAD_PARTITION_SIZE Handle = 0x80310014 + FVE_E_NOT_SUPPORTED Handle = 0x80310015 + FVE_E_BAD_DATA Handle = 0x80310016 + FVE_E_VOLUME_NOT_BOUND Handle = 0x80310017 + FVE_E_TPM_NOT_OWNED Handle = 0x80310018 + FVE_E_NOT_DATA_VOLUME Handle = 0x80310019 + FVE_E_AD_INSUFFICIENT_BUFFER Handle = 0x8031001A + FVE_E_CONV_READ Handle = 0x8031001B + FVE_E_CONV_WRITE Handle = 0x8031001C + FVE_E_KEY_REQUIRED Handle = 0x8031001D + FVE_E_CLUSTERING_NOT_SUPPORTED Handle = 0x8031001E + FVE_E_VOLUME_BOUND_ALREADY Handle = 0x8031001F + FVE_E_OS_NOT_PROTECTED Handle = 0x80310020 + FVE_E_PROTECTION_DISABLED Handle = 0x80310021 + FVE_E_RECOVERY_KEY_REQUIRED Handle = 0x80310022 + FVE_E_FOREIGN_VOLUME Handle = 0x80310023 + FVE_E_OVERLAPPED_UPDATE Handle = 0x80310024 + FVE_E_TPM_SRK_AUTH_NOT_ZERO Handle = 0x80310025 + FVE_E_FAILED_SECTOR_SIZE Handle = 0x80310026 + FVE_E_FAILED_AUTHENTICATION Handle = 0x80310027 + FVE_E_NOT_OS_VOLUME Handle = 0x80310028 + FVE_E_AUTOUNLOCK_ENABLED Handle = 0x80310029 + FVE_E_WRONG_BOOTSECTOR Handle = 0x8031002A + FVE_E_WRONG_SYSTEM_FS Handle = 0x8031002B + FVE_E_POLICY_PASSWORD_REQUIRED Handle = 0x8031002C + FVE_E_CANNOT_SET_FVEK_ENCRYPTED Handle = 0x8031002D + FVE_E_CANNOT_ENCRYPT_NO_KEY Handle = 0x8031002E + FVE_E_BOOTABLE_CDDVD Handle = 0x80310030 + FVE_E_PROTECTOR_EXISTS Handle = 0x80310031 + FVE_E_RELATIVE_PATH Handle = 0x80310032 + FVE_E_PROTECTOR_NOT_FOUND Handle = 0x80310033 + FVE_E_INVALID_KEY_FORMAT Handle = 0x80310034 + FVE_E_INVALID_PASSWORD_FORMAT Handle = 0x80310035 + FVE_E_FIPS_RNG_CHECK_FAILED Handle = 0x80310036 + FVE_E_FIPS_PREVENTS_RECOVERY_PASSWORD Handle = 0x80310037 + FVE_E_FIPS_PREVENTS_EXTERNAL_KEY_EXPORT Handle = 0x80310038 + FVE_E_NOT_DECRYPTED Handle = 0x80310039 + FVE_E_INVALID_PROTECTOR_TYPE Handle = 0x8031003A + FVE_E_NO_PROTECTORS_TO_TEST Handle = 0x8031003B + FVE_E_KEYFILE_NOT_FOUND Handle = 0x8031003C + FVE_E_KEYFILE_INVALID Handle = 0x8031003D + FVE_E_KEYFILE_NO_VMK Handle = 0x8031003E + FVE_E_TPM_DISABLED Handle = 0x8031003F + FVE_E_NOT_ALLOWED_IN_SAFE_MODE Handle = 0x80310040 + FVE_E_TPM_INVALID_PCR Handle = 0x80310041 + FVE_E_TPM_NO_VMK Handle = 0x80310042 + FVE_E_PIN_INVALID Handle = 0x80310043 + FVE_E_AUTH_INVALID_APPLICATION Handle = 0x80310044 + FVE_E_AUTH_INVALID_CONFIG Handle = 0x80310045 + FVE_E_FIPS_DISABLE_PROTECTION_NOT_ALLOWED Handle = 0x80310046 + FVE_E_FS_NOT_EXTENDED Handle = 0x80310047 + FVE_E_FIRMWARE_TYPE_NOT_SUPPORTED Handle = 0x80310048 + FVE_E_NO_LICENSE Handle = 0x80310049 + FVE_E_NOT_ON_STACK Handle = 0x8031004A + FVE_E_FS_MOUNTED Handle = 0x8031004B + FVE_E_TOKEN_NOT_IMPERSONATED Handle = 0x8031004C + FVE_E_DRY_RUN_FAILED Handle = 0x8031004D + FVE_E_REBOOT_REQUIRED Handle = 0x8031004E + FVE_E_DEBUGGER_ENABLED Handle = 0x8031004F + FVE_E_RAW_ACCESS Handle = 0x80310050 + FVE_E_RAW_BLOCKED Handle = 0x80310051 + FVE_E_BCD_APPLICATIONS_PATH_INCORRECT Handle = 0x80310052 + FVE_E_NOT_ALLOWED_IN_VERSION Handle = 0x80310053 + FVE_E_NO_AUTOUNLOCK_MASTER_KEY Handle = 0x80310054 + FVE_E_MOR_FAILED Handle = 0x80310055 + FVE_E_HIDDEN_VOLUME Handle = 0x80310056 + FVE_E_TRANSIENT_STATE Handle = 0x80310057 + FVE_E_PUBKEY_NOT_ALLOWED Handle = 0x80310058 + FVE_E_VOLUME_HANDLE_OPEN Handle = 0x80310059 + FVE_E_NO_FEATURE_LICENSE Handle = 0x8031005A + FVE_E_INVALID_STARTUP_OPTIONS Handle = 0x8031005B + FVE_E_POLICY_RECOVERY_PASSWORD_NOT_ALLOWED Handle = 0x8031005C + FVE_E_POLICY_RECOVERY_PASSWORD_REQUIRED Handle = 0x8031005D + FVE_E_POLICY_RECOVERY_KEY_NOT_ALLOWED Handle = 0x8031005E + FVE_E_POLICY_RECOVERY_KEY_REQUIRED Handle = 0x8031005F + FVE_E_POLICY_STARTUP_PIN_NOT_ALLOWED Handle = 0x80310060 + FVE_E_POLICY_STARTUP_PIN_REQUIRED Handle = 0x80310061 + FVE_E_POLICY_STARTUP_KEY_NOT_ALLOWED Handle = 0x80310062 + FVE_E_POLICY_STARTUP_KEY_REQUIRED Handle = 0x80310063 + FVE_E_POLICY_STARTUP_PIN_KEY_NOT_ALLOWED Handle = 0x80310064 + FVE_E_POLICY_STARTUP_PIN_KEY_REQUIRED Handle = 0x80310065 + FVE_E_POLICY_STARTUP_TPM_NOT_ALLOWED Handle = 0x80310066 + FVE_E_POLICY_STARTUP_TPM_REQUIRED Handle = 0x80310067 + FVE_E_POLICY_INVALID_PIN_LENGTH Handle = 0x80310068 + FVE_E_KEY_PROTECTOR_NOT_SUPPORTED Handle = 0x80310069 + FVE_E_POLICY_PASSPHRASE_NOT_ALLOWED Handle = 0x8031006A + FVE_E_POLICY_PASSPHRASE_REQUIRED Handle = 0x8031006B + FVE_E_FIPS_PREVENTS_PASSPHRASE Handle = 0x8031006C + FVE_E_OS_VOLUME_PASSPHRASE_NOT_ALLOWED Handle = 0x8031006D + FVE_E_INVALID_BITLOCKER_OID Handle = 0x8031006E + FVE_E_VOLUME_TOO_SMALL Handle = 0x8031006F + FVE_E_DV_NOT_SUPPORTED_ON_FS Handle = 0x80310070 + FVE_E_DV_NOT_ALLOWED_BY_GP Handle = 0x80310071 + FVE_E_POLICY_USER_CERTIFICATE_NOT_ALLOWED Handle = 0x80310072 + FVE_E_POLICY_USER_CERTIFICATE_REQUIRED Handle = 0x80310073 + FVE_E_POLICY_USER_CERT_MUST_BE_HW Handle = 0x80310074 + FVE_E_POLICY_USER_CONFIGURE_FDV_AUTOUNLOCK_NOT_ALLOWED Handle = 0x80310075 + FVE_E_POLICY_USER_CONFIGURE_RDV_AUTOUNLOCK_NOT_ALLOWED Handle = 0x80310076 + FVE_E_POLICY_USER_CONFIGURE_RDV_NOT_ALLOWED Handle = 0x80310077 + FVE_E_POLICY_USER_ENABLE_RDV_NOT_ALLOWED Handle = 0x80310078 + FVE_E_POLICY_USER_DISABLE_RDV_NOT_ALLOWED Handle = 0x80310079 + FVE_E_POLICY_INVALID_PASSPHRASE_LENGTH Handle = 0x80310080 + FVE_E_POLICY_PASSPHRASE_TOO_SIMPLE Handle = 0x80310081 + FVE_E_RECOVERY_PARTITION Handle = 0x80310082 + FVE_E_POLICY_CONFLICT_FDV_RK_OFF_AUK_ON Handle = 0x80310083 + FVE_E_POLICY_CONFLICT_RDV_RK_OFF_AUK_ON Handle = 0x80310084 + FVE_E_NON_BITLOCKER_OID Handle = 0x80310085 + FVE_E_POLICY_PROHIBITS_SELFSIGNED Handle = 0x80310086 + FVE_E_POLICY_CONFLICT_RO_AND_STARTUP_KEY_REQUIRED Handle = 0x80310087 + FVE_E_CONV_RECOVERY_FAILED Handle = 0x80310088 + FVE_E_VIRTUALIZED_SPACE_TOO_BIG Handle = 0x80310089 + FVE_E_POLICY_CONFLICT_OSV_RP_OFF_ADB_ON Handle = 0x80310090 + FVE_E_POLICY_CONFLICT_FDV_RP_OFF_ADB_ON Handle = 0x80310091 + FVE_E_POLICY_CONFLICT_RDV_RP_OFF_ADB_ON Handle = 0x80310092 + FVE_E_NON_BITLOCKER_KU Handle = 0x80310093 + FVE_E_PRIVATEKEY_AUTH_FAILED Handle = 0x80310094 + FVE_E_REMOVAL_OF_DRA_FAILED Handle = 0x80310095 + FVE_E_OPERATION_NOT_SUPPORTED_ON_VISTA_VOLUME Handle = 0x80310096 + FVE_E_CANT_LOCK_AUTOUNLOCK_ENABLED_VOLUME Handle = 0x80310097 + FVE_E_FIPS_HASH_KDF_NOT_ALLOWED Handle = 0x80310098 + FVE_E_ENH_PIN_INVALID Handle = 0x80310099 + FVE_E_INVALID_PIN_CHARS Handle = 0x8031009A + FVE_E_INVALID_DATUM_TYPE Handle = 0x8031009B + FVE_E_EFI_ONLY Handle = 0x8031009C + FVE_E_MULTIPLE_NKP_CERTS Handle = 0x8031009D + FVE_E_REMOVAL_OF_NKP_FAILED Handle = 0x8031009E + FVE_E_INVALID_NKP_CERT Handle = 0x8031009F + FVE_E_NO_EXISTING_PIN Handle = 0x803100A0 + FVE_E_PROTECTOR_CHANGE_PIN_MISMATCH Handle = 0x803100A1 + FVE_E_PIN_PROTECTOR_CHANGE_BY_STD_USER_DISALLOWED Handle = 0x803100A2 + FVE_E_PROTECTOR_CHANGE_MAX_PIN_CHANGE_ATTEMPTS_REACHED Handle = 0x803100A3 + FVE_E_POLICY_PASSPHRASE_REQUIRES_ASCII Handle = 0x803100A4 + FVE_E_FULL_ENCRYPTION_NOT_ALLOWED_ON_TP_STORAGE Handle = 0x803100A5 + FVE_E_WIPE_NOT_ALLOWED_ON_TP_STORAGE Handle = 0x803100A6 + FVE_E_KEY_LENGTH_NOT_SUPPORTED_BY_EDRIVE Handle = 0x803100A7 + FVE_E_NO_EXISTING_PASSPHRASE Handle = 0x803100A8 + FVE_E_PROTECTOR_CHANGE_PASSPHRASE_MISMATCH Handle = 0x803100A9 + FVE_E_PASSPHRASE_TOO_LONG Handle = 0x803100AA + FVE_E_NO_PASSPHRASE_WITH_TPM Handle = 0x803100AB + FVE_E_NO_TPM_WITH_PASSPHRASE Handle = 0x803100AC + FVE_E_NOT_ALLOWED_ON_CSV_STACK Handle = 0x803100AD + FVE_E_NOT_ALLOWED_ON_CLUSTER Handle = 0x803100AE + FVE_E_EDRIVE_NO_FAILOVER_TO_SW Handle = 0x803100AF + FVE_E_EDRIVE_BAND_IN_USE Handle = 0x803100B0 + FVE_E_EDRIVE_DISALLOWED_BY_GP Handle = 0x803100B1 + FVE_E_EDRIVE_INCOMPATIBLE_VOLUME Handle = 0x803100B2 + FVE_E_NOT_ALLOWED_TO_UPGRADE_WHILE_CONVERTING Handle = 0x803100B3 + FVE_E_EDRIVE_DV_NOT_SUPPORTED Handle = 0x803100B4 + FVE_E_NO_PREBOOT_KEYBOARD_DETECTED Handle = 0x803100B5 + FVE_E_NO_PREBOOT_KEYBOARD_OR_WINRE_DETECTED Handle = 0x803100B6 + FVE_E_POLICY_REQUIRES_STARTUP_PIN_ON_TOUCH_DEVICE Handle = 0x803100B7 + FVE_E_POLICY_REQUIRES_RECOVERY_PASSWORD_ON_TOUCH_DEVICE Handle = 0x803100B8 + FVE_E_WIPE_CANCEL_NOT_APPLICABLE Handle = 0x803100B9 + FVE_E_SECUREBOOT_DISABLED Handle = 0x803100BA + FVE_E_SECUREBOOT_CONFIGURATION_INVALID Handle = 0x803100BB + FVE_E_EDRIVE_DRY_RUN_FAILED Handle = 0x803100BC + FVE_E_SHADOW_COPY_PRESENT Handle = 0x803100BD + FVE_E_POLICY_INVALID_ENHANCED_BCD_SETTINGS Handle = 0x803100BE + FVE_E_EDRIVE_INCOMPATIBLE_FIRMWARE Handle = 0x803100BF + FVE_E_PROTECTOR_CHANGE_MAX_PASSPHRASE_CHANGE_ATTEMPTS_REACHED Handle = 0x803100C0 + FVE_E_PASSPHRASE_PROTECTOR_CHANGE_BY_STD_USER_DISALLOWED Handle = 0x803100C1 + FVE_E_LIVEID_ACCOUNT_SUSPENDED Handle = 0x803100C2 + FVE_E_LIVEID_ACCOUNT_BLOCKED Handle = 0x803100C3 + FVE_E_NOT_PROVISIONED_ON_ALL_VOLUMES Handle = 0x803100C4 + FVE_E_DE_FIXED_DATA_NOT_SUPPORTED Handle = 0x803100C5 + FVE_E_DE_HARDWARE_NOT_COMPLIANT Handle = 0x803100C6 + FVE_E_DE_WINRE_NOT_CONFIGURED Handle = 0x803100C7 + FVE_E_DE_PROTECTION_SUSPENDED Handle = 0x803100C8 + FVE_E_DE_OS_VOLUME_NOT_PROTECTED Handle = 0x803100C9 + FVE_E_DE_DEVICE_LOCKEDOUT Handle = 0x803100CA + FVE_E_DE_PROTECTION_NOT_YET_ENABLED Handle = 0x803100CB + FVE_E_INVALID_PIN_CHARS_DETAILED Handle = 0x803100CC + FVE_E_DEVICE_LOCKOUT_COUNTER_UNAVAILABLE Handle = 0x803100CD + FVE_E_DEVICELOCKOUT_COUNTER_MISMATCH Handle = 0x803100CE + FVE_E_BUFFER_TOO_LARGE Handle = 0x803100CF + FVE_E_NO_SUCH_CAPABILITY_ON_TARGET Handle = 0x803100D0 + FVE_E_DE_PREVENTED_FOR_OS Handle = 0x803100D1 + FVE_E_DE_VOLUME_OPTED_OUT Handle = 0x803100D2 + FVE_E_DE_VOLUME_NOT_SUPPORTED Handle = 0x803100D3 + FVE_E_EOW_NOT_SUPPORTED_IN_VERSION Handle = 0x803100D4 + FVE_E_ADBACKUP_NOT_ENABLED Handle = 0x803100D5 + FVE_E_VOLUME_EXTEND_PREVENTS_EOW_DECRYPT Handle = 0x803100D6 + FVE_E_NOT_DE_VOLUME Handle = 0x803100D7 + FVE_E_PROTECTION_CANNOT_BE_DISABLED Handle = 0x803100D8 + FVE_E_OSV_KSR_NOT_ALLOWED Handle = 0x803100D9 + FVE_E_AD_BACKUP_REQUIRED_POLICY_NOT_SET_OS_DRIVE Handle = 0x803100DA + FVE_E_AD_BACKUP_REQUIRED_POLICY_NOT_SET_FIXED_DRIVE Handle = 0x803100DB + FVE_E_AD_BACKUP_REQUIRED_POLICY_NOT_SET_REMOVABLE_DRIVE Handle = 0x803100DC + FVE_E_KEY_ROTATION_NOT_SUPPORTED Handle = 0x803100DD + FVE_E_EXECUTE_REQUEST_SENT_TOO_SOON Handle = 0x803100DE + FVE_E_KEY_ROTATION_NOT_ENABLED Handle = 0x803100DF + FVE_E_DEVICE_NOT_JOINED Handle = 0x803100E0 + FWP_E_CALLOUT_NOT_FOUND Handle = 0x80320001 + FWP_E_CONDITION_NOT_FOUND Handle = 0x80320002 + FWP_E_FILTER_NOT_FOUND Handle = 0x80320003 + FWP_E_LAYER_NOT_FOUND Handle = 0x80320004 + FWP_E_PROVIDER_NOT_FOUND Handle = 0x80320005 + FWP_E_PROVIDER_CONTEXT_NOT_FOUND Handle = 0x80320006 + FWP_E_SUBLAYER_NOT_FOUND Handle = 0x80320007 + FWP_E_NOT_FOUND Handle = 0x80320008 + FWP_E_ALREADY_EXISTS Handle = 0x80320009 + FWP_E_IN_USE Handle = 0x8032000A + FWP_E_DYNAMIC_SESSION_IN_PROGRESS Handle = 0x8032000B + FWP_E_WRONG_SESSION Handle = 0x8032000C + FWP_E_NO_TXN_IN_PROGRESS Handle = 0x8032000D + FWP_E_TXN_IN_PROGRESS Handle = 0x8032000E + FWP_E_TXN_ABORTED Handle = 0x8032000F + FWP_E_SESSION_ABORTED Handle = 0x80320010 + FWP_E_INCOMPATIBLE_TXN Handle = 0x80320011 + FWP_E_TIMEOUT Handle = 0x80320012 + FWP_E_NET_EVENTS_DISABLED Handle = 0x80320013 + FWP_E_INCOMPATIBLE_LAYER Handle = 0x80320014 + FWP_E_KM_CLIENTS_ONLY Handle = 0x80320015 + FWP_E_LIFETIME_MISMATCH Handle = 0x80320016 + FWP_E_BUILTIN_OBJECT Handle = 0x80320017 + FWP_E_TOO_MANY_CALLOUTS Handle = 0x80320018 + FWP_E_NOTIFICATION_DROPPED Handle = 0x80320019 + FWP_E_TRAFFIC_MISMATCH Handle = 0x8032001A + FWP_E_INCOMPATIBLE_SA_STATE Handle = 0x8032001B + FWP_E_NULL_POINTER Handle = 0x8032001C + FWP_E_INVALID_ENUMERATOR Handle = 0x8032001D + FWP_E_INVALID_FLAGS Handle = 0x8032001E + FWP_E_INVALID_NET_MASK Handle = 0x8032001F + FWP_E_INVALID_RANGE Handle = 0x80320020 + FWP_E_INVALID_INTERVAL Handle = 0x80320021 + FWP_E_ZERO_LENGTH_ARRAY Handle = 0x80320022 + FWP_E_NULL_DISPLAY_NAME Handle = 0x80320023 + FWP_E_INVALID_ACTION_TYPE Handle = 0x80320024 + FWP_E_INVALID_WEIGHT Handle = 0x80320025 + FWP_E_MATCH_TYPE_MISMATCH Handle = 0x80320026 + FWP_E_TYPE_MISMATCH Handle = 0x80320027 + FWP_E_OUT_OF_BOUNDS Handle = 0x80320028 + FWP_E_RESERVED Handle = 0x80320029 + FWP_E_DUPLICATE_CONDITION Handle = 0x8032002A + FWP_E_DUPLICATE_KEYMOD Handle = 0x8032002B + FWP_E_ACTION_INCOMPATIBLE_WITH_LAYER Handle = 0x8032002C + FWP_E_ACTION_INCOMPATIBLE_WITH_SUBLAYER Handle = 0x8032002D + FWP_E_CONTEXT_INCOMPATIBLE_WITH_LAYER Handle = 0x8032002E + FWP_E_CONTEXT_INCOMPATIBLE_WITH_CALLOUT Handle = 0x8032002F + FWP_E_INCOMPATIBLE_AUTH_METHOD Handle = 0x80320030 + FWP_E_INCOMPATIBLE_DH_GROUP Handle = 0x80320031 + FWP_E_EM_NOT_SUPPORTED Handle = 0x80320032 + FWP_E_NEVER_MATCH Handle = 0x80320033 + FWP_E_PROVIDER_CONTEXT_MISMATCH Handle = 0x80320034 + FWP_E_INVALID_PARAMETER Handle = 0x80320035 + FWP_E_TOO_MANY_SUBLAYERS Handle = 0x80320036 + FWP_E_CALLOUT_NOTIFICATION_FAILED Handle = 0x80320037 + FWP_E_INVALID_AUTH_TRANSFORM Handle = 0x80320038 + FWP_E_INVALID_CIPHER_TRANSFORM Handle = 0x80320039 + FWP_E_INCOMPATIBLE_CIPHER_TRANSFORM Handle = 0x8032003A + FWP_E_INVALID_TRANSFORM_COMBINATION Handle = 0x8032003B + FWP_E_DUPLICATE_AUTH_METHOD Handle = 0x8032003C + FWP_E_INVALID_TUNNEL_ENDPOINT Handle = 0x8032003D + FWP_E_L2_DRIVER_NOT_READY Handle = 0x8032003E + FWP_E_KEY_DICTATOR_ALREADY_REGISTERED Handle = 0x8032003F + FWP_E_KEY_DICTATION_INVALID_KEYING_MATERIAL Handle = 0x80320040 + FWP_E_CONNECTIONS_DISABLED Handle = 0x80320041 + FWP_E_INVALID_DNS_NAME Handle = 0x80320042 + FWP_E_STILL_ON Handle = 0x80320043 + FWP_E_IKEEXT_NOT_RUNNING Handle = 0x80320044 + FWP_E_DROP_NOICMP Handle = 0x80320104 + WS_S_ASYNC Handle = 0x003D0000 + WS_S_END Handle = 0x003D0001 + WS_E_INVALID_FORMAT Handle = 0x803D0000 + WS_E_OBJECT_FAULTED Handle = 0x803D0001 + WS_E_NUMERIC_OVERFLOW Handle = 0x803D0002 + WS_E_INVALID_OPERATION Handle = 0x803D0003 + WS_E_OPERATION_ABORTED Handle = 0x803D0004 + WS_E_ENDPOINT_ACCESS_DENIED Handle = 0x803D0005 + WS_E_OPERATION_TIMED_OUT Handle = 0x803D0006 + WS_E_OPERATION_ABANDONED Handle = 0x803D0007 + WS_E_QUOTA_EXCEEDED Handle = 0x803D0008 + WS_E_NO_TRANSLATION_AVAILABLE Handle = 0x803D0009 + WS_E_SECURITY_VERIFICATION_FAILURE Handle = 0x803D000A + WS_E_ADDRESS_IN_USE Handle = 0x803D000B + WS_E_ADDRESS_NOT_AVAILABLE Handle = 0x803D000C + WS_E_ENDPOINT_NOT_FOUND Handle = 0x803D000D + WS_E_ENDPOINT_NOT_AVAILABLE Handle = 0x803D000E + WS_E_ENDPOINT_FAILURE Handle = 0x803D000F + WS_E_ENDPOINT_UNREACHABLE Handle = 0x803D0010 + WS_E_ENDPOINT_ACTION_NOT_SUPPORTED Handle = 0x803D0011 + WS_E_ENDPOINT_TOO_BUSY Handle = 0x803D0012 + WS_E_ENDPOINT_FAULT_RECEIVED Handle = 0x803D0013 + WS_E_ENDPOINT_DISCONNECTED Handle = 0x803D0014 + WS_E_PROXY_FAILURE Handle = 0x803D0015 + WS_E_PROXY_ACCESS_DENIED Handle = 0x803D0016 + WS_E_NOT_SUPPORTED Handle = 0x803D0017 + WS_E_PROXY_REQUIRES_BASIC_AUTH Handle = 0x803D0018 + WS_E_PROXY_REQUIRES_DIGEST_AUTH Handle = 0x803D0019 + WS_E_PROXY_REQUIRES_NTLM_AUTH Handle = 0x803D001A + WS_E_PROXY_REQUIRES_NEGOTIATE_AUTH Handle = 0x803D001B + WS_E_SERVER_REQUIRES_BASIC_AUTH Handle = 0x803D001C + WS_E_SERVER_REQUIRES_DIGEST_AUTH Handle = 0x803D001D + WS_E_SERVER_REQUIRES_NTLM_AUTH Handle = 0x803D001E + WS_E_SERVER_REQUIRES_NEGOTIATE_AUTH Handle = 0x803D001F + WS_E_INVALID_ENDPOINT_URL Handle = 0x803D0020 + WS_E_OTHER Handle = 0x803D0021 + WS_E_SECURITY_TOKEN_EXPIRED Handle = 0x803D0022 + WS_E_SECURITY_SYSTEM_FAILURE Handle = 0x803D0023 + ERROR_NDIS_INTERFACE_CLOSING syscall.Errno = 0x80340002 + ERROR_NDIS_BAD_VERSION syscall.Errno = 0x80340004 + ERROR_NDIS_BAD_CHARACTERISTICS syscall.Errno = 0x80340005 + ERROR_NDIS_ADAPTER_NOT_FOUND syscall.Errno = 0x80340006 + ERROR_NDIS_OPEN_FAILED syscall.Errno = 0x80340007 + ERROR_NDIS_DEVICE_FAILED syscall.Errno = 0x80340008 + ERROR_NDIS_MULTICAST_FULL syscall.Errno = 0x80340009 + ERROR_NDIS_MULTICAST_EXISTS syscall.Errno = 0x8034000A + ERROR_NDIS_MULTICAST_NOT_FOUND syscall.Errno = 0x8034000B + ERROR_NDIS_REQUEST_ABORTED syscall.Errno = 0x8034000C + ERROR_NDIS_RESET_IN_PROGRESS syscall.Errno = 0x8034000D + ERROR_NDIS_NOT_SUPPORTED syscall.Errno = 0x803400BB + ERROR_NDIS_INVALID_PACKET syscall.Errno = 0x8034000F + ERROR_NDIS_ADAPTER_NOT_READY syscall.Errno = 0x80340011 + ERROR_NDIS_INVALID_LENGTH syscall.Errno = 0x80340014 + ERROR_NDIS_INVALID_DATA syscall.Errno = 0x80340015 + ERROR_NDIS_BUFFER_TOO_SHORT syscall.Errno = 0x80340016 + ERROR_NDIS_INVALID_OID syscall.Errno = 0x80340017 + ERROR_NDIS_ADAPTER_REMOVED syscall.Errno = 0x80340018 + ERROR_NDIS_UNSUPPORTED_MEDIA syscall.Errno = 0x80340019 + ERROR_NDIS_GROUP_ADDRESS_IN_USE syscall.Errno = 0x8034001A + ERROR_NDIS_FILE_NOT_FOUND syscall.Errno = 0x8034001B + ERROR_NDIS_ERROR_READING_FILE syscall.Errno = 0x8034001C + ERROR_NDIS_ALREADY_MAPPED syscall.Errno = 0x8034001D + ERROR_NDIS_RESOURCE_CONFLICT syscall.Errno = 0x8034001E + ERROR_NDIS_MEDIA_DISCONNECTED syscall.Errno = 0x8034001F + ERROR_NDIS_INVALID_ADDRESS syscall.Errno = 0x80340022 + ERROR_NDIS_INVALID_DEVICE_REQUEST syscall.Errno = 0x80340010 + ERROR_NDIS_PAUSED syscall.Errno = 0x8034002A + ERROR_NDIS_INTERFACE_NOT_FOUND syscall.Errno = 0x8034002B + ERROR_NDIS_UNSUPPORTED_REVISION syscall.Errno = 0x8034002C + ERROR_NDIS_INVALID_PORT syscall.Errno = 0x8034002D + ERROR_NDIS_INVALID_PORT_STATE syscall.Errno = 0x8034002E + ERROR_NDIS_LOW_POWER_STATE syscall.Errno = 0x8034002F + ERROR_NDIS_REINIT_REQUIRED syscall.Errno = 0x80340030 + ERROR_NDIS_NO_QUEUES syscall.Errno = 0x80340031 + ERROR_NDIS_DOT11_AUTO_CONFIG_ENABLED syscall.Errno = 0x80342000 + ERROR_NDIS_DOT11_MEDIA_IN_USE syscall.Errno = 0x80342001 + ERROR_NDIS_DOT11_POWER_STATE_INVALID syscall.Errno = 0x80342002 + ERROR_NDIS_PM_WOL_PATTERN_LIST_FULL syscall.Errno = 0x80342003 + ERROR_NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL syscall.Errno = 0x80342004 + ERROR_NDIS_DOT11_AP_CHANNEL_CURRENTLY_NOT_AVAILABLE syscall.Errno = 0x80342005 + ERROR_NDIS_DOT11_AP_BAND_CURRENTLY_NOT_AVAILABLE syscall.Errno = 0x80342006 + ERROR_NDIS_DOT11_AP_CHANNEL_NOT_ALLOWED syscall.Errno = 0x80342007 + ERROR_NDIS_DOT11_AP_BAND_NOT_ALLOWED syscall.Errno = 0x80342008 + ERROR_NDIS_INDICATION_REQUIRED syscall.Errno = 0x00340001 + ERROR_NDIS_OFFLOAD_POLICY syscall.Errno = 0xC034100F + ERROR_NDIS_OFFLOAD_CONNECTION_REJECTED syscall.Errno = 0xC0341012 + ERROR_NDIS_OFFLOAD_PATH_REJECTED syscall.Errno = 0xC0341013 + ERROR_HV_INVALID_HYPERCALL_CODE syscall.Errno = 0xC0350002 + ERROR_HV_INVALID_HYPERCALL_INPUT syscall.Errno = 0xC0350003 + ERROR_HV_INVALID_ALIGNMENT syscall.Errno = 0xC0350004 + ERROR_HV_INVALID_PARAMETER syscall.Errno = 0xC0350005 + ERROR_HV_ACCESS_DENIED syscall.Errno = 0xC0350006 + ERROR_HV_INVALID_PARTITION_STATE syscall.Errno = 0xC0350007 + ERROR_HV_OPERATION_DENIED syscall.Errno = 0xC0350008 + ERROR_HV_UNKNOWN_PROPERTY syscall.Errno = 0xC0350009 + ERROR_HV_PROPERTY_VALUE_OUT_OF_RANGE syscall.Errno = 0xC035000A + ERROR_HV_INSUFFICIENT_MEMORY syscall.Errno = 0xC035000B + ERROR_HV_PARTITION_TOO_DEEP syscall.Errno = 0xC035000C + ERROR_HV_INVALID_PARTITION_ID syscall.Errno = 0xC035000D + ERROR_HV_INVALID_VP_INDEX syscall.Errno = 0xC035000E + ERROR_HV_INVALID_PORT_ID syscall.Errno = 0xC0350011 + ERROR_HV_INVALID_CONNECTION_ID syscall.Errno = 0xC0350012 + ERROR_HV_INSUFFICIENT_BUFFERS syscall.Errno = 0xC0350013 + ERROR_HV_NOT_ACKNOWLEDGED syscall.Errno = 0xC0350014 + ERROR_HV_INVALID_VP_STATE syscall.Errno = 0xC0350015 + ERROR_HV_ACKNOWLEDGED syscall.Errno = 0xC0350016 + ERROR_HV_INVALID_SAVE_RESTORE_STATE syscall.Errno = 0xC0350017 + ERROR_HV_INVALID_SYNIC_STATE syscall.Errno = 0xC0350018 + ERROR_HV_OBJECT_IN_USE syscall.Errno = 0xC0350019 + ERROR_HV_INVALID_PROXIMITY_DOMAIN_INFO syscall.Errno = 0xC035001A + ERROR_HV_NO_DATA syscall.Errno = 0xC035001B + ERROR_HV_INACTIVE syscall.Errno = 0xC035001C + ERROR_HV_NO_RESOURCES syscall.Errno = 0xC035001D + ERROR_HV_FEATURE_UNAVAILABLE syscall.Errno = 0xC035001E + ERROR_HV_INSUFFICIENT_BUFFER syscall.Errno = 0xC0350033 + ERROR_HV_INSUFFICIENT_DEVICE_DOMAINS syscall.Errno = 0xC0350038 + ERROR_HV_CPUID_FEATURE_VALIDATION syscall.Errno = 0xC035003C + ERROR_HV_CPUID_XSAVE_FEATURE_VALIDATION syscall.Errno = 0xC035003D + ERROR_HV_PROCESSOR_STARTUP_TIMEOUT syscall.Errno = 0xC035003E + ERROR_HV_SMX_ENABLED syscall.Errno = 0xC035003F + ERROR_HV_INVALID_LP_INDEX syscall.Errno = 0xC0350041 + ERROR_HV_INVALID_REGISTER_VALUE syscall.Errno = 0xC0350050 + ERROR_HV_INVALID_VTL_STATE syscall.Errno = 0xC0350051 + ERROR_HV_NX_NOT_DETECTED syscall.Errno = 0xC0350055 + ERROR_HV_INVALID_DEVICE_ID syscall.Errno = 0xC0350057 + ERROR_HV_INVALID_DEVICE_STATE syscall.Errno = 0xC0350058 + ERROR_HV_PENDING_PAGE_REQUESTS syscall.Errno = 0x00350059 + ERROR_HV_PAGE_REQUEST_INVALID syscall.Errno = 0xC0350060 + ERROR_HV_INVALID_CPU_GROUP_ID syscall.Errno = 0xC035006F + ERROR_HV_INVALID_CPU_GROUP_STATE syscall.Errno = 0xC0350070 + ERROR_HV_OPERATION_FAILED syscall.Errno = 0xC0350071 + ERROR_HV_NOT_ALLOWED_WITH_NESTED_VIRT_ACTIVE syscall.Errno = 0xC0350072 + ERROR_HV_INSUFFICIENT_ROOT_MEMORY syscall.Errno = 0xC0350073 + ERROR_HV_NOT_PRESENT syscall.Errno = 0xC0351000 + ERROR_VID_DUPLICATE_HANDLER syscall.Errno = 0xC0370001 + ERROR_VID_TOO_MANY_HANDLERS syscall.Errno = 0xC0370002 + ERROR_VID_QUEUE_FULL syscall.Errno = 0xC0370003 + ERROR_VID_HANDLER_NOT_PRESENT syscall.Errno = 0xC0370004 + ERROR_VID_INVALID_OBJECT_NAME syscall.Errno = 0xC0370005 + ERROR_VID_PARTITION_NAME_TOO_LONG syscall.Errno = 0xC0370006 + ERROR_VID_MESSAGE_QUEUE_NAME_TOO_LONG syscall.Errno = 0xC0370007 + ERROR_VID_PARTITION_ALREADY_EXISTS syscall.Errno = 0xC0370008 + ERROR_VID_PARTITION_DOES_NOT_EXIST syscall.Errno = 0xC0370009 + ERROR_VID_PARTITION_NAME_NOT_FOUND syscall.Errno = 0xC037000A + ERROR_VID_MESSAGE_QUEUE_ALREADY_EXISTS syscall.Errno = 0xC037000B + ERROR_VID_EXCEEDED_MBP_ENTRY_MAP_LIMIT syscall.Errno = 0xC037000C + ERROR_VID_MB_STILL_REFERENCED syscall.Errno = 0xC037000D + ERROR_VID_CHILD_GPA_PAGE_SET_CORRUPTED syscall.Errno = 0xC037000E + ERROR_VID_INVALID_NUMA_SETTINGS syscall.Errno = 0xC037000F + ERROR_VID_INVALID_NUMA_NODE_INDEX syscall.Errno = 0xC0370010 + ERROR_VID_NOTIFICATION_QUEUE_ALREADY_ASSOCIATED syscall.Errno = 0xC0370011 + ERROR_VID_INVALID_MEMORY_BLOCK_HANDLE syscall.Errno = 0xC0370012 + ERROR_VID_PAGE_RANGE_OVERFLOW syscall.Errno = 0xC0370013 + ERROR_VID_INVALID_MESSAGE_QUEUE_HANDLE syscall.Errno = 0xC0370014 + ERROR_VID_INVALID_GPA_RANGE_HANDLE syscall.Errno = 0xC0370015 + ERROR_VID_NO_MEMORY_BLOCK_NOTIFICATION_QUEUE syscall.Errno = 0xC0370016 + ERROR_VID_MEMORY_BLOCK_LOCK_COUNT_EXCEEDED syscall.Errno = 0xC0370017 + ERROR_VID_INVALID_PPM_HANDLE syscall.Errno = 0xC0370018 + ERROR_VID_MBPS_ARE_LOCKED syscall.Errno = 0xC0370019 + ERROR_VID_MESSAGE_QUEUE_CLOSED syscall.Errno = 0xC037001A + ERROR_VID_VIRTUAL_PROCESSOR_LIMIT_EXCEEDED syscall.Errno = 0xC037001B + ERROR_VID_STOP_PENDING syscall.Errno = 0xC037001C + ERROR_VID_INVALID_PROCESSOR_STATE syscall.Errno = 0xC037001D + ERROR_VID_EXCEEDED_KM_CONTEXT_COUNT_LIMIT syscall.Errno = 0xC037001E + ERROR_VID_KM_INTERFACE_ALREADY_INITIALIZED syscall.Errno = 0xC037001F + ERROR_VID_MB_PROPERTY_ALREADY_SET_RESET syscall.Errno = 0xC0370020 + ERROR_VID_MMIO_RANGE_DESTROYED syscall.Errno = 0xC0370021 + ERROR_VID_INVALID_CHILD_GPA_PAGE_SET syscall.Errno = 0xC0370022 + ERROR_VID_RESERVE_PAGE_SET_IS_BEING_USED syscall.Errno = 0xC0370023 + ERROR_VID_RESERVE_PAGE_SET_TOO_SMALL syscall.Errno = 0xC0370024 + ERROR_VID_MBP_ALREADY_LOCKED_USING_RESERVED_PAGE syscall.Errno = 0xC0370025 + ERROR_VID_MBP_COUNT_EXCEEDED_LIMIT syscall.Errno = 0xC0370026 + ERROR_VID_SAVED_STATE_CORRUPT syscall.Errno = 0xC0370027 + ERROR_VID_SAVED_STATE_UNRECOGNIZED_ITEM syscall.Errno = 0xC0370028 + ERROR_VID_SAVED_STATE_INCOMPATIBLE syscall.Errno = 0xC0370029 + ERROR_VID_VTL_ACCESS_DENIED syscall.Errno = 0xC037002A + ERROR_VMCOMPUTE_TERMINATED_DURING_START syscall.Errno = 0xC0370100 + ERROR_VMCOMPUTE_IMAGE_MISMATCH syscall.Errno = 0xC0370101 + ERROR_VMCOMPUTE_HYPERV_NOT_INSTALLED syscall.Errno = 0xC0370102 + ERROR_VMCOMPUTE_OPERATION_PENDING syscall.Errno = 0xC0370103 + ERROR_VMCOMPUTE_TOO_MANY_NOTIFICATIONS syscall.Errno = 0xC0370104 + ERROR_VMCOMPUTE_INVALID_STATE syscall.Errno = 0xC0370105 + ERROR_VMCOMPUTE_UNEXPECTED_EXIT syscall.Errno = 0xC0370106 + ERROR_VMCOMPUTE_TERMINATED syscall.Errno = 0xC0370107 + ERROR_VMCOMPUTE_CONNECT_FAILED syscall.Errno = 0xC0370108 + ERROR_VMCOMPUTE_TIMEOUT syscall.Errno = 0xC0370109 + ERROR_VMCOMPUTE_CONNECTION_CLOSED syscall.Errno = 0xC037010A + ERROR_VMCOMPUTE_UNKNOWN_MESSAGE syscall.Errno = 0xC037010B + ERROR_VMCOMPUTE_UNSUPPORTED_PROTOCOL_VERSION syscall.Errno = 0xC037010C + ERROR_VMCOMPUTE_INVALID_JSON syscall.Errno = 0xC037010D + ERROR_VMCOMPUTE_SYSTEM_NOT_FOUND syscall.Errno = 0xC037010E + ERROR_VMCOMPUTE_SYSTEM_ALREADY_EXISTS syscall.Errno = 0xC037010F + ERROR_VMCOMPUTE_SYSTEM_ALREADY_STOPPED syscall.Errno = 0xC0370110 + ERROR_VMCOMPUTE_PROTOCOL_ERROR syscall.Errno = 0xC0370111 + ERROR_VMCOMPUTE_INVALID_LAYER syscall.Errno = 0xC0370112 + ERROR_VMCOMPUTE_WINDOWS_INSIDER_REQUIRED syscall.Errno = 0xC0370113 + HCS_E_TERMINATED_DURING_START Handle = 0x80370100 + HCS_E_IMAGE_MISMATCH Handle = 0x80370101 + HCS_E_HYPERV_NOT_INSTALLED Handle = 0x80370102 + HCS_E_INVALID_STATE Handle = 0x80370105 + HCS_E_UNEXPECTED_EXIT Handle = 0x80370106 + HCS_E_TERMINATED Handle = 0x80370107 + HCS_E_CONNECT_FAILED Handle = 0x80370108 + HCS_E_CONNECTION_TIMEOUT Handle = 0x80370109 + HCS_E_CONNECTION_CLOSED Handle = 0x8037010A + HCS_E_UNKNOWN_MESSAGE Handle = 0x8037010B + HCS_E_UNSUPPORTED_PROTOCOL_VERSION Handle = 0x8037010C + HCS_E_INVALID_JSON Handle = 0x8037010D + HCS_E_SYSTEM_NOT_FOUND Handle = 0x8037010E + HCS_E_SYSTEM_ALREADY_EXISTS Handle = 0x8037010F + HCS_E_SYSTEM_ALREADY_STOPPED Handle = 0x80370110 + HCS_E_PROTOCOL_ERROR Handle = 0x80370111 + HCS_E_INVALID_LAYER Handle = 0x80370112 + HCS_E_WINDOWS_INSIDER_REQUIRED Handle = 0x80370113 + HCS_E_SERVICE_NOT_AVAILABLE Handle = 0x80370114 + HCS_E_OPERATION_NOT_STARTED Handle = 0x80370115 + HCS_E_OPERATION_ALREADY_STARTED Handle = 0x80370116 + HCS_E_OPERATION_PENDING Handle = 0x80370117 + HCS_E_OPERATION_TIMEOUT Handle = 0x80370118 + HCS_E_OPERATION_SYSTEM_CALLBACK_ALREADY_SET Handle = 0x80370119 + HCS_E_OPERATION_RESULT_ALLOCATION_FAILED Handle = 0x8037011A + HCS_E_ACCESS_DENIED Handle = 0x8037011B + HCS_E_GUEST_CRITICAL_ERROR Handle = 0x8037011C + ERROR_VNET_VIRTUAL_SWITCH_NAME_NOT_FOUND syscall.Errno = 0xC0370200 + ERROR_VID_REMOTE_NODE_PARENT_GPA_PAGES_USED syscall.Errno = 0x80370001 + WHV_E_UNKNOWN_CAPABILITY Handle = 0x80370300 + WHV_E_INSUFFICIENT_BUFFER Handle = 0x80370301 + WHV_E_UNKNOWN_PROPERTY Handle = 0x80370302 + WHV_E_UNSUPPORTED_HYPERVISOR_CONFIG Handle = 0x80370303 + WHV_E_INVALID_PARTITION_CONFIG Handle = 0x80370304 + WHV_E_GPA_RANGE_NOT_FOUND Handle = 0x80370305 + WHV_E_VP_ALREADY_EXISTS Handle = 0x80370306 + WHV_E_VP_DOES_NOT_EXIST Handle = 0x80370307 + WHV_E_INVALID_VP_STATE Handle = 0x80370308 + WHV_E_INVALID_VP_REGISTER_NAME Handle = 0x80370309 + ERROR_VSMB_SAVED_STATE_FILE_NOT_FOUND syscall.Errno = 0xC0370400 + ERROR_VSMB_SAVED_STATE_CORRUPT syscall.Errno = 0xC0370401 + ERROR_VOLMGR_INCOMPLETE_REGENERATION syscall.Errno = 0x80380001 + ERROR_VOLMGR_INCOMPLETE_DISK_MIGRATION syscall.Errno = 0x80380002 + ERROR_VOLMGR_DATABASE_FULL syscall.Errno = 0xC0380001 + ERROR_VOLMGR_DISK_CONFIGURATION_CORRUPTED syscall.Errno = 0xC0380002 + ERROR_VOLMGR_DISK_CONFIGURATION_NOT_IN_SYNC syscall.Errno = 0xC0380003 + ERROR_VOLMGR_PACK_CONFIG_UPDATE_FAILED syscall.Errno = 0xC0380004 + ERROR_VOLMGR_DISK_CONTAINS_NON_SIMPLE_VOLUME syscall.Errno = 0xC0380005 + ERROR_VOLMGR_DISK_DUPLICATE syscall.Errno = 0xC0380006 + ERROR_VOLMGR_DISK_DYNAMIC syscall.Errno = 0xC0380007 + ERROR_VOLMGR_DISK_ID_INVALID syscall.Errno = 0xC0380008 + ERROR_VOLMGR_DISK_INVALID syscall.Errno = 0xC0380009 + ERROR_VOLMGR_DISK_LAST_VOTER syscall.Errno = 0xC038000A + ERROR_VOLMGR_DISK_LAYOUT_INVALID syscall.Errno = 0xC038000B + ERROR_VOLMGR_DISK_LAYOUT_NON_BASIC_BETWEEN_BASIC_PARTITIONS syscall.Errno = 0xC038000C + ERROR_VOLMGR_DISK_LAYOUT_NOT_CYLINDER_ALIGNED syscall.Errno = 0xC038000D + ERROR_VOLMGR_DISK_LAYOUT_PARTITIONS_TOO_SMALL syscall.Errno = 0xC038000E + ERROR_VOLMGR_DISK_LAYOUT_PRIMARY_BETWEEN_LOGICAL_PARTITIONS syscall.Errno = 0xC038000F + ERROR_VOLMGR_DISK_LAYOUT_TOO_MANY_PARTITIONS syscall.Errno = 0xC0380010 + ERROR_VOLMGR_DISK_MISSING syscall.Errno = 0xC0380011 + ERROR_VOLMGR_DISK_NOT_EMPTY syscall.Errno = 0xC0380012 + ERROR_VOLMGR_DISK_NOT_ENOUGH_SPACE syscall.Errno = 0xC0380013 + ERROR_VOLMGR_DISK_REVECTORING_FAILED syscall.Errno = 0xC0380014 + ERROR_VOLMGR_DISK_SECTOR_SIZE_INVALID syscall.Errno = 0xC0380015 + ERROR_VOLMGR_DISK_SET_NOT_CONTAINED syscall.Errno = 0xC0380016 + ERROR_VOLMGR_DISK_USED_BY_MULTIPLE_MEMBERS syscall.Errno = 0xC0380017 + ERROR_VOLMGR_DISK_USED_BY_MULTIPLE_PLEXES syscall.Errno = 0xC0380018 + ERROR_VOLMGR_DYNAMIC_DISK_NOT_SUPPORTED syscall.Errno = 0xC0380019 + ERROR_VOLMGR_EXTENT_ALREADY_USED syscall.Errno = 0xC038001A + ERROR_VOLMGR_EXTENT_NOT_CONTIGUOUS syscall.Errno = 0xC038001B + ERROR_VOLMGR_EXTENT_NOT_IN_PUBLIC_REGION syscall.Errno = 0xC038001C + ERROR_VOLMGR_EXTENT_NOT_SECTOR_ALIGNED syscall.Errno = 0xC038001D + ERROR_VOLMGR_EXTENT_OVERLAPS_EBR_PARTITION syscall.Errno = 0xC038001E + ERROR_VOLMGR_EXTENT_VOLUME_LENGTHS_DO_NOT_MATCH syscall.Errno = 0xC038001F + ERROR_VOLMGR_FAULT_TOLERANT_NOT_SUPPORTED syscall.Errno = 0xC0380020 + ERROR_VOLMGR_INTERLEAVE_LENGTH_INVALID syscall.Errno = 0xC0380021 + ERROR_VOLMGR_MAXIMUM_REGISTERED_USERS syscall.Errno = 0xC0380022 + ERROR_VOLMGR_MEMBER_IN_SYNC syscall.Errno = 0xC0380023 + ERROR_VOLMGR_MEMBER_INDEX_DUPLICATE syscall.Errno = 0xC0380024 + ERROR_VOLMGR_MEMBER_INDEX_INVALID syscall.Errno = 0xC0380025 + ERROR_VOLMGR_MEMBER_MISSING syscall.Errno = 0xC0380026 + ERROR_VOLMGR_MEMBER_NOT_DETACHED syscall.Errno = 0xC0380027 + ERROR_VOLMGR_MEMBER_REGENERATING syscall.Errno = 0xC0380028 + ERROR_VOLMGR_ALL_DISKS_FAILED syscall.Errno = 0xC0380029 + ERROR_VOLMGR_NO_REGISTERED_USERS syscall.Errno = 0xC038002A + ERROR_VOLMGR_NO_SUCH_USER syscall.Errno = 0xC038002B + ERROR_VOLMGR_NOTIFICATION_RESET syscall.Errno = 0xC038002C + ERROR_VOLMGR_NUMBER_OF_MEMBERS_INVALID syscall.Errno = 0xC038002D + ERROR_VOLMGR_NUMBER_OF_PLEXES_INVALID syscall.Errno = 0xC038002E + ERROR_VOLMGR_PACK_DUPLICATE syscall.Errno = 0xC038002F + ERROR_VOLMGR_PACK_ID_INVALID syscall.Errno = 0xC0380030 + ERROR_VOLMGR_PACK_INVALID syscall.Errno = 0xC0380031 + ERROR_VOLMGR_PACK_NAME_INVALID syscall.Errno = 0xC0380032 + ERROR_VOLMGR_PACK_OFFLINE syscall.Errno = 0xC0380033 + ERROR_VOLMGR_PACK_HAS_QUORUM syscall.Errno = 0xC0380034 + ERROR_VOLMGR_PACK_WITHOUT_QUORUM syscall.Errno = 0xC0380035 + ERROR_VOLMGR_PARTITION_STYLE_INVALID syscall.Errno = 0xC0380036 + ERROR_VOLMGR_PARTITION_UPDATE_FAILED syscall.Errno = 0xC0380037 + ERROR_VOLMGR_PLEX_IN_SYNC syscall.Errno = 0xC0380038 + ERROR_VOLMGR_PLEX_INDEX_DUPLICATE syscall.Errno = 0xC0380039 + ERROR_VOLMGR_PLEX_INDEX_INVALID syscall.Errno = 0xC038003A + ERROR_VOLMGR_PLEX_LAST_ACTIVE syscall.Errno = 0xC038003B + ERROR_VOLMGR_PLEX_MISSING syscall.Errno = 0xC038003C + ERROR_VOLMGR_PLEX_REGENERATING syscall.Errno = 0xC038003D + ERROR_VOLMGR_PLEX_TYPE_INVALID syscall.Errno = 0xC038003E + ERROR_VOLMGR_PLEX_NOT_RAID5 syscall.Errno = 0xC038003F + ERROR_VOLMGR_PLEX_NOT_SIMPLE syscall.Errno = 0xC0380040 + ERROR_VOLMGR_STRUCTURE_SIZE_INVALID syscall.Errno = 0xC0380041 + ERROR_VOLMGR_TOO_MANY_NOTIFICATION_REQUESTS syscall.Errno = 0xC0380042 + ERROR_VOLMGR_TRANSACTION_IN_PROGRESS syscall.Errno = 0xC0380043 + ERROR_VOLMGR_UNEXPECTED_DISK_LAYOUT_CHANGE syscall.Errno = 0xC0380044 + ERROR_VOLMGR_VOLUME_CONTAINS_MISSING_DISK syscall.Errno = 0xC0380045 + ERROR_VOLMGR_VOLUME_ID_INVALID syscall.Errno = 0xC0380046 + ERROR_VOLMGR_VOLUME_LENGTH_INVALID syscall.Errno = 0xC0380047 + ERROR_VOLMGR_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE syscall.Errno = 0xC0380048 + ERROR_VOLMGR_VOLUME_NOT_MIRRORED syscall.Errno = 0xC0380049 + ERROR_VOLMGR_VOLUME_NOT_RETAINED syscall.Errno = 0xC038004A + ERROR_VOLMGR_VOLUME_OFFLINE syscall.Errno = 0xC038004B + ERROR_VOLMGR_VOLUME_RETAINED syscall.Errno = 0xC038004C + ERROR_VOLMGR_NUMBER_OF_EXTENTS_INVALID syscall.Errno = 0xC038004D + ERROR_VOLMGR_DIFFERENT_SECTOR_SIZE syscall.Errno = 0xC038004E + ERROR_VOLMGR_BAD_BOOT_DISK syscall.Errno = 0xC038004F + ERROR_VOLMGR_PACK_CONFIG_OFFLINE syscall.Errno = 0xC0380050 + ERROR_VOLMGR_PACK_CONFIG_ONLINE syscall.Errno = 0xC0380051 + ERROR_VOLMGR_NOT_PRIMARY_PACK syscall.Errno = 0xC0380052 + ERROR_VOLMGR_PACK_LOG_UPDATE_FAILED syscall.Errno = 0xC0380053 + ERROR_VOLMGR_NUMBER_OF_DISKS_IN_PLEX_INVALID syscall.Errno = 0xC0380054 + ERROR_VOLMGR_NUMBER_OF_DISKS_IN_MEMBER_INVALID syscall.Errno = 0xC0380055 + ERROR_VOLMGR_VOLUME_MIRRORED syscall.Errno = 0xC0380056 + ERROR_VOLMGR_PLEX_NOT_SIMPLE_SPANNED syscall.Errno = 0xC0380057 + ERROR_VOLMGR_NO_VALID_LOG_COPIES syscall.Errno = 0xC0380058 + ERROR_VOLMGR_PRIMARY_PACK_PRESENT syscall.Errno = 0xC0380059 + ERROR_VOLMGR_NUMBER_OF_DISKS_INVALID syscall.Errno = 0xC038005A + ERROR_VOLMGR_MIRROR_NOT_SUPPORTED syscall.Errno = 0xC038005B + ERROR_VOLMGR_RAID5_NOT_SUPPORTED syscall.Errno = 0xC038005C + ERROR_BCD_NOT_ALL_ENTRIES_IMPORTED syscall.Errno = 0x80390001 + ERROR_BCD_TOO_MANY_ELEMENTS syscall.Errno = 0xC0390002 + ERROR_BCD_NOT_ALL_ENTRIES_SYNCHRONIZED syscall.Errno = 0x80390003 + ERROR_VHD_DRIVE_FOOTER_MISSING syscall.Errno = 0xC03A0001 + ERROR_VHD_DRIVE_FOOTER_CHECKSUM_MISMATCH syscall.Errno = 0xC03A0002 + ERROR_VHD_DRIVE_FOOTER_CORRUPT syscall.Errno = 0xC03A0003 + ERROR_VHD_FORMAT_UNKNOWN syscall.Errno = 0xC03A0004 + ERROR_VHD_FORMAT_UNSUPPORTED_VERSION syscall.Errno = 0xC03A0005 + ERROR_VHD_SPARSE_HEADER_CHECKSUM_MISMATCH syscall.Errno = 0xC03A0006 + ERROR_VHD_SPARSE_HEADER_UNSUPPORTED_VERSION syscall.Errno = 0xC03A0007 + ERROR_VHD_SPARSE_HEADER_CORRUPT syscall.Errno = 0xC03A0008 + ERROR_VHD_BLOCK_ALLOCATION_FAILURE syscall.Errno = 0xC03A0009 + ERROR_VHD_BLOCK_ALLOCATION_TABLE_CORRUPT syscall.Errno = 0xC03A000A + ERROR_VHD_INVALID_BLOCK_SIZE syscall.Errno = 0xC03A000B + ERROR_VHD_BITMAP_MISMATCH syscall.Errno = 0xC03A000C + ERROR_VHD_PARENT_VHD_NOT_FOUND syscall.Errno = 0xC03A000D + ERROR_VHD_CHILD_PARENT_ID_MISMATCH syscall.Errno = 0xC03A000E + ERROR_VHD_CHILD_PARENT_TIMESTAMP_MISMATCH syscall.Errno = 0xC03A000F + ERROR_VHD_METADATA_READ_FAILURE syscall.Errno = 0xC03A0010 + ERROR_VHD_METADATA_WRITE_FAILURE syscall.Errno = 0xC03A0011 + ERROR_VHD_INVALID_SIZE syscall.Errno = 0xC03A0012 + ERROR_VHD_INVALID_FILE_SIZE syscall.Errno = 0xC03A0013 + ERROR_VIRTDISK_PROVIDER_NOT_FOUND syscall.Errno = 0xC03A0014 + ERROR_VIRTDISK_NOT_VIRTUAL_DISK syscall.Errno = 0xC03A0015 + ERROR_VHD_PARENT_VHD_ACCESS_DENIED syscall.Errno = 0xC03A0016 + ERROR_VHD_CHILD_PARENT_SIZE_MISMATCH syscall.Errno = 0xC03A0017 + ERROR_VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED syscall.Errno = 0xC03A0018 + ERROR_VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT syscall.Errno = 0xC03A0019 + ERROR_VIRTUAL_DISK_LIMITATION syscall.Errno = 0xC03A001A + ERROR_VHD_INVALID_TYPE syscall.Errno = 0xC03A001B + ERROR_VHD_INVALID_STATE syscall.Errno = 0xC03A001C + ERROR_VIRTDISK_UNSUPPORTED_DISK_SECTOR_SIZE syscall.Errno = 0xC03A001D + ERROR_VIRTDISK_DISK_ALREADY_OWNED syscall.Errno = 0xC03A001E + ERROR_VIRTDISK_DISK_ONLINE_AND_WRITABLE syscall.Errno = 0xC03A001F + ERROR_CTLOG_TRACKING_NOT_INITIALIZED syscall.Errno = 0xC03A0020 + ERROR_CTLOG_LOGFILE_SIZE_EXCEEDED_MAXSIZE syscall.Errno = 0xC03A0021 + ERROR_CTLOG_VHD_CHANGED_OFFLINE syscall.Errno = 0xC03A0022 + ERROR_CTLOG_INVALID_TRACKING_STATE syscall.Errno = 0xC03A0023 + ERROR_CTLOG_INCONSISTENT_TRACKING_FILE syscall.Errno = 0xC03A0024 + ERROR_VHD_RESIZE_WOULD_TRUNCATE_DATA syscall.Errno = 0xC03A0025 + ERROR_VHD_COULD_NOT_COMPUTE_MINIMUM_VIRTUAL_SIZE syscall.Errno = 0xC03A0026 + ERROR_VHD_ALREADY_AT_OR_BELOW_MINIMUM_VIRTUAL_SIZE syscall.Errno = 0xC03A0027 + ERROR_VHD_METADATA_FULL syscall.Errno = 0xC03A0028 + ERROR_VHD_INVALID_CHANGE_TRACKING_ID syscall.Errno = 0xC03A0029 + ERROR_VHD_CHANGE_TRACKING_DISABLED syscall.Errno = 0xC03A002A + ERROR_VHD_MISSING_CHANGE_TRACKING_INFORMATION syscall.Errno = 0xC03A0030 + ERROR_QUERY_STORAGE_ERROR syscall.Errno = 0x803A0001 + HCN_E_NETWORK_NOT_FOUND Handle = 0x803B0001 + HCN_E_ENDPOINT_NOT_FOUND Handle = 0x803B0002 + HCN_E_LAYER_NOT_FOUND Handle = 0x803B0003 + HCN_E_SWITCH_NOT_FOUND Handle = 0x803B0004 + HCN_E_SUBNET_NOT_FOUND Handle = 0x803B0005 + HCN_E_ADAPTER_NOT_FOUND Handle = 0x803B0006 + HCN_E_PORT_NOT_FOUND Handle = 0x803B0007 + HCN_E_POLICY_NOT_FOUND Handle = 0x803B0008 + HCN_E_VFP_PORTSETTING_NOT_FOUND Handle = 0x803B0009 + HCN_E_INVALID_NETWORK Handle = 0x803B000A + HCN_E_INVALID_NETWORK_TYPE Handle = 0x803B000B + HCN_E_INVALID_ENDPOINT Handle = 0x803B000C + HCN_E_INVALID_POLICY Handle = 0x803B000D + HCN_E_INVALID_POLICY_TYPE Handle = 0x803B000E + HCN_E_INVALID_REMOTE_ENDPOINT_OPERATION Handle = 0x803B000F + HCN_E_NETWORK_ALREADY_EXISTS Handle = 0x803B0010 + HCN_E_LAYER_ALREADY_EXISTS Handle = 0x803B0011 + HCN_E_POLICY_ALREADY_EXISTS Handle = 0x803B0012 + HCN_E_PORT_ALREADY_EXISTS Handle = 0x803B0013 + HCN_E_ENDPOINT_ALREADY_ATTACHED Handle = 0x803B0014 + HCN_E_REQUEST_UNSUPPORTED Handle = 0x803B0015 + HCN_E_MAPPING_NOT_SUPPORTED Handle = 0x803B0016 + HCN_E_DEGRADED_OPERATION Handle = 0x803B0017 + HCN_E_SHARED_SWITCH_MODIFICATION Handle = 0x803B0018 + HCN_E_GUID_CONVERSION_FAILURE Handle = 0x803B0019 + HCN_E_REGKEY_FAILURE Handle = 0x803B001A + HCN_E_INVALID_JSON Handle = 0x803B001B + HCN_E_INVALID_JSON_REFERENCE Handle = 0x803B001C + HCN_E_ENDPOINT_SHARING_DISABLED Handle = 0x803B001D + HCN_E_INVALID_IP Handle = 0x803B001E + HCN_E_SWITCH_EXTENSION_NOT_FOUND Handle = 0x803B001F + HCN_E_MANAGER_STOPPED Handle = 0x803B0020 + GCN_E_MODULE_NOT_FOUND Handle = 0x803B0021 + GCN_E_NO_REQUEST_HANDLERS Handle = 0x803B0022 + GCN_E_REQUEST_UNSUPPORTED Handle = 0x803B0023 + GCN_E_RUNTIMEKEYS_FAILED Handle = 0x803B0024 + GCN_E_NETADAPTER_TIMEOUT Handle = 0x803B0025 + GCN_E_NETADAPTER_NOT_FOUND Handle = 0x803B0026 + GCN_E_NETCOMPARTMENT_NOT_FOUND Handle = 0x803B0027 + GCN_E_NETINTERFACE_NOT_FOUND Handle = 0x803B0028 + GCN_E_DEFAULTNAMESPACE_EXISTS Handle = 0x803B0029 + HCN_E_ICS_DISABLED Handle = 0x803B002A + HCN_E_ENDPOINT_NAMESPACE_ALREADY_EXISTS Handle = 0x803B002B + HCN_E_ENTITY_HAS_REFERENCES Handle = 0x803B002C + HCN_E_INVALID_INTERNAL_PORT Handle = 0x803B002D + HCN_E_NAMESPACE_ATTACH_FAILED Handle = 0x803B002E + HCN_E_ADDR_INVALID_OR_RESERVED Handle = 0x803B002F + SDIAG_E_CANCELLED syscall.Errno = 0x803C0100 + SDIAG_E_SCRIPT syscall.Errno = 0x803C0101 + SDIAG_E_POWERSHELL syscall.Errno = 0x803C0102 + SDIAG_E_MANAGEDHOST syscall.Errno = 0x803C0103 + SDIAG_E_NOVERIFIER syscall.Errno = 0x803C0104 + SDIAG_S_CANNOTRUN syscall.Errno = 0x003C0105 + SDIAG_E_DISABLED syscall.Errno = 0x803C0106 + SDIAG_E_TRUST syscall.Errno = 0x803C0107 + SDIAG_E_CANNOTRUN syscall.Errno = 0x803C0108 + SDIAG_E_VERSION syscall.Errno = 0x803C0109 + SDIAG_E_RESOURCE syscall.Errno = 0x803C010A + SDIAG_E_ROOTCAUSE syscall.Errno = 0x803C010B + WPN_E_CHANNEL_CLOSED Handle = 0x803E0100 + WPN_E_CHANNEL_REQUEST_NOT_COMPLETE Handle = 0x803E0101 + WPN_E_INVALID_APP Handle = 0x803E0102 + WPN_E_OUTSTANDING_CHANNEL_REQUEST Handle = 0x803E0103 + WPN_E_DUPLICATE_CHANNEL Handle = 0x803E0104 + WPN_E_PLATFORM_UNAVAILABLE Handle = 0x803E0105 + WPN_E_NOTIFICATION_POSTED Handle = 0x803E0106 + WPN_E_NOTIFICATION_HIDDEN Handle = 0x803E0107 + WPN_E_NOTIFICATION_NOT_POSTED Handle = 0x803E0108 + WPN_E_CLOUD_DISABLED Handle = 0x803E0109 + WPN_E_CLOUD_INCAPABLE Handle = 0x803E0110 + WPN_E_CLOUD_AUTH_UNAVAILABLE Handle = 0x803E011A + WPN_E_CLOUD_SERVICE_UNAVAILABLE Handle = 0x803E011B + WPN_E_FAILED_LOCK_SCREEN_UPDATE_INTIALIZATION Handle = 0x803E011C + WPN_E_NOTIFICATION_DISABLED Handle = 0x803E0111 + WPN_E_NOTIFICATION_INCAPABLE Handle = 0x803E0112 + WPN_E_INTERNET_INCAPABLE Handle = 0x803E0113 + WPN_E_NOTIFICATION_TYPE_DISABLED Handle = 0x803E0114 + WPN_E_NOTIFICATION_SIZE Handle = 0x803E0115 + WPN_E_TAG_SIZE Handle = 0x803E0116 + WPN_E_ACCESS_DENIED Handle = 0x803E0117 + WPN_E_DUPLICATE_REGISTRATION Handle = 0x803E0118 + WPN_E_PUSH_NOTIFICATION_INCAPABLE Handle = 0x803E0119 + WPN_E_DEV_ID_SIZE Handle = 0x803E0120 + WPN_E_TAG_ALPHANUMERIC Handle = 0x803E012A + WPN_E_INVALID_HTTP_STATUS_CODE Handle = 0x803E012B + WPN_E_OUT_OF_SESSION Handle = 0x803E0200 + WPN_E_POWER_SAVE Handle = 0x803E0201 + WPN_E_IMAGE_NOT_FOUND_IN_CACHE Handle = 0x803E0202 + WPN_E_ALL_URL_NOT_COMPLETED Handle = 0x803E0203 + WPN_E_INVALID_CLOUD_IMAGE Handle = 0x803E0204 + WPN_E_NOTIFICATION_ID_MATCHED Handle = 0x803E0205 + WPN_E_CALLBACK_ALREADY_REGISTERED Handle = 0x803E0206 + WPN_E_TOAST_NOTIFICATION_DROPPED Handle = 0x803E0207 + WPN_E_STORAGE_LOCKED Handle = 0x803E0208 + WPN_E_GROUP_SIZE Handle = 0x803E0209 + WPN_E_GROUP_ALPHANUMERIC Handle = 0x803E020A + WPN_E_CLOUD_DISABLED_FOR_APP Handle = 0x803E020B + E_MBN_CONTEXT_NOT_ACTIVATED Handle = 0x80548201 + E_MBN_BAD_SIM Handle = 0x80548202 + E_MBN_DATA_CLASS_NOT_AVAILABLE Handle = 0x80548203 + E_MBN_INVALID_ACCESS_STRING Handle = 0x80548204 + E_MBN_MAX_ACTIVATED_CONTEXTS Handle = 0x80548205 + E_MBN_PACKET_SVC_DETACHED Handle = 0x80548206 + E_MBN_PROVIDER_NOT_VISIBLE Handle = 0x80548207 + E_MBN_RADIO_POWER_OFF Handle = 0x80548208 + E_MBN_SERVICE_NOT_ACTIVATED Handle = 0x80548209 + E_MBN_SIM_NOT_INSERTED Handle = 0x8054820A + E_MBN_VOICE_CALL_IN_PROGRESS Handle = 0x8054820B + E_MBN_INVALID_CACHE Handle = 0x8054820C + E_MBN_NOT_REGISTERED Handle = 0x8054820D + E_MBN_PROVIDERS_NOT_FOUND Handle = 0x8054820E + E_MBN_PIN_NOT_SUPPORTED Handle = 0x8054820F + E_MBN_PIN_REQUIRED Handle = 0x80548210 + E_MBN_PIN_DISABLED Handle = 0x80548211 + E_MBN_FAILURE Handle = 0x80548212 + E_MBN_INVALID_PROFILE Handle = 0x80548218 + E_MBN_DEFAULT_PROFILE_EXIST Handle = 0x80548219 + E_MBN_SMS_ENCODING_NOT_SUPPORTED Handle = 0x80548220 + E_MBN_SMS_FILTER_NOT_SUPPORTED Handle = 0x80548221 + E_MBN_SMS_INVALID_MEMORY_INDEX Handle = 0x80548222 + E_MBN_SMS_LANG_NOT_SUPPORTED Handle = 0x80548223 + E_MBN_SMS_MEMORY_FAILURE Handle = 0x80548224 + E_MBN_SMS_NETWORK_TIMEOUT Handle = 0x80548225 + E_MBN_SMS_UNKNOWN_SMSC_ADDRESS Handle = 0x80548226 + E_MBN_SMS_FORMAT_NOT_SUPPORTED Handle = 0x80548227 + E_MBN_SMS_OPERATION_NOT_ALLOWED Handle = 0x80548228 + E_MBN_SMS_MEMORY_FULL Handle = 0x80548229 + PEER_E_IPV6_NOT_INSTALLED Handle = 0x80630001 + PEER_E_NOT_INITIALIZED Handle = 0x80630002 + PEER_E_CANNOT_START_SERVICE Handle = 0x80630003 + PEER_E_NOT_LICENSED Handle = 0x80630004 + PEER_E_INVALID_GRAPH Handle = 0x80630010 + PEER_E_DBNAME_CHANGED Handle = 0x80630011 + PEER_E_DUPLICATE_GRAPH Handle = 0x80630012 + PEER_E_GRAPH_NOT_READY Handle = 0x80630013 + PEER_E_GRAPH_SHUTTING_DOWN Handle = 0x80630014 + PEER_E_GRAPH_IN_USE Handle = 0x80630015 + PEER_E_INVALID_DATABASE Handle = 0x80630016 + PEER_E_TOO_MANY_ATTRIBUTES Handle = 0x80630017 + PEER_E_CONNECTION_NOT_FOUND Handle = 0x80630103 + PEER_E_CONNECT_SELF Handle = 0x80630106 + PEER_E_ALREADY_LISTENING Handle = 0x80630107 + PEER_E_NODE_NOT_FOUND Handle = 0x80630108 + PEER_E_CONNECTION_FAILED Handle = 0x80630109 + PEER_E_CONNECTION_NOT_AUTHENTICATED Handle = 0x8063010A + PEER_E_CONNECTION_REFUSED Handle = 0x8063010B + PEER_E_CLASSIFIER_TOO_LONG Handle = 0x80630201 + PEER_E_TOO_MANY_IDENTITIES Handle = 0x80630202 + PEER_E_NO_KEY_ACCESS Handle = 0x80630203 + PEER_E_GROUPS_EXIST Handle = 0x80630204 + PEER_E_RECORD_NOT_FOUND Handle = 0x80630301 + PEER_E_DATABASE_ACCESSDENIED Handle = 0x80630302 + PEER_E_DBINITIALIZATION_FAILED Handle = 0x80630303 + PEER_E_MAX_RECORD_SIZE_EXCEEDED Handle = 0x80630304 + PEER_E_DATABASE_ALREADY_PRESENT Handle = 0x80630305 + PEER_E_DATABASE_NOT_PRESENT Handle = 0x80630306 + PEER_E_IDENTITY_NOT_FOUND Handle = 0x80630401 + PEER_E_EVENT_HANDLE_NOT_FOUND Handle = 0x80630501 + PEER_E_INVALID_SEARCH Handle = 0x80630601 + PEER_E_INVALID_ATTRIBUTES Handle = 0x80630602 + PEER_E_INVITATION_NOT_TRUSTED Handle = 0x80630701 + PEER_E_CHAIN_TOO_LONG Handle = 0x80630703 + PEER_E_INVALID_TIME_PERIOD Handle = 0x80630705 + PEER_E_CIRCULAR_CHAIN_DETECTED Handle = 0x80630706 + PEER_E_CERT_STORE_CORRUPTED Handle = 0x80630801 + PEER_E_NO_CLOUD Handle = 0x80631001 + PEER_E_CLOUD_NAME_AMBIGUOUS Handle = 0x80631005 + PEER_E_INVALID_RECORD Handle = 0x80632010 + PEER_E_NOT_AUTHORIZED Handle = 0x80632020 + PEER_E_PASSWORD_DOES_NOT_MEET_POLICY Handle = 0x80632021 + PEER_E_DEFERRED_VALIDATION Handle = 0x80632030 + PEER_E_INVALID_GROUP_PROPERTIES Handle = 0x80632040 + PEER_E_INVALID_PEER_NAME Handle = 0x80632050 + PEER_E_INVALID_CLASSIFIER Handle = 0x80632060 + PEER_E_INVALID_FRIENDLY_NAME Handle = 0x80632070 + PEER_E_INVALID_ROLE_PROPERTY Handle = 0x80632071 + PEER_E_INVALID_CLASSIFIER_PROPERTY Handle = 0x80632072 + PEER_E_INVALID_RECORD_EXPIRATION Handle = 0x80632080 + PEER_E_INVALID_CREDENTIAL_INFO Handle = 0x80632081 + PEER_E_INVALID_CREDENTIAL Handle = 0x80632082 + PEER_E_INVALID_RECORD_SIZE Handle = 0x80632083 + PEER_E_UNSUPPORTED_VERSION Handle = 0x80632090 + PEER_E_GROUP_NOT_READY Handle = 0x80632091 + PEER_E_GROUP_IN_USE Handle = 0x80632092 + PEER_E_INVALID_GROUP Handle = 0x80632093 + PEER_E_NO_MEMBERS_FOUND Handle = 0x80632094 + PEER_E_NO_MEMBER_CONNECTIONS Handle = 0x80632095 + PEER_E_UNABLE_TO_LISTEN Handle = 0x80632096 + PEER_E_IDENTITY_DELETED Handle = 0x806320A0 + PEER_E_SERVICE_NOT_AVAILABLE Handle = 0x806320A1 + PEER_E_CONTACT_NOT_FOUND Handle = 0x80636001 + PEER_S_GRAPH_DATA_CREATED Handle = 0x00630001 + PEER_S_NO_EVENT_DATA Handle = 0x00630002 + PEER_S_ALREADY_CONNECTED Handle = 0x00632000 + PEER_S_SUBSCRIPTION_EXISTS Handle = 0x00636000 + PEER_S_NO_CONNECTIVITY Handle = 0x00630005 + PEER_S_ALREADY_A_MEMBER Handle = 0x00630006 + PEER_E_CANNOT_CONVERT_PEER_NAME Handle = 0x80634001 + PEER_E_INVALID_PEER_HOST_NAME Handle = 0x80634002 + PEER_E_NO_MORE Handle = 0x80634003 + PEER_E_PNRP_DUPLICATE_PEER_NAME Handle = 0x80634005 + PEER_E_INVITE_CANCELLED Handle = 0x80637000 + PEER_E_INVITE_RESPONSE_NOT_AVAILABLE Handle = 0x80637001 + PEER_E_NOT_SIGNED_IN Handle = 0x80637003 + PEER_E_PRIVACY_DECLINED Handle = 0x80637004 + PEER_E_TIMEOUT Handle = 0x80637005 + PEER_E_INVALID_ADDRESS Handle = 0x80637007 + PEER_E_FW_EXCEPTION_DISABLED Handle = 0x80637008 + PEER_E_FW_BLOCKED_BY_POLICY Handle = 0x80637009 + PEER_E_FW_BLOCKED_BY_SHIELDS_UP Handle = 0x8063700A + PEER_E_FW_DECLINED Handle = 0x8063700B + UI_E_CREATE_FAILED Handle = 0x802A0001 + UI_E_SHUTDOWN_CALLED Handle = 0x802A0002 + UI_E_ILLEGAL_REENTRANCY Handle = 0x802A0003 + UI_E_OBJECT_SEALED Handle = 0x802A0004 + UI_E_VALUE_NOT_SET Handle = 0x802A0005 + UI_E_VALUE_NOT_DETERMINED Handle = 0x802A0006 + UI_E_INVALID_OUTPUT Handle = 0x802A0007 + UI_E_BOOLEAN_EXPECTED Handle = 0x802A0008 + UI_E_DIFFERENT_OWNER Handle = 0x802A0009 + UI_E_AMBIGUOUS_MATCH Handle = 0x802A000A + UI_E_FP_OVERFLOW Handle = 0x802A000B + UI_E_WRONG_THREAD Handle = 0x802A000C + UI_E_STORYBOARD_ACTIVE Handle = 0x802A0101 + UI_E_STORYBOARD_NOT_PLAYING Handle = 0x802A0102 + UI_E_START_KEYFRAME_AFTER_END Handle = 0x802A0103 + UI_E_END_KEYFRAME_NOT_DETERMINED Handle = 0x802A0104 + UI_E_LOOPS_OVERLAP Handle = 0x802A0105 + UI_E_TRANSITION_ALREADY_USED Handle = 0x802A0106 + UI_E_TRANSITION_NOT_IN_STORYBOARD Handle = 0x802A0107 + UI_E_TRANSITION_ECLIPSED Handle = 0x802A0108 + UI_E_TIME_BEFORE_LAST_UPDATE Handle = 0x802A0109 + UI_E_TIMER_CLIENT_ALREADY_CONNECTED Handle = 0x802A010A + UI_E_INVALID_DIMENSION Handle = 0x802A010B + UI_E_PRIMITIVE_OUT_OF_BOUNDS Handle = 0x802A010C + UI_E_WINDOW_CLOSED Handle = 0x802A0201 + E_BLUETOOTH_ATT_INVALID_HANDLE Handle = 0x80650001 + E_BLUETOOTH_ATT_READ_NOT_PERMITTED Handle = 0x80650002 + E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED Handle = 0x80650003 + E_BLUETOOTH_ATT_INVALID_PDU Handle = 0x80650004 + E_BLUETOOTH_ATT_INSUFFICIENT_AUTHENTICATION Handle = 0x80650005 + E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED Handle = 0x80650006 + E_BLUETOOTH_ATT_INVALID_OFFSET Handle = 0x80650007 + E_BLUETOOTH_ATT_INSUFFICIENT_AUTHORIZATION Handle = 0x80650008 + E_BLUETOOTH_ATT_PREPARE_QUEUE_FULL Handle = 0x80650009 + E_BLUETOOTH_ATT_ATTRIBUTE_NOT_FOUND Handle = 0x8065000A + E_BLUETOOTH_ATT_ATTRIBUTE_NOT_LONG Handle = 0x8065000B + E_BLUETOOTH_ATT_INSUFFICIENT_ENCRYPTION_KEY_SIZE Handle = 0x8065000C + E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH Handle = 0x8065000D + E_BLUETOOTH_ATT_UNLIKELY Handle = 0x8065000E + E_BLUETOOTH_ATT_INSUFFICIENT_ENCRYPTION Handle = 0x8065000F + E_BLUETOOTH_ATT_UNSUPPORTED_GROUP_TYPE Handle = 0x80650010 + E_BLUETOOTH_ATT_INSUFFICIENT_RESOURCES Handle = 0x80650011 + E_BLUETOOTH_ATT_UNKNOWN_ERROR Handle = 0x80651000 + E_AUDIO_ENGINE_NODE_NOT_FOUND Handle = 0x80660001 + E_HDAUDIO_EMPTY_CONNECTION_LIST Handle = 0x80660002 + E_HDAUDIO_CONNECTION_LIST_NOT_SUPPORTED Handle = 0x80660003 + E_HDAUDIO_NO_LOGICAL_DEVICES_CREATED Handle = 0x80660004 + E_HDAUDIO_NULL_LINKED_LIST_ENTRY Handle = 0x80660005 + STATEREPOSITORY_E_CONCURRENCY_LOCKING_FAILURE Handle = 0x80670001 + STATEREPOSITORY_E_STATEMENT_INPROGRESS Handle = 0x80670002 + STATEREPOSITORY_E_CONFIGURATION_INVALID Handle = 0x80670003 + STATEREPOSITORY_E_UNKNOWN_SCHEMA_VERSION Handle = 0x80670004 + STATEREPOSITORY_ERROR_DICTIONARY_CORRUPTED Handle = 0x80670005 + STATEREPOSITORY_E_BLOCKED Handle = 0x80670006 + STATEREPOSITORY_E_BUSY_RETRY Handle = 0x80670007 + STATEREPOSITORY_E_BUSY_RECOVERY_RETRY Handle = 0x80670008 + STATEREPOSITORY_E_LOCKED_RETRY Handle = 0x80670009 + STATEREPOSITORY_E_LOCKED_SHAREDCACHE_RETRY Handle = 0x8067000A + STATEREPOSITORY_E_TRANSACTION_REQUIRED Handle = 0x8067000B + STATEREPOSITORY_E_BUSY_TIMEOUT_EXCEEDED Handle = 0x8067000C + STATEREPOSITORY_E_BUSY_RECOVERY_TIMEOUT_EXCEEDED Handle = 0x8067000D + STATEREPOSITORY_E_LOCKED_TIMEOUT_EXCEEDED Handle = 0x8067000E + STATEREPOSITORY_E_LOCKED_SHAREDCACHE_TIMEOUT_EXCEEDED Handle = 0x8067000F + STATEREPOSITORY_E_SERVICE_STOP_IN_PROGRESS Handle = 0x80670010 + STATEREPOSTORY_E_NESTED_TRANSACTION_NOT_SUPPORTED Handle = 0x80670011 + STATEREPOSITORY_ERROR_CACHE_CORRUPTED Handle = 0x80670012 + STATEREPOSITORY_TRANSACTION_CALLER_ID_CHANGED Handle = 0x00670013 + STATEREPOSITORY_TRANSACTION_IN_PROGRESS Handle = 0x00670014 + ERROR_SPACES_POOL_WAS_DELETED Handle = 0x00E70001 + ERROR_SPACES_FAULT_DOMAIN_TYPE_INVALID Handle = 0x80E70001 + ERROR_SPACES_INTERNAL_ERROR Handle = 0x80E70002 + ERROR_SPACES_RESILIENCY_TYPE_INVALID Handle = 0x80E70003 + ERROR_SPACES_DRIVE_SECTOR_SIZE_INVALID Handle = 0x80E70004 + ERROR_SPACES_DRIVE_REDUNDANCY_INVALID Handle = 0x80E70006 + ERROR_SPACES_NUMBER_OF_DATA_COPIES_INVALID Handle = 0x80E70007 + ERROR_SPACES_PARITY_LAYOUT_INVALID Handle = 0x80E70008 + ERROR_SPACES_INTERLEAVE_LENGTH_INVALID Handle = 0x80E70009 + ERROR_SPACES_NUMBER_OF_COLUMNS_INVALID Handle = 0x80E7000A + ERROR_SPACES_NOT_ENOUGH_DRIVES Handle = 0x80E7000B + ERROR_SPACES_EXTENDED_ERROR Handle = 0x80E7000C + ERROR_SPACES_PROVISIONING_TYPE_INVALID Handle = 0x80E7000D + ERROR_SPACES_ALLOCATION_SIZE_INVALID Handle = 0x80E7000E + ERROR_SPACES_ENCLOSURE_AWARE_INVALID Handle = 0x80E7000F + ERROR_SPACES_WRITE_CACHE_SIZE_INVALID Handle = 0x80E70010 + ERROR_SPACES_NUMBER_OF_GROUPS_INVALID Handle = 0x80E70011 + ERROR_SPACES_DRIVE_OPERATIONAL_STATE_INVALID Handle = 0x80E70012 + ERROR_SPACES_ENTRY_INCOMPLETE Handle = 0x80E70013 + ERROR_SPACES_ENTRY_INVALID Handle = 0x80E70014 + ERROR_VOLSNAP_BOOTFILE_NOT_VALID Handle = 0x80820001 + ERROR_VOLSNAP_ACTIVATION_TIMEOUT Handle = 0x80820002 + ERROR_TIERING_NOT_SUPPORTED_ON_VOLUME Handle = 0x80830001 + ERROR_TIERING_VOLUME_DISMOUNT_IN_PROGRESS Handle = 0x80830002 + ERROR_TIERING_STORAGE_TIER_NOT_FOUND Handle = 0x80830003 + ERROR_TIERING_INVALID_FILE_ID Handle = 0x80830004 + ERROR_TIERING_WRONG_CLUSTER_NODE Handle = 0x80830005 + ERROR_TIERING_ALREADY_PROCESSING Handle = 0x80830006 + ERROR_TIERING_CANNOT_PIN_OBJECT Handle = 0x80830007 + ERROR_TIERING_FILE_IS_NOT_PINNED Handle = 0x80830008 + ERROR_NOT_A_TIERED_VOLUME Handle = 0x80830009 + ERROR_ATTRIBUTE_NOT_PRESENT Handle = 0x8083000A + ERROR_SECCORE_INVALID_COMMAND Handle = 0xC0E80000 + ERROR_NO_APPLICABLE_APP_LICENSES_FOUND Handle = 0xC0EA0001 + ERROR_CLIP_LICENSE_NOT_FOUND Handle = 0xC0EA0002 + ERROR_CLIP_DEVICE_LICENSE_MISSING Handle = 0xC0EA0003 + ERROR_CLIP_LICENSE_INVALID_SIGNATURE Handle = 0xC0EA0004 + ERROR_CLIP_KEYHOLDER_LICENSE_MISSING_OR_INVALID Handle = 0xC0EA0005 + ERROR_CLIP_LICENSE_EXPIRED Handle = 0xC0EA0006 + ERROR_CLIP_LICENSE_SIGNED_BY_UNKNOWN_SOURCE Handle = 0xC0EA0007 + ERROR_CLIP_LICENSE_NOT_SIGNED Handle = 0xC0EA0008 + ERROR_CLIP_LICENSE_HARDWARE_ID_OUT_OF_TOLERANCE Handle = 0xC0EA0009 + ERROR_CLIP_LICENSE_DEVICE_ID_MISMATCH Handle = 0xC0EA000A + DXGI_STATUS_OCCLUDED Handle = 0x087A0001 + DXGI_STATUS_CLIPPED Handle = 0x087A0002 + DXGI_STATUS_NO_REDIRECTION Handle = 0x087A0004 + DXGI_STATUS_NO_DESKTOP_ACCESS Handle = 0x087A0005 + DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE Handle = 0x087A0006 + DXGI_STATUS_MODE_CHANGED Handle = 0x087A0007 + DXGI_STATUS_MODE_CHANGE_IN_PROGRESS Handle = 0x087A0008 + DXGI_ERROR_INVALID_CALL Handle = 0x887A0001 + DXGI_ERROR_NOT_FOUND Handle = 0x887A0002 + DXGI_ERROR_MORE_DATA Handle = 0x887A0003 + DXGI_ERROR_UNSUPPORTED Handle = 0x887A0004 + DXGI_ERROR_DEVICE_REMOVED Handle = 0x887A0005 + DXGI_ERROR_DEVICE_HUNG Handle = 0x887A0006 + DXGI_ERROR_DEVICE_RESET Handle = 0x887A0007 + DXGI_ERROR_WAS_STILL_DRAWING Handle = 0x887A000A + DXGI_ERROR_FRAME_STATISTICS_DISJOINT Handle = 0x887A000B + DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE Handle = 0x887A000C + DXGI_ERROR_DRIVER_INTERNAL_ERROR Handle = 0x887A0020 + DXGI_ERROR_NONEXCLUSIVE Handle = 0x887A0021 + DXGI_ERROR_NOT_CURRENTLY_AVAILABLE Handle = 0x887A0022 + DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED Handle = 0x887A0023 + DXGI_ERROR_REMOTE_OUTOFMEMORY Handle = 0x887A0024 + DXGI_ERROR_ACCESS_LOST Handle = 0x887A0026 + DXGI_ERROR_WAIT_TIMEOUT Handle = 0x887A0027 + DXGI_ERROR_SESSION_DISCONNECTED Handle = 0x887A0028 + DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE Handle = 0x887A0029 + DXGI_ERROR_CANNOT_PROTECT_CONTENT Handle = 0x887A002A + DXGI_ERROR_ACCESS_DENIED Handle = 0x887A002B + DXGI_ERROR_NAME_ALREADY_EXISTS Handle = 0x887A002C + DXGI_ERROR_SDK_COMPONENT_MISSING Handle = 0x887A002D + DXGI_ERROR_NOT_CURRENT Handle = 0x887A002E + DXGI_ERROR_HW_PROTECTION_OUTOFMEMORY Handle = 0x887A0030 + DXGI_ERROR_DYNAMIC_CODE_POLICY_VIOLATION Handle = 0x887A0031 + DXGI_ERROR_NON_COMPOSITED_UI Handle = 0x887A0032 + DXGI_STATUS_UNOCCLUDED Handle = 0x087A0009 + DXGI_STATUS_DDA_WAS_STILL_DRAWING Handle = 0x087A000A + DXGI_ERROR_MODE_CHANGE_IN_PROGRESS Handle = 0x887A0025 + DXGI_STATUS_PRESENT_REQUIRED Handle = 0x087A002F + DXGI_ERROR_CACHE_CORRUPT Handle = 0x887A0033 + DXGI_ERROR_CACHE_FULL Handle = 0x887A0034 + DXGI_ERROR_CACHE_HASH_COLLISION Handle = 0x887A0035 + DXGI_ERROR_ALREADY_EXISTS Handle = 0x887A0036 + DXGI_DDI_ERR_WASSTILLDRAWING Handle = 0x887B0001 + DXGI_DDI_ERR_UNSUPPORTED Handle = 0x887B0002 + DXGI_DDI_ERR_NONEXCLUSIVE Handle = 0x887B0003 + D3D10_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS Handle = 0x88790001 + D3D10_ERROR_FILE_NOT_FOUND Handle = 0x88790002 + D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS Handle = 0x887C0001 + D3D11_ERROR_FILE_NOT_FOUND Handle = 0x887C0002 + D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS Handle = 0x887C0003 + D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD Handle = 0x887C0004 + D3D12_ERROR_ADAPTER_NOT_FOUND Handle = 0x887E0001 + D3D12_ERROR_DRIVER_VERSION_MISMATCH Handle = 0x887E0002 + D2DERR_WRONG_STATE Handle = 0x88990001 + D2DERR_NOT_INITIALIZED Handle = 0x88990002 + D2DERR_UNSUPPORTED_OPERATION Handle = 0x88990003 + D2DERR_SCANNER_FAILED Handle = 0x88990004 + D2DERR_SCREEN_ACCESS_DENIED Handle = 0x88990005 + D2DERR_DISPLAY_STATE_INVALID Handle = 0x88990006 + D2DERR_ZERO_VECTOR Handle = 0x88990007 + D2DERR_INTERNAL_ERROR Handle = 0x88990008 + D2DERR_DISPLAY_FORMAT_NOT_SUPPORTED Handle = 0x88990009 + D2DERR_INVALID_CALL Handle = 0x8899000A + D2DERR_NO_HARDWARE_DEVICE Handle = 0x8899000B + D2DERR_RECREATE_TARGET Handle = 0x8899000C + D2DERR_TOO_MANY_SHADER_ELEMENTS Handle = 0x8899000D + D2DERR_SHADER_COMPILE_FAILED Handle = 0x8899000E + D2DERR_MAX_TEXTURE_SIZE_EXCEEDED Handle = 0x8899000F + D2DERR_UNSUPPORTED_VERSION Handle = 0x88990010 + D2DERR_BAD_NUMBER Handle = 0x88990011 + D2DERR_WRONG_FACTORY Handle = 0x88990012 + D2DERR_LAYER_ALREADY_IN_USE Handle = 0x88990013 + D2DERR_POP_CALL_DID_NOT_MATCH_PUSH Handle = 0x88990014 + D2DERR_WRONG_RESOURCE_DOMAIN Handle = 0x88990015 + D2DERR_PUSH_POP_UNBALANCED Handle = 0x88990016 + D2DERR_RENDER_TARGET_HAS_LAYER_OR_CLIPRECT Handle = 0x88990017 + D2DERR_INCOMPATIBLE_BRUSH_TYPES Handle = 0x88990018 + D2DERR_WIN32_ERROR Handle = 0x88990019 + D2DERR_TARGET_NOT_GDI_COMPATIBLE Handle = 0x8899001A + D2DERR_TEXT_EFFECT_IS_WRONG_TYPE Handle = 0x8899001B + D2DERR_TEXT_RENDERER_NOT_RELEASED Handle = 0x8899001C + D2DERR_EXCEEDS_MAX_BITMAP_SIZE Handle = 0x8899001D + D2DERR_INVALID_GRAPH_CONFIGURATION Handle = 0x8899001E + D2DERR_INVALID_INTERNAL_GRAPH_CONFIGURATION Handle = 0x8899001F + D2DERR_CYCLIC_GRAPH Handle = 0x88990020 + D2DERR_BITMAP_CANNOT_DRAW Handle = 0x88990021 + D2DERR_OUTSTANDING_BITMAP_REFERENCES Handle = 0x88990022 + D2DERR_ORIGINAL_TARGET_NOT_BOUND Handle = 0x88990023 + D2DERR_INVALID_TARGET Handle = 0x88990024 + D2DERR_BITMAP_BOUND_AS_TARGET Handle = 0x88990025 + D2DERR_INSUFFICIENT_DEVICE_CAPABILITIES Handle = 0x88990026 + D2DERR_INTERMEDIATE_TOO_LARGE Handle = 0x88990027 + D2DERR_EFFECT_IS_NOT_REGISTERED Handle = 0x88990028 + D2DERR_INVALID_PROPERTY Handle = 0x88990029 + D2DERR_NO_SUBPROPERTIES Handle = 0x8899002A + D2DERR_PRINT_JOB_CLOSED Handle = 0x8899002B + D2DERR_PRINT_FORMAT_NOT_SUPPORTED Handle = 0x8899002C + D2DERR_TOO_MANY_TRANSFORM_INPUTS Handle = 0x8899002D + D2DERR_INVALID_GLYPH_IMAGE Handle = 0x8899002E + DWRITE_E_FILEFORMAT Handle = 0x88985000 + DWRITE_E_UNEXPECTED Handle = 0x88985001 + DWRITE_E_NOFONT Handle = 0x88985002 + DWRITE_E_FILENOTFOUND Handle = 0x88985003 + DWRITE_E_FILEACCESS Handle = 0x88985004 + DWRITE_E_FONTCOLLECTIONOBSOLETE Handle = 0x88985005 + DWRITE_E_ALREADYREGISTERED Handle = 0x88985006 + DWRITE_E_CACHEFORMAT Handle = 0x88985007 + DWRITE_E_CACHEVERSION Handle = 0x88985008 + DWRITE_E_UNSUPPORTEDOPERATION Handle = 0x88985009 + DWRITE_E_TEXTRENDERERINCOMPATIBLE Handle = 0x8898500A + DWRITE_E_FLOWDIRECTIONCONFLICTS Handle = 0x8898500B + DWRITE_E_NOCOLOR Handle = 0x8898500C + DWRITE_E_REMOTEFONT Handle = 0x8898500D + DWRITE_E_DOWNLOADCANCELLED Handle = 0x8898500E + DWRITE_E_DOWNLOADFAILED Handle = 0x8898500F + DWRITE_E_TOOMANYDOWNLOADS Handle = 0x88985010 + WINCODEC_ERR_WRONGSTATE Handle = 0x88982F04 + WINCODEC_ERR_VALUEOUTOFRANGE Handle = 0x88982F05 + WINCODEC_ERR_UNKNOWNIMAGEFORMAT Handle = 0x88982F07 + WINCODEC_ERR_UNSUPPORTEDVERSION Handle = 0x88982F0B + WINCODEC_ERR_NOTINITIALIZED Handle = 0x88982F0C + WINCODEC_ERR_ALREADYLOCKED Handle = 0x88982F0D + WINCODEC_ERR_PROPERTYNOTFOUND Handle = 0x88982F40 + WINCODEC_ERR_PROPERTYNOTSUPPORTED Handle = 0x88982F41 + WINCODEC_ERR_PROPERTYSIZE Handle = 0x88982F42 + WINCODEC_ERR_CODECPRESENT Handle = 0x88982F43 + WINCODEC_ERR_CODECNOTHUMBNAIL Handle = 0x88982F44 + WINCODEC_ERR_PALETTEUNAVAILABLE Handle = 0x88982F45 + WINCODEC_ERR_CODECTOOMANYSCANLINES Handle = 0x88982F46 + WINCODEC_ERR_INTERNALERROR Handle = 0x88982F48 + WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS Handle = 0x88982F49 + WINCODEC_ERR_COMPONENTNOTFOUND Handle = 0x88982F50 + WINCODEC_ERR_IMAGESIZEOUTOFRANGE Handle = 0x88982F51 + WINCODEC_ERR_TOOMUCHMETADATA Handle = 0x88982F52 + WINCODEC_ERR_BADIMAGE Handle = 0x88982F60 + WINCODEC_ERR_BADHEADER Handle = 0x88982F61 + WINCODEC_ERR_FRAMEMISSING Handle = 0x88982F62 + WINCODEC_ERR_BADMETADATAHEADER Handle = 0x88982F63 + WINCODEC_ERR_BADSTREAMDATA Handle = 0x88982F70 + WINCODEC_ERR_STREAMWRITE Handle = 0x88982F71 + WINCODEC_ERR_STREAMREAD Handle = 0x88982F72 + WINCODEC_ERR_STREAMNOTAVAILABLE Handle = 0x88982F73 + WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT Handle = 0x88982F80 + WINCODEC_ERR_UNSUPPORTEDOPERATION Handle = 0x88982F81 + WINCODEC_ERR_INVALIDREGISTRATION Handle = 0x88982F8A + WINCODEC_ERR_COMPONENTINITIALIZEFAILURE Handle = 0x88982F8B + WINCODEC_ERR_INSUFFICIENTBUFFER Handle = 0x88982F8C + WINCODEC_ERR_DUPLICATEMETADATAPRESENT Handle = 0x88982F8D + WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE Handle = 0x88982F8E + WINCODEC_ERR_UNEXPECTEDSIZE Handle = 0x88982F8F + WINCODEC_ERR_INVALIDQUERYREQUEST Handle = 0x88982F90 + WINCODEC_ERR_UNEXPECTEDMETADATATYPE Handle = 0x88982F91 + WINCODEC_ERR_REQUESTONLYVALIDATMETADATAROOT Handle = 0x88982F92 + WINCODEC_ERR_INVALIDQUERYCHARACTER Handle = 0x88982F93 + WINCODEC_ERR_WIN32ERROR Handle = 0x88982F94 + WINCODEC_ERR_INVALIDPROGRESSIVELEVEL Handle = 0x88982F95 + WINCODEC_ERR_INVALIDJPEGSCANINDEX Handle = 0x88982F96 + MILERR_OBJECTBUSY Handle = 0x88980001 + MILERR_INSUFFICIENTBUFFER Handle = 0x88980002 + MILERR_WIN32ERROR Handle = 0x88980003 + MILERR_SCANNER_FAILED Handle = 0x88980004 + MILERR_SCREENACCESSDENIED Handle = 0x88980005 + MILERR_DISPLAYSTATEINVALID Handle = 0x88980006 + MILERR_NONINVERTIBLEMATRIX Handle = 0x88980007 + MILERR_ZEROVECTOR Handle = 0x88980008 + MILERR_TERMINATED Handle = 0x88980009 + MILERR_BADNUMBER Handle = 0x8898000A + MILERR_INTERNALERROR Handle = 0x88980080 + MILERR_DISPLAYFORMATNOTSUPPORTED Handle = 0x88980084 + MILERR_INVALIDCALL Handle = 0x88980085 + MILERR_ALREADYLOCKED Handle = 0x88980086 + MILERR_NOTLOCKED Handle = 0x88980087 + MILERR_DEVICECANNOTRENDERTEXT Handle = 0x88980088 + MILERR_GLYPHBITMAPMISSED Handle = 0x88980089 + MILERR_MALFORMEDGLYPHCACHE Handle = 0x8898008A + MILERR_GENERIC_IGNORE Handle = 0x8898008B + MILERR_MALFORMED_GUIDELINE_DATA Handle = 0x8898008C + MILERR_NO_HARDWARE_DEVICE Handle = 0x8898008D + MILERR_NEED_RECREATE_AND_PRESENT Handle = 0x8898008E + MILERR_ALREADY_INITIALIZED Handle = 0x8898008F + MILERR_MISMATCHED_SIZE Handle = 0x88980090 + MILERR_NO_REDIRECTION_SURFACE_AVAILABLE Handle = 0x88980091 + MILERR_REMOTING_NOT_SUPPORTED Handle = 0x88980092 + MILERR_QUEUED_PRESENT_NOT_SUPPORTED Handle = 0x88980093 + MILERR_NOT_QUEUING_PRESENTS Handle = 0x88980094 + MILERR_NO_REDIRECTION_SURFACE_RETRY_LATER Handle = 0x88980095 + MILERR_TOOMANYSHADERELEMNTS Handle = 0x88980096 + MILERR_MROW_READLOCK_FAILED Handle = 0x88980097 + MILERR_MROW_UPDATE_FAILED Handle = 0x88980098 + MILERR_SHADER_COMPILE_FAILED Handle = 0x88980099 + MILERR_MAX_TEXTURE_SIZE_EXCEEDED Handle = 0x8898009A + MILERR_QPC_TIME_WENT_BACKWARD Handle = 0x8898009B + MILERR_DXGI_ENUMERATION_OUT_OF_SYNC Handle = 0x8898009D + MILERR_ADAPTER_NOT_FOUND Handle = 0x8898009E + MILERR_COLORSPACE_NOT_SUPPORTED Handle = 0x8898009F + MILERR_PREFILTER_NOT_SUPPORTED Handle = 0x889800A0 + MILERR_DISPLAYID_ACCESS_DENIED Handle = 0x889800A1 + UCEERR_INVALIDPACKETHEADER Handle = 0x88980400 + UCEERR_UNKNOWNPACKET Handle = 0x88980401 + UCEERR_ILLEGALPACKET Handle = 0x88980402 + UCEERR_MALFORMEDPACKET Handle = 0x88980403 + UCEERR_ILLEGALHANDLE Handle = 0x88980404 + UCEERR_HANDLELOOKUPFAILED Handle = 0x88980405 + UCEERR_RENDERTHREADFAILURE Handle = 0x88980406 + UCEERR_CTXSTACKFRSTTARGETNULL Handle = 0x88980407 + UCEERR_CONNECTIONIDLOOKUPFAILED Handle = 0x88980408 + UCEERR_BLOCKSFULL Handle = 0x88980409 + UCEERR_MEMORYFAILURE Handle = 0x8898040A + UCEERR_PACKETRECORDOUTOFRANGE Handle = 0x8898040B + UCEERR_ILLEGALRECORDTYPE Handle = 0x8898040C + UCEERR_OUTOFHANDLES Handle = 0x8898040D + UCEERR_UNCHANGABLE_UPDATE_ATTEMPTED Handle = 0x8898040E + UCEERR_NO_MULTIPLE_WORKER_THREADS Handle = 0x8898040F + UCEERR_REMOTINGNOTSUPPORTED Handle = 0x88980410 + UCEERR_MISSINGENDCOMMAND Handle = 0x88980411 + UCEERR_MISSINGBEGINCOMMAND Handle = 0x88980412 + UCEERR_CHANNELSYNCTIMEDOUT Handle = 0x88980413 + UCEERR_CHANNELSYNCABANDONED Handle = 0x88980414 + UCEERR_UNSUPPORTEDTRANSPORTVERSION Handle = 0x88980415 + UCEERR_TRANSPORTUNAVAILABLE Handle = 0x88980416 + UCEERR_FEEDBACK_UNSUPPORTED Handle = 0x88980417 + UCEERR_COMMANDTRANSPORTDENIED Handle = 0x88980418 + UCEERR_GRAPHICSSTREAMUNAVAILABLE Handle = 0x88980419 + UCEERR_GRAPHICSSTREAMALREADYOPEN Handle = 0x88980420 + UCEERR_TRANSPORTDISCONNECTED Handle = 0x88980421 + UCEERR_TRANSPORTOVERLOADED Handle = 0x88980422 + UCEERR_PARTITION_ZOMBIED Handle = 0x88980423 + MILAVERR_NOCLOCK Handle = 0x88980500 + MILAVERR_NOMEDIATYPE Handle = 0x88980501 + MILAVERR_NOVIDEOMIXER Handle = 0x88980502 + MILAVERR_NOVIDEOPRESENTER Handle = 0x88980503 + MILAVERR_NOREADYFRAMES Handle = 0x88980504 + MILAVERR_MODULENOTLOADED Handle = 0x88980505 + MILAVERR_WMPFACTORYNOTREGISTERED Handle = 0x88980506 + MILAVERR_INVALIDWMPVERSION Handle = 0x88980507 + MILAVERR_INSUFFICIENTVIDEORESOURCES Handle = 0x88980508 + MILAVERR_VIDEOACCELERATIONNOTAVAILABLE Handle = 0x88980509 + MILAVERR_REQUESTEDTEXTURETOOBIG Handle = 0x8898050A + MILAVERR_SEEKFAILED Handle = 0x8898050B + MILAVERR_UNEXPECTEDWMPFAILURE Handle = 0x8898050C + MILAVERR_MEDIAPLAYERCLOSED Handle = 0x8898050D + MILAVERR_UNKNOWNHARDWAREERROR Handle = 0x8898050E + MILEFFECTSERR_UNKNOWNPROPERTY Handle = 0x8898060E + MILEFFECTSERR_EFFECTNOTPARTOFGROUP Handle = 0x8898060F + MILEFFECTSERR_NOINPUTSOURCEATTACHED Handle = 0x88980610 + MILEFFECTSERR_CONNECTORNOTCONNECTED Handle = 0x88980611 + MILEFFECTSERR_CONNECTORNOTASSOCIATEDWITHEFFECT Handle = 0x88980612 + MILEFFECTSERR_RESERVED Handle = 0x88980613 + MILEFFECTSERR_CYCLEDETECTED Handle = 0x88980614 + MILEFFECTSERR_EFFECTINMORETHANONEGRAPH Handle = 0x88980615 + MILEFFECTSERR_EFFECTALREADYINAGRAPH Handle = 0x88980616 + MILEFFECTSERR_EFFECTHASNOCHILDREN Handle = 0x88980617 + MILEFFECTSERR_ALREADYATTACHEDTOLISTENER Handle = 0x88980618 + MILEFFECTSERR_NOTAFFINETRANSFORM Handle = 0x88980619 + MILEFFECTSERR_EMPTYBOUNDS Handle = 0x8898061A + MILEFFECTSERR_OUTPUTSIZETOOLARGE Handle = 0x8898061B + DWMERR_STATE_TRANSITION_FAILED Handle = 0x88980700 + DWMERR_THEME_FAILED Handle = 0x88980701 + DWMERR_CATASTROPHIC_FAILURE Handle = 0x88980702 + DCOMPOSITION_ERROR_WINDOW_ALREADY_COMPOSED Handle = 0x88980800 + DCOMPOSITION_ERROR_SURFACE_BEING_RENDERED Handle = 0x88980801 + DCOMPOSITION_ERROR_SURFACE_NOT_BEING_RENDERED Handle = 0x88980802 + ONL_E_INVALID_AUTHENTICATION_TARGET Handle = 0x80860001 + ONL_E_ACCESS_DENIED_BY_TOU Handle = 0x80860002 + ONL_E_INVALID_APPLICATION Handle = 0x80860003 + ONL_E_PASSWORD_UPDATE_REQUIRED Handle = 0x80860004 + ONL_E_ACCOUNT_UPDATE_REQUIRED Handle = 0x80860005 + ONL_E_FORCESIGNIN Handle = 0x80860006 + ONL_E_ACCOUNT_LOCKED Handle = 0x80860007 + ONL_E_PARENTAL_CONSENT_REQUIRED Handle = 0x80860008 + ONL_E_EMAIL_VERIFICATION_REQUIRED Handle = 0x80860009 + ONL_E_ACCOUNT_SUSPENDED_COMPROIMISE Handle = 0x8086000A + ONL_E_ACCOUNT_SUSPENDED_ABUSE Handle = 0x8086000B + ONL_E_ACTION_REQUIRED Handle = 0x8086000C + ONL_CONNECTION_COUNT_LIMIT Handle = 0x8086000D + ONL_E_CONNECTED_ACCOUNT_CAN_NOT_SIGNOUT Handle = 0x8086000E + ONL_E_USER_AUTHENTICATION_REQUIRED Handle = 0x8086000F + ONL_E_REQUEST_THROTTLED Handle = 0x80860010 + FA_E_MAX_PERSISTED_ITEMS_REACHED Handle = 0x80270220 + FA_E_HOMEGROUP_NOT_AVAILABLE Handle = 0x80270222 + E_MONITOR_RESOLUTION_TOO_LOW Handle = 0x80270250 + E_ELEVATED_ACTIVATION_NOT_SUPPORTED Handle = 0x80270251 + E_UAC_DISABLED Handle = 0x80270252 + E_FULL_ADMIN_NOT_SUPPORTED Handle = 0x80270253 + E_APPLICATION_NOT_REGISTERED Handle = 0x80270254 + E_MULTIPLE_EXTENSIONS_FOR_APPLICATION Handle = 0x80270255 + E_MULTIPLE_PACKAGES_FOR_FAMILY Handle = 0x80270256 + E_APPLICATION_MANAGER_NOT_RUNNING Handle = 0x80270257 + S_STORE_LAUNCHED_FOR_REMEDIATION Handle = 0x00270258 + S_APPLICATION_ACTIVATION_ERROR_HANDLED_BY_DIALOG Handle = 0x00270259 + E_APPLICATION_ACTIVATION_TIMED_OUT Handle = 0x8027025A + E_APPLICATION_ACTIVATION_EXEC_FAILURE Handle = 0x8027025B + E_APPLICATION_TEMPORARY_LICENSE_ERROR Handle = 0x8027025C + E_APPLICATION_TRIAL_LICENSE_EXPIRED Handle = 0x8027025D + E_SKYDRIVE_ROOT_TARGET_FILE_SYSTEM_NOT_SUPPORTED Handle = 0x80270260 + E_SKYDRIVE_ROOT_TARGET_OVERLAP Handle = 0x80270261 + E_SKYDRIVE_ROOT_TARGET_CANNOT_INDEX Handle = 0x80270262 + E_SKYDRIVE_FILE_NOT_UPLOADED Handle = 0x80270263 + E_SKYDRIVE_UPDATE_AVAILABILITY_FAIL Handle = 0x80270264 + E_SKYDRIVE_ROOT_TARGET_VOLUME_ROOT_NOT_SUPPORTED Handle = 0x80270265 + E_SYNCENGINE_FILE_SIZE_OVER_LIMIT Handle = 0x8802B001 + E_SYNCENGINE_FILE_SIZE_EXCEEDS_REMAINING_QUOTA Handle = 0x8802B002 + E_SYNCENGINE_UNSUPPORTED_FILE_NAME Handle = 0x8802B003 + E_SYNCENGINE_FOLDER_ITEM_COUNT_LIMIT_EXCEEDED Handle = 0x8802B004 + E_SYNCENGINE_FILE_SYNC_PARTNER_ERROR Handle = 0x8802B005 + E_SYNCENGINE_SYNC_PAUSED_BY_SERVICE Handle = 0x8802B006 + E_SYNCENGINE_FILE_IDENTIFIER_UNKNOWN Handle = 0x8802C002 + E_SYNCENGINE_SERVICE_AUTHENTICATION_FAILED Handle = 0x8802C003 + E_SYNCENGINE_UNKNOWN_SERVICE_ERROR Handle = 0x8802C004 + E_SYNCENGINE_SERVICE_RETURNED_UNEXPECTED_SIZE Handle = 0x8802C005 + E_SYNCENGINE_REQUEST_BLOCKED_BY_SERVICE Handle = 0x8802C006 + E_SYNCENGINE_REQUEST_BLOCKED_DUE_TO_CLIENT_ERROR Handle = 0x8802C007 + E_SYNCENGINE_FOLDER_INACCESSIBLE Handle = 0x8802D001 + E_SYNCENGINE_UNSUPPORTED_FOLDER_NAME Handle = 0x8802D002 + E_SYNCENGINE_UNSUPPORTED_MARKET Handle = 0x8802D003 + E_SYNCENGINE_PATH_LENGTH_LIMIT_EXCEEDED Handle = 0x8802D004 + E_SYNCENGINE_REMOTE_PATH_LENGTH_LIMIT_EXCEEDED Handle = 0x8802D005 + E_SYNCENGINE_CLIENT_UPDATE_NEEDED Handle = 0x8802D006 + E_SYNCENGINE_PROXY_AUTHENTICATION_REQUIRED Handle = 0x8802D007 + E_SYNCENGINE_STORAGE_SERVICE_PROVISIONING_FAILED Handle = 0x8802D008 + E_SYNCENGINE_UNSUPPORTED_REPARSE_POINT Handle = 0x8802D009 + E_SYNCENGINE_STORAGE_SERVICE_BLOCKED Handle = 0x8802D00A + E_SYNCENGINE_FOLDER_IN_REDIRECTION Handle = 0x8802D00B + EAS_E_POLICY_NOT_MANAGED_BY_OS Handle = 0x80550001 + EAS_E_POLICY_COMPLIANT_WITH_ACTIONS Handle = 0x80550002 + EAS_E_REQUESTED_POLICY_NOT_ENFORCEABLE Handle = 0x80550003 + EAS_E_CURRENT_USER_HAS_BLANK_PASSWORD Handle = 0x80550004 + EAS_E_REQUESTED_POLICY_PASSWORD_EXPIRATION_INCOMPATIBLE Handle = 0x80550005 + EAS_E_USER_CANNOT_CHANGE_PASSWORD Handle = 0x80550006 + EAS_E_ADMINS_HAVE_BLANK_PASSWORD Handle = 0x80550007 + EAS_E_ADMINS_CANNOT_CHANGE_PASSWORD Handle = 0x80550008 + EAS_E_LOCAL_CONTROLLED_USERS_CANNOT_CHANGE_PASSWORD Handle = 0x80550009 + EAS_E_PASSWORD_POLICY_NOT_ENFORCEABLE_FOR_CONNECTED_ADMINS Handle = 0x8055000A + EAS_E_CONNECTED_ADMINS_NEED_TO_CHANGE_PASSWORD Handle = 0x8055000B + EAS_E_PASSWORD_POLICY_NOT_ENFORCEABLE_FOR_CURRENT_CONNECTED_USER Handle = 0x8055000C + EAS_E_CURRENT_CONNECTED_USER_NEED_TO_CHANGE_PASSWORD Handle = 0x8055000D + WEB_E_UNSUPPORTED_FORMAT Handle = 0x83750001 + WEB_E_INVALID_XML Handle = 0x83750002 + WEB_E_MISSING_REQUIRED_ELEMENT Handle = 0x83750003 + WEB_E_MISSING_REQUIRED_ATTRIBUTE Handle = 0x83750004 + WEB_E_UNEXPECTED_CONTENT Handle = 0x83750005 + WEB_E_RESOURCE_TOO_LARGE Handle = 0x83750006 + WEB_E_INVALID_JSON_STRING Handle = 0x83750007 + WEB_E_INVALID_JSON_NUMBER Handle = 0x83750008 + WEB_E_JSON_VALUE_NOT_FOUND Handle = 0x83750009 + HTTP_E_STATUS_UNEXPECTED Handle = 0x80190001 + HTTP_E_STATUS_UNEXPECTED_REDIRECTION Handle = 0x80190003 + HTTP_E_STATUS_UNEXPECTED_CLIENT_ERROR Handle = 0x80190004 + HTTP_E_STATUS_UNEXPECTED_SERVER_ERROR Handle = 0x80190005 + HTTP_E_STATUS_AMBIGUOUS Handle = 0x8019012C + HTTP_E_STATUS_MOVED Handle = 0x8019012D + HTTP_E_STATUS_REDIRECT Handle = 0x8019012E + HTTP_E_STATUS_REDIRECT_METHOD Handle = 0x8019012F + HTTP_E_STATUS_NOT_MODIFIED Handle = 0x80190130 + HTTP_E_STATUS_USE_PROXY Handle = 0x80190131 + HTTP_E_STATUS_REDIRECT_KEEP_VERB Handle = 0x80190133 + HTTP_E_STATUS_BAD_REQUEST Handle = 0x80190190 + HTTP_E_STATUS_DENIED Handle = 0x80190191 + HTTP_E_STATUS_PAYMENT_REQ Handle = 0x80190192 + HTTP_E_STATUS_FORBIDDEN Handle = 0x80190193 + HTTP_E_STATUS_NOT_FOUND Handle = 0x80190194 + HTTP_E_STATUS_BAD_METHOD Handle = 0x80190195 + HTTP_E_STATUS_NONE_ACCEPTABLE Handle = 0x80190196 + HTTP_E_STATUS_PROXY_AUTH_REQ Handle = 0x80190197 + HTTP_E_STATUS_REQUEST_TIMEOUT Handle = 0x80190198 + HTTP_E_STATUS_CONFLICT Handle = 0x80190199 + HTTP_E_STATUS_GONE Handle = 0x8019019A + HTTP_E_STATUS_LENGTH_REQUIRED Handle = 0x8019019B + HTTP_E_STATUS_PRECOND_FAILED Handle = 0x8019019C + HTTP_E_STATUS_REQUEST_TOO_LARGE Handle = 0x8019019D + HTTP_E_STATUS_URI_TOO_LONG Handle = 0x8019019E + HTTP_E_STATUS_UNSUPPORTED_MEDIA Handle = 0x8019019F + HTTP_E_STATUS_RANGE_NOT_SATISFIABLE Handle = 0x801901A0 + HTTP_E_STATUS_EXPECTATION_FAILED Handle = 0x801901A1 + HTTP_E_STATUS_SERVER_ERROR Handle = 0x801901F4 + HTTP_E_STATUS_NOT_SUPPORTED Handle = 0x801901F5 + HTTP_E_STATUS_BAD_GATEWAY Handle = 0x801901F6 + HTTP_E_STATUS_SERVICE_UNAVAIL Handle = 0x801901F7 + HTTP_E_STATUS_GATEWAY_TIMEOUT Handle = 0x801901F8 + HTTP_E_STATUS_VERSION_NOT_SUP Handle = 0x801901F9 + E_INVALID_PROTOCOL_OPERATION Handle = 0x83760001 + E_INVALID_PROTOCOL_FORMAT Handle = 0x83760002 + E_PROTOCOL_EXTENSIONS_NOT_SUPPORTED Handle = 0x83760003 + E_SUBPROTOCOL_NOT_SUPPORTED Handle = 0x83760004 + E_PROTOCOL_VERSION_NOT_SUPPORTED Handle = 0x83760005 + INPUT_E_OUT_OF_ORDER Handle = 0x80400000 + INPUT_E_REENTRANCY Handle = 0x80400001 + INPUT_E_MULTIMODAL Handle = 0x80400002 + INPUT_E_PACKET Handle = 0x80400003 + INPUT_E_FRAME Handle = 0x80400004 + INPUT_E_HISTORY Handle = 0x80400005 + INPUT_E_DEVICE_INFO Handle = 0x80400006 + INPUT_E_TRANSFORM Handle = 0x80400007 + INPUT_E_DEVICE_PROPERTY Handle = 0x80400008 + INET_E_INVALID_URL Handle = 0x800C0002 + INET_E_NO_SESSION Handle = 0x800C0003 + INET_E_CANNOT_CONNECT Handle = 0x800C0004 + INET_E_RESOURCE_NOT_FOUND Handle = 0x800C0005 + INET_E_OBJECT_NOT_FOUND Handle = 0x800C0006 + INET_E_DATA_NOT_AVAILABLE Handle = 0x800C0007 + INET_E_DOWNLOAD_FAILURE Handle = 0x800C0008 + INET_E_AUTHENTICATION_REQUIRED Handle = 0x800C0009 + INET_E_NO_VALID_MEDIA Handle = 0x800C000A + INET_E_CONNECTION_TIMEOUT Handle = 0x800C000B + INET_E_INVALID_REQUEST Handle = 0x800C000C + INET_E_UNKNOWN_PROTOCOL Handle = 0x800C000D + INET_E_SECURITY_PROBLEM Handle = 0x800C000E + INET_E_CANNOT_LOAD_DATA Handle = 0x800C000F + INET_E_CANNOT_INSTANTIATE_OBJECT Handle = 0x800C0010 + INET_E_INVALID_CERTIFICATE Handle = 0x800C0019 + INET_E_REDIRECT_FAILED Handle = 0x800C0014 + INET_E_REDIRECT_TO_DIR Handle = 0x800C0015 + ERROR_DBG_CREATE_PROCESS_FAILURE_LOCKDOWN Handle = 0x80B00001 + ERROR_DBG_ATTACH_PROCESS_FAILURE_LOCKDOWN Handle = 0x80B00002 + ERROR_DBG_CONNECT_SERVER_FAILURE_LOCKDOWN Handle = 0x80B00003 + ERROR_DBG_START_SERVER_FAILURE_LOCKDOWN Handle = 0x80B00004 + ERROR_IO_PREEMPTED Handle = 0x89010001 + JSCRIPT_E_CANTEXECUTE Handle = 0x89020001 + WEP_E_NOT_PROVISIONED_ON_ALL_VOLUMES Handle = 0x88010001 + WEP_E_FIXED_DATA_NOT_SUPPORTED Handle = 0x88010002 + WEP_E_HARDWARE_NOT_COMPLIANT Handle = 0x88010003 + WEP_E_LOCK_NOT_CONFIGURED Handle = 0x88010004 + WEP_E_PROTECTION_SUSPENDED Handle = 0x88010005 + WEP_E_NO_LICENSE Handle = 0x88010006 + WEP_E_OS_NOT_PROTECTED Handle = 0x88010007 + WEP_E_UNEXPECTED_FAIL Handle = 0x88010008 + WEP_E_BUFFER_TOO_LARGE Handle = 0x88010009 + ERROR_SVHDX_ERROR_STORED Handle = 0xC05C0000 + ERROR_SVHDX_ERROR_NOT_AVAILABLE Handle = 0xC05CFF00 + ERROR_SVHDX_UNIT_ATTENTION_AVAILABLE Handle = 0xC05CFF01 + ERROR_SVHDX_UNIT_ATTENTION_CAPACITY_DATA_CHANGED Handle = 0xC05CFF02 + ERROR_SVHDX_UNIT_ATTENTION_RESERVATIONS_PREEMPTED Handle = 0xC05CFF03 + ERROR_SVHDX_UNIT_ATTENTION_RESERVATIONS_RELEASED Handle = 0xC05CFF04 + ERROR_SVHDX_UNIT_ATTENTION_REGISTRATIONS_PREEMPTED Handle = 0xC05CFF05 + ERROR_SVHDX_UNIT_ATTENTION_OPERATING_DEFINITION_CHANGED Handle = 0xC05CFF06 + ERROR_SVHDX_RESERVATION_CONFLICT Handle = 0xC05CFF07 + ERROR_SVHDX_WRONG_FILE_TYPE Handle = 0xC05CFF08 + ERROR_SVHDX_VERSION_MISMATCH Handle = 0xC05CFF09 + ERROR_VHD_SHARED Handle = 0xC05CFF0A + ERROR_SVHDX_NO_INITIATOR Handle = 0xC05CFF0B + ERROR_VHDSET_BACKING_STORAGE_NOT_FOUND Handle = 0xC05CFF0C + ERROR_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP Handle = 0xC05D0000 + ERROR_SMB_BAD_CLUSTER_DIALECT Handle = 0xC05D0001 + WININET_E_OUT_OF_HANDLES Handle = 0x80072EE1 + WININET_E_TIMEOUT Handle = 0x80072EE2 + WININET_E_EXTENDED_ERROR Handle = 0x80072EE3 + WININET_E_INTERNAL_ERROR Handle = 0x80072EE4 + WININET_E_INVALID_URL Handle = 0x80072EE5 + WININET_E_UNRECOGNIZED_SCHEME Handle = 0x80072EE6 + WININET_E_NAME_NOT_RESOLVED Handle = 0x80072EE7 + WININET_E_PROTOCOL_NOT_FOUND Handle = 0x80072EE8 + WININET_E_INVALID_OPTION Handle = 0x80072EE9 + WININET_E_BAD_OPTION_LENGTH Handle = 0x80072EEA + WININET_E_OPTION_NOT_SETTABLE Handle = 0x80072EEB + WININET_E_SHUTDOWN Handle = 0x80072EEC + WININET_E_INCORRECT_USER_NAME Handle = 0x80072EED + WININET_E_INCORRECT_PASSWORD Handle = 0x80072EEE + WININET_E_LOGIN_FAILURE Handle = 0x80072EEF + WININET_E_INVALID_OPERATION Handle = 0x80072EF0 + WININET_E_OPERATION_CANCELLED Handle = 0x80072EF1 + WININET_E_INCORRECT_HANDLE_TYPE Handle = 0x80072EF2 + WININET_E_INCORRECT_HANDLE_STATE Handle = 0x80072EF3 + WININET_E_NOT_PROXY_REQUEST Handle = 0x80072EF4 + WININET_E_REGISTRY_VALUE_NOT_FOUND Handle = 0x80072EF5 + WININET_E_BAD_REGISTRY_PARAMETER Handle = 0x80072EF6 + WININET_E_NO_DIRECT_ACCESS Handle = 0x80072EF7 + WININET_E_NO_CONTEXT Handle = 0x80072EF8 + WININET_E_NO_CALLBACK Handle = 0x80072EF9 + WININET_E_REQUEST_PENDING Handle = 0x80072EFA + WININET_E_INCORRECT_FORMAT Handle = 0x80072EFB + WININET_E_ITEM_NOT_FOUND Handle = 0x80072EFC + WININET_E_CANNOT_CONNECT Handle = 0x80072EFD + WININET_E_CONNECTION_ABORTED Handle = 0x80072EFE + WININET_E_CONNECTION_RESET Handle = 0x80072EFF + WININET_E_FORCE_RETRY Handle = 0x80072F00 + WININET_E_INVALID_PROXY_REQUEST Handle = 0x80072F01 + WININET_E_NEED_UI Handle = 0x80072F02 + WININET_E_HANDLE_EXISTS Handle = 0x80072F04 + WININET_E_SEC_CERT_DATE_INVALID Handle = 0x80072F05 + WININET_E_SEC_CERT_CN_INVALID Handle = 0x80072F06 + WININET_E_HTTP_TO_HTTPS_ON_REDIR Handle = 0x80072F07 + WININET_E_HTTPS_TO_HTTP_ON_REDIR Handle = 0x80072F08 + WININET_E_MIXED_SECURITY Handle = 0x80072F09 + WININET_E_CHG_POST_IS_NON_SECURE Handle = 0x80072F0A + WININET_E_POST_IS_NON_SECURE Handle = 0x80072F0B + WININET_E_CLIENT_AUTH_CERT_NEEDED Handle = 0x80072F0C + WININET_E_INVALID_CA Handle = 0x80072F0D + WININET_E_CLIENT_AUTH_NOT_SETUP Handle = 0x80072F0E + WININET_E_ASYNC_THREAD_FAILED Handle = 0x80072F0F + WININET_E_REDIRECT_SCHEME_CHANGE Handle = 0x80072F10 + WININET_E_DIALOG_PENDING Handle = 0x80072F11 + WININET_E_RETRY_DIALOG Handle = 0x80072F12 + WININET_E_NO_NEW_CONTAINERS Handle = 0x80072F13 + WININET_E_HTTPS_HTTP_SUBMIT_REDIR Handle = 0x80072F14 + WININET_E_SEC_CERT_ERRORS Handle = 0x80072F17 + WININET_E_SEC_CERT_REV_FAILED Handle = 0x80072F19 + WININET_E_HEADER_NOT_FOUND Handle = 0x80072F76 + WININET_E_DOWNLEVEL_SERVER Handle = 0x80072F77 + WININET_E_INVALID_SERVER_RESPONSE Handle = 0x80072F78 + WININET_E_INVALID_HEADER Handle = 0x80072F79 + WININET_E_INVALID_QUERY_REQUEST Handle = 0x80072F7A + WININET_E_HEADER_ALREADY_EXISTS Handle = 0x80072F7B + WININET_E_REDIRECT_FAILED Handle = 0x80072F7C + WININET_E_SECURITY_CHANNEL_ERROR Handle = 0x80072F7D + WININET_E_UNABLE_TO_CACHE_FILE Handle = 0x80072F7E + WININET_E_TCPIP_NOT_INSTALLED Handle = 0x80072F7F + WININET_E_DISCONNECTED Handle = 0x80072F83 + WININET_E_SERVER_UNREACHABLE Handle = 0x80072F84 + WININET_E_PROXY_SERVER_UNREACHABLE Handle = 0x80072F85 + WININET_E_BAD_AUTO_PROXY_SCRIPT Handle = 0x80072F86 + WININET_E_UNABLE_TO_DOWNLOAD_SCRIPT Handle = 0x80072F87 + WININET_E_SEC_INVALID_CERT Handle = 0x80072F89 + WININET_E_SEC_CERT_REVOKED Handle = 0x80072F8A + WININET_E_FAILED_DUETOSECURITYCHECK Handle = 0x80072F8B + WININET_E_NOT_INITIALIZED Handle = 0x80072F8C + WININET_E_LOGIN_FAILURE_DISPLAY_ENTITY_BODY Handle = 0x80072F8E + WININET_E_DECODING_FAILED Handle = 0x80072F8F + WININET_E_NOT_REDIRECTED Handle = 0x80072F80 + WININET_E_COOKIE_NEEDS_CONFIRMATION Handle = 0x80072F81 + WININET_E_COOKIE_DECLINED Handle = 0x80072F82 + WININET_E_REDIRECT_NEEDS_CONFIRMATION Handle = 0x80072F88 + SQLITE_E_ERROR Handle = 0x87AF0001 + SQLITE_E_INTERNAL Handle = 0x87AF0002 + SQLITE_E_PERM Handle = 0x87AF0003 + SQLITE_E_ABORT Handle = 0x87AF0004 + SQLITE_E_BUSY Handle = 0x87AF0005 + SQLITE_E_LOCKED Handle = 0x87AF0006 + SQLITE_E_NOMEM Handle = 0x87AF0007 + SQLITE_E_READONLY Handle = 0x87AF0008 + SQLITE_E_INTERRUPT Handle = 0x87AF0009 + SQLITE_E_IOERR Handle = 0x87AF000A + SQLITE_E_CORRUPT Handle = 0x87AF000B + SQLITE_E_NOTFOUND Handle = 0x87AF000C + SQLITE_E_FULL Handle = 0x87AF000D + SQLITE_E_CANTOPEN Handle = 0x87AF000E + SQLITE_E_PROTOCOL Handle = 0x87AF000F + SQLITE_E_EMPTY Handle = 0x87AF0010 + SQLITE_E_SCHEMA Handle = 0x87AF0011 + SQLITE_E_TOOBIG Handle = 0x87AF0012 + SQLITE_E_CONSTRAINT Handle = 0x87AF0013 + SQLITE_E_MISMATCH Handle = 0x87AF0014 + SQLITE_E_MISUSE Handle = 0x87AF0015 + SQLITE_E_NOLFS Handle = 0x87AF0016 + SQLITE_E_AUTH Handle = 0x87AF0017 + SQLITE_E_FORMAT Handle = 0x87AF0018 + SQLITE_E_RANGE Handle = 0x87AF0019 + SQLITE_E_NOTADB Handle = 0x87AF001A + SQLITE_E_NOTICE Handle = 0x87AF001B + SQLITE_E_WARNING Handle = 0x87AF001C + SQLITE_E_ROW Handle = 0x87AF0064 + SQLITE_E_DONE Handle = 0x87AF0065 + SQLITE_E_IOERR_READ Handle = 0x87AF010A + SQLITE_E_IOERR_SHORT_READ Handle = 0x87AF020A + SQLITE_E_IOERR_WRITE Handle = 0x87AF030A + SQLITE_E_IOERR_FSYNC Handle = 0x87AF040A + SQLITE_E_IOERR_DIR_FSYNC Handle = 0x87AF050A + SQLITE_E_IOERR_TRUNCATE Handle = 0x87AF060A + SQLITE_E_IOERR_FSTAT Handle = 0x87AF070A + SQLITE_E_IOERR_UNLOCK Handle = 0x87AF080A + SQLITE_E_IOERR_RDLOCK Handle = 0x87AF090A + SQLITE_E_IOERR_DELETE Handle = 0x87AF0A0A + SQLITE_E_IOERR_BLOCKED Handle = 0x87AF0B0A + SQLITE_E_IOERR_NOMEM Handle = 0x87AF0C0A + SQLITE_E_IOERR_ACCESS Handle = 0x87AF0D0A + SQLITE_E_IOERR_CHECKRESERVEDLOCK Handle = 0x87AF0E0A + SQLITE_E_IOERR_LOCK Handle = 0x87AF0F0A + SQLITE_E_IOERR_CLOSE Handle = 0x87AF100A + SQLITE_E_IOERR_DIR_CLOSE Handle = 0x87AF110A + SQLITE_E_IOERR_SHMOPEN Handle = 0x87AF120A + SQLITE_E_IOERR_SHMSIZE Handle = 0x87AF130A + SQLITE_E_IOERR_SHMLOCK Handle = 0x87AF140A + SQLITE_E_IOERR_SHMMAP Handle = 0x87AF150A + SQLITE_E_IOERR_SEEK Handle = 0x87AF160A + SQLITE_E_IOERR_DELETE_NOENT Handle = 0x87AF170A + SQLITE_E_IOERR_MMAP Handle = 0x87AF180A + SQLITE_E_IOERR_GETTEMPPATH Handle = 0x87AF190A + SQLITE_E_IOERR_CONVPATH Handle = 0x87AF1A0A + SQLITE_E_IOERR_VNODE Handle = 0x87AF1A02 + SQLITE_E_IOERR_AUTH Handle = 0x87AF1A03 + SQLITE_E_LOCKED_SHAREDCACHE Handle = 0x87AF0106 + SQLITE_E_BUSY_RECOVERY Handle = 0x87AF0105 + SQLITE_E_BUSY_SNAPSHOT Handle = 0x87AF0205 + SQLITE_E_CANTOPEN_NOTEMPDIR Handle = 0x87AF010E + SQLITE_E_CANTOPEN_ISDIR Handle = 0x87AF020E + SQLITE_E_CANTOPEN_FULLPATH Handle = 0x87AF030E + SQLITE_E_CANTOPEN_CONVPATH Handle = 0x87AF040E + SQLITE_E_CORRUPT_VTAB Handle = 0x87AF010B + SQLITE_E_READONLY_RECOVERY Handle = 0x87AF0108 + SQLITE_E_READONLY_CANTLOCK Handle = 0x87AF0208 + SQLITE_E_READONLY_ROLLBACK Handle = 0x87AF0308 + SQLITE_E_READONLY_DBMOVED Handle = 0x87AF0408 + SQLITE_E_ABORT_ROLLBACK Handle = 0x87AF0204 + SQLITE_E_CONSTRAINT_CHECK Handle = 0x87AF0113 + SQLITE_E_CONSTRAINT_COMMITHOOK Handle = 0x87AF0213 + SQLITE_E_CONSTRAINT_FOREIGNKEY Handle = 0x87AF0313 + SQLITE_E_CONSTRAINT_FUNCTION Handle = 0x87AF0413 + SQLITE_E_CONSTRAINT_NOTNULL Handle = 0x87AF0513 + SQLITE_E_CONSTRAINT_PRIMARYKEY Handle = 0x87AF0613 + SQLITE_E_CONSTRAINT_TRIGGER Handle = 0x87AF0713 + SQLITE_E_CONSTRAINT_UNIQUE Handle = 0x87AF0813 + SQLITE_E_CONSTRAINT_VTAB Handle = 0x87AF0913 + SQLITE_E_CONSTRAINT_ROWID Handle = 0x87AF0A13 + SQLITE_E_NOTICE_RECOVER_WAL Handle = 0x87AF011B + SQLITE_E_NOTICE_RECOVER_ROLLBACK Handle = 0x87AF021B + SQLITE_E_WARNING_AUTOINDEX Handle = 0x87AF011C + UTC_E_TOGGLE_TRACE_STARTED Handle = 0x87C51001 + UTC_E_ALTERNATIVE_TRACE_CANNOT_PREEMPT Handle = 0x87C51002 + UTC_E_AOT_NOT_RUNNING Handle = 0x87C51003 + UTC_E_SCRIPT_TYPE_INVALID Handle = 0x87C51004 + UTC_E_SCENARIODEF_NOT_FOUND Handle = 0x87C51005 + UTC_E_TRACEPROFILE_NOT_FOUND Handle = 0x87C51006 + UTC_E_FORWARDER_ALREADY_ENABLED Handle = 0x87C51007 + UTC_E_FORWARDER_ALREADY_DISABLED Handle = 0x87C51008 + UTC_E_EVENTLOG_ENTRY_MALFORMED Handle = 0x87C51009 + UTC_E_DIAGRULES_SCHEMAVERSION_MISMATCH Handle = 0x87C5100A + UTC_E_SCRIPT_TERMINATED Handle = 0x87C5100B + UTC_E_INVALID_CUSTOM_FILTER Handle = 0x87C5100C + UTC_E_TRACE_NOT_RUNNING Handle = 0x87C5100D + UTC_E_REESCALATED_TOO_QUICKLY Handle = 0x87C5100E + UTC_E_ESCALATION_ALREADY_RUNNING Handle = 0x87C5100F + UTC_E_PERFTRACK_ALREADY_TRACING Handle = 0x87C51010 + UTC_E_REACHED_MAX_ESCALATIONS Handle = 0x87C51011 + UTC_E_FORWARDER_PRODUCER_MISMATCH Handle = 0x87C51012 + UTC_E_INTENTIONAL_SCRIPT_FAILURE Handle = 0x87C51013 + UTC_E_SQM_INIT_FAILED Handle = 0x87C51014 + UTC_E_NO_WER_LOGGER_SUPPORTED Handle = 0x87C51015 + UTC_E_TRACERS_DONT_EXIST Handle = 0x87C51016 + UTC_E_WINRT_INIT_FAILED Handle = 0x87C51017 + UTC_E_SCENARIODEF_SCHEMAVERSION_MISMATCH Handle = 0x87C51018 + UTC_E_INVALID_FILTER Handle = 0x87C51019 + UTC_E_EXE_TERMINATED Handle = 0x87C5101A + UTC_E_ESCALATION_NOT_AUTHORIZED Handle = 0x87C5101B + UTC_E_SETUP_NOT_AUTHORIZED Handle = 0x87C5101C + UTC_E_CHILD_PROCESS_FAILED Handle = 0x87C5101D + UTC_E_COMMAND_LINE_NOT_AUTHORIZED Handle = 0x87C5101E + UTC_E_CANNOT_LOAD_SCENARIO_EDITOR_XML Handle = 0x87C5101F + UTC_E_ESCALATION_TIMED_OUT Handle = 0x87C51020 + UTC_E_SETUP_TIMED_OUT Handle = 0x87C51021 + UTC_E_TRIGGER_MISMATCH Handle = 0x87C51022 + UTC_E_TRIGGER_NOT_FOUND Handle = 0x87C51023 + UTC_E_SIF_NOT_SUPPORTED Handle = 0x87C51024 + UTC_E_DELAY_TERMINATED Handle = 0x87C51025 + UTC_E_DEVICE_TICKET_ERROR Handle = 0x87C51026 + UTC_E_TRACE_BUFFER_LIMIT_EXCEEDED Handle = 0x87C51027 + UTC_E_API_RESULT_UNAVAILABLE Handle = 0x87C51028 + UTC_E_RPC_TIMEOUT Handle = 0x87C51029 + UTC_E_RPC_WAIT_FAILED Handle = 0x87C5102A + UTC_E_API_BUSY Handle = 0x87C5102B + UTC_E_TRACE_MIN_DURATION_REQUIREMENT_NOT_MET Handle = 0x87C5102C + UTC_E_EXCLUSIVITY_NOT_AVAILABLE Handle = 0x87C5102D + UTC_E_GETFILE_FILE_PATH_NOT_APPROVED Handle = 0x87C5102E + UTC_E_ESCALATION_DIRECTORY_ALREADY_EXISTS Handle = 0x87C5102F + UTC_E_TIME_TRIGGER_ON_START_INVALID Handle = 0x87C51030 + UTC_E_TIME_TRIGGER_ONLY_VALID_ON_SINGLE_TRANSITION Handle = 0x87C51031 + UTC_E_TIME_TRIGGER_INVALID_TIME_RANGE Handle = 0x87C51032 + UTC_E_MULTIPLE_TIME_TRIGGER_ON_SINGLE_STATE Handle = 0x87C51033 + UTC_E_BINARY_MISSING Handle = 0x87C51034 + UTC_E_NETWORK_CAPTURE_NOT_ALLOWED Handle = 0x87C51035 + UTC_E_FAILED_TO_RESOLVE_CONTAINER_ID Handle = 0x87C51036 + UTC_E_UNABLE_TO_RESOLVE_SESSION Handle = 0x87C51037 + UTC_E_THROTTLED Handle = 0x87C51038 + UTC_E_UNAPPROVED_SCRIPT Handle = 0x87C51039 + UTC_E_SCRIPT_MISSING Handle = 0x87C5103A + UTC_E_SCENARIO_THROTTLED Handle = 0x87C5103B + UTC_E_API_NOT_SUPPORTED Handle = 0x87C5103C + UTC_E_GETFILE_EXTERNAL_PATH_NOT_APPROVED Handle = 0x87C5103D + UTC_E_TRY_GET_SCENARIO_TIMEOUT_EXCEEDED Handle = 0x87C5103E + UTC_E_CERT_REV_FAILED Handle = 0x87C5103F + UTC_E_FAILED_TO_START_NDISCAP Handle = 0x87C51040 + UTC_E_KERNELDUMP_LIMIT_REACHED Handle = 0x87C51041 + UTC_E_MISSING_AGGREGATE_EVENT_TAG Handle = 0x87C51042 + UTC_E_INVALID_AGGREGATION_STRUCT Handle = 0x87C51043 + UTC_E_ACTION_NOT_SUPPORTED_IN_DESTINATION Handle = 0x87C51044 + UTC_E_FILTER_MISSING_ATTRIBUTE Handle = 0x87C51045 + UTC_E_FILTER_INVALID_TYPE Handle = 0x87C51046 + UTC_E_FILTER_VARIABLE_NOT_FOUND Handle = 0x87C51047 + UTC_E_FILTER_FUNCTION_RESTRICTED Handle = 0x87C51048 + UTC_E_FILTER_VERSION_MISMATCH Handle = 0x87C51049 + UTC_E_FILTER_INVALID_FUNCTION Handle = 0x87C51050 + UTC_E_FILTER_INVALID_FUNCTION_PARAMS Handle = 0x87C51051 + UTC_E_FILTER_INVALID_COMMAND Handle = 0x87C51052 + UTC_E_FILTER_ILLEGAL_EVAL Handle = 0x87C51053 + UTC_E_TTTRACER_RETURNED_ERROR Handle = 0x87C51054 + UTC_E_AGENT_DIAGNOSTICS_TOO_LARGE Handle = 0x87C51055 + UTC_E_FAILED_TO_RECEIVE_AGENT_DIAGNOSTICS Handle = 0x87C51056 + UTC_E_SCENARIO_HAS_NO_ACTIONS Handle = 0x87C51057 + UTC_E_TTTRACER_STORAGE_FULL Handle = 0x87C51058 + UTC_E_INSUFFICIENT_SPACE_TO_START_TRACE Handle = 0x87C51059 + UTC_E_ESCALATION_CANCELLED_AT_SHUTDOWN Handle = 0x87C5105A + UTC_E_GETFILEINFOACTION_FILE_NOT_APPROVED Handle = 0x87C5105B + UTC_E_SETREGKEYACTION_TYPE_NOT_APPROVED Handle = 0x87C5105C + WINML_ERR_INVALID_DEVICE Handle = 0x88900001 + WINML_ERR_INVALID_BINDING Handle = 0x88900002 + WINML_ERR_VALUE_NOTFOUND Handle = 0x88900003 + WINML_ERR_SIZE_MISMATCH Handle = 0x88900004 + STATUS_WAIT_0 NTStatus = 0x00000000 + STATUS_SUCCESS NTStatus = 0x00000000 + STATUS_WAIT_1 NTStatus = 0x00000001 + STATUS_WAIT_2 NTStatus = 0x00000002 + STATUS_WAIT_3 NTStatus = 0x00000003 + STATUS_WAIT_63 NTStatus = 0x0000003F + STATUS_ABANDONED NTStatus = 0x00000080 + STATUS_ABANDONED_WAIT_0 NTStatus = 0x00000080 + STATUS_ABANDONED_WAIT_63 NTStatus = 0x000000BF + STATUS_USER_APC NTStatus = 0x000000C0 + STATUS_ALREADY_COMPLETE NTStatus = 0x000000FF + STATUS_KERNEL_APC NTStatus = 0x00000100 + STATUS_ALERTED NTStatus = 0x00000101 + STATUS_TIMEOUT NTStatus = 0x00000102 + STATUS_PENDING NTStatus = 0x00000103 + STATUS_REPARSE NTStatus = 0x00000104 + STATUS_MORE_ENTRIES NTStatus = 0x00000105 + STATUS_NOT_ALL_ASSIGNED NTStatus = 0x00000106 + STATUS_SOME_NOT_MAPPED NTStatus = 0x00000107 + STATUS_OPLOCK_BREAK_IN_PROGRESS NTStatus = 0x00000108 + STATUS_VOLUME_MOUNTED NTStatus = 0x00000109 + STATUS_RXACT_COMMITTED NTStatus = 0x0000010A + STATUS_NOTIFY_CLEANUP NTStatus = 0x0000010B + STATUS_NOTIFY_ENUM_DIR NTStatus = 0x0000010C + STATUS_NO_QUOTAS_FOR_ACCOUNT NTStatus = 0x0000010D + STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED NTStatus = 0x0000010E + STATUS_PAGE_FAULT_TRANSITION NTStatus = 0x00000110 + STATUS_PAGE_FAULT_DEMAND_ZERO NTStatus = 0x00000111 + STATUS_PAGE_FAULT_COPY_ON_WRITE NTStatus = 0x00000112 + STATUS_PAGE_FAULT_GUARD_PAGE NTStatus = 0x00000113 + STATUS_PAGE_FAULT_PAGING_FILE NTStatus = 0x00000114 + STATUS_CACHE_PAGE_LOCKED NTStatus = 0x00000115 + STATUS_CRASH_DUMP NTStatus = 0x00000116 + STATUS_BUFFER_ALL_ZEROS NTStatus = 0x00000117 + STATUS_REPARSE_OBJECT NTStatus = 0x00000118 + STATUS_RESOURCE_REQUIREMENTS_CHANGED NTStatus = 0x00000119 + STATUS_TRANSLATION_COMPLETE NTStatus = 0x00000120 + STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY NTStatus = 0x00000121 + STATUS_NOTHING_TO_TERMINATE NTStatus = 0x00000122 + STATUS_PROCESS_NOT_IN_JOB NTStatus = 0x00000123 + STATUS_PROCESS_IN_JOB NTStatus = 0x00000124 + STATUS_VOLSNAP_HIBERNATE_READY NTStatus = 0x00000125 + STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY NTStatus = 0x00000126 + STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED NTStatus = 0x00000127 + STATUS_INTERRUPT_STILL_CONNECTED NTStatus = 0x00000128 + STATUS_PROCESS_CLONED NTStatus = 0x00000129 + STATUS_FILE_LOCKED_WITH_ONLY_READERS NTStatus = 0x0000012A + STATUS_FILE_LOCKED_WITH_WRITERS NTStatus = 0x0000012B + STATUS_VALID_IMAGE_HASH NTStatus = 0x0000012C + STATUS_VALID_CATALOG_HASH NTStatus = 0x0000012D + STATUS_VALID_STRONG_CODE_HASH NTStatus = 0x0000012E + STATUS_GHOSTED NTStatus = 0x0000012F + STATUS_DATA_OVERWRITTEN NTStatus = 0x00000130 + STATUS_RESOURCEMANAGER_READ_ONLY NTStatus = 0x00000202 + STATUS_RING_PREVIOUSLY_EMPTY NTStatus = 0x00000210 + STATUS_RING_PREVIOUSLY_FULL NTStatus = 0x00000211 + STATUS_RING_PREVIOUSLY_ABOVE_QUOTA NTStatus = 0x00000212 + STATUS_RING_NEWLY_EMPTY NTStatus = 0x00000213 + STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT NTStatus = 0x00000214 + STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE NTStatus = 0x00000215 + STATUS_OPLOCK_HANDLE_CLOSED NTStatus = 0x00000216 + STATUS_WAIT_FOR_OPLOCK NTStatus = 0x00000367 + STATUS_REPARSE_GLOBAL NTStatus = 0x00000368 + STATUS_FLT_IO_COMPLETE NTStatus = 0x001C0001 + STATUS_OBJECT_NAME_EXISTS NTStatus = 0x40000000 + STATUS_THREAD_WAS_SUSPENDED NTStatus = 0x40000001 + STATUS_WORKING_SET_LIMIT_RANGE NTStatus = 0x40000002 + STATUS_IMAGE_NOT_AT_BASE NTStatus = 0x40000003 + STATUS_RXACT_STATE_CREATED NTStatus = 0x40000004 + STATUS_SEGMENT_NOTIFICATION NTStatus = 0x40000005 + STATUS_LOCAL_USER_SESSION_KEY NTStatus = 0x40000006 + STATUS_BAD_CURRENT_DIRECTORY NTStatus = 0x40000007 + STATUS_SERIAL_MORE_WRITES NTStatus = 0x40000008 + STATUS_REGISTRY_RECOVERED NTStatus = 0x40000009 + STATUS_FT_READ_RECOVERY_FROM_BACKUP NTStatus = 0x4000000A + STATUS_FT_WRITE_RECOVERY NTStatus = 0x4000000B + STATUS_SERIAL_COUNTER_TIMEOUT NTStatus = 0x4000000C + STATUS_NULL_LM_PASSWORD NTStatus = 0x4000000D + STATUS_IMAGE_MACHINE_TYPE_MISMATCH NTStatus = 0x4000000E + STATUS_RECEIVE_PARTIAL NTStatus = 0x4000000F + STATUS_RECEIVE_EXPEDITED NTStatus = 0x40000010 + STATUS_RECEIVE_PARTIAL_EXPEDITED NTStatus = 0x40000011 + STATUS_EVENT_DONE NTStatus = 0x40000012 + STATUS_EVENT_PENDING NTStatus = 0x40000013 + STATUS_CHECKING_FILE_SYSTEM NTStatus = 0x40000014 + STATUS_FATAL_APP_EXIT NTStatus = 0x40000015 + STATUS_PREDEFINED_HANDLE NTStatus = 0x40000016 + STATUS_WAS_UNLOCKED NTStatus = 0x40000017 + STATUS_SERVICE_NOTIFICATION NTStatus = 0x40000018 + STATUS_WAS_LOCKED NTStatus = 0x40000019 + STATUS_LOG_HARD_ERROR NTStatus = 0x4000001A + STATUS_ALREADY_WIN32 NTStatus = 0x4000001B + STATUS_WX86_UNSIMULATE NTStatus = 0x4000001C + STATUS_WX86_CONTINUE NTStatus = 0x4000001D + STATUS_WX86_SINGLE_STEP NTStatus = 0x4000001E + STATUS_WX86_BREAKPOINT NTStatus = 0x4000001F + STATUS_WX86_EXCEPTION_CONTINUE NTStatus = 0x40000020 + STATUS_WX86_EXCEPTION_LASTCHANCE NTStatus = 0x40000021 + STATUS_WX86_EXCEPTION_CHAIN NTStatus = 0x40000022 + STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE NTStatus = 0x40000023 + STATUS_NO_YIELD_PERFORMED NTStatus = 0x40000024 + STATUS_TIMER_RESUME_IGNORED NTStatus = 0x40000025 + STATUS_ARBITRATION_UNHANDLED NTStatus = 0x40000026 + STATUS_CARDBUS_NOT_SUPPORTED NTStatus = 0x40000027 + STATUS_WX86_CREATEWX86TIB NTStatus = 0x40000028 + STATUS_MP_PROCESSOR_MISMATCH NTStatus = 0x40000029 + STATUS_HIBERNATED NTStatus = 0x4000002A + STATUS_RESUME_HIBERNATION NTStatus = 0x4000002B + STATUS_FIRMWARE_UPDATED NTStatus = 0x4000002C + STATUS_DRIVERS_LEAKING_LOCKED_PAGES NTStatus = 0x4000002D + STATUS_MESSAGE_RETRIEVED NTStatus = 0x4000002E + STATUS_SYSTEM_POWERSTATE_TRANSITION NTStatus = 0x4000002F + STATUS_ALPC_CHECK_COMPLETION_LIST NTStatus = 0x40000030 + STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION NTStatus = 0x40000031 + STATUS_ACCESS_AUDIT_BY_POLICY NTStatus = 0x40000032 + STATUS_ABANDON_HIBERFILE NTStatus = 0x40000033 + STATUS_BIZRULES_NOT_ENABLED NTStatus = 0x40000034 + STATUS_FT_READ_FROM_COPY NTStatus = 0x40000035 + STATUS_IMAGE_AT_DIFFERENT_BASE NTStatus = 0x40000036 + STATUS_PATCH_DEFERRED NTStatus = 0x40000037 + STATUS_HEURISTIC_DAMAGE_POSSIBLE NTStatus = 0x40190001 + STATUS_GUARD_PAGE_VIOLATION NTStatus = 0x80000001 + STATUS_DATATYPE_MISALIGNMENT NTStatus = 0x80000002 + STATUS_BREAKPOINT NTStatus = 0x80000003 + STATUS_SINGLE_STEP NTStatus = 0x80000004 + STATUS_BUFFER_OVERFLOW NTStatus = 0x80000005 + STATUS_NO_MORE_FILES NTStatus = 0x80000006 + STATUS_WAKE_SYSTEM_DEBUGGER NTStatus = 0x80000007 + STATUS_HANDLES_CLOSED NTStatus = 0x8000000A + STATUS_NO_INHERITANCE NTStatus = 0x8000000B + STATUS_GUID_SUBSTITUTION_MADE NTStatus = 0x8000000C + STATUS_PARTIAL_COPY NTStatus = 0x8000000D + STATUS_DEVICE_PAPER_EMPTY NTStatus = 0x8000000E + STATUS_DEVICE_POWERED_OFF NTStatus = 0x8000000F + STATUS_DEVICE_OFF_LINE NTStatus = 0x80000010 + STATUS_DEVICE_BUSY NTStatus = 0x80000011 + STATUS_NO_MORE_EAS NTStatus = 0x80000012 + STATUS_INVALID_EA_NAME NTStatus = 0x80000013 + STATUS_EA_LIST_INCONSISTENT NTStatus = 0x80000014 + STATUS_INVALID_EA_FLAG NTStatus = 0x80000015 + STATUS_VERIFY_REQUIRED NTStatus = 0x80000016 + STATUS_EXTRANEOUS_INFORMATION NTStatus = 0x80000017 + STATUS_RXACT_COMMIT_NECESSARY NTStatus = 0x80000018 + STATUS_NO_MORE_ENTRIES NTStatus = 0x8000001A + STATUS_FILEMARK_DETECTED NTStatus = 0x8000001B + STATUS_MEDIA_CHANGED NTStatus = 0x8000001C + STATUS_BUS_RESET NTStatus = 0x8000001D + STATUS_END_OF_MEDIA NTStatus = 0x8000001E + STATUS_BEGINNING_OF_MEDIA NTStatus = 0x8000001F + STATUS_MEDIA_CHECK NTStatus = 0x80000020 + STATUS_SETMARK_DETECTED NTStatus = 0x80000021 + STATUS_NO_DATA_DETECTED NTStatus = 0x80000022 + STATUS_REDIRECTOR_HAS_OPEN_HANDLES NTStatus = 0x80000023 + STATUS_SERVER_HAS_OPEN_HANDLES NTStatus = 0x80000024 + STATUS_ALREADY_DISCONNECTED NTStatus = 0x80000025 + STATUS_LONGJUMP NTStatus = 0x80000026 + STATUS_CLEANER_CARTRIDGE_INSTALLED NTStatus = 0x80000027 + STATUS_PLUGPLAY_QUERY_VETOED NTStatus = 0x80000028 + STATUS_UNWIND_CONSOLIDATE NTStatus = 0x80000029 + STATUS_REGISTRY_HIVE_RECOVERED NTStatus = 0x8000002A + STATUS_DLL_MIGHT_BE_INSECURE NTStatus = 0x8000002B + STATUS_DLL_MIGHT_BE_INCOMPATIBLE NTStatus = 0x8000002C + STATUS_STOPPED_ON_SYMLINK NTStatus = 0x8000002D + STATUS_CANNOT_GRANT_REQUESTED_OPLOCK NTStatus = 0x8000002E + STATUS_NO_ACE_CONDITION NTStatus = 0x8000002F + STATUS_DEVICE_SUPPORT_IN_PROGRESS NTStatus = 0x80000030 + STATUS_DEVICE_POWER_CYCLE_REQUIRED NTStatus = 0x80000031 + STATUS_NO_WORK_DONE NTStatus = 0x80000032 + STATUS_CLUSTER_NODE_ALREADY_UP NTStatus = 0x80130001 + STATUS_CLUSTER_NODE_ALREADY_DOWN NTStatus = 0x80130002 + STATUS_CLUSTER_NETWORK_ALREADY_ONLINE NTStatus = 0x80130003 + STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE NTStatus = 0x80130004 + STATUS_CLUSTER_NODE_ALREADY_MEMBER NTStatus = 0x80130005 + STATUS_FLT_BUFFER_TOO_SMALL NTStatus = 0x801C0001 + STATUS_FVE_PARTIAL_METADATA NTStatus = 0x80210001 + STATUS_FVE_TRANSIENT_STATE NTStatus = 0x80210002 + STATUS_CLOUD_FILE_PROPERTY_BLOB_CHECKSUM_MISMATCH NTStatus = 0x8000CF00 + STATUS_UNSUCCESSFUL NTStatus = 0xC0000001 + STATUS_NOT_IMPLEMENTED NTStatus = 0xC0000002 + STATUS_INVALID_INFO_CLASS NTStatus = 0xC0000003 + STATUS_INFO_LENGTH_MISMATCH NTStatus = 0xC0000004 + STATUS_ACCESS_VIOLATION NTStatus = 0xC0000005 + STATUS_IN_PAGE_ERROR NTStatus = 0xC0000006 + STATUS_PAGEFILE_QUOTA NTStatus = 0xC0000007 + STATUS_INVALID_HANDLE NTStatus = 0xC0000008 + STATUS_BAD_INITIAL_STACK NTStatus = 0xC0000009 + STATUS_BAD_INITIAL_PC NTStatus = 0xC000000A + STATUS_INVALID_CID NTStatus = 0xC000000B + STATUS_TIMER_NOT_CANCELED NTStatus = 0xC000000C + STATUS_INVALID_PARAMETER NTStatus = 0xC000000D + STATUS_NO_SUCH_DEVICE NTStatus = 0xC000000E + STATUS_NO_SUCH_FILE NTStatus = 0xC000000F + STATUS_INVALID_DEVICE_REQUEST NTStatus = 0xC0000010 + STATUS_END_OF_FILE NTStatus = 0xC0000011 + STATUS_WRONG_VOLUME NTStatus = 0xC0000012 + STATUS_NO_MEDIA_IN_DEVICE NTStatus = 0xC0000013 + STATUS_UNRECOGNIZED_MEDIA NTStatus = 0xC0000014 + STATUS_NONEXISTENT_SECTOR NTStatus = 0xC0000015 + STATUS_MORE_PROCESSING_REQUIRED NTStatus = 0xC0000016 + STATUS_NO_MEMORY NTStatus = 0xC0000017 + STATUS_CONFLICTING_ADDRESSES NTStatus = 0xC0000018 + STATUS_NOT_MAPPED_VIEW NTStatus = 0xC0000019 + STATUS_UNABLE_TO_FREE_VM NTStatus = 0xC000001A + STATUS_UNABLE_TO_DELETE_SECTION NTStatus = 0xC000001B + STATUS_INVALID_SYSTEM_SERVICE NTStatus = 0xC000001C + STATUS_ILLEGAL_INSTRUCTION NTStatus = 0xC000001D + STATUS_INVALID_LOCK_SEQUENCE NTStatus = 0xC000001E + STATUS_INVALID_VIEW_SIZE NTStatus = 0xC000001F + STATUS_INVALID_FILE_FOR_SECTION NTStatus = 0xC0000020 + STATUS_ALREADY_COMMITTED NTStatus = 0xC0000021 + STATUS_ACCESS_DENIED NTStatus = 0xC0000022 + STATUS_BUFFER_TOO_SMALL NTStatus = 0xC0000023 + STATUS_OBJECT_TYPE_MISMATCH NTStatus = 0xC0000024 + STATUS_NONCONTINUABLE_EXCEPTION NTStatus = 0xC0000025 + STATUS_INVALID_DISPOSITION NTStatus = 0xC0000026 + STATUS_UNWIND NTStatus = 0xC0000027 + STATUS_BAD_STACK NTStatus = 0xC0000028 + STATUS_INVALID_UNWIND_TARGET NTStatus = 0xC0000029 + STATUS_NOT_LOCKED NTStatus = 0xC000002A + STATUS_PARITY_ERROR NTStatus = 0xC000002B + STATUS_UNABLE_TO_DECOMMIT_VM NTStatus = 0xC000002C + STATUS_NOT_COMMITTED NTStatus = 0xC000002D + STATUS_INVALID_PORT_ATTRIBUTES NTStatus = 0xC000002E + STATUS_PORT_MESSAGE_TOO_LONG NTStatus = 0xC000002F + STATUS_INVALID_PARAMETER_MIX NTStatus = 0xC0000030 + STATUS_INVALID_QUOTA_LOWER NTStatus = 0xC0000031 + STATUS_DISK_CORRUPT_ERROR NTStatus = 0xC0000032 + STATUS_OBJECT_NAME_INVALID NTStatus = 0xC0000033 + STATUS_OBJECT_NAME_NOT_FOUND NTStatus = 0xC0000034 + STATUS_OBJECT_NAME_COLLISION NTStatus = 0xC0000035 + STATUS_PORT_DO_NOT_DISTURB NTStatus = 0xC0000036 + STATUS_PORT_DISCONNECTED NTStatus = 0xC0000037 + STATUS_DEVICE_ALREADY_ATTACHED NTStatus = 0xC0000038 + STATUS_OBJECT_PATH_INVALID NTStatus = 0xC0000039 + STATUS_OBJECT_PATH_NOT_FOUND NTStatus = 0xC000003A + STATUS_OBJECT_PATH_SYNTAX_BAD NTStatus = 0xC000003B + STATUS_DATA_OVERRUN NTStatus = 0xC000003C + STATUS_DATA_LATE_ERROR NTStatus = 0xC000003D + STATUS_DATA_ERROR NTStatus = 0xC000003E + STATUS_CRC_ERROR NTStatus = 0xC000003F + STATUS_SECTION_TOO_BIG NTStatus = 0xC0000040 + STATUS_PORT_CONNECTION_REFUSED NTStatus = 0xC0000041 + STATUS_INVALID_PORT_HANDLE NTStatus = 0xC0000042 + STATUS_SHARING_VIOLATION NTStatus = 0xC0000043 + STATUS_QUOTA_EXCEEDED NTStatus = 0xC0000044 + STATUS_INVALID_PAGE_PROTECTION NTStatus = 0xC0000045 + STATUS_MUTANT_NOT_OWNED NTStatus = 0xC0000046 + STATUS_SEMAPHORE_LIMIT_EXCEEDED NTStatus = 0xC0000047 + STATUS_PORT_ALREADY_SET NTStatus = 0xC0000048 + STATUS_SECTION_NOT_IMAGE NTStatus = 0xC0000049 + STATUS_SUSPEND_COUNT_EXCEEDED NTStatus = 0xC000004A + STATUS_THREAD_IS_TERMINATING NTStatus = 0xC000004B + STATUS_BAD_WORKING_SET_LIMIT NTStatus = 0xC000004C + STATUS_INCOMPATIBLE_FILE_MAP NTStatus = 0xC000004D + STATUS_SECTION_PROTECTION NTStatus = 0xC000004E + STATUS_EAS_NOT_SUPPORTED NTStatus = 0xC000004F + STATUS_EA_TOO_LARGE NTStatus = 0xC0000050 + STATUS_NONEXISTENT_EA_ENTRY NTStatus = 0xC0000051 + STATUS_NO_EAS_ON_FILE NTStatus = 0xC0000052 + STATUS_EA_CORRUPT_ERROR NTStatus = 0xC0000053 + STATUS_FILE_LOCK_CONFLICT NTStatus = 0xC0000054 + STATUS_LOCK_NOT_GRANTED NTStatus = 0xC0000055 + STATUS_DELETE_PENDING NTStatus = 0xC0000056 + STATUS_CTL_FILE_NOT_SUPPORTED NTStatus = 0xC0000057 + STATUS_UNKNOWN_REVISION NTStatus = 0xC0000058 + STATUS_REVISION_MISMATCH NTStatus = 0xC0000059 + STATUS_INVALID_OWNER NTStatus = 0xC000005A + STATUS_INVALID_PRIMARY_GROUP NTStatus = 0xC000005B + STATUS_NO_IMPERSONATION_TOKEN NTStatus = 0xC000005C + STATUS_CANT_DISABLE_MANDATORY NTStatus = 0xC000005D + STATUS_NO_LOGON_SERVERS NTStatus = 0xC000005E + STATUS_NO_SUCH_LOGON_SESSION NTStatus = 0xC000005F + STATUS_NO_SUCH_PRIVILEGE NTStatus = 0xC0000060 + STATUS_PRIVILEGE_NOT_HELD NTStatus = 0xC0000061 + STATUS_INVALID_ACCOUNT_NAME NTStatus = 0xC0000062 + STATUS_USER_EXISTS NTStatus = 0xC0000063 + STATUS_NO_SUCH_USER NTStatus = 0xC0000064 + STATUS_GROUP_EXISTS NTStatus = 0xC0000065 + STATUS_NO_SUCH_GROUP NTStatus = 0xC0000066 + STATUS_MEMBER_IN_GROUP NTStatus = 0xC0000067 + STATUS_MEMBER_NOT_IN_GROUP NTStatus = 0xC0000068 + STATUS_LAST_ADMIN NTStatus = 0xC0000069 + STATUS_WRONG_PASSWORD NTStatus = 0xC000006A + STATUS_ILL_FORMED_PASSWORD NTStatus = 0xC000006B + STATUS_PASSWORD_RESTRICTION NTStatus = 0xC000006C + STATUS_LOGON_FAILURE NTStatus = 0xC000006D + STATUS_ACCOUNT_RESTRICTION NTStatus = 0xC000006E + STATUS_INVALID_LOGON_HOURS NTStatus = 0xC000006F + STATUS_INVALID_WORKSTATION NTStatus = 0xC0000070 + STATUS_PASSWORD_EXPIRED NTStatus = 0xC0000071 + STATUS_ACCOUNT_DISABLED NTStatus = 0xC0000072 + STATUS_NONE_MAPPED NTStatus = 0xC0000073 + STATUS_TOO_MANY_LUIDS_REQUESTED NTStatus = 0xC0000074 + STATUS_LUIDS_EXHAUSTED NTStatus = 0xC0000075 + STATUS_INVALID_SUB_AUTHORITY NTStatus = 0xC0000076 + STATUS_INVALID_ACL NTStatus = 0xC0000077 + STATUS_INVALID_SID NTStatus = 0xC0000078 + STATUS_INVALID_SECURITY_DESCR NTStatus = 0xC0000079 + STATUS_PROCEDURE_NOT_FOUND NTStatus = 0xC000007A + STATUS_INVALID_IMAGE_FORMAT NTStatus = 0xC000007B + STATUS_NO_TOKEN NTStatus = 0xC000007C + STATUS_BAD_INHERITANCE_ACL NTStatus = 0xC000007D + STATUS_RANGE_NOT_LOCKED NTStatus = 0xC000007E + STATUS_DISK_FULL NTStatus = 0xC000007F + STATUS_SERVER_DISABLED NTStatus = 0xC0000080 + STATUS_SERVER_NOT_DISABLED NTStatus = 0xC0000081 + STATUS_TOO_MANY_GUIDS_REQUESTED NTStatus = 0xC0000082 + STATUS_GUIDS_EXHAUSTED NTStatus = 0xC0000083 + STATUS_INVALID_ID_AUTHORITY NTStatus = 0xC0000084 + STATUS_AGENTS_EXHAUSTED NTStatus = 0xC0000085 + STATUS_INVALID_VOLUME_LABEL NTStatus = 0xC0000086 + STATUS_SECTION_NOT_EXTENDED NTStatus = 0xC0000087 + STATUS_NOT_MAPPED_DATA NTStatus = 0xC0000088 + STATUS_RESOURCE_DATA_NOT_FOUND NTStatus = 0xC0000089 + STATUS_RESOURCE_TYPE_NOT_FOUND NTStatus = 0xC000008A + STATUS_RESOURCE_NAME_NOT_FOUND NTStatus = 0xC000008B + STATUS_ARRAY_BOUNDS_EXCEEDED NTStatus = 0xC000008C + STATUS_FLOAT_DENORMAL_OPERAND NTStatus = 0xC000008D + STATUS_FLOAT_DIVIDE_BY_ZERO NTStatus = 0xC000008E + STATUS_FLOAT_INEXACT_RESULT NTStatus = 0xC000008F + STATUS_FLOAT_INVALID_OPERATION NTStatus = 0xC0000090 + STATUS_FLOAT_OVERFLOW NTStatus = 0xC0000091 + STATUS_FLOAT_STACK_CHECK NTStatus = 0xC0000092 + STATUS_FLOAT_UNDERFLOW NTStatus = 0xC0000093 + STATUS_INTEGER_DIVIDE_BY_ZERO NTStatus = 0xC0000094 + STATUS_INTEGER_OVERFLOW NTStatus = 0xC0000095 + STATUS_PRIVILEGED_INSTRUCTION NTStatus = 0xC0000096 + STATUS_TOO_MANY_PAGING_FILES NTStatus = 0xC0000097 + STATUS_FILE_INVALID NTStatus = 0xC0000098 + STATUS_ALLOTTED_SPACE_EXCEEDED NTStatus = 0xC0000099 + STATUS_INSUFFICIENT_RESOURCES NTStatus = 0xC000009A + STATUS_DFS_EXIT_PATH_FOUND NTStatus = 0xC000009B + STATUS_DEVICE_DATA_ERROR NTStatus = 0xC000009C + STATUS_DEVICE_NOT_CONNECTED NTStatus = 0xC000009D + STATUS_DEVICE_POWER_FAILURE NTStatus = 0xC000009E + STATUS_FREE_VM_NOT_AT_BASE NTStatus = 0xC000009F + STATUS_MEMORY_NOT_ALLOCATED NTStatus = 0xC00000A0 + STATUS_WORKING_SET_QUOTA NTStatus = 0xC00000A1 + STATUS_MEDIA_WRITE_PROTECTED NTStatus = 0xC00000A2 + STATUS_DEVICE_NOT_READY NTStatus = 0xC00000A3 + STATUS_INVALID_GROUP_ATTRIBUTES NTStatus = 0xC00000A4 + STATUS_BAD_IMPERSONATION_LEVEL NTStatus = 0xC00000A5 + STATUS_CANT_OPEN_ANONYMOUS NTStatus = 0xC00000A6 + STATUS_BAD_VALIDATION_CLASS NTStatus = 0xC00000A7 + STATUS_BAD_TOKEN_TYPE NTStatus = 0xC00000A8 + STATUS_BAD_MASTER_BOOT_RECORD NTStatus = 0xC00000A9 + STATUS_INSTRUCTION_MISALIGNMENT NTStatus = 0xC00000AA + STATUS_INSTANCE_NOT_AVAILABLE NTStatus = 0xC00000AB + STATUS_PIPE_NOT_AVAILABLE NTStatus = 0xC00000AC + STATUS_INVALID_PIPE_STATE NTStatus = 0xC00000AD + STATUS_PIPE_BUSY NTStatus = 0xC00000AE + STATUS_ILLEGAL_FUNCTION NTStatus = 0xC00000AF + STATUS_PIPE_DISCONNECTED NTStatus = 0xC00000B0 + STATUS_PIPE_CLOSING NTStatus = 0xC00000B1 + STATUS_PIPE_CONNECTED NTStatus = 0xC00000B2 + STATUS_PIPE_LISTENING NTStatus = 0xC00000B3 + STATUS_INVALID_READ_MODE NTStatus = 0xC00000B4 + STATUS_IO_TIMEOUT NTStatus = 0xC00000B5 + STATUS_FILE_FORCED_CLOSED NTStatus = 0xC00000B6 + STATUS_PROFILING_NOT_STARTED NTStatus = 0xC00000B7 + STATUS_PROFILING_NOT_STOPPED NTStatus = 0xC00000B8 + STATUS_COULD_NOT_INTERPRET NTStatus = 0xC00000B9 + STATUS_FILE_IS_A_DIRECTORY NTStatus = 0xC00000BA + STATUS_NOT_SUPPORTED NTStatus = 0xC00000BB + STATUS_REMOTE_NOT_LISTENING NTStatus = 0xC00000BC + STATUS_DUPLICATE_NAME NTStatus = 0xC00000BD + STATUS_BAD_NETWORK_PATH NTStatus = 0xC00000BE + STATUS_NETWORK_BUSY NTStatus = 0xC00000BF + STATUS_DEVICE_DOES_NOT_EXIST NTStatus = 0xC00000C0 + STATUS_TOO_MANY_COMMANDS NTStatus = 0xC00000C1 + STATUS_ADAPTER_HARDWARE_ERROR NTStatus = 0xC00000C2 + STATUS_INVALID_NETWORK_RESPONSE NTStatus = 0xC00000C3 + STATUS_UNEXPECTED_NETWORK_ERROR NTStatus = 0xC00000C4 + STATUS_BAD_REMOTE_ADAPTER NTStatus = 0xC00000C5 + STATUS_PRINT_QUEUE_FULL NTStatus = 0xC00000C6 + STATUS_NO_SPOOL_SPACE NTStatus = 0xC00000C7 + STATUS_PRINT_CANCELLED NTStatus = 0xC00000C8 + STATUS_NETWORK_NAME_DELETED NTStatus = 0xC00000C9 + STATUS_NETWORK_ACCESS_DENIED NTStatus = 0xC00000CA + STATUS_BAD_DEVICE_TYPE NTStatus = 0xC00000CB + STATUS_BAD_NETWORK_NAME NTStatus = 0xC00000CC + STATUS_TOO_MANY_NAMES NTStatus = 0xC00000CD + STATUS_TOO_MANY_SESSIONS NTStatus = 0xC00000CE + STATUS_SHARING_PAUSED NTStatus = 0xC00000CF + STATUS_REQUEST_NOT_ACCEPTED NTStatus = 0xC00000D0 + STATUS_REDIRECTOR_PAUSED NTStatus = 0xC00000D1 + STATUS_NET_WRITE_FAULT NTStatus = 0xC00000D2 + STATUS_PROFILING_AT_LIMIT NTStatus = 0xC00000D3 + STATUS_NOT_SAME_DEVICE NTStatus = 0xC00000D4 + STATUS_FILE_RENAMED NTStatus = 0xC00000D5 + STATUS_VIRTUAL_CIRCUIT_CLOSED NTStatus = 0xC00000D6 + STATUS_NO_SECURITY_ON_OBJECT NTStatus = 0xC00000D7 + STATUS_CANT_WAIT NTStatus = 0xC00000D8 + STATUS_PIPE_EMPTY NTStatus = 0xC00000D9 + STATUS_CANT_ACCESS_DOMAIN_INFO NTStatus = 0xC00000DA + STATUS_CANT_TERMINATE_SELF NTStatus = 0xC00000DB + STATUS_INVALID_SERVER_STATE NTStatus = 0xC00000DC + STATUS_INVALID_DOMAIN_STATE NTStatus = 0xC00000DD + STATUS_INVALID_DOMAIN_ROLE NTStatus = 0xC00000DE + STATUS_NO_SUCH_DOMAIN NTStatus = 0xC00000DF + STATUS_DOMAIN_EXISTS NTStatus = 0xC00000E0 + STATUS_DOMAIN_LIMIT_EXCEEDED NTStatus = 0xC00000E1 + STATUS_OPLOCK_NOT_GRANTED NTStatus = 0xC00000E2 + STATUS_INVALID_OPLOCK_PROTOCOL NTStatus = 0xC00000E3 + STATUS_INTERNAL_DB_CORRUPTION NTStatus = 0xC00000E4 + STATUS_INTERNAL_ERROR NTStatus = 0xC00000E5 + STATUS_GENERIC_NOT_MAPPED NTStatus = 0xC00000E6 + STATUS_BAD_DESCRIPTOR_FORMAT NTStatus = 0xC00000E7 + STATUS_INVALID_USER_BUFFER NTStatus = 0xC00000E8 + STATUS_UNEXPECTED_IO_ERROR NTStatus = 0xC00000E9 + STATUS_UNEXPECTED_MM_CREATE_ERR NTStatus = 0xC00000EA + STATUS_UNEXPECTED_MM_MAP_ERROR NTStatus = 0xC00000EB + STATUS_UNEXPECTED_MM_EXTEND_ERR NTStatus = 0xC00000EC + STATUS_NOT_LOGON_PROCESS NTStatus = 0xC00000ED + STATUS_LOGON_SESSION_EXISTS NTStatus = 0xC00000EE + STATUS_INVALID_PARAMETER_1 NTStatus = 0xC00000EF + STATUS_INVALID_PARAMETER_2 NTStatus = 0xC00000F0 + STATUS_INVALID_PARAMETER_3 NTStatus = 0xC00000F1 + STATUS_INVALID_PARAMETER_4 NTStatus = 0xC00000F2 + STATUS_INVALID_PARAMETER_5 NTStatus = 0xC00000F3 + STATUS_INVALID_PARAMETER_6 NTStatus = 0xC00000F4 + STATUS_INVALID_PARAMETER_7 NTStatus = 0xC00000F5 + STATUS_INVALID_PARAMETER_8 NTStatus = 0xC00000F6 + STATUS_INVALID_PARAMETER_9 NTStatus = 0xC00000F7 + STATUS_INVALID_PARAMETER_10 NTStatus = 0xC00000F8 + STATUS_INVALID_PARAMETER_11 NTStatus = 0xC00000F9 + STATUS_INVALID_PARAMETER_12 NTStatus = 0xC00000FA + STATUS_REDIRECTOR_NOT_STARTED NTStatus = 0xC00000FB + STATUS_REDIRECTOR_STARTED NTStatus = 0xC00000FC + STATUS_STACK_OVERFLOW NTStatus = 0xC00000FD + STATUS_NO_SUCH_PACKAGE NTStatus = 0xC00000FE + STATUS_BAD_FUNCTION_TABLE NTStatus = 0xC00000FF + STATUS_VARIABLE_NOT_FOUND NTStatus = 0xC0000100 + STATUS_DIRECTORY_NOT_EMPTY NTStatus = 0xC0000101 + STATUS_FILE_CORRUPT_ERROR NTStatus = 0xC0000102 + STATUS_NOT_A_DIRECTORY NTStatus = 0xC0000103 + STATUS_BAD_LOGON_SESSION_STATE NTStatus = 0xC0000104 + STATUS_LOGON_SESSION_COLLISION NTStatus = 0xC0000105 + STATUS_NAME_TOO_LONG NTStatus = 0xC0000106 + STATUS_FILES_OPEN NTStatus = 0xC0000107 + STATUS_CONNECTION_IN_USE NTStatus = 0xC0000108 + STATUS_MESSAGE_NOT_FOUND NTStatus = 0xC0000109 + STATUS_PROCESS_IS_TERMINATING NTStatus = 0xC000010A + STATUS_INVALID_LOGON_TYPE NTStatus = 0xC000010B + STATUS_NO_GUID_TRANSLATION NTStatus = 0xC000010C + STATUS_CANNOT_IMPERSONATE NTStatus = 0xC000010D + STATUS_IMAGE_ALREADY_LOADED NTStatus = 0xC000010E + STATUS_ABIOS_NOT_PRESENT NTStatus = 0xC000010F + STATUS_ABIOS_LID_NOT_EXIST NTStatus = 0xC0000110 + STATUS_ABIOS_LID_ALREADY_OWNED NTStatus = 0xC0000111 + STATUS_ABIOS_NOT_LID_OWNER NTStatus = 0xC0000112 + STATUS_ABIOS_INVALID_COMMAND NTStatus = 0xC0000113 + STATUS_ABIOS_INVALID_LID NTStatus = 0xC0000114 + STATUS_ABIOS_SELECTOR_NOT_AVAILABLE NTStatus = 0xC0000115 + STATUS_ABIOS_INVALID_SELECTOR NTStatus = 0xC0000116 + STATUS_NO_LDT NTStatus = 0xC0000117 + STATUS_INVALID_LDT_SIZE NTStatus = 0xC0000118 + STATUS_INVALID_LDT_OFFSET NTStatus = 0xC0000119 + STATUS_INVALID_LDT_DESCRIPTOR NTStatus = 0xC000011A + STATUS_INVALID_IMAGE_NE_FORMAT NTStatus = 0xC000011B + STATUS_RXACT_INVALID_STATE NTStatus = 0xC000011C + STATUS_RXACT_COMMIT_FAILURE NTStatus = 0xC000011D + STATUS_MAPPED_FILE_SIZE_ZERO NTStatus = 0xC000011E + STATUS_TOO_MANY_OPENED_FILES NTStatus = 0xC000011F + STATUS_CANCELLED NTStatus = 0xC0000120 + STATUS_CANNOT_DELETE NTStatus = 0xC0000121 + STATUS_INVALID_COMPUTER_NAME NTStatus = 0xC0000122 + STATUS_FILE_DELETED NTStatus = 0xC0000123 + STATUS_SPECIAL_ACCOUNT NTStatus = 0xC0000124 + STATUS_SPECIAL_GROUP NTStatus = 0xC0000125 + STATUS_SPECIAL_USER NTStatus = 0xC0000126 + STATUS_MEMBERS_PRIMARY_GROUP NTStatus = 0xC0000127 + STATUS_FILE_CLOSED NTStatus = 0xC0000128 + STATUS_TOO_MANY_THREADS NTStatus = 0xC0000129 + STATUS_THREAD_NOT_IN_PROCESS NTStatus = 0xC000012A + STATUS_TOKEN_ALREADY_IN_USE NTStatus = 0xC000012B + STATUS_PAGEFILE_QUOTA_EXCEEDED NTStatus = 0xC000012C + STATUS_COMMITMENT_LIMIT NTStatus = 0xC000012D + STATUS_INVALID_IMAGE_LE_FORMAT NTStatus = 0xC000012E + STATUS_INVALID_IMAGE_NOT_MZ NTStatus = 0xC000012F + STATUS_INVALID_IMAGE_PROTECT NTStatus = 0xC0000130 + STATUS_INVALID_IMAGE_WIN_16 NTStatus = 0xC0000131 + STATUS_LOGON_SERVER_CONFLICT NTStatus = 0xC0000132 + STATUS_TIME_DIFFERENCE_AT_DC NTStatus = 0xC0000133 + STATUS_SYNCHRONIZATION_REQUIRED NTStatus = 0xC0000134 + STATUS_DLL_NOT_FOUND NTStatus = 0xC0000135 + STATUS_OPEN_FAILED NTStatus = 0xC0000136 + STATUS_IO_PRIVILEGE_FAILED NTStatus = 0xC0000137 + STATUS_ORDINAL_NOT_FOUND NTStatus = 0xC0000138 + STATUS_ENTRYPOINT_NOT_FOUND NTStatus = 0xC0000139 + STATUS_CONTROL_C_EXIT NTStatus = 0xC000013A + STATUS_LOCAL_DISCONNECT NTStatus = 0xC000013B + STATUS_REMOTE_DISCONNECT NTStatus = 0xC000013C + STATUS_REMOTE_RESOURCES NTStatus = 0xC000013D + STATUS_LINK_FAILED NTStatus = 0xC000013E + STATUS_LINK_TIMEOUT NTStatus = 0xC000013F + STATUS_INVALID_CONNECTION NTStatus = 0xC0000140 + STATUS_INVALID_ADDRESS NTStatus = 0xC0000141 + STATUS_DLL_INIT_FAILED NTStatus = 0xC0000142 + STATUS_MISSING_SYSTEMFILE NTStatus = 0xC0000143 + STATUS_UNHANDLED_EXCEPTION NTStatus = 0xC0000144 + STATUS_APP_INIT_FAILURE NTStatus = 0xC0000145 + STATUS_PAGEFILE_CREATE_FAILED NTStatus = 0xC0000146 + STATUS_NO_PAGEFILE NTStatus = 0xC0000147 + STATUS_INVALID_LEVEL NTStatus = 0xC0000148 + STATUS_WRONG_PASSWORD_CORE NTStatus = 0xC0000149 + STATUS_ILLEGAL_FLOAT_CONTEXT NTStatus = 0xC000014A + STATUS_PIPE_BROKEN NTStatus = 0xC000014B + STATUS_REGISTRY_CORRUPT NTStatus = 0xC000014C + STATUS_REGISTRY_IO_FAILED NTStatus = 0xC000014D + STATUS_NO_EVENT_PAIR NTStatus = 0xC000014E + STATUS_UNRECOGNIZED_VOLUME NTStatus = 0xC000014F + STATUS_SERIAL_NO_DEVICE_INITED NTStatus = 0xC0000150 + STATUS_NO_SUCH_ALIAS NTStatus = 0xC0000151 + STATUS_MEMBER_NOT_IN_ALIAS NTStatus = 0xC0000152 + STATUS_MEMBER_IN_ALIAS NTStatus = 0xC0000153 + STATUS_ALIAS_EXISTS NTStatus = 0xC0000154 + STATUS_LOGON_NOT_GRANTED NTStatus = 0xC0000155 + STATUS_TOO_MANY_SECRETS NTStatus = 0xC0000156 + STATUS_SECRET_TOO_LONG NTStatus = 0xC0000157 + STATUS_INTERNAL_DB_ERROR NTStatus = 0xC0000158 + STATUS_FULLSCREEN_MODE NTStatus = 0xC0000159 + STATUS_TOO_MANY_CONTEXT_IDS NTStatus = 0xC000015A + STATUS_LOGON_TYPE_NOT_GRANTED NTStatus = 0xC000015B + STATUS_NOT_REGISTRY_FILE NTStatus = 0xC000015C + STATUS_NT_CROSS_ENCRYPTION_REQUIRED NTStatus = 0xC000015D + STATUS_DOMAIN_CTRLR_CONFIG_ERROR NTStatus = 0xC000015E + STATUS_FT_MISSING_MEMBER NTStatus = 0xC000015F + STATUS_ILL_FORMED_SERVICE_ENTRY NTStatus = 0xC0000160 + STATUS_ILLEGAL_CHARACTER NTStatus = 0xC0000161 + STATUS_UNMAPPABLE_CHARACTER NTStatus = 0xC0000162 + STATUS_UNDEFINED_CHARACTER NTStatus = 0xC0000163 + STATUS_FLOPPY_VOLUME NTStatus = 0xC0000164 + STATUS_FLOPPY_ID_MARK_NOT_FOUND NTStatus = 0xC0000165 + STATUS_FLOPPY_WRONG_CYLINDER NTStatus = 0xC0000166 + STATUS_FLOPPY_UNKNOWN_ERROR NTStatus = 0xC0000167 + STATUS_FLOPPY_BAD_REGISTERS NTStatus = 0xC0000168 + STATUS_DISK_RECALIBRATE_FAILED NTStatus = 0xC0000169 + STATUS_DISK_OPERATION_FAILED NTStatus = 0xC000016A + STATUS_DISK_RESET_FAILED NTStatus = 0xC000016B + STATUS_SHARED_IRQ_BUSY NTStatus = 0xC000016C + STATUS_FT_ORPHANING NTStatus = 0xC000016D + STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT NTStatus = 0xC000016E + STATUS_PARTITION_FAILURE NTStatus = 0xC0000172 + STATUS_INVALID_BLOCK_LENGTH NTStatus = 0xC0000173 + STATUS_DEVICE_NOT_PARTITIONED NTStatus = 0xC0000174 + STATUS_UNABLE_TO_LOCK_MEDIA NTStatus = 0xC0000175 + STATUS_UNABLE_TO_UNLOAD_MEDIA NTStatus = 0xC0000176 + STATUS_EOM_OVERFLOW NTStatus = 0xC0000177 + STATUS_NO_MEDIA NTStatus = 0xC0000178 + STATUS_NO_SUCH_MEMBER NTStatus = 0xC000017A + STATUS_INVALID_MEMBER NTStatus = 0xC000017B + STATUS_KEY_DELETED NTStatus = 0xC000017C + STATUS_NO_LOG_SPACE NTStatus = 0xC000017D + STATUS_TOO_MANY_SIDS NTStatus = 0xC000017E + STATUS_LM_CROSS_ENCRYPTION_REQUIRED NTStatus = 0xC000017F + STATUS_KEY_HAS_CHILDREN NTStatus = 0xC0000180 + STATUS_CHILD_MUST_BE_VOLATILE NTStatus = 0xC0000181 + STATUS_DEVICE_CONFIGURATION_ERROR NTStatus = 0xC0000182 + STATUS_DRIVER_INTERNAL_ERROR NTStatus = 0xC0000183 + STATUS_INVALID_DEVICE_STATE NTStatus = 0xC0000184 + STATUS_IO_DEVICE_ERROR NTStatus = 0xC0000185 + STATUS_DEVICE_PROTOCOL_ERROR NTStatus = 0xC0000186 + STATUS_BACKUP_CONTROLLER NTStatus = 0xC0000187 + STATUS_LOG_FILE_FULL NTStatus = 0xC0000188 + STATUS_TOO_LATE NTStatus = 0xC0000189 + STATUS_NO_TRUST_LSA_SECRET NTStatus = 0xC000018A + STATUS_NO_TRUST_SAM_ACCOUNT NTStatus = 0xC000018B + STATUS_TRUSTED_DOMAIN_FAILURE NTStatus = 0xC000018C + STATUS_TRUSTED_RELATIONSHIP_FAILURE NTStatus = 0xC000018D + STATUS_EVENTLOG_FILE_CORRUPT NTStatus = 0xC000018E + STATUS_EVENTLOG_CANT_START NTStatus = 0xC000018F + STATUS_TRUST_FAILURE NTStatus = 0xC0000190 + STATUS_MUTANT_LIMIT_EXCEEDED NTStatus = 0xC0000191 + STATUS_NETLOGON_NOT_STARTED NTStatus = 0xC0000192 + STATUS_ACCOUNT_EXPIRED NTStatus = 0xC0000193 + STATUS_POSSIBLE_DEADLOCK NTStatus = 0xC0000194 + STATUS_NETWORK_CREDENTIAL_CONFLICT NTStatus = 0xC0000195 + STATUS_REMOTE_SESSION_LIMIT NTStatus = 0xC0000196 + STATUS_EVENTLOG_FILE_CHANGED NTStatus = 0xC0000197 + STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT NTStatus = 0xC0000198 + STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT NTStatus = 0xC0000199 + STATUS_NOLOGON_SERVER_TRUST_ACCOUNT NTStatus = 0xC000019A + STATUS_DOMAIN_TRUST_INCONSISTENT NTStatus = 0xC000019B + STATUS_FS_DRIVER_REQUIRED NTStatus = 0xC000019C + STATUS_IMAGE_ALREADY_LOADED_AS_DLL NTStatus = 0xC000019D + STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING NTStatus = 0xC000019E + STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME NTStatus = 0xC000019F + STATUS_SECURITY_STREAM_IS_INCONSISTENT NTStatus = 0xC00001A0 + STATUS_INVALID_LOCK_RANGE NTStatus = 0xC00001A1 + STATUS_INVALID_ACE_CONDITION NTStatus = 0xC00001A2 + STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT NTStatus = 0xC00001A3 + STATUS_NOTIFICATION_GUID_ALREADY_DEFINED NTStatus = 0xC00001A4 + STATUS_INVALID_EXCEPTION_HANDLER NTStatus = 0xC00001A5 + STATUS_DUPLICATE_PRIVILEGES NTStatus = 0xC00001A6 + STATUS_NOT_ALLOWED_ON_SYSTEM_FILE NTStatus = 0xC00001A7 + STATUS_REPAIR_NEEDED NTStatus = 0xC00001A8 + STATUS_QUOTA_NOT_ENABLED NTStatus = 0xC00001A9 + STATUS_NO_APPLICATION_PACKAGE NTStatus = 0xC00001AA + STATUS_FILE_METADATA_OPTIMIZATION_IN_PROGRESS NTStatus = 0xC00001AB + STATUS_NOT_SAME_OBJECT NTStatus = 0xC00001AC + STATUS_FATAL_MEMORY_EXHAUSTION NTStatus = 0xC00001AD + STATUS_ERROR_PROCESS_NOT_IN_JOB NTStatus = 0xC00001AE + STATUS_CPU_SET_INVALID NTStatus = 0xC00001AF + STATUS_IO_DEVICE_INVALID_DATA NTStatus = 0xC00001B0 + STATUS_IO_UNALIGNED_WRITE NTStatus = 0xC00001B1 + STATUS_NETWORK_OPEN_RESTRICTION NTStatus = 0xC0000201 + STATUS_NO_USER_SESSION_KEY NTStatus = 0xC0000202 + STATUS_USER_SESSION_DELETED NTStatus = 0xC0000203 + STATUS_RESOURCE_LANG_NOT_FOUND NTStatus = 0xC0000204 + STATUS_INSUFF_SERVER_RESOURCES NTStatus = 0xC0000205 + STATUS_INVALID_BUFFER_SIZE NTStatus = 0xC0000206 + STATUS_INVALID_ADDRESS_COMPONENT NTStatus = 0xC0000207 + STATUS_INVALID_ADDRESS_WILDCARD NTStatus = 0xC0000208 + STATUS_TOO_MANY_ADDRESSES NTStatus = 0xC0000209 + STATUS_ADDRESS_ALREADY_EXISTS NTStatus = 0xC000020A + STATUS_ADDRESS_CLOSED NTStatus = 0xC000020B + STATUS_CONNECTION_DISCONNECTED NTStatus = 0xC000020C + STATUS_CONNECTION_RESET NTStatus = 0xC000020D + STATUS_TOO_MANY_NODES NTStatus = 0xC000020E + STATUS_TRANSACTION_ABORTED NTStatus = 0xC000020F + STATUS_TRANSACTION_TIMED_OUT NTStatus = 0xC0000210 + STATUS_TRANSACTION_NO_RELEASE NTStatus = 0xC0000211 + STATUS_TRANSACTION_NO_MATCH NTStatus = 0xC0000212 + STATUS_TRANSACTION_RESPONDED NTStatus = 0xC0000213 + STATUS_TRANSACTION_INVALID_ID NTStatus = 0xC0000214 + STATUS_TRANSACTION_INVALID_TYPE NTStatus = 0xC0000215 + STATUS_NOT_SERVER_SESSION NTStatus = 0xC0000216 + STATUS_NOT_CLIENT_SESSION NTStatus = 0xC0000217 + STATUS_CANNOT_LOAD_REGISTRY_FILE NTStatus = 0xC0000218 + STATUS_DEBUG_ATTACH_FAILED NTStatus = 0xC0000219 + STATUS_SYSTEM_PROCESS_TERMINATED NTStatus = 0xC000021A + STATUS_DATA_NOT_ACCEPTED NTStatus = 0xC000021B + STATUS_NO_BROWSER_SERVERS_FOUND NTStatus = 0xC000021C + STATUS_VDM_HARD_ERROR NTStatus = 0xC000021D + STATUS_DRIVER_CANCEL_TIMEOUT NTStatus = 0xC000021E + STATUS_REPLY_MESSAGE_MISMATCH NTStatus = 0xC000021F + STATUS_MAPPED_ALIGNMENT NTStatus = 0xC0000220 + STATUS_IMAGE_CHECKSUM_MISMATCH NTStatus = 0xC0000221 + STATUS_LOST_WRITEBEHIND_DATA NTStatus = 0xC0000222 + STATUS_CLIENT_SERVER_PARAMETERS_INVALID NTStatus = 0xC0000223 + STATUS_PASSWORD_MUST_CHANGE NTStatus = 0xC0000224 + STATUS_NOT_FOUND NTStatus = 0xC0000225 + STATUS_NOT_TINY_STREAM NTStatus = 0xC0000226 + STATUS_RECOVERY_FAILURE NTStatus = 0xC0000227 + STATUS_STACK_OVERFLOW_READ NTStatus = 0xC0000228 + STATUS_FAIL_CHECK NTStatus = 0xC0000229 + STATUS_DUPLICATE_OBJECTID NTStatus = 0xC000022A + STATUS_OBJECTID_EXISTS NTStatus = 0xC000022B + STATUS_CONVERT_TO_LARGE NTStatus = 0xC000022C + STATUS_RETRY NTStatus = 0xC000022D + STATUS_FOUND_OUT_OF_SCOPE NTStatus = 0xC000022E + STATUS_ALLOCATE_BUCKET NTStatus = 0xC000022F + STATUS_PROPSET_NOT_FOUND NTStatus = 0xC0000230 + STATUS_MARSHALL_OVERFLOW NTStatus = 0xC0000231 + STATUS_INVALID_VARIANT NTStatus = 0xC0000232 + STATUS_DOMAIN_CONTROLLER_NOT_FOUND NTStatus = 0xC0000233 + STATUS_ACCOUNT_LOCKED_OUT NTStatus = 0xC0000234 + STATUS_HANDLE_NOT_CLOSABLE NTStatus = 0xC0000235 + STATUS_CONNECTION_REFUSED NTStatus = 0xC0000236 + STATUS_GRACEFUL_DISCONNECT NTStatus = 0xC0000237 + STATUS_ADDRESS_ALREADY_ASSOCIATED NTStatus = 0xC0000238 + STATUS_ADDRESS_NOT_ASSOCIATED NTStatus = 0xC0000239 + STATUS_CONNECTION_INVALID NTStatus = 0xC000023A + STATUS_CONNECTION_ACTIVE NTStatus = 0xC000023B + STATUS_NETWORK_UNREACHABLE NTStatus = 0xC000023C + STATUS_HOST_UNREACHABLE NTStatus = 0xC000023D + STATUS_PROTOCOL_UNREACHABLE NTStatus = 0xC000023E + STATUS_PORT_UNREACHABLE NTStatus = 0xC000023F + STATUS_REQUEST_ABORTED NTStatus = 0xC0000240 + STATUS_CONNECTION_ABORTED NTStatus = 0xC0000241 + STATUS_BAD_COMPRESSION_BUFFER NTStatus = 0xC0000242 + STATUS_USER_MAPPED_FILE NTStatus = 0xC0000243 + STATUS_AUDIT_FAILED NTStatus = 0xC0000244 + STATUS_TIMER_RESOLUTION_NOT_SET NTStatus = 0xC0000245 + STATUS_CONNECTION_COUNT_LIMIT NTStatus = 0xC0000246 + STATUS_LOGIN_TIME_RESTRICTION NTStatus = 0xC0000247 + STATUS_LOGIN_WKSTA_RESTRICTION NTStatus = 0xC0000248 + STATUS_IMAGE_MP_UP_MISMATCH NTStatus = 0xC0000249 + STATUS_INSUFFICIENT_LOGON_INFO NTStatus = 0xC0000250 + STATUS_BAD_DLL_ENTRYPOINT NTStatus = 0xC0000251 + STATUS_BAD_SERVICE_ENTRYPOINT NTStatus = 0xC0000252 + STATUS_LPC_REPLY_LOST NTStatus = 0xC0000253 + STATUS_IP_ADDRESS_CONFLICT1 NTStatus = 0xC0000254 + STATUS_IP_ADDRESS_CONFLICT2 NTStatus = 0xC0000255 + STATUS_REGISTRY_QUOTA_LIMIT NTStatus = 0xC0000256 + STATUS_PATH_NOT_COVERED NTStatus = 0xC0000257 + STATUS_NO_CALLBACK_ACTIVE NTStatus = 0xC0000258 + STATUS_LICENSE_QUOTA_EXCEEDED NTStatus = 0xC0000259 + STATUS_PWD_TOO_SHORT NTStatus = 0xC000025A + STATUS_PWD_TOO_RECENT NTStatus = 0xC000025B + STATUS_PWD_HISTORY_CONFLICT NTStatus = 0xC000025C + STATUS_PLUGPLAY_NO_DEVICE NTStatus = 0xC000025E + STATUS_UNSUPPORTED_COMPRESSION NTStatus = 0xC000025F + STATUS_INVALID_HW_PROFILE NTStatus = 0xC0000260 + STATUS_INVALID_PLUGPLAY_DEVICE_PATH NTStatus = 0xC0000261 + STATUS_DRIVER_ORDINAL_NOT_FOUND NTStatus = 0xC0000262 + STATUS_DRIVER_ENTRYPOINT_NOT_FOUND NTStatus = 0xC0000263 + STATUS_RESOURCE_NOT_OWNED NTStatus = 0xC0000264 + STATUS_TOO_MANY_LINKS NTStatus = 0xC0000265 + STATUS_QUOTA_LIST_INCONSISTENT NTStatus = 0xC0000266 + STATUS_FILE_IS_OFFLINE NTStatus = 0xC0000267 + STATUS_EVALUATION_EXPIRATION NTStatus = 0xC0000268 + STATUS_ILLEGAL_DLL_RELOCATION NTStatus = 0xC0000269 + STATUS_LICENSE_VIOLATION NTStatus = 0xC000026A + STATUS_DLL_INIT_FAILED_LOGOFF NTStatus = 0xC000026B + STATUS_DRIVER_UNABLE_TO_LOAD NTStatus = 0xC000026C + STATUS_DFS_UNAVAILABLE NTStatus = 0xC000026D + STATUS_VOLUME_DISMOUNTED NTStatus = 0xC000026E + STATUS_WX86_INTERNAL_ERROR NTStatus = 0xC000026F + STATUS_WX86_FLOAT_STACK_CHECK NTStatus = 0xC0000270 + STATUS_VALIDATE_CONTINUE NTStatus = 0xC0000271 + STATUS_NO_MATCH NTStatus = 0xC0000272 + STATUS_NO_MORE_MATCHES NTStatus = 0xC0000273 + STATUS_NOT_A_REPARSE_POINT NTStatus = 0xC0000275 + STATUS_IO_REPARSE_TAG_INVALID NTStatus = 0xC0000276 + STATUS_IO_REPARSE_TAG_MISMATCH NTStatus = 0xC0000277 + STATUS_IO_REPARSE_DATA_INVALID NTStatus = 0xC0000278 + STATUS_IO_REPARSE_TAG_NOT_HANDLED NTStatus = 0xC0000279 + STATUS_PWD_TOO_LONG NTStatus = 0xC000027A + STATUS_STOWED_EXCEPTION NTStatus = 0xC000027B + STATUS_CONTEXT_STOWED_EXCEPTION NTStatus = 0xC000027C + STATUS_REPARSE_POINT_NOT_RESOLVED NTStatus = 0xC0000280 + STATUS_DIRECTORY_IS_A_REPARSE_POINT NTStatus = 0xC0000281 + STATUS_RANGE_LIST_CONFLICT NTStatus = 0xC0000282 + STATUS_SOURCE_ELEMENT_EMPTY NTStatus = 0xC0000283 + STATUS_DESTINATION_ELEMENT_FULL NTStatus = 0xC0000284 + STATUS_ILLEGAL_ELEMENT_ADDRESS NTStatus = 0xC0000285 + STATUS_MAGAZINE_NOT_PRESENT NTStatus = 0xC0000286 + STATUS_REINITIALIZATION_NEEDED NTStatus = 0xC0000287 + STATUS_DEVICE_REQUIRES_CLEANING NTStatus = 0x80000288 + STATUS_DEVICE_DOOR_OPEN NTStatus = 0x80000289 + STATUS_ENCRYPTION_FAILED NTStatus = 0xC000028A + STATUS_DECRYPTION_FAILED NTStatus = 0xC000028B + STATUS_RANGE_NOT_FOUND NTStatus = 0xC000028C + STATUS_NO_RECOVERY_POLICY NTStatus = 0xC000028D + STATUS_NO_EFS NTStatus = 0xC000028E + STATUS_WRONG_EFS NTStatus = 0xC000028F + STATUS_NO_USER_KEYS NTStatus = 0xC0000290 + STATUS_FILE_NOT_ENCRYPTED NTStatus = 0xC0000291 + STATUS_NOT_EXPORT_FORMAT NTStatus = 0xC0000292 + STATUS_FILE_ENCRYPTED NTStatus = 0xC0000293 + STATUS_WAKE_SYSTEM NTStatus = 0x40000294 + STATUS_WMI_GUID_NOT_FOUND NTStatus = 0xC0000295 + STATUS_WMI_INSTANCE_NOT_FOUND NTStatus = 0xC0000296 + STATUS_WMI_ITEMID_NOT_FOUND NTStatus = 0xC0000297 + STATUS_WMI_TRY_AGAIN NTStatus = 0xC0000298 + STATUS_SHARED_POLICY NTStatus = 0xC0000299 + STATUS_POLICY_OBJECT_NOT_FOUND NTStatus = 0xC000029A + STATUS_POLICY_ONLY_IN_DS NTStatus = 0xC000029B + STATUS_VOLUME_NOT_UPGRADED NTStatus = 0xC000029C + STATUS_REMOTE_STORAGE_NOT_ACTIVE NTStatus = 0xC000029D + STATUS_REMOTE_STORAGE_MEDIA_ERROR NTStatus = 0xC000029E + STATUS_NO_TRACKING_SERVICE NTStatus = 0xC000029F + STATUS_SERVER_SID_MISMATCH NTStatus = 0xC00002A0 + STATUS_DS_NO_ATTRIBUTE_OR_VALUE NTStatus = 0xC00002A1 + STATUS_DS_INVALID_ATTRIBUTE_SYNTAX NTStatus = 0xC00002A2 + STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED NTStatus = 0xC00002A3 + STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS NTStatus = 0xC00002A4 + STATUS_DS_BUSY NTStatus = 0xC00002A5 + STATUS_DS_UNAVAILABLE NTStatus = 0xC00002A6 + STATUS_DS_NO_RIDS_ALLOCATED NTStatus = 0xC00002A7 + STATUS_DS_NO_MORE_RIDS NTStatus = 0xC00002A8 + STATUS_DS_INCORRECT_ROLE_OWNER NTStatus = 0xC00002A9 + STATUS_DS_RIDMGR_INIT_ERROR NTStatus = 0xC00002AA + STATUS_DS_OBJ_CLASS_VIOLATION NTStatus = 0xC00002AB + STATUS_DS_CANT_ON_NON_LEAF NTStatus = 0xC00002AC + STATUS_DS_CANT_ON_RDN NTStatus = 0xC00002AD + STATUS_DS_CANT_MOD_OBJ_CLASS NTStatus = 0xC00002AE + STATUS_DS_CROSS_DOM_MOVE_FAILED NTStatus = 0xC00002AF + STATUS_DS_GC_NOT_AVAILABLE NTStatus = 0xC00002B0 + STATUS_DIRECTORY_SERVICE_REQUIRED NTStatus = 0xC00002B1 + STATUS_REPARSE_ATTRIBUTE_CONFLICT NTStatus = 0xC00002B2 + STATUS_CANT_ENABLE_DENY_ONLY NTStatus = 0xC00002B3 + STATUS_FLOAT_MULTIPLE_FAULTS NTStatus = 0xC00002B4 + STATUS_FLOAT_MULTIPLE_TRAPS NTStatus = 0xC00002B5 + STATUS_DEVICE_REMOVED NTStatus = 0xC00002B6 + STATUS_JOURNAL_DELETE_IN_PROGRESS NTStatus = 0xC00002B7 + STATUS_JOURNAL_NOT_ACTIVE NTStatus = 0xC00002B8 + STATUS_NOINTERFACE NTStatus = 0xC00002B9 + STATUS_DS_RIDMGR_DISABLED NTStatus = 0xC00002BA + STATUS_DS_ADMIN_LIMIT_EXCEEDED NTStatus = 0xC00002C1 + STATUS_DRIVER_FAILED_SLEEP NTStatus = 0xC00002C2 + STATUS_MUTUAL_AUTHENTICATION_FAILED NTStatus = 0xC00002C3 + STATUS_CORRUPT_SYSTEM_FILE NTStatus = 0xC00002C4 + STATUS_DATATYPE_MISALIGNMENT_ERROR NTStatus = 0xC00002C5 + STATUS_WMI_READ_ONLY NTStatus = 0xC00002C6 + STATUS_WMI_SET_FAILURE NTStatus = 0xC00002C7 + STATUS_COMMITMENT_MINIMUM NTStatus = 0xC00002C8 + STATUS_REG_NAT_CONSUMPTION NTStatus = 0xC00002C9 + STATUS_TRANSPORT_FULL NTStatus = 0xC00002CA + STATUS_DS_SAM_INIT_FAILURE NTStatus = 0xC00002CB + STATUS_ONLY_IF_CONNECTED NTStatus = 0xC00002CC + STATUS_DS_SENSITIVE_GROUP_VIOLATION NTStatus = 0xC00002CD + STATUS_PNP_RESTART_ENUMERATION NTStatus = 0xC00002CE + STATUS_JOURNAL_ENTRY_DELETED NTStatus = 0xC00002CF + STATUS_DS_CANT_MOD_PRIMARYGROUPID NTStatus = 0xC00002D0 + STATUS_SYSTEM_IMAGE_BAD_SIGNATURE NTStatus = 0xC00002D1 + STATUS_PNP_REBOOT_REQUIRED NTStatus = 0xC00002D2 + STATUS_POWER_STATE_INVALID NTStatus = 0xC00002D3 + STATUS_DS_INVALID_GROUP_TYPE NTStatus = 0xC00002D4 + STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN NTStatus = 0xC00002D5 + STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN NTStatus = 0xC00002D6 + STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER NTStatus = 0xC00002D7 + STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER NTStatus = 0xC00002D8 + STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER NTStatus = 0xC00002D9 + STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER NTStatus = 0xC00002DA + STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER NTStatus = 0xC00002DB + STATUS_DS_HAVE_PRIMARY_MEMBERS NTStatus = 0xC00002DC + STATUS_WMI_NOT_SUPPORTED NTStatus = 0xC00002DD + STATUS_INSUFFICIENT_POWER NTStatus = 0xC00002DE + STATUS_SAM_NEED_BOOTKEY_PASSWORD NTStatus = 0xC00002DF + STATUS_SAM_NEED_BOOTKEY_FLOPPY NTStatus = 0xC00002E0 + STATUS_DS_CANT_START NTStatus = 0xC00002E1 + STATUS_DS_INIT_FAILURE NTStatus = 0xC00002E2 + STATUS_SAM_INIT_FAILURE NTStatus = 0xC00002E3 + STATUS_DS_GC_REQUIRED NTStatus = 0xC00002E4 + STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY NTStatus = 0xC00002E5 + STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS NTStatus = 0xC00002E6 + STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED NTStatus = 0xC00002E7 + STATUS_MULTIPLE_FAULT_VIOLATION NTStatus = 0xC00002E8 + STATUS_CURRENT_DOMAIN_NOT_ALLOWED NTStatus = 0xC00002E9 + STATUS_CANNOT_MAKE NTStatus = 0xC00002EA + STATUS_SYSTEM_SHUTDOWN NTStatus = 0xC00002EB + STATUS_DS_INIT_FAILURE_CONSOLE NTStatus = 0xC00002EC + STATUS_DS_SAM_INIT_FAILURE_CONSOLE NTStatus = 0xC00002ED + STATUS_UNFINISHED_CONTEXT_DELETED NTStatus = 0xC00002EE + STATUS_NO_TGT_REPLY NTStatus = 0xC00002EF + STATUS_OBJECTID_NOT_FOUND NTStatus = 0xC00002F0 + STATUS_NO_IP_ADDRESSES NTStatus = 0xC00002F1 + STATUS_WRONG_CREDENTIAL_HANDLE NTStatus = 0xC00002F2 + STATUS_CRYPTO_SYSTEM_INVALID NTStatus = 0xC00002F3 + STATUS_MAX_REFERRALS_EXCEEDED NTStatus = 0xC00002F4 + STATUS_MUST_BE_KDC NTStatus = 0xC00002F5 + STATUS_STRONG_CRYPTO_NOT_SUPPORTED NTStatus = 0xC00002F6 + STATUS_TOO_MANY_PRINCIPALS NTStatus = 0xC00002F7 + STATUS_NO_PA_DATA NTStatus = 0xC00002F8 + STATUS_PKINIT_NAME_MISMATCH NTStatus = 0xC00002F9 + STATUS_SMARTCARD_LOGON_REQUIRED NTStatus = 0xC00002FA + STATUS_KDC_INVALID_REQUEST NTStatus = 0xC00002FB + STATUS_KDC_UNABLE_TO_REFER NTStatus = 0xC00002FC + STATUS_KDC_UNKNOWN_ETYPE NTStatus = 0xC00002FD + STATUS_SHUTDOWN_IN_PROGRESS NTStatus = 0xC00002FE + STATUS_SERVER_SHUTDOWN_IN_PROGRESS NTStatus = 0xC00002FF + STATUS_NOT_SUPPORTED_ON_SBS NTStatus = 0xC0000300 + STATUS_WMI_GUID_DISCONNECTED NTStatus = 0xC0000301 + STATUS_WMI_ALREADY_DISABLED NTStatus = 0xC0000302 + STATUS_WMI_ALREADY_ENABLED NTStatus = 0xC0000303 + STATUS_MFT_TOO_FRAGMENTED NTStatus = 0xC0000304 + STATUS_COPY_PROTECTION_FAILURE NTStatus = 0xC0000305 + STATUS_CSS_AUTHENTICATION_FAILURE NTStatus = 0xC0000306 + STATUS_CSS_KEY_NOT_PRESENT NTStatus = 0xC0000307 + STATUS_CSS_KEY_NOT_ESTABLISHED NTStatus = 0xC0000308 + STATUS_CSS_SCRAMBLED_SECTOR NTStatus = 0xC0000309 + STATUS_CSS_REGION_MISMATCH NTStatus = 0xC000030A + STATUS_CSS_RESETS_EXHAUSTED NTStatus = 0xC000030B + STATUS_PASSWORD_CHANGE_REQUIRED NTStatus = 0xC000030C + STATUS_LOST_MODE_LOGON_RESTRICTION NTStatus = 0xC000030D + STATUS_PKINIT_FAILURE NTStatus = 0xC0000320 + STATUS_SMARTCARD_SUBSYSTEM_FAILURE NTStatus = 0xC0000321 + STATUS_NO_KERB_KEY NTStatus = 0xC0000322 + STATUS_HOST_DOWN NTStatus = 0xC0000350 + STATUS_UNSUPPORTED_PREAUTH NTStatus = 0xC0000351 + STATUS_EFS_ALG_BLOB_TOO_BIG NTStatus = 0xC0000352 + STATUS_PORT_NOT_SET NTStatus = 0xC0000353 + STATUS_DEBUGGER_INACTIVE NTStatus = 0xC0000354 + STATUS_DS_VERSION_CHECK_FAILURE NTStatus = 0xC0000355 + STATUS_AUDITING_DISABLED NTStatus = 0xC0000356 + STATUS_PRENT4_MACHINE_ACCOUNT NTStatus = 0xC0000357 + STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER NTStatus = 0xC0000358 + STATUS_INVALID_IMAGE_WIN_32 NTStatus = 0xC0000359 + STATUS_INVALID_IMAGE_WIN_64 NTStatus = 0xC000035A + STATUS_BAD_BINDINGS NTStatus = 0xC000035B + STATUS_NETWORK_SESSION_EXPIRED NTStatus = 0xC000035C + STATUS_APPHELP_BLOCK NTStatus = 0xC000035D + STATUS_ALL_SIDS_FILTERED NTStatus = 0xC000035E + STATUS_NOT_SAFE_MODE_DRIVER NTStatus = 0xC000035F + STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT NTStatus = 0xC0000361 + STATUS_ACCESS_DISABLED_BY_POLICY_PATH NTStatus = 0xC0000362 + STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER NTStatus = 0xC0000363 + STATUS_ACCESS_DISABLED_BY_POLICY_OTHER NTStatus = 0xC0000364 + STATUS_FAILED_DRIVER_ENTRY NTStatus = 0xC0000365 + STATUS_DEVICE_ENUMERATION_ERROR NTStatus = 0xC0000366 + STATUS_MOUNT_POINT_NOT_RESOLVED NTStatus = 0xC0000368 + STATUS_INVALID_DEVICE_OBJECT_PARAMETER NTStatus = 0xC0000369 + STATUS_MCA_OCCURED NTStatus = 0xC000036A + STATUS_DRIVER_BLOCKED_CRITICAL NTStatus = 0xC000036B + STATUS_DRIVER_BLOCKED NTStatus = 0xC000036C + STATUS_DRIVER_DATABASE_ERROR NTStatus = 0xC000036D + STATUS_SYSTEM_HIVE_TOO_LARGE NTStatus = 0xC000036E + STATUS_INVALID_IMPORT_OF_NON_DLL NTStatus = 0xC000036F + STATUS_DS_SHUTTING_DOWN NTStatus = 0x40000370 + STATUS_NO_SECRETS NTStatus = 0xC0000371 + STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY NTStatus = 0xC0000372 + STATUS_FAILED_STACK_SWITCH NTStatus = 0xC0000373 + STATUS_HEAP_CORRUPTION NTStatus = 0xC0000374 + STATUS_SMARTCARD_WRONG_PIN NTStatus = 0xC0000380 + STATUS_SMARTCARD_CARD_BLOCKED NTStatus = 0xC0000381 + STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED NTStatus = 0xC0000382 + STATUS_SMARTCARD_NO_CARD NTStatus = 0xC0000383 + STATUS_SMARTCARD_NO_KEY_CONTAINER NTStatus = 0xC0000384 + STATUS_SMARTCARD_NO_CERTIFICATE NTStatus = 0xC0000385 + STATUS_SMARTCARD_NO_KEYSET NTStatus = 0xC0000386 + STATUS_SMARTCARD_IO_ERROR NTStatus = 0xC0000387 + STATUS_DOWNGRADE_DETECTED NTStatus = 0xC0000388 + STATUS_SMARTCARD_CERT_REVOKED NTStatus = 0xC0000389 + STATUS_ISSUING_CA_UNTRUSTED NTStatus = 0xC000038A + STATUS_REVOCATION_OFFLINE_C NTStatus = 0xC000038B + STATUS_PKINIT_CLIENT_FAILURE NTStatus = 0xC000038C + STATUS_SMARTCARD_CERT_EXPIRED NTStatus = 0xC000038D + STATUS_DRIVER_FAILED_PRIOR_UNLOAD NTStatus = 0xC000038E + STATUS_SMARTCARD_SILENT_CONTEXT NTStatus = 0xC000038F + STATUS_PER_USER_TRUST_QUOTA_EXCEEDED NTStatus = 0xC0000401 + STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED NTStatus = 0xC0000402 + STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED NTStatus = 0xC0000403 + STATUS_DS_NAME_NOT_UNIQUE NTStatus = 0xC0000404 + STATUS_DS_DUPLICATE_ID_FOUND NTStatus = 0xC0000405 + STATUS_DS_GROUP_CONVERSION_ERROR NTStatus = 0xC0000406 + STATUS_VOLSNAP_PREPARE_HIBERNATE NTStatus = 0xC0000407 + STATUS_USER2USER_REQUIRED NTStatus = 0xC0000408 + STATUS_STACK_BUFFER_OVERRUN NTStatus = 0xC0000409 + STATUS_NO_S4U_PROT_SUPPORT NTStatus = 0xC000040A + STATUS_CROSSREALM_DELEGATION_FAILURE NTStatus = 0xC000040B + STATUS_REVOCATION_OFFLINE_KDC NTStatus = 0xC000040C + STATUS_ISSUING_CA_UNTRUSTED_KDC NTStatus = 0xC000040D + STATUS_KDC_CERT_EXPIRED NTStatus = 0xC000040E + STATUS_KDC_CERT_REVOKED NTStatus = 0xC000040F + STATUS_PARAMETER_QUOTA_EXCEEDED NTStatus = 0xC0000410 + STATUS_HIBERNATION_FAILURE NTStatus = 0xC0000411 + STATUS_DELAY_LOAD_FAILED NTStatus = 0xC0000412 + STATUS_AUTHENTICATION_FIREWALL_FAILED NTStatus = 0xC0000413 + STATUS_VDM_DISALLOWED NTStatus = 0xC0000414 + STATUS_HUNG_DISPLAY_DRIVER_THREAD NTStatus = 0xC0000415 + STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE NTStatus = 0xC0000416 + STATUS_INVALID_CRUNTIME_PARAMETER NTStatus = 0xC0000417 + STATUS_NTLM_BLOCKED NTStatus = 0xC0000418 + STATUS_DS_SRC_SID_EXISTS_IN_FOREST NTStatus = 0xC0000419 + STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST NTStatus = 0xC000041A + STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST NTStatus = 0xC000041B + STATUS_INVALID_USER_PRINCIPAL_NAME NTStatus = 0xC000041C + STATUS_FATAL_USER_CALLBACK_EXCEPTION NTStatus = 0xC000041D + STATUS_ASSERTION_FAILURE NTStatus = 0xC0000420 + STATUS_VERIFIER_STOP NTStatus = 0xC0000421 + STATUS_CALLBACK_POP_STACK NTStatus = 0xC0000423 + STATUS_INCOMPATIBLE_DRIVER_BLOCKED NTStatus = 0xC0000424 + STATUS_HIVE_UNLOADED NTStatus = 0xC0000425 + STATUS_COMPRESSION_DISABLED NTStatus = 0xC0000426 + STATUS_FILE_SYSTEM_LIMITATION NTStatus = 0xC0000427 + STATUS_INVALID_IMAGE_HASH NTStatus = 0xC0000428 + STATUS_NOT_CAPABLE NTStatus = 0xC0000429 + STATUS_REQUEST_OUT_OF_SEQUENCE NTStatus = 0xC000042A + STATUS_IMPLEMENTATION_LIMIT NTStatus = 0xC000042B + STATUS_ELEVATION_REQUIRED NTStatus = 0xC000042C + STATUS_NO_SECURITY_CONTEXT NTStatus = 0xC000042D + STATUS_PKU2U_CERT_FAILURE NTStatus = 0xC000042F + STATUS_BEYOND_VDL NTStatus = 0xC0000432 + STATUS_ENCOUNTERED_WRITE_IN_PROGRESS NTStatus = 0xC0000433 + STATUS_PTE_CHANGED NTStatus = 0xC0000434 + STATUS_PURGE_FAILED NTStatus = 0xC0000435 + STATUS_CRED_REQUIRES_CONFIRMATION NTStatus = 0xC0000440 + STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE NTStatus = 0xC0000441 + STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER NTStatus = 0xC0000442 + STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE NTStatus = 0xC0000443 + STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE NTStatus = 0xC0000444 + STATUS_CS_ENCRYPTION_FILE_NOT_CSE NTStatus = 0xC0000445 + STATUS_INVALID_LABEL NTStatus = 0xC0000446 + STATUS_DRIVER_PROCESS_TERMINATED NTStatus = 0xC0000450 + STATUS_AMBIGUOUS_SYSTEM_DEVICE NTStatus = 0xC0000451 + STATUS_SYSTEM_DEVICE_NOT_FOUND NTStatus = 0xC0000452 + STATUS_RESTART_BOOT_APPLICATION NTStatus = 0xC0000453 + STATUS_INSUFFICIENT_NVRAM_RESOURCES NTStatus = 0xC0000454 + STATUS_INVALID_SESSION NTStatus = 0xC0000455 + STATUS_THREAD_ALREADY_IN_SESSION NTStatus = 0xC0000456 + STATUS_THREAD_NOT_IN_SESSION NTStatus = 0xC0000457 + STATUS_INVALID_WEIGHT NTStatus = 0xC0000458 + STATUS_REQUEST_PAUSED NTStatus = 0xC0000459 + STATUS_NO_RANGES_PROCESSED NTStatus = 0xC0000460 + STATUS_DISK_RESOURCES_EXHAUSTED NTStatus = 0xC0000461 + STATUS_NEEDS_REMEDIATION NTStatus = 0xC0000462 + STATUS_DEVICE_FEATURE_NOT_SUPPORTED NTStatus = 0xC0000463 + STATUS_DEVICE_UNREACHABLE NTStatus = 0xC0000464 + STATUS_INVALID_TOKEN NTStatus = 0xC0000465 + STATUS_SERVER_UNAVAILABLE NTStatus = 0xC0000466 + STATUS_FILE_NOT_AVAILABLE NTStatus = 0xC0000467 + STATUS_DEVICE_INSUFFICIENT_RESOURCES NTStatus = 0xC0000468 + STATUS_PACKAGE_UPDATING NTStatus = 0xC0000469 + STATUS_NOT_READ_FROM_COPY NTStatus = 0xC000046A + STATUS_FT_WRITE_FAILURE NTStatus = 0xC000046B + STATUS_FT_DI_SCAN_REQUIRED NTStatus = 0xC000046C + STATUS_OBJECT_NOT_EXTERNALLY_BACKED NTStatus = 0xC000046D + STATUS_EXTERNAL_BACKING_PROVIDER_UNKNOWN NTStatus = 0xC000046E + STATUS_COMPRESSION_NOT_BENEFICIAL NTStatus = 0xC000046F + STATUS_DATA_CHECKSUM_ERROR NTStatus = 0xC0000470 + STATUS_INTERMIXED_KERNEL_EA_OPERATION NTStatus = 0xC0000471 + STATUS_TRIM_READ_ZERO_NOT_SUPPORTED NTStatus = 0xC0000472 + STATUS_TOO_MANY_SEGMENT_DESCRIPTORS NTStatus = 0xC0000473 + STATUS_INVALID_OFFSET_ALIGNMENT NTStatus = 0xC0000474 + STATUS_INVALID_FIELD_IN_PARAMETER_LIST NTStatus = 0xC0000475 + STATUS_OPERATION_IN_PROGRESS NTStatus = 0xC0000476 + STATUS_INVALID_INITIATOR_TARGET_PATH NTStatus = 0xC0000477 + STATUS_SCRUB_DATA_DISABLED NTStatus = 0xC0000478 + STATUS_NOT_REDUNDANT_STORAGE NTStatus = 0xC0000479 + STATUS_RESIDENT_FILE_NOT_SUPPORTED NTStatus = 0xC000047A + STATUS_COMPRESSED_FILE_NOT_SUPPORTED NTStatus = 0xC000047B + STATUS_DIRECTORY_NOT_SUPPORTED NTStatus = 0xC000047C + STATUS_IO_OPERATION_TIMEOUT NTStatus = 0xC000047D + STATUS_SYSTEM_NEEDS_REMEDIATION NTStatus = 0xC000047E + STATUS_APPX_INTEGRITY_FAILURE_CLR_NGEN NTStatus = 0xC000047F + STATUS_SHARE_UNAVAILABLE NTStatus = 0xC0000480 + STATUS_APISET_NOT_HOSTED NTStatus = 0xC0000481 + STATUS_APISET_NOT_PRESENT NTStatus = 0xC0000482 + STATUS_DEVICE_HARDWARE_ERROR NTStatus = 0xC0000483 + STATUS_FIRMWARE_SLOT_INVALID NTStatus = 0xC0000484 + STATUS_FIRMWARE_IMAGE_INVALID NTStatus = 0xC0000485 + STATUS_STORAGE_TOPOLOGY_ID_MISMATCH NTStatus = 0xC0000486 + STATUS_WIM_NOT_BOOTABLE NTStatus = 0xC0000487 + STATUS_BLOCKED_BY_PARENTAL_CONTROLS NTStatus = 0xC0000488 + STATUS_NEEDS_REGISTRATION NTStatus = 0xC0000489 + STATUS_QUOTA_ACTIVITY NTStatus = 0xC000048A + STATUS_CALLBACK_INVOKE_INLINE NTStatus = 0xC000048B + STATUS_BLOCK_TOO_MANY_REFERENCES NTStatus = 0xC000048C + STATUS_MARKED_TO_DISALLOW_WRITES NTStatus = 0xC000048D + STATUS_NETWORK_ACCESS_DENIED_EDP NTStatus = 0xC000048E + STATUS_ENCLAVE_FAILURE NTStatus = 0xC000048F + STATUS_PNP_NO_COMPAT_DRIVERS NTStatus = 0xC0000490 + STATUS_PNP_DRIVER_PACKAGE_NOT_FOUND NTStatus = 0xC0000491 + STATUS_PNP_DRIVER_CONFIGURATION_NOT_FOUND NTStatus = 0xC0000492 + STATUS_PNP_DRIVER_CONFIGURATION_INCOMPLETE NTStatus = 0xC0000493 + STATUS_PNP_FUNCTION_DRIVER_REQUIRED NTStatus = 0xC0000494 + STATUS_PNP_DEVICE_CONFIGURATION_PENDING NTStatus = 0xC0000495 + STATUS_DEVICE_HINT_NAME_BUFFER_TOO_SMALL NTStatus = 0xC0000496 + STATUS_PACKAGE_NOT_AVAILABLE NTStatus = 0xC0000497 + STATUS_DEVICE_IN_MAINTENANCE NTStatus = 0xC0000499 + STATUS_NOT_SUPPORTED_ON_DAX NTStatus = 0xC000049A + STATUS_FREE_SPACE_TOO_FRAGMENTED NTStatus = 0xC000049B + STATUS_DAX_MAPPING_EXISTS NTStatus = 0xC000049C + STATUS_CHILD_PROCESS_BLOCKED NTStatus = 0xC000049D + STATUS_STORAGE_LOST_DATA_PERSISTENCE NTStatus = 0xC000049E + STATUS_VRF_CFG_ENABLED NTStatus = 0xC000049F + STATUS_PARTITION_TERMINATING NTStatus = 0xC00004A0 + STATUS_EXTERNAL_SYSKEY_NOT_SUPPORTED NTStatus = 0xC00004A1 + STATUS_ENCLAVE_VIOLATION NTStatus = 0xC00004A2 + STATUS_FILE_PROTECTED_UNDER_DPL NTStatus = 0xC00004A3 + STATUS_VOLUME_NOT_CLUSTER_ALIGNED NTStatus = 0xC00004A4 + STATUS_NO_PHYSICALLY_ALIGNED_FREE_SPACE_FOUND NTStatus = 0xC00004A5 + STATUS_APPX_FILE_NOT_ENCRYPTED NTStatus = 0xC00004A6 + STATUS_RWRAW_ENCRYPTED_FILE_NOT_ENCRYPTED NTStatus = 0xC00004A7 + STATUS_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILEOFFSET NTStatus = 0xC00004A8 + STATUS_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILERANGE NTStatus = 0xC00004A9 + STATUS_RWRAW_ENCRYPTED_INVALID_EDATAINFO_PARAMETER NTStatus = 0xC00004AA + STATUS_FT_READ_FAILURE NTStatus = 0xC00004AB + STATUS_PATCH_CONFLICT NTStatus = 0xC00004AC + STATUS_STORAGE_RESERVE_ID_INVALID NTStatus = 0xC00004AD + STATUS_STORAGE_RESERVE_DOES_NOT_EXIST NTStatus = 0xC00004AE + STATUS_STORAGE_RESERVE_ALREADY_EXISTS NTStatus = 0xC00004AF + STATUS_STORAGE_RESERVE_NOT_EMPTY NTStatus = 0xC00004B0 + STATUS_NOT_A_DAX_VOLUME NTStatus = 0xC00004B1 + STATUS_NOT_DAX_MAPPABLE NTStatus = 0xC00004B2 + STATUS_CASE_DIFFERING_NAMES_IN_DIR NTStatus = 0xC00004B3 + STATUS_FILE_NOT_SUPPORTED NTStatus = 0xC00004B4 + STATUS_NOT_SUPPORTED_WITH_BTT NTStatus = 0xC00004B5 + STATUS_ENCRYPTION_DISABLED NTStatus = 0xC00004B6 + STATUS_ENCRYPTING_METADATA_DISALLOWED NTStatus = 0xC00004B7 + STATUS_CANT_CLEAR_ENCRYPTION_FLAG NTStatus = 0xC00004B8 + STATUS_INVALID_TASK_NAME NTStatus = 0xC0000500 + STATUS_INVALID_TASK_INDEX NTStatus = 0xC0000501 + STATUS_THREAD_ALREADY_IN_TASK NTStatus = 0xC0000502 + STATUS_CALLBACK_BYPASS NTStatus = 0xC0000503 + STATUS_UNDEFINED_SCOPE NTStatus = 0xC0000504 + STATUS_INVALID_CAP NTStatus = 0xC0000505 + STATUS_NOT_GUI_PROCESS NTStatus = 0xC0000506 + STATUS_DEVICE_HUNG NTStatus = 0xC0000507 + STATUS_CONTAINER_ASSIGNED NTStatus = 0xC0000508 + STATUS_JOB_NO_CONTAINER NTStatus = 0xC0000509 + STATUS_DEVICE_UNRESPONSIVE NTStatus = 0xC000050A + STATUS_REPARSE_POINT_ENCOUNTERED NTStatus = 0xC000050B + STATUS_ATTRIBUTE_NOT_PRESENT NTStatus = 0xC000050C + STATUS_NOT_A_TIERED_VOLUME NTStatus = 0xC000050D + STATUS_ALREADY_HAS_STREAM_ID NTStatus = 0xC000050E + STATUS_JOB_NOT_EMPTY NTStatus = 0xC000050F + STATUS_ALREADY_INITIALIZED NTStatus = 0xC0000510 + STATUS_ENCLAVE_NOT_TERMINATED NTStatus = 0xC0000511 + STATUS_ENCLAVE_IS_TERMINATING NTStatus = 0xC0000512 + STATUS_SMB1_NOT_AVAILABLE NTStatus = 0xC0000513 + STATUS_SMR_GARBAGE_COLLECTION_REQUIRED NTStatus = 0xC0000514 + STATUS_INTERRUPTED NTStatus = 0xC0000515 + STATUS_THREAD_NOT_RUNNING NTStatus = 0xC0000516 + STATUS_FAIL_FAST_EXCEPTION NTStatus = 0xC0000602 + STATUS_IMAGE_CERT_REVOKED NTStatus = 0xC0000603 + STATUS_DYNAMIC_CODE_BLOCKED NTStatus = 0xC0000604 + STATUS_IMAGE_CERT_EXPIRED NTStatus = 0xC0000605 + STATUS_STRICT_CFG_VIOLATION NTStatus = 0xC0000606 + STATUS_SET_CONTEXT_DENIED NTStatus = 0xC000060A + STATUS_CROSS_PARTITION_VIOLATION NTStatus = 0xC000060B + STATUS_PORT_CLOSED NTStatus = 0xC0000700 + STATUS_MESSAGE_LOST NTStatus = 0xC0000701 + STATUS_INVALID_MESSAGE NTStatus = 0xC0000702 + STATUS_REQUEST_CANCELED NTStatus = 0xC0000703 + STATUS_RECURSIVE_DISPATCH NTStatus = 0xC0000704 + STATUS_LPC_RECEIVE_BUFFER_EXPECTED NTStatus = 0xC0000705 + STATUS_LPC_INVALID_CONNECTION_USAGE NTStatus = 0xC0000706 + STATUS_LPC_REQUESTS_NOT_ALLOWED NTStatus = 0xC0000707 + STATUS_RESOURCE_IN_USE NTStatus = 0xC0000708 + STATUS_HARDWARE_MEMORY_ERROR NTStatus = 0xC0000709 + STATUS_THREADPOOL_HANDLE_EXCEPTION NTStatus = 0xC000070A + STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED NTStatus = 0xC000070B + STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED NTStatus = 0xC000070C + STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED NTStatus = 0xC000070D + STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED NTStatus = 0xC000070E + STATUS_THREADPOOL_RELEASED_DURING_OPERATION NTStatus = 0xC000070F + STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING NTStatus = 0xC0000710 + STATUS_APC_RETURNED_WHILE_IMPERSONATING NTStatus = 0xC0000711 + STATUS_PROCESS_IS_PROTECTED NTStatus = 0xC0000712 + STATUS_MCA_EXCEPTION NTStatus = 0xC0000713 + STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE NTStatus = 0xC0000714 + STATUS_SYMLINK_CLASS_DISABLED NTStatus = 0xC0000715 + STATUS_INVALID_IDN_NORMALIZATION NTStatus = 0xC0000716 + STATUS_NO_UNICODE_TRANSLATION NTStatus = 0xC0000717 + STATUS_ALREADY_REGISTERED NTStatus = 0xC0000718 + STATUS_CONTEXT_MISMATCH NTStatus = 0xC0000719 + STATUS_PORT_ALREADY_HAS_COMPLETION_LIST NTStatus = 0xC000071A + STATUS_CALLBACK_RETURNED_THREAD_PRIORITY NTStatus = 0xC000071B + STATUS_INVALID_THREAD NTStatus = 0xC000071C + STATUS_CALLBACK_RETURNED_TRANSACTION NTStatus = 0xC000071D + STATUS_CALLBACK_RETURNED_LDR_LOCK NTStatus = 0xC000071E + STATUS_CALLBACK_RETURNED_LANG NTStatus = 0xC000071F + STATUS_CALLBACK_RETURNED_PRI_BACK NTStatus = 0xC0000720 + STATUS_CALLBACK_RETURNED_THREAD_AFFINITY NTStatus = 0xC0000721 + STATUS_LPC_HANDLE_COUNT_EXCEEDED NTStatus = 0xC0000722 + STATUS_EXECUTABLE_MEMORY_WRITE NTStatus = 0xC0000723 + STATUS_KERNEL_EXECUTABLE_MEMORY_WRITE NTStatus = 0xC0000724 + STATUS_ATTACHED_EXECUTABLE_MEMORY_WRITE NTStatus = 0xC0000725 + STATUS_TRIGGERED_EXECUTABLE_MEMORY_WRITE NTStatus = 0xC0000726 + STATUS_DISK_REPAIR_DISABLED NTStatus = 0xC0000800 + STATUS_DS_DOMAIN_RENAME_IN_PROGRESS NTStatus = 0xC0000801 + STATUS_DISK_QUOTA_EXCEEDED NTStatus = 0xC0000802 + STATUS_DATA_LOST_REPAIR NTStatus = 0x80000803 + STATUS_CONTENT_BLOCKED NTStatus = 0xC0000804 + STATUS_BAD_CLUSTERS NTStatus = 0xC0000805 + STATUS_VOLUME_DIRTY NTStatus = 0xC0000806 + STATUS_DISK_REPAIR_REDIRECTED NTStatus = 0x40000807 + STATUS_DISK_REPAIR_UNSUCCESSFUL NTStatus = 0xC0000808 + STATUS_CORRUPT_LOG_OVERFULL NTStatus = 0xC0000809 + STATUS_CORRUPT_LOG_CORRUPTED NTStatus = 0xC000080A + STATUS_CORRUPT_LOG_UNAVAILABLE NTStatus = 0xC000080B + STATUS_CORRUPT_LOG_DELETED_FULL NTStatus = 0xC000080C + STATUS_CORRUPT_LOG_CLEARED NTStatus = 0xC000080D + STATUS_ORPHAN_NAME_EXHAUSTED NTStatus = 0xC000080E + STATUS_PROACTIVE_SCAN_IN_PROGRESS NTStatus = 0xC000080F + STATUS_ENCRYPTED_IO_NOT_POSSIBLE NTStatus = 0xC0000810 + STATUS_CORRUPT_LOG_UPLEVEL_RECORDS NTStatus = 0xC0000811 + STATUS_FILE_CHECKED_OUT NTStatus = 0xC0000901 + STATUS_CHECKOUT_REQUIRED NTStatus = 0xC0000902 + STATUS_BAD_FILE_TYPE NTStatus = 0xC0000903 + STATUS_FILE_TOO_LARGE NTStatus = 0xC0000904 + STATUS_FORMS_AUTH_REQUIRED NTStatus = 0xC0000905 + STATUS_VIRUS_INFECTED NTStatus = 0xC0000906 + STATUS_VIRUS_DELETED NTStatus = 0xC0000907 + STATUS_BAD_MCFG_TABLE NTStatus = 0xC0000908 + STATUS_CANNOT_BREAK_OPLOCK NTStatus = 0xC0000909 + STATUS_BAD_KEY NTStatus = 0xC000090A + STATUS_BAD_DATA NTStatus = 0xC000090B + STATUS_NO_KEY NTStatus = 0xC000090C + STATUS_FILE_HANDLE_REVOKED NTStatus = 0xC0000910 + STATUS_WOW_ASSERTION NTStatus = 0xC0009898 + STATUS_INVALID_SIGNATURE NTStatus = 0xC000A000 + STATUS_HMAC_NOT_SUPPORTED NTStatus = 0xC000A001 + STATUS_AUTH_TAG_MISMATCH NTStatus = 0xC000A002 + STATUS_INVALID_STATE_TRANSITION NTStatus = 0xC000A003 + STATUS_INVALID_KERNEL_INFO_VERSION NTStatus = 0xC000A004 + STATUS_INVALID_PEP_INFO_VERSION NTStatus = 0xC000A005 + STATUS_HANDLE_REVOKED NTStatus = 0xC000A006 + STATUS_EOF_ON_GHOSTED_RANGE NTStatus = 0xC000A007 + STATUS_IPSEC_QUEUE_OVERFLOW NTStatus = 0xC000A010 + STATUS_ND_QUEUE_OVERFLOW NTStatus = 0xC000A011 + STATUS_HOPLIMIT_EXCEEDED NTStatus = 0xC000A012 + STATUS_PROTOCOL_NOT_SUPPORTED NTStatus = 0xC000A013 + STATUS_FASTPATH_REJECTED NTStatus = 0xC000A014 + STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED NTStatus = 0xC000A080 + STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR NTStatus = 0xC000A081 + STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR NTStatus = 0xC000A082 + STATUS_XML_PARSE_ERROR NTStatus = 0xC000A083 + STATUS_XMLDSIG_ERROR NTStatus = 0xC000A084 + STATUS_WRONG_COMPARTMENT NTStatus = 0xC000A085 + STATUS_AUTHIP_FAILURE NTStatus = 0xC000A086 + STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS NTStatus = 0xC000A087 + STATUS_DS_OID_NOT_FOUND NTStatus = 0xC000A088 + STATUS_INCORRECT_ACCOUNT_TYPE NTStatus = 0xC000A089 + STATUS_HASH_NOT_SUPPORTED NTStatus = 0xC000A100 + STATUS_HASH_NOT_PRESENT NTStatus = 0xC000A101 + STATUS_SECONDARY_IC_PROVIDER_NOT_REGISTERED NTStatus = 0xC000A121 + STATUS_GPIO_CLIENT_INFORMATION_INVALID NTStatus = 0xC000A122 + STATUS_GPIO_VERSION_NOT_SUPPORTED NTStatus = 0xC000A123 + STATUS_GPIO_INVALID_REGISTRATION_PACKET NTStatus = 0xC000A124 + STATUS_GPIO_OPERATION_DENIED NTStatus = 0xC000A125 + STATUS_GPIO_INCOMPATIBLE_CONNECT_MODE NTStatus = 0xC000A126 + STATUS_GPIO_INTERRUPT_ALREADY_UNMASKED NTStatus = 0x8000A127 + STATUS_CANNOT_SWITCH_RUNLEVEL NTStatus = 0xC000A141 + STATUS_INVALID_RUNLEVEL_SETTING NTStatus = 0xC000A142 + STATUS_RUNLEVEL_SWITCH_TIMEOUT NTStatus = 0xC000A143 + STATUS_SERVICES_FAILED_AUTOSTART NTStatus = 0x4000A144 + STATUS_RUNLEVEL_SWITCH_AGENT_TIMEOUT NTStatus = 0xC000A145 + STATUS_RUNLEVEL_SWITCH_IN_PROGRESS NTStatus = 0xC000A146 + STATUS_NOT_APPCONTAINER NTStatus = 0xC000A200 + STATUS_NOT_SUPPORTED_IN_APPCONTAINER NTStatus = 0xC000A201 + STATUS_INVALID_PACKAGE_SID_LENGTH NTStatus = 0xC000A202 + STATUS_LPAC_ACCESS_DENIED NTStatus = 0xC000A203 + STATUS_ADMINLESS_ACCESS_DENIED NTStatus = 0xC000A204 + STATUS_APP_DATA_NOT_FOUND NTStatus = 0xC000A281 + STATUS_APP_DATA_EXPIRED NTStatus = 0xC000A282 + STATUS_APP_DATA_CORRUPT NTStatus = 0xC000A283 + STATUS_APP_DATA_LIMIT_EXCEEDED NTStatus = 0xC000A284 + STATUS_APP_DATA_REBOOT_REQUIRED NTStatus = 0xC000A285 + STATUS_OFFLOAD_READ_FLT_NOT_SUPPORTED NTStatus = 0xC000A2A1 + STATUS_OFFLOAD_WRITE_FLT_NOT_SUPPORTED NTStatus = 0xC000A2A2 + STATUS_OFFLOAD_READ_FILE_NOT_SUPPORTED NTStatus = 0xC000A2A3 + STATUS_OFFLOAD_WRITE_FILE_NOT_SUPPORTED NTStatus = 0xC000A2A4 + STATUS_WOF_WIM_HEADER_CORRUPT NTStatus = 0xC000A2A5 + STATUS_WOF_WIM_RESOURCE_TABLE_CORRUPT NTStatus = 0xC000A2A6 + STATUS_WOF_FILE_RESOURCE_TABLE_CORRUPT NTStatus = 0xC000A2A7 + STATUS_FILE_SYSTEM_VIRTUALIZATION_UNAVAILABLE NTStatus = 0xC000CE01 + STATUS_FILE_SYSTEM_VIRTUALIZATION_METADATA_CORRUPT NTStatus = 0xC000CE02 + STATUS_FILE_SYSTEM_VIRTUALIZATION_BUSY NTStatus = 0xC000CE03 + STATUS_FILE_SYSTEM_VIRTUALIZATION_PROVIDER_UNKNOWN NTStatus = 0xC000CE04 + STATUS_FILE_SYSTEM_VIRTUALIZATION_INVALID_OPERATION NTStatus = 0xC000CE05 + STATUS_CLOUD_FILE_SYNC_ROOT_METADATA_CORRUPT NTStatus = 0xC000CF00 + STATUS_CLOUD_FILE_PROVIDER_NOT_RUNNING NTStatus = 0xC000CF01 + STATUS_CLOUD_FILE_METADATA_CORRUPT NTStatus = 0xC000CF02 + STATUS_CLOUD_FILE_METADATA_TOO_LARGE NTStatus = 0xC000CF03 + STATUS_CLOUD_FILE_PROPERTY_BLOB_TOO_LARGE NTStatus = 0x8000CF04 + STATUS_CLOUD_FILE_TOO_MANY_PROPERTY_BLOBS NTStatus = 0x8000CF05 + STATUS_CLOUD_FILE_PROPERTY_VERSION_NOT_SUPPORTED NTStatus = 0xC000CF06 + STATUS_NOT_A_CLOUD_FILE NTStatus = 0xC000CF07 + STATUS_CLOUD_FILE_NOT_IN_SYNC NTStatus = 0xC000CF08 + STATUS_CLOUD_FILE_ALREADY_CONNECTED NTStatus = 0xC000CF09 + STATUS_CLOUD_FILE_NOT_SUPPORTED NTStatus = 0xC000CF0A + STATUS_CLOUD_FILE_INVALID_REQUEST NTStatus = 0xC000CF0B + STATUS_CLOUD_FILE_READ_ONLY_VOLUME NTStatus = 0xC000CF0C + STATUS_CLOUD_FILE_CONNECTED_PROVIDER_ONLY NTStatus = 0xC000CF0D + STATUS_CLOUD_FILE_VALIDATION_FAILED NTStatus = 0xC000CF0E + STATUS_CLOUD_FILE_AUTHENTICATION_FAILED NTStatus = 0xC000CF0F + STATUS_CLOUD_FILE_INSUFFICIENT_RESOURCES NTStatus = 0xC000CF10 + STATUS_CLOUD_FILE_NETWORK_UNAVAILABLE NTStatus = 0xC000CF11 + STATUS_CLOUD_FILE_UNSUCCESSFUL NTStatus = 0xC000CF12 + STATUS_CLOUD_FILE_NOT_UNDER_SYNC_ROOT NTStatus = 0xC000CF13 + STATUS_CLOUD_FILE_IN_USE NTStatus = 0xC000CF14 + STATUS_CLOUD_FILE_PINNED NTStatus = 0xC000CF15 + STATUS_CLOUD_FILE_REQUEST_ABORTED NTStatus = 0xC000CF16 + STATUS_CLOUD_FILE_PROPERTY_CORRUPT NTStatus = 0xC000CF17 + STATUS_CLOUD_FILE_ACCESS_DENIED NTStatus = 0xC000CF18 + STATUS_CLOUD_FILE_INCOMPATIBLE_HARDLINKS NTStatus = 0xC000CF19 + STATUS_CLOUD_FILE_PROPERTY_LOCK_CONFLICT NTStatus = 0xC000CF1A + STATUS_CLOUD_FILE_REQUEST_CANCELED NTStatus = 0xC000CF1B + STATUS_CLOUD_FILE_PROVIDER_TERMINATED NTStatus = 0xC000CF1D + STATUS_NOT_A_CLOUD_SYNC_ROOT NTStatus = 0xC000CF1E + STATUS_CLOUD_FILE_REQUEST_TIMEOUT NTStatus = 0xC000CF1F + STATUS_ACPI_INVALID_OPCODE NTStatus = 0xC0140001 + STATUS_ACPI_STACK_OVERFLOW NTStatus = 0xC0140002 + STATUS_ACPI_ASSERT_FAILED NTStatus = 0xC0140003 + STATUS_ACPI_INVALID_INDEX NTStatus = 0xC0140004 + STATUS_ACPI_INVALID_ARGUMENT NTStatus = 0xC0140005 + STATUS_ACPI_FATAL NTStatus = 0xC0140006 + STATUS_ACPI_INVALID_SUPERNAME NTStatus = 0xC0140007 + STATUS_ACPI_INVALID_ARGTYPE NTStatus = 0xC0140008 + STATUS_ACPI_INVALID_OBJTYPE NTStatus = 0xC0140009 + STATUS_ACPI_INVALID_TARGETTYPE NTStatus = 0xC014000A + STATUS_ACPI_INCORRECT_ARGUMENT_COUNT NTStatus = 0xC014000B + STATUS_ACPI_ADDRESS_NOT_MAPPED NTStatus = 0xC014000C + STATUS_ACPI_INVALID_EVENTTYPE NTStatus = 0xC014000D + STATUS_ACPI_HANDLER_COLLISION NTStatus = 0xC014000E + STATUS_ACPI_INVALID_DATA NTStatus = 0xC014000F + STATUS_ACPI_INVALID_REGION NTStatus = 0xC0140010 + STATUS_ACPI_INVALID_ACCESS_SIZE NTStatus = 0xC0140011 + STATUS_ACPI_ACQUIRE_GLOBAL_LOCK NTStatus = 0xC0140012 + STATUS_ACPI_ALREADY_INITIALIZED NTStatus = 0xC0140013 + STATUS_ACPI_NOT_INITIALIZED NTStatus = 0xC0140014 + STATUS_ACPI_INVALID_MUTEX_LEVEL NTStatus = 0xC0140015 + STATUS_ACPI_MUTEX_NOT_OWNED NTStatus = 0xC0140016 + STATUS_ACPI_MUTEX_NOT_OWNER NTStatus = 0xC0140017 + STATUS_ACPI_RS_ACCESS NTStatus = 0xC0140018 + STATUS_ACPI_INVALID_TABLE NTStatus = 0xC0140019 + STATUS_ACPI_REG_HANDLER_FAILED NTStatus = 0xC0140020 + STATUS_ACPI_POWER_REQUEST_FAILED NTStatus = 0xC0140021 + STATUS_CTX_WINSTATION_NAME_INVALID NTStatus = 0xC00A0001 + STATUS_CTX_INVALID_PD NTStatus = 0xC00A0002 + STATUS_CTX_PD_NOT_FOUND NTStatus = 0xC00A0003 + STATUS_CTX_CDM_CONNECT NTStatus = 0x400A0004 + STATUS_CTX_CDM_DISCONNECT NTStatus = 0x400A0005 + STATUS_CTX_CLOSE_PENDING NTStatus = 0xC00A0006 + STATUS_CTX_NO_OUTBUF NTStatus = 0xC00A0007 + STATUS_CTX_MODEM_INF_NOT_FOUND NTStatus = 0xC00A0008 + STATUS_CTX_INVALID_MODEMNAME NTStatus = 0xC00A0009 + STATUS_CTX_RESPONSE_ERROR NTStatus = 0xC00A000A + STATUS_CTX_MODEM_RESPONSE_TIMEOUT NTStatus = 0xC00A000B + STATUS_CTX_MODEM_RESPONSE_NO_CARRIER NTStatus = 0xC00A000C + STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE NTStatus = 0xC00A000D + STATUS_CTX_MODEM_RESPONSE_BUSY NTStatus = 0xC00A000E + STATUS_CTX_MODEM_RESPONSE_VOICE NTStatus = 0xC00A000F + STATUS_CTX_TD_ERROR NTStatus = 0xC00A0010 + STATUS_CTX_LICENSE_CLIENT_INVALID NTStatus = 0xC00A0012 + STATUS_CTX_LICENSE_NOT_AVAILABLE NTStatus = 0xC00A0013 + STATUS_CTX_LICENSE_EXPIRED NTStatus = 0xC00A0014 + STATUS_CTX_WINSTATION_NOT_FOUND NTStatus = 0xC00A0015 + STATUS_CTX_WINSTATION_NAME_COLLISION NTStatus = 0xC00A0016 + STATUS_CTX_WINSTATION_BUSY NTStatus = 0xC00A0017 + STATUS_CTX_BAD_VIDEO_MODE NTStatus = 0xC00A0018 + STATUS_CTX_GRAPHICS_INVALID NTStatus = 0xC00A0022 + STATUS_CTX_NOT_CONSOLE NTStatus = 0xC00A0024 + STATUS_CTX_CLIENT_QUERY_TIMEOUT NTStatus = 0xC00A0026 + STATUS_CTX_CONSOLE_DISCONNECT NTStatus = 0xC00A0027 + STATUS_CTX_CONSOLE_CONNECT NTStatus = 0xC00A0028 + STATUS_CTX_SHADOW_DENIED NTStatus = 0xC00A002A + STATUS_CTX_WINSTATION_ACCESS_DENIED NTStatus = 0xC00A002B + STATUS_CTX_INVALID_WD NTStatus = 0xC00A002E + STATUS_CTX_WD_NOT_FOUND NTStatus = 0xC00A002F + STATUS_CTX_SHADOW_INVALID NTStatus = 0xC00A0030 + STATUS_CTX_SHADOW_DISABLED NTStatus = 0xC00A0031 + STATUS_RDP_PROTOCOL_ERROR NTStatus = 0xC00A0032 + STATUS_CTX_CLIENT_LICENSE_NOT_SET NTStatus = 0xC00A0033 + STATUS_CTX_CLIENT_LICENSE_IN_USE NTStatus = 0xC00A0034 + STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE NTStatus = 0xC00A0035 + STATUS_CTX_SHADOW_NOT_RUNNING NTStatus = 0xC00A0036 + STATUS_CTX_LOGON_DISABLED NTStatus = 0xC00A0037 + STATUS_CTX_SECURITY_LAYER_ERROR NTStatus = 0xC00A0038 + STATUS_TS_INCOMPATIBLE_SESSIONS NTStatus = 0xC00A0039 + STATUS_TS_VIDEO_SUBSYSTEM_ERROR NTStatus = 0xC00A003A + STATUS_PNP_BAD_MPS_TABLE NTStatus = 0xC0040035 + STATUS_PNP_TRANSLATION_FAILED NTStatus = 0xC0040036 + STATUS_PNP_IRQ_TRANSLATION_FAILED NTStatus = 0xC0040037 + STATUS_PNP_INVALID_ID NTStatus = 0xC0040038 + STATUS_IO_REISSUE_AS_CACHED NTStatus = 0xC0040039 + STATUS_MUI_FILE_NOT_FOUND NTStatus = 0xC00B0001 + STATUS_MUI_INVALID_FILE NTStatus = 0xC00B0002 + STATUS_MUI_INVALID_RC_CONFIG NTStatus = 0xC00B0003 + STATUS_MUI_INVALID_LOCALE_NAME NTStatus = 0xC00B0004 + STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME NTStatus = 0xC00B0005 + STATUS_MUI_FILE_NOT_LOADED NTStatus = 0xC00B0006 + STATUS_RESOURCE_ENUM_USER_STOP NTStatus = 0xC00B0007 + STATUS_FLT_NO_HANDLER_DEFINED NTStatus = 0xC01C0001 + STATUS_FLT_CONTEXT_ALREADY_DEFINED NTStatus = 0xC01C0002 + STATUS_FLT_INVALID_ASYNCHRONOUS_REQUEST NTStatus = 0xC01C0003 + STATUS_FLT_DISALLOW_FAST_IO NTStatus = 0xC01C0004 + STATUS_FLT_INVALID_NAME_REQUEST NTStatus = 0xC01C0005 + STATUS_FLT_NOT_SAFE_TO_POST_OPERATION NTStatus = 0xC01C0006 + STATUS_FLT_NOT_INITIALIZED NTStatus = 0xC01C0007 + STATUS_FLT_FILTER_NOT_READY NTStatus = 0xC01C0008 + STATUS_FLT_POST_OPERATION_CLEANUP NTStatus = 0xC01C0009 + STATUS_FLT_INTERNAL_ERROR NTStatus = 0xC01C000A + STATUS_FLT_DELETING_OBJECT NTStatus = 0xC01C000B + STATUS_FLT_MUST_BE_NONPAGED_POOL NTStatus = 0xC01C000C + STATUS_FLT_DUPLICATE_ENTRY NTStatus = 0xC01C000D + STATUS_FLT_CBDQ_DISABLED NTStatus = 0xC01C000E + STATUS_FLT_DO_NOT_ATTACH NTStatus = 0xC01C000F + STATUS_FLT_DO_NOT_DETACH NTStatus = 0xC01C0010 + STATUS_FLT_INSTANCE_ALTITUDE_COLLISION NTStatus = 0xC01C0011 + STATUS_FLT_INSTANCE_NAME_COLLISION NTStatus = 0xC01C0012 + STATUS_FLT_FILTER_NOT_FOUND NTStatus = 0xC01C0013 + STATUS_FLT_VOLUME_NOT_FOUND NTStatus = 0xC01C0014 + STATUS_FLT_INSTANCE_NOT_FOUND NTStatus = 0xC01C0015 + STATUS_FLT_CONTEXT_ALLOCATION_NOT_FOUND NTStatus = 0xC01C0016 + STATUS_FLT_INVALID_CONTEXT_REGISTRATION NTStatus = 0xC01C0017 + STATUS_FLT_NAME_CACHE_MISS NTStatus = 0xC01C0018 + STATUS_FLT_NO_DEVICE_OBJECT NTStatus = 0xC01C0019 + STATUS_FLT_VOLUME_ALREADY_MOUNTED NTStatus = 0xC01C001A + STATUS_FLT_ALREADY_ENLISTED NTStatus = 0xC01C001B + STATUS_FLT_CONTEXT_ALREADY_LINKED NTStatus = 0xC01C001C + STATUS_FLT_NO_WAITER_FOR_REPLY NTStatus = 0xC01C0020 + STATUS_FLT_REGISTRATION_BUSY NTStatus = 0xC01C0023 + STATUS_SXS_SECTION_NOT_FOUND NTStatus = 0xC0150001 + STATUS_SXS_CANT_GEN_ACTCTX NTStatus = 0xC0150002 + STATUS_SXS_INVALID_ACTCTXDATA_FORMAT NTStatus = 0xC0150003 + STATUS_SXS_ASSEMBLY_NOT_FOUND NTStatus = 0xC0150004 + STATUS_SXS_MANIFEST_FORMAT_ERROR NTStatus = 0xC0150005 + STATUS_SXS_MANIFEST_PARSE_ERROR NTStatus = 0xC0150006 + STATUS_SXS_ACTIVATION_CONTEXT_DISABLED NTStatus = 0xC0150007 + STATUS_SXS_KEY_NOT_FOUND NTStatus = 0xC0150008 + STATUS_SXS_VERSION_CONFLICT NTStatus = 0xC0150009 + STATUS_SXS_WRONG_SECTION_TYPE NTStatus = 0xC015000A + STATUS_SXS_THREAD_QUERIES_DISABLED NTStatus = 0xC015000B + STATUS_SXS_ASSEMBLY_MISSING NTStatus = 0xC015000C + STATUS_SXS_RELEASE_ACTIVATION_CONTEXT NTStatus = 0x4015000D + STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET NTStatus = 0xC015000E + STATUS_SXS_EARLY_DEACTIVATION NTStatus = 0xC015000F + STATUS_SXS_INVALID_DEACTIVATION NTStatus = 0xC0150010 + STATUS_SXS_MULTIPLE_DEACTIVATION NTStatus = 0xC0150011 + STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY NTStatus = 0xC0150012 + STATUS_SXS_PROCESS_TERMINATION_REQUESTED NTStatus = 0xC0150013 + STATUS_SXS_CORRUPT_ACTIVATION_STACK NTStatus = 0xC0150014 + STATUS_SXS_CORRUPTION NTStatus = 0xC0150015 + STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE NTStatus = 0xC0150016 + STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME NTStatus = 0xC0150017 + STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE NTStatus = 0xC0150018 + STATUS_SXS_IDENTITY_PARSE_ERROR NTStatus = 0xC0150019 + STATUS_SXS_COMPONENT_STORE_CORRUPT NTStatus = 0xC015001A + STATUS_SXS_FILE_HASH_MISMATCH NTStatus = 0xC015001B + STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT NTStatus = 0xC015001C + STATUS_SXS_IDENTITIES_DIFFERENT NTStatus = 0xC015001D + STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT NTStatus = 0xC015001E + STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY NTStatus = 0xC015001F + STATUS_ADVANCED_INSTALLER_FAILED NTStatus = 0xC0150020 + STATUS_XML_ENCODING_MISMATCH NTStatus = 0xC0150021 + STATUS_SXS_MANIFEST_TOO_BIG NTStatus = 0xC0150022 + STATUS_SXS_SETTING_NOT_REGISTERED NTStatus = 0xC0150023 + STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE NTStatus = 0xC0150024 + STATUS_SMI_PRIMITIVE_INSTALLER_FAILED NTStatus = 0xC0150025 + STATUS_GENERIC_COMMAND_FAILED NTStatus = 0xC0150026 + STATUS_SXS_FILE_HASH_MISSING NTStatus = 0xC0150027 + STATUS_CLUSTER_INVALID_NODE NTStatus = 0xC0130001 + STATUS_CLUSTER_NODE_EXISTS NTStatus = 0xC0130002 + STATUS_CLUSTER_JOIN_IN_PROGRESS NTStatus = 0xC0130003 + STATUS_CLUSTER_NODE_NOT_FOUND NTStatus = 0xC0130004 + STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND NTStatus = 0xC0130005 + STATUS_CLUSTER_NETWORK_EXISTS NTStatus = 0xC0130006 + STATUS_CLUSTER_NETWORK_NOT_FOUND NTStatus = 0xC0130007 + STATUS_CLUSTER_NETINTERFACE_EXISTS NTStatus = 0xC0130008 + STATUS_CLUSTER_NETINTERFACE_NOT_FOUND NTStatus = 0xC0130009 + STATUS_CLUSTER_INVALID_REQUEST NTStatus = 0xC013000A + STATUS_CLUSTER_INVALID_NETWORK_PROVIDER NTStatus = 0xC013000B + STATUS_CLUSTER_NODE_DOWN NTStatus = 0xC013000C + STATUS_CLUSTER_NODE_UNREACHABLE NTStatus = 0xC013000D + STATUS_CLUSTER_NODE_NOT_MEMBER NTStatus = 0xC013000E + STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS NTStatus = 0xC013000F + STATUS_CLUSTER_INVALID_NETWORK NTStatus = 0xC0130010 + STATUS_CLUSTER_NO_NET_ADAPTERS NTStatus = 0xC0130011 + STATUS_CLUSTER_NODE_UP NTStatus = 0xC0130012 + STATUS_CLUSTER_NODE_PAUSED NTStatus = 0xC0130013 + STATUS_CLUSTER_NODE_NOT_PAUSED NTStatus = 0xC0130014 + STATUS_CLUSTER_NO_SECURITY_CONTEXT NTStatus = 0xC0130015 + STATUS_CLUSTER_NETWORK_NOT_INTERNAL NTStatus = 0xC0130016 + STATUS_CLUSTER_POISONED NTStatus = 0xC0130017 + STATUS_CLUSTER_NON_CSV_PATH NTStatus = 0xC0130018 + STATUS_CLUSTER_CSV_VOLUME_NOT_LOCAL NTStatus = 0xC0130019 + STATUS_CLUSTER_CSV_READ_OPLOCK_BREAK_IN_PROGRESS NTStatus = 0xC0130020 + STATUS_CLUSTER_CSV_AUTO_PAUSE_ERROR NTStatus = 0xC0130021 + STATUS_CLUSTER_CSV_REDIRECTED NTStatus = 0xC0130022 + STATUS_CLUSTER_CSV_NOT_REDIRECTED NTStatus = 0xC0130023 + STATUS_CLUSTER_CSV_VOLUME_DRAINING NTStatus = 0xC0130024 + STATUS_CLUSTER_CSV_SNAPSHOT_CREATION_IN_PROGRESS NTStatus = 0xC0130025 + STATUS_CLUSTER_CSV_VOLUME_DRAINING_SUCCEEDED_DOWNLEVEL NTStatus = 0xC0130026 + STATUS_CLUSTER_CSV_NO_SNAPSHOTS NTStatus = 0xC0130027 + STATUS_CSV_IO_PAUSE_TIMEOUT NTStatus = 0xC0130028 + STATUS_CLUSTER_CSV_INVALID_HANDLE NTStatus = 0xC0130029 + STATUS_CLUSTER_CSV_SUPPORTED_ONLY_ON_COORDINATOR NTStatus = 0xC0130030 + STATUS_CLUSTER_CAM_TICKET_REPLAY_DETECTED NTStatus = 0xC0130031 + STATUS_TRANSACTIONAL_CONFLICT NTStatus = 0xC0190001 + STATUS_INVALID_TRANSACTION NTStatus = 0xC0190002 + STATUS_TRANSACTION_NOT_ACTIVE NTStatus = 0xC0190003 + STATUS_TM_INITIALIZATION_FAILED NTStatus = 0xC0190004 + STATUS_RM_NOT_ACTIVE NTStatus = 0xC0190005 + STATUS_RM_METADATA_CORRUPT NTStatus = 0xC0190006 + STATUS_TRANSACTION_NOT_JOINED NTStatus = 0xC0190007 + STATUS_DIRECTORY_NOT_RM NTStatus = 0xC0190008 + STATUS_COULD_NOT_RESIZE_LOG NTStatus = 0x80190009 + STATUS_TRANSACTIONS_UNSUPPORTED_REMOTE NTStatus = 0xC019000A + STATUS_LOG_RESIZE_INVALID_SIZE NTStatus = 0xC019000B + STATUS_REMOTE_FILE_VERSION_MISMATCH NTStatus = 0xC019000C + STATUS_CRM_PROTOCOL_ALREADY_EXISTS NTStatus = 0xC019000F + STATUS_TRANSACTION_PROPAGATION_FAILED NTStatus = 0xC0190010 + STATUS_CRM_PROTOCOL_NOT_FOUND NTStatus = 0xC0190011 + STATUS_TRANSACTION_SUPERIOR_EXISTS NTStatus = 0xC0190012 + STATUS_TRANSACTION_REQUEST_NOT_VALID NTStatus = 0xC0190013 + STATUS_TRANSACTION_NOT_REQUESTED NTStatus = 0xC0190014 + STATUS_TRANSACTION_ALREADY_ABORTED NTStatus = 0xC0190015 + STATUS_TRANSACTION_ALREADY_COMMITTED NTStatus = 0xC0190016 + STATUS_TRANSACTION_INVALID_MARSHALL_BUFFER NTStatus = 0xC0190017 + STATUS_CURRENT_TRANSACTION_NOT_VALID NTStatus = 0xC0190018 + STATUS_LOG_GROWTH_FAILED NTStatus = 0xC0190019 + STATUS_OBJECT_NO_LONGER_EXISTS NTStatus = 0xC0190021 + STATUS_STREAM_MINIVERSION_NOT_FOUND NTStatus = 0xC0190022 + STATUS_STREAM_MINIVERSION_NOT_VALID NTStatus = 0xC0190023 + STATUS_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION NTStatus = 0xC0190024 + STATUS_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT NTStatus = 0xC0190025 + STATUS_CANT_CREATE_MORE_STREAM_MINIVERSIONS NTStatus = 0xC0190026 + STATUS_HANDLE_NO_LONGER_VALID NTStatus = 0xC0190028 + STATUS_NO_TXF_METADATA NTStatus = 0x80190029 + STATUS_LOG_CORRUPTION_DETECTED NTStatus = 0xC0190030 + STATUS_CANT_RECOVER_WITH_HANDLE_OPEN NTStatus = 0x80190031 + STATUS_RM_DISCONNECTED NTStatus = 0xC0190032 + STATUS_ENLISTMENT_NOT_SUPERIOR NTStatus = 0xC0190033 + STATUS_RECOVERY_NOT_NEEDED NTStatus = 0x40190034 + STATUS_RM_ALREADY_STARTED NTStatus = 0x40190035 + STATUS_FILE_IDENTITY_NOT_PERSISTENT NTStatus = 0xC0190036 + STATUS_CANT_BREAK_TRANSACTIONAL_DEPENDENCY NTStatus = 0xC0190037 + STATUS_CANT_CROSS_RM_BOUNDARY NTStatus = 0xC0190038 + STATUS_TXF_DIR_NOT_EMPTY NTStatus = 0xC0190039 + STATUS_INDOUBT_TRANSACTIONS_EXIST NTStatus = 0xC019003A + STATUS_TM_VOLATILE NTStatus = 0xC019003B + STATUS_ROLLBACK_TIMER_EXPIRED NTStatus = 0xC019003C + STATUS_TXF_ATTRIBUTE_CORRUPT NTStatus = 0xC019003D + STATUS_EFS_NOT_ALLOWED_IN_TRANSACTION NTStatus = 0xC019003E + STATUS_TRANSACTIONAL_OPEN_NOT_ALLOWED NTStatus = 0xC019003F + STATUS_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE NTStatus = 0xC0190040 + STATUS_TXF_METADATA_ALREADY_PRESENT NTStatus = 0x80190041 + STATUS_TRANSACTION_SCOPE_CALLBACKS_NOT_SET NTStatus = 0x80190042 + STATUS_TRANSACTION_REQUIRED_PROMOTION NTStatus = 0xC0190043 + STATUS_CANNOT_EXECUTE_FILE_IN_TRANSACTION NTStatus = 0xC0190044 + STATUS_TRANSACTIONS_NOT_FROZEN NTStatus = 0xC0190045 + STATUS_TRANSACTION_FREEZE_IN_PROGRESS NTStatus = 0xC0190046 + STATUS_NOT_SNAPSHOT_VOLUME NTStatus = 0xC0190047 + STATUS_NO_SAVEPOINT_WITH_OPEN_FILES NTStatus = 0xC0190048 + STATUS_SPARSE_NOT_ALLOWED_IN_TRANSACTION NTStatus = 0xC0190049 + STATUS_TM_IDENTITY_MISMATCH NTStatus = 0xC019004A + STATUS_FLOATED_SECTION NTStatus = 0xC019004B + STATUS_CANNOT_ACCEPT_TRANSACTED_WORK NTStatus = 0xC019004C + STATUS_CANNOT_ABORT_TRANSACTIONS NTStatus = 0xC019004D + STATUS_TRANSACTION_NOT_FOUND NTStatus = 0xC019004E + STATUS_RESOURCEMANAGER_NOT_FOUND NTStatus = 0xC019004F + STATUS_ENLISTMENT_NOT_FOUND NTStatus = 0xC0190050 + STATUS_TRANSACTIONMANAGER_NOT_FOUND NTStatus = 0xC0190051 + STATUS_TRANSACTIONMANAGER_NOT_ONLINE NTStatus = 0xC0190052 + STATUS_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION NTStatus = 0xC0190053 + STATUS_TRANSACTION_NOT_ROOT NTStatus = 0xC0190054 + STATUS_TRANSACTION_OBJECT_EXPIRED NTStatus = 0xC0190055 + STATUS_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION NTStatus = 0xC0190056 + STATUS_TRANSACTION_RESPONSE_NOT_ENLISTED NTStatus = 0xC0190057 + STATUS_TRANSACTION_RECORD_TOO_LONG NTStatus = 0xC0190058 + STATUS_NO_LINK_TRACKING_IN_TRANSACTION NTStatus = 0xC0190059 + STATUS_OPERATION_NOT_SUPPORTED_IN_TRANSACTION NTStatus = 0xC019005A + STATUS_TRANSACTION_INTEGRITY_VIOLATED NTStatus = 0xC019005B + STATUS_TRANSACTIONMANAGER_IDENTITY_MISMATCH NTStatus = 0xC019005C + STATUS_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT NTStatus = 0xC019005D + STATUS_TRANSACTION_MUST_WRITETHROUGH NTStatus = 0xC019005E + STATUS_TRANSACTION_NO_SUPERIOR NTStatus = 0xC019005F + STATUS_EXPIRED_HANDLE NTStatus = 0xC0190060 + STATUS_TRANSACTION_NOT_ENLISTED NTStatus = 0xC0190061 + STATUS_LOG_SECTOR_INVALID NTStatus = 0xC01A0001 + STATUS_LOG_SECTOR_PARITY_INVALID NTStatus = 0xC01A0002 + STATUS_LOG_SECTOR_REMAPPED NTStatus = 0xC01A0003 + STATUS_LOG_BLOCK_INCOMPLETE NTStatus = 0xC01A0004 + STATUS_LOG_INVALID_RANGE NTStatus = 0xC01A0005 + STATUS_LOG_BLOCKS_EXHAUSTED NTStatus = 0xC01A0006 + STATUS_LOG_READ_CONTEXT_INVALID NTStatus = 0xC01A0007 + STATUS_LOG_RESTART_INVALID NTStatus = 0xC01A0008 + STATUS_LOG_BLOCK_VERSION NTStatus = 0xC01A0009 + STATUS_LOG_BLOCK_INVALID NTStatus = 0xC01A000A + STATUS_LOG_READ_MODE_INVALID NTStatus = 0xC01A000B + STATUS_LOG_NO_RESTART NTStatus = 0x401A000C + STATUS_LOG_METADATA_CORRUPT NTStatus = 0xC01A000D + STATUS_LOG_METADATA_INVALID NTStatus = 0xC01A000E + STATUS_LOG_METADATA_INCONSISTENT NTStatus = 0xC01A000F + STATUS_LOG_RESERVATION_INVALID NTStatus = 0xC01A0010 + STATUS_LOG_CANT_DELETE NTStatus = 0xC01A0011 + STATUS_LOG_CONTAINER_LIMIT_EXCEEDED NTStatus = 0xC01A0012 + STATUS_LOG_START_OF_LOG NTStatus = 0xC01A0013 + STATUS_LOG_POLICY_ALREADY_INSTALLED NTStatus = 0xC01A0014 + STATUS_LOG_POLICY_NOT_INSTALLED NTStatus = 0xC01A0015 + STATUS_LOG_POLICY_INVALID NTStatus = 0xC01A0016 + STATUS_LOG_POLICY_CONFLICT NTStatus = 0xC01A0017 + STATUS_LOG_PINNED_ARCHIVE_TAIL NTStatus = 0xC01A0018 + STATUS_LOG_RECORD_NONEXISTENT NTStatus = 0xC01A0019 + STATUS_LOG_RECORDS_RESERVED_INVALID NTStatus = 0xC01A001A + STATUS_LOG_SPACE_RESERVED_INVALID NTStatus = 0xC01A001B + STATUS_LOG_TAIL_INVALID NTStatus = 0xC01A001C + STATUS_LOG_FULL NTStatus = 0xC01A001D + STATUS_LOG_MULTIPLEXED NTStatus = 0xC01A001E + STATUS_LOG_DEDICATED NTStatus = 0xC01A001F + STATUS_LOG_ARCHIVE_NOT_IN_PROGRESS NTStatus = 0xC01A0020 + STATUS_LOG_ARCHIVE_IN_PROGRESS NTStatus = 0xC01A0021 + STATUS_LOG_EPHEMERAL NTStatus = 0xC01A0022 + STATUS_LOG_NOT_ENOUGH_CONTAINERS NTStatus = 0xC01A0023 + STATUS_LOG_CLIENT_ALREADY_REGISTERED NTStatus = 0xC01A0024 + STATUS_LOG_CLIENT_NOT_REGISTERED NTStatus = 0xC01A0025 + STATUS_LOG_FULL_HANDLER_IN_PROGRESS NTStatus = 0xC01A0026 + STATUS_LOG_CONTAINER_READ_FAILED NTStatus = 0xC01A0027 + STATUS_LOG_CONTAINER_WRITE_FAILED NTStatus = 0xC01A0028 + STATUS_LOG_CONTAINER_OPEN_FAILED NTStatus = 0xC01A0029 + STATUS_LOG_CONTAINER_STATE_INVALID NTStatus = 0xC01A002A + STATUS_LOG_STATE_INVALID NTStatus = 0xC01A002B + STATUS_LOG_PINNED NTStatus = 0xC01A002C + STATUS_LOG_METADATA_FLUSH_FAILED NTStatus = 0xC01A002D + STATUS_LOG_INCONSISTENT_SECURITY NTStatus = 0xC01A002E + STATUS_LOG_APPENDED_FLUSH_FAILED NTStatus = 0xC01A002F + STATUS_LOG_PINNED_RESERVATION NTStatus = 0xC01A0030 + STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD NTStatus = 0xC01B00EA + STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD_RECOVERED NTStatus = 0x801B00EB + STATUS_VIDEO_DRIVER_DEBUG_REPORT_REQUEST NTStatus = 0x401B00EC + STATUS_MONITOR_NO_DESCRIPTOR NTStatus = 0xC01D0001 + STATUS_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT NTStatus = 0xC01D0002 + STATUS_MONITOR_INVALID_DESCRIPTOR_CHECKSUM NTStatus = 0xC01D0003 + STATUS_MONITOR_INVALID_STANDARD_TIMING_BLOCK NTStatus = 0xC01D0004 + STATUS_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED NTStatus = 0xC01D0005 + STATUS_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK NTStatus = 0xC01D0006 + STATUS_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK NTStatus = 0xC01D0007 + STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA NTStatus = 0xC01D0008 + STATUS_MONITOR_INVALID_DETAILED_TIMING_BLOCK NTStatus = 0xC01D0009 + STATUS_MONITOR_INVALID_MANUFACTURE_DATE NTStatus = 0xC01D000A + STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER NTStatus = 0xC01E0000 + STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER NTStatus = 0xC01E0001 + STATUS_GRAPHICS_INVALID_DISPLAY_ADAPTER NTStatus = 0xC01E0002 + STATUS_GRAPHICS_ADAPTER_WAS_RESET NTStatus = 0xC01E0003 + STATUS_GRAPHICS_INVALID_DRIVER_MODEL NTStatus = 0xC01E0004 + STATUS_GRAPHICS_PRESENT_MODE_CHANGED NTStatus = 0xC01E0005 + STATUS_GRAPHICS_PRESENT_OCCLUDED NTStatus = 0xC01E0006 + STATUS_GRAPHICS_PRESENT_DENIED NTStatus = 0xC01E0007 + STATUS_GRAPHICS_CANNOTCOLORCONVERT NTStatus = 0xC01E0008 + STATUS_GRAPHICS_DRIVER_MISMATCH NTStatus = 0xC01E0009 + STATUS_GRAPHICS_PARTIAL_DATA_POPULATED NTStatus = 0x401E000A + STATUS_GRAPHICS_PRESENT_REDIRECTION_DISABLED NTStatus = 0xC01E000B + STATUS_GRAPHICS_PRESENT_UNOCCLUDED NTStatus = 0xC01E000C + STATUS_GRAPHICS_WINDOWDC_NOT_AVAILABLE NTStatus = 0xC01E000D + STATUS_GRAPHICS_WINDOWLESS_PRESENT_DISABLED NTStatus = 0xC01E000E + STATUS_GRAPHICS_PRESENT_INVALID_WINDOW NTStatus = 0xC01E000F + STATUS_GRAPHICS_PRESENT_BUFFER_NOT_BOUND NTStatus = 0xC01E0010 + STATUS_GRAPHICS_VAIL_STATE_CHANGED NTStatus = 0xC01E0011 + STATUS_GRAPHICS_INDIRECT_DISPLAY_ABANDON_SWAPCHAIN NTStatus = 0xC01E0012 + STATUS_GRAPHICS_INDIRECT_DISPLAY_DEVICE_STOPPED NTStatus = 0xC01E0013 + STATUS_GRAPHICS_NO_VIDEO_MEMORY NTStatus = 0xC01E0100 + STATUS_GRAPHICS_CANT_LOCK_MEMORY NTStatus = 0xC01E0101 + STATUS_GRAPHICS_ALLOCATION_BUSY NTStatus = 0xC01E0102 + STATUS_GRAPHICS_TOO_MANY_REFERENCES NTStatus = 0xC01E0103 + STATUS_GRAPHICS_TRY_AGAIN_LATER NTStatus = 0xC01E0104 + STATUS_GRAPHICS_TRY_AGAIN_NOW NTStatus = 0xC01E0105 + STATUS_GRAPHICS_ALLOCATION_INVALID NTStatus = 0xC01E0106 + STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE NTStatus = 0xC01E0107 + STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED NTStatus = 0xC01E0108 + STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION NTStatus = 0xC01E0109 + STATUS_GRAPHICS_INVALID_ALLOCATION_USAGE NTStatus = 0xC01E0110 + STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION NTStatus = 0xC01E0111 + STATUS_GRAPHICS_ALLOCATION_CLOSED NTStatus = 0xC01E0112 + STATUS_GRAPHICS_INVALID_ALLOCATION_INSTANCE NTStatus = 0xC01E0113 + STATUS_GRAPHICS_INVALID_ALLOCATION_HANDLE NTStatus = 0xC01E0114 + STATUS_GRAPHICS_WRONG_ALLOCATION_DEVICE NTStatus = 0xC01E0115 + STATUS_GRAPHICS_ALLOCATION_CONTENT_LOST NTStatus = 0xC01E0116 + STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE NTStatus = 0xC01E0200 + STATUS_GRAPHICS_SKIP_ALLOCATION_PREPARATION NTStatus = 0x401E0201 + STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY NTStatus = 0xC01E0300 + STATUS_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED NTStatus = 0xC01E0301 + STATUS_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED NTStatus = 0xC01E0302 + STATUS_GRAPHICS_INVALID_VIDPN NTStatus = 0xC01E0303 + STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE NTStatus = 0xC01E0304 + STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET NTStatus = 0xC01E0305 + STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED NTStatus = 0xC01E0306 + STATUS_GRAPHICS_MODE_NOT_PINNED NTStatus = 0x401E0307 + STATUS_GRAPHICS_INVALID_VIDPN_SOURCEMODESET NTStatus = 0xC01E0308 + STATUS_GRAPHICS_INVALID_VIDPN_TARGETMODESET NTStatus = 0xC01E0309 + STATUS_GRAPHICS_INVALID_FREQUENCY NTStatus = 0xC01E030A + STATUS_GRAPHICS_INVALID_ACTIVE_REGION NTStatus = 0xC01E030B + STATUS_GRAPHICS_INVALID_TOTAL_REGION NTStatus = 0xC01E030C + STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE NTStatus = 0xC01E0310 + STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE NTStatus = 0xC01E0311 + STATUS_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET NTStatus = 0xC01E0312 + STATUS_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY NTStatus = 0xC01E0313 + STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET NTStatus = 0xC01E0314 + STATUS_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET NTStatus = 0xC01E0315 + STATUS_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET NTStatus = 0xC01E0316 + STATUS_GRAPHICS_SOURCE_ALREADY_IN_SET NTStatus = 0xC01E0317 + STATUS_GRAPHICS_TARGET_ALREADY_IN_SET NTStatus = 0xC01E0318 + STATUS_GRAPHICS_INVALID_VIDPN_PRESENT_PATH NTStatus = 0xC01E0319 + STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY NTStatus = 0xC01E031A + STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET NTStatus = 0xC01E031B + STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE NTStatus = 0xC01E031C + STATUS_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET NTStatus = 0xC01E031D + STATUS_GRAPHICS_NO_PREFERRED_MODE NTStatus = 0x401E031E + STATUS_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET NTStatus = 0xC01E031F + STATUS_GRAPHICS_STALE_MODESET NTStatus = 0xC01E0320 + STATUS_GRAPHICS_INVALID_MONITOR_SOURCEMODESET NTStatus = 0xC01E0321 + STATUS_GRAPHICS_INVALID_MONITOR_SOURCE_MODE NTStatus = 0xC01E0322 + STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN NTStatus = 0xC01E0323 + STATUS_GRAPHICS_MODE_ID_MUST_BE_UNIQUE NTStatus = 0xC01E0324 + STATUS_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION NTStatus = 0xC01E0325 + STATUS_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES NTStatus = 0xC01E0326 + STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY NTStatus = 0xC01E0327 + STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE NTStatus = 0xC01E0328 + STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET NTStatus = 0xC01E0329 + STATUS_GRAPHICS_INVALID_MONITORDESCRIPTORSET NTStatus = 0xC01E032A + STATUS_GRAPHICS_INVALID_MONITORDESCRIPTOR NTStatus = 0xC01E032B + STATUS_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET NTStatus = 0xC01E032C + STATUS_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET NTStatus = 0xC01E032D + STATUS_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE NTStatus = 0xC01E032E + STATUS_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE NTStatus = 0xC01E032F + STATUS_GRAPHICS_RESOURCES_NOT_RELATED NTStatus = 0xC01E0330 + STATUS_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE NTStatus = 0xC01E0331 + STATUS_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE NTStatus = 0xC01E0332 + STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET NTStatus = 0xC01E0333 + STATUS_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER NTStatus = 0xC01E0334 + STATUS_GRAPHICS_NO_VIDPNMGR NTStatus = 0xC01E0335 + STATUS_GRAPHICS_NO_ACTIVE_VIDPN NTStatus = 0xC01E0336 + STATUS_GRAPHICS_STALE_VIDPN_TOPOLOGY NTStatus = 0xC01E0337 + STATUS_GRAPHICS_MONITOR_NOT_CONNECTED NTStatus = 0xC01E0338 + STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY NTStatus = 0xC01E0339 + STATUS_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE NTStatus = 0xC01E033A + STATUS_GRAPHICS_INVALID_VISIBLEREGION_SIZE NTStatus = 0xC01E033B + STATUS_GRAPHICS_INVALID_STRIDE NTStatus = 0xC01E033C + STATUS_GRAPHICS_INVALID_PIXELFORMAT NTStatus = 0xC01E033D + STATUS_GRAPHICS_INVALID_COLORBASIS NTStatus = 0xC01E033E + STATUS_GRAPHICS_INVALID_PIXELVALUEACCESSMODE NTStatus = 0xC01E033F + STATUS_GRAPHICS_TARGET_NOT_IN_TOPOLOGY NTStatus = 0xC01E0340 + STATUS_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT NTStatus = 0xC01E0341 + STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE NTStatus = 0xC01E0342 + STATUS_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN NTStatus = 0xC01E0343 + STATUS_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL NTStatus = 0xC01E0344 + STATUS_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION NTStatus = 0xC01E0345 + STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED NTStatus = 0xC01E0346 + STATUS_GRAPHICS_INVALID_GAMMA_RAMP NTStatus = 0xC01E0347 + STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED NTStatus = 0xC01E0348 + STATUS_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED NTStatus = 0xC01E0349 + STATUS_GRAPHICS_MODE_NOT_IN_MODESET NTStatus = 0xC01E034A + STATUS_GRAPHICS_DATASET_IS_EMPTY NTStatus = 0x401E034B + STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET NTStatus = 0x401E034C + STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON NTStatus = 0xC01E034D + STATUS_GRAPHICS_INVALID_PATH_CONTENT_TYPE NTStatus = 0xC01E034E + STATUS_GRAPHICS_INVALID_COPYPROTECTION_TYPE NTStatus = 0xC01E034F + STATUS_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS NTStatus = 0xC01E0350 + STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_PINNED NTStatus = 0x401E0351 + STATUS_GRAPHICS_INVALID_SCANLINE_ORDERING NTStatus = 0xC01E0352 + STATUS_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED NTStatus = 0xC01E0353 + STATUS_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS NTStatus = 0xC01E0354 + STATUS_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT NTStatus = 0xC01E0355 + STATUS_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM NTStatus = 0xC01E0356 + STATUS_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN NTStatus = 0xC01E0357 + STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT NTStatus = 0xC01E0358 + STATUS_GRAPHICS_MAX_NUM_PATHS_REACHED NTStatus = 0xC01E0359 + STATUS_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION NTStatus = 0xC01E035A + STATUS_GRAPHICS_INVALID_CLIENT_TYPE NTStatus = 0xC01E035B + STATUS_GRAPHICS_CLIENTVIDPN_NOT_SET NTStatus = 0xC01E035C + STATUS_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED NTStatus = 0xC01E0400 + STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED NTStatus = 0xC01E0401 + STATUS_GRAPHICS_UNKNOWN_CHILD_STATUS NTStatus = 0x401E042F + STATUS_GRAPHICS_NOT_A_LINKED_ADAPTER NTStatus = 0xC01E0430 + STATUS_GRAPHICS_LEADLINK_NOT_ENUMERATED NTStatus = 0xC01E0431 + STATUS_GRAPHICS_CHAINLINKS_NOT_ENUMERATED NTStatus = 0xC01E0432 + STATUS_GRAPHICS_ADAPTER_CHAIN_NOT_READY NTStatus = 0xC01E0433 + STATUS_GRAPHICS_CHAINLINKS_NOT_STARTED NTStatus = 0xC01E0434 + STATUS_GRAPHICS_CHAINLINKS_NOT_POWERED_ON NTStatus = 0xC01E0435 + STATUS_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE NTStatus = 0xC01E0436 + STATUS_GRAPHICS_LEADLINK_START_DEFERRED NTStatus = 0x401E0437 + STATUS_GRAPHICS_NOT_POST_DEVICE_DRIVER NTStatus = 0xC01E0438 + STATUS_GRAPHICS_POLLING_TOO_FREQUENTLY NTStatus = 0x401E0439 + STATUS_GRAPHICS_START_DEFERRED NTStatus = 0x401E043A + STATUS_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED NTStatus = 0xC01E043B + STATUS_GRAPHICS_DEPENDABLE_CHILD_STATUS NTStatus = 0x401E043C + STATUS_GRAPHICS_OPM_NOT_SUPPORTED NTStatus = 0xC01E0500 + STATUS_GRAPHICS_COPP_NOT_SUPPORTED NTStatus = 0xC01E0501 + STATUS_GRAPHICS_UAB_NOT_SUPPORTED NTStatus = 0xC01E0502 + STATUS_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS NTStatus = 0xC01E0503 + STATUS_GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST NTStatus = 0xC01E0505 + STATUS_GRAPHICS_OPM_INTERNAL_ERROR NTStatus = 0xC01E050B + STATUS_GRAPHICS_OPM_INVALID_HANDLE NTStatus = 0xC01E050C + STATUS_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH NTStatus = 0xC01E050E + STATUS_GRAPHICS_OPM_SPANNING_MODE_ENABLED NTStatus = 0xC01E050F + STATUS_GRAPHICS_OPM_THEATER_MODE_ENABLED NTStatus = 0xC01E0510 + STATUS_GRAPHICS_PVP_HFS_FAILED NTStatus = 0xC01E0511 + STATUS_GRAPHICS_OPM_INVALID_SRM NTStatus = 0xC01E0512 + STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP NTStatus = 0xC01E0513 + STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP NTStatus = 0xC01E0514 + STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA NTStatus = 0xC01E0515 + STATUS_GRAPHICS_OPM_HDCP_SRM_NEVER_SET NTStatus = 0xC01E0516 + STATUS_GRAPHICS_OPM_RESOLUTION_TOO_HIGH NTStatus = 0xC01E0517 + STATUS_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE NTStatus = 0xC01E0518 + STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS NTStatus = 0xC01E051A + STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS NTStatus = 0xC01E051C + STATUS_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST NTStatus = 0xC01E051D + STATUS_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR NTStatus = 0xC01E051E + STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS NTStatus = 0xC01E051F + STATUS_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED NTStatus = 0xC01E0520 + STATUS_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST NTStatus = 0xC01E0521 + STATUS_GRAPHICS_I2C_NOT_SUPPORTED NTStatus = 0xC01E0580 + STATUS_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST NTStatus = 0xC01E0581 + STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA NTStatus = 0xC01E0582 + STATUS_GRAPHICS_I2C_ERROR_RECEIVING_DATA NTStatus = 0xC01E0583 + STATUS_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED NTStatus = 0xC01E0584 + STATUS_GRAPHICS_DDCCI_INVALID_DATA NTStatus = 0xC01E0585 + STATUS_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE NTStatus = 0xC01E0586 + STATUS_GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING NTStatus = 0xC01E0587 + STATUS_GRAPHICS_MCA_INTERNAL_ERROR NTStatus = 0xC01E0588 + STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND NTStatus = 0xC01E0589 + STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH NTStatus = 0xC01E058A + STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM NTStatus = 0xC01E058B + STATUS_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE NTStatus = 0xC01E058C + STATUS_GRAPHICS_MONITOR_NO_LONGER_EXISTS NTStatus = 0xC01E058D + STATUS_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED NTStatus = 0xC01E05E0 + STATUS_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME NTStatus = 0xC01E05E1 + STATUS_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP NTStatus = 0xC01E05E2 + STATUS_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED NTStatus = 0xC01E05E3 + STATUS_GRAPHICS_INVALID_POINTER NTStatus = 0xC01E05E4 + STATUS_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE NTStatus = 0xC01E05E5 + STATUS_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL NTStatus = 0xC01E05E6 + STATUS_GRAPHICS_INTERNAL_ERROR NTStatus = 0xC01E05E7 + STATUS_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS NTStatus = 0xC01E05E8 + STATUS_FVE_LOCKED_VOLUME NTStatus = 0xC0210000 + STATUS_FVE_NOT_ENCRYPTED NTStatus = 0xC0210001 + STATUS_FVE_BAD_INFORMATION NTStatus = 0xC0210002 + STATUS_FVE_TOO_SMALL NTStatus = 0xC0210003 + STATUS_FVE_FAILED_WRONG_FS NTStatus = 0xC0210004 + STATUS_FVE_BAD_PARTITION_SIZE NTStatus = 0xC0210005 + STATUS_FVE_FS_NOT_EXTENDED NTStatus = 0xC0210006 + STATUS_FVE_FS_MOUNTED NTStatus = 0xC0210007 + STATUS_FVE_NO_LICENSE NTStatus = 0xC0210008 + STATUS_FVE_ACTION_NOT_ALLOWED NTStatus = 0xC0210009 + STATUS_FVE_BAD_DATA NTStatus = 0xC021000A + STATUS_FVE_VOLUME_NOT_BOUND NTStatus = 0xC021000B + STATUS_FVE_NOT_DATA_VOLUME NTStatus = 0xC021000C + STATUS_FVE_CONV_READ_ERROR NTStatus = 0xC021000D + STATUS_FVE_CONV_WRITE_ERROR NTStatus = 0xC021000E + STATUS_FVE_OVERLAPPED_UPDATE NTStatus = 0xC021000F + STATUS_FVE_FAILED_SECTOR_SIZE NTStatus = 0xC0210010 + STATUS_FVE_FAILED_AUTHENTICATION NTStatus = 0xC0210011 + STATUS_FVE_NOT_OS_VOLUME NTStatus = 0xC0210012 + STATUS_FVE_KEYFILE_NOT_FOUND NTStatus = 0xC0210013 + STATUS_FVE_KEYFILE_INVALID NTStatus = 0xC0210014 + STATUS_FVE_KEYFILE_NO_VMK NTStatus = 0xC0210015 + STATUS_FVE_TPM_DISABLED NTStatus = 0xC0210016 + STATUS_FVE_TPM_SRK_AUTH_NOT_ZERO NTStatus = 0xC0210017 + STATUS_FVE_TPM_INVALID_PCR NTStatus = 0xC0210018 + STATUS_FVE_TPM_NO_VMK NTStatus = 0xC0210019 + STATUS_FVE_PIN_INVALID NTStatus = 0xC021001A + STATUS_FVE_AUTH_INVALID_APPLICATION NTStatus = 0xC021001B + STATUS_FVE_AUTH_INVALID_CONFIG NTStatus = 0xC021001C + STATUS_FVE_DEBUGGER_ENABLED NTStatus = 0xC021001D + STATUS_FVE_DRY_RUN_FAILED NTStatus = 0xC021001E + STATUS_FVE_BAD_METADATA_POINTER NTStatus = 0xC021001F + STATUS_FVE_OLD_METADATA_COPY NTStatus = 0xC0210020 + STATUS_FVE_REBOOT_REQUIRED NTStatus = 0xC0210021 + STATUS_FVE_RAW_ACCESS NTStatus = 0xC0210022 + STATUS_FVE_RAW_BLOCKED NTStatus = 0xC0210023 + STATUS_FVE_NO_AUTOUNLOCK_MASTER_KEY NTStatus = 0xC0210024 + STATUS_FVE_MOR_FAILED NTStatus = 0xC0210025 + STATUS_FVE_NO_FEATURE_LICENSE NTStatus = 0xC0210026 + STATUS_FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED NTStatus = 0xC0210027 + STATUS_FVE_CONV_RECOVERY_FAILED NTStatus = 0xC0210028 + STATUS_FVE_VIRTUALIZED_SPACE_TOO_BIG NTStatus = 0xC0210029 + STATUS_FVE_INVALID_DATUM_TYPE NTStatus = 0xC021002A + STATUS_FVE_VOLUME_TOO_SMALL NTStatus = 0xC0210030 + STATUS_FVE_ENH_PIN_INVALID NTStatus = 0xC0210031 + STATUS_FVE_FULL_ENCRYPTION_NOT_ALLOWED_ON_TP_STORAGE NTStatus = 0xC0210032 + STATUS_FVE_WIPE_NOT_ALLOWED_ON_TP_STORAGE NTStatus = 0xC0210033 + STATUS_FVE_NOT_ALLOWED_ON_CSV_STACK NTStatus = 0xC0210034 + STATUS_FVE_NOT_ALLOWED_ON_CLUSTER NTStatus = 0xC0210035 + STATUS_FVE_NOT_ALLOWED_TO_UPGRADE_WHILE_CONVERTING NTStatus = 0xC0210036 + STATUS_FVE_WIPE_CANCEL_NOT_APPLICABLE NTStatus = 0xC0210037 + STATUS_FVE_EDRIVE_DRY_RUN_FAILED NTStatus = 0xC0210038 + STATUS_FVE_SECUREBOOT_DISABLED NTStatus = 0xC0210039 + STATUS_FVE_SECUREBOOT_CONFIG_CHANGE NTStatus = 0xC021003A + STATUS_FVE_DEVICE_LOCKEDOUT NTStatus = 0xC021003B + STATUS_FVE_VOLUME_EXTEND_PREVENTS_EOW_DECRYPT NTStatus = 0xC021003C + STATUS_FVE_NOT_DE_VOLUME NTStatus = 0xC021003D + STATUS_FVE_PROTECTION_DISABLED NTStatus = 0xC021003E + STATUS_FVE_PROTECTION_CANNOT_BE_DISABLED NTStatus = 0xC021003F + STATUS_FVE_OSV_KSR_NOT_ALLOWED NTStatus = 0xC0210040 + STATUS_FWP_CALLOUT_NOT_FOUND NTStatus = 0xC0220001 + STATUS_FWP_CONDITION_NOT_FOUND NTStatus = 0xC0220002 + STATUS_FWP_FILTER_NOT_FOUND NTStatus = 0xC0220003 + STATUS_FWP_LAYER_NOT_FOUND NTStatus = 0xC0220004 + STATUS_FWP_PROVIDER_NOT_FOUND NTStatus = 0xC0220005 + STATUS_FWP_PROVIDER_CONTEXT_NOT_FOUND NTStatus = 0xC0220006 + STATUS_FWP_SUBLAYER_NOT_FOUND NTStatus = 0xC0220007 + STATUS_FWP_NOT_FOUND NTStatus = 0xC0220008 + STATUS_FWP_ALREADY_EXISTS NTStatus = 0xC0220009 + STATUS_FWP_IN_USE NTStatus = 0xC022000A + STATUS_FWP_DYNAMIC_SESSION_IN_PROGRESS NTStatus = 0xC022000B + STATUS_FWP_WRONG_SESSION NTStatus = 0xC022000C + STATUS_FWP_NO_TXN_IN_PROGRESS NTStatus = 0xC022000D + STATUS_FWP_TXN_IN_PROGRESS NTStatus = 0xC022000E + STATUS_FWP_TXN_ABORTED NTStatus = 0xC022000F + STATUS_FWP_SESSION_ABORTED NTStatus = 0xC0220010 + STATUS_FWP_INCOMPATIBLE_TXN NTStatus = 0xC0220011 + STATUS_FWP_TIMEOUT NTStatus = 0xC0220012 + STATUS_FWP_NET_EVENTS_DISABLED NTStatus = 0xC0220013 + STATUS_FWP_INCOMPATIBLE_LAYER NTStatus = 0xC0220014 + STATUS_FWP_KM_CLIENTS_ONLY NTStatus = 0xC0220015 + STATUS_FWP_LIFETIME_MISMATCH NTStatus = 0xC0220016 + STATUS_FWP_BUILTIN_OBJECT NTStatus = 0xC0220017 + STATUS_FWP_TOO_MANY_CALLOUTS NTStatus = 0xC0220018 + STATUS_FWP_NOTIFICATION_DROPPED NTStatus = 0xC0220019 + STATUS_FWP_TRAFFIC_MISMATCH NTStatus = 0xC022001A + STATUS_FWP_INCOMPATIBLE_SA_STATE NTStatus = 0xC022001B + STATUS_FWP_NULL_POINTER NTStatus = 0xC022001C + STATUS_FWP_INVALID_ENUMERATOR NTStatus = 0xC022001D + STATUS_FWP_INVALID_FLAGS NTStatus = 0xC022001E + STATUS_FWP_INVALID_NET_MASK NTStatus = 0xC022001F + STATUS_FWP_INVALID_RANGE NTStatus = 0xC0220020 + STATUS_FWP_INVALID_INTERVAL NTStatus = 0xC0220021 + STATUS_FWP_ZERO_LENGTH_ARRAY NTStatus = 0xC0220022 + STATUS_FWP_NULL_DISPLAY_NAME NTStatus = 0xC0220023 + STATUS_FWP_INVALID_ACTION_TYPE NTStatus = 0xC0220024 + STATUS_FWP_INVALID_WEIGHT NTStatus = 0xC0220025 + STATUS_FWP_MATCH_TYPE_MISMATCH NTStatus = 0xC0220026 + STATUS_FWP_TYPE_MISMATCH NTStatus = 0xC0220027 + STATUS_FWP_OUT_OF_BOUNDS NTStatus = 0xC0220028 + STATUS_FWP_RESERVED NTStatus = 0xC0220029 + STATUS_FWP_DUPLICATE_CONDITION NTStatus = 0xC022002A + STATUS_FWP_DUPLICATE_KEYMOD NTStatus = 0xC022002B + STATUS_FWP_ACTION_INCOMPATIBLE_WITH_LAYER NTStatus = 0xC022002C + STATUS_FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER NTStatus = 0xC022002D + STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER NTStatus = 0xC022002E + STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT NTStatus = 0xC022002F + STATUS_FWP_INCOMPATIBLE_AUTH_METHOD NTStatus = 0xC0220030 + STATUS_FWP_INCOMPATIBLE_DH_GROUP NTStatus = 0xC0220031 + STATUS_FWP_EM_NOT_SUPPORTED NTStatus = 0xC0220032 + STATUS_FWP_NEVER_MATCH NTStatus = 0xC0220033 + STATUS_FWP_PROVIDER_CONTEXT_MISMATCH NTStatus = 0xC0220034 + STATUS_FWP_INVALID_PARAMETER NTStatus = 0xC0220035 + STATUS_FWP_TOO_MANY_SUBLAYERS NTStatus = 0xC0220036 + STATUS_FWP_CALLOUT_NOTIFICATION_FAILED NTStatus = 0xC0220037 + STATUS_FWP_INVALID_AUTH_TRANSFORM NTStatus = 0xC0220038 + STATUS_FWP_INVALID_CIPHER_TRANSFORM NTStatus = 0xC0220039 + STATUS_FWP_INCOMPATIBLE_CIPHER_TRANSFORM NTStatus = 0xC022003A + STATUS_FWP_INVALID_TRANSFORM_COMBINATION NTStatus = 0xC022003B + STATUS_FWP_DUPLICATE_AUTH_METHOD NTStatus = 0xC022003C + STATUS_FWP_INVALID_TUNNEL_ENDPOINT NTStatus = 0xC022003D + STATUS_FWP_L2_DRIVER_NOT_READY NTStatus = 0xC022003E + STATUS_FWP_KEY_DICTATOR_ALREADY_REGISTERED NTStatus = 0xC022003F + STATUS_FWP_KEY_DICTATION_INVALID_KEYING_MATERIAL NTStatus = 0xC0220040 + STATUS_FWP_CONNECTIONS_DISABLED NTStatus = 0xC0220041 + STATUS_FWP_INVALID_DNS_NAME NTStatus = 0xC0220042 + STATUS_FWP_STILL_ON NTStatus = 0xC0220043 + STATUS_FWP_IKEEXT_NOT_RUNNING NTStatus = 0xC0220044 + STATUS_FWP_TCPIP_NOT_READY NTStatus = 0xC0220100 + STATUS_FWP_INJECT_HANDLE_CLOSING NTStatus = 0xC0220101 + STATUS_FWP_INJECT_HANDLE_STALE NTStatus = 0xC0220102 + STATUS_FWP_CANNOT_PEND NTStatus = 0xC0220103 + STATUS_FWP_DROP_NOICMP NTStatus = 0xC0220104 + STATUS_NDIS_CLOSING NTStatus = 0xC0230002 + STATUS_NDIS_BAD_VERSION NTStatus = 0xC0230004 + STATUS_NDIS_BAD_CHARACTERISTICS NTStatus = 0xC0230005 + STATUS_NDIS_ADAPTER_NOT_FOUND NTStatus = 0xC0230006 + STATUS_NDIS_OPEN_FAILED NTStatus = 0xC0230007 + STATUS_NDIS_DEVICE_FAILED NTStatus = 0xC0230008 + STATUS_NDIS_MULTICAST_FULL NTStatus = 0xC0230009 + STATUS_NDIS_MULTICAST_EXISTS NTStatus = 0xC023000A + STATUS_NDIS_MULTICAST_NOT_FOUND NTStatus = 0xC023000B + STATUS_NDIS_REQUEST_ABORTED NTStatus = 0xC023000C + STATUS_NDIS_RESET_IN_PROGRESS NTStatus = 0xC023000D + STATUS_NDIS_NOT_SUPPORTED NTStatus = 0xC02300BB + STATUS_NDIS_INVALID_PACKET NTStatus = 0xC023000F + STATUS_NDIS_ADAPTER_NOT_READY NTStatus = 0xC0230011 + STATUS_NDIS_INVALID_LENGTH NTStatus = 0xC0230014 + STATUS_NDIS_INVALID_DATA NTStatus = 0xC0230015 + STATUS_NDIS_BUFFER_TOO_SHORT NTStatus = 0xC0230016 + STATUS_NDIS_INVALID_OID NTStatus = 0xC0230017 + STATUS_NDIS_ADAPTER_REMOVED NTStatus = 0xC0230018 + STATUS_NDIS_UNSUPPORTED_MEDIA NTStatus = 0xC0230019 + STATUS_NDIS_GROUP_ADDRESS_IN_USE NTStatus = 0xC023001A + STATUS_NDIS_FILE_NOT_FOUND NTStatus = 0xC023001B + STATUS_NDIS_ERROR_READING_FILE NTStatus = 0xC023001C + STATUS_NDIS_ALREADY_MAPPED NTStatus = 0xC023001D + STATUS_NDIS_RESOURCE_CONFLICT NTStatus = 0xC023001E + STATUS_NDIS_MEDIA_DISCONNECTED NTStatus = 0xC023001F + STATUS_NDIS_INVALID_ADDRESS NTStatus = 0xC0230022 + STATUS_NDIS_INVALID_DEVICE_REQUEST NTStatus = 0xC0230010 + STATUS_NDIS_PAUSED NTStatus = 0xC023002A + STATUS_NDIS_INTERFACE_NOT_FOUND NTStatus = 0xC023002B + STATUS_NDIS_UNSUPPORTED_REVISION NTStatus = 0xC023002C + STATUS_NDIS_INVALID_PORT NTStatus = 0xC023002D + STATUS_NDIS_INVALID_PORT_STATE NTStatus = 0xC023002E + STATUS_NDIS_LOW_POWER_STATE NTStatus = 0xC023002F + STATUS_NDIS_REINIT_REQUIRED NTStatus = 0xC0230030 + STATUS_NDIS_NO_QUEUES NTStatus = 0xC0230031 + STATUS_NDIS_DOT11_AUTO_CONFIG_ENABLED NTStatus = 0xC0232000 + STATUS_NDIS_DOT11_MEDIA_IN_USE NTStatus = 0xC0232001 + STATUS_NDIS_DOT11_POWER_STATE_INVALID NTStatus = 0xC0232002 + STATUS_NDIS_PM_WOL_PATTERN_LIST_FULL NTStatus = 0xC0232003 + STATUS_NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL NTStatus = 0xC0232004 + STATUS_NDIS_DOT11_AP_CHANNEL_CURRENTLY_NOT_AVAILABLE NTStatus = 0xC0232005 + STATUS_NDIS_DOT11_AP_BAND_CURRENTLY_NOT_AVAILABLE NTStatus = 0xC0232006 + STATUS_NDIS_DOT11_AP_CHANNEL_NOT_ALLOWED NTStatus = 0xC0232007 + STATUS_NDIS_DOT11_AP_BAND_NOT_ALLOWED NTStatus = 0xC0232008 + STATUS_NDIS_INDICATION_REQUIRED NTStatus = 0x40230001 + STATUS_NDIS_OFFLOAD_POLICY NTStatus = 0xC023100F + STATUS_NDIS_OFFLOAD_CONNECTION_REJECTED NTStatus = 0xC0231012 + STATUS_NDIS_OFFLOAD_PATH_REJECTED NTStatus = 0xC0231013 + STATUS_TPM_ERROR_MASK NTStatus = 0xC0290000 + STATUS_TPM_AUTHFAIL NTStatus = 0xC0290001 + STATUS_TPM_BADINDEX NTStatus = 0xC0290002 + STATUS_TPM_BAD_PARAMETER NTStatus = 0xC0290003 + STATUS_TPM_AUDITFAILURE NTStatus = 0xC0290004 + STATUS_TPM_CLEAR_DISABLED NTStatus = 0xC0290005 + STATUS_TPM_DEACTIVATED NTStatus = 0xC0290006 + STATUS_TPM_DISABLED NTStatus = 0xC0290007 + STATUS_TPM_DISABLED_CMD NTStatus = 0xC0290008 + STATUS_TPM_FAIL NTStatus = 0xC0290009 + STATUS_TPM_BAD_ORDINAL NTStatus = 0xC029000A + STATUS_TPM_INSTALL_DISABLED NTStatus = 0xC029000B + STATUS_TPM_INVALID_KEYHANDLE NTStatus = 0xC029000C + STATUS_TPM_KEYNOTFOUND NTStatus = 0xC029000D + STATUS_TPM_INAPPROPRIATE_ENC NTStatus = 0xC029000E + STATUS_TPM_MIGRATEFAIL NTStatus = 0xC029000F + STATUS_TPM_INVALID_PCR_INFO NTStatus = 0xC0290010 + STATUS_TPM_NOSPACE NTStatus = 0xC0290011 + STATUS_TPM_NOSRK NTStatus = 0xC0290012 + STATUS_TPM_NOTSEALED_BLOB NTStatus = 0xC0290013 + STATUS_TPM_OWNER_SET NTStatus = 0xC0290014 + STATUS_TPM_RESOURCES NTStatus = 0xC0290015 + STATUS_TPM_SHORTRANDOM NTStatus = 0xC0290016 + STATUS_TPM_SIZE NTStatus = 0xC0290017 + STATUS_TPM_WRONGPCRVAL NTStatus = 0xC0290018 + STATUS_TPM_BAD_PARAM_SIZE NTStatus = 0xC0290019 + STATUS_TPM_SHA_THREAD NTStatus = 0xC029001A + STATUS_TPM_SHA_ERROR NTStatus = 0xC029001B + STATUS_TPM_FAILEDSELFTEST NTStatus = 0xC029001C + STATUS_TPM_AUTH2FAIL NTStatus = 0xC029001D + STATUS_TPM_BADTAG NTStatus = 0xC029001E + STATUS_TPM_IOERROR NTStatus = 0xC029001F + STATUS_TPM_ENCRYPT_ERROR NTStatus = 0xC0290020 + STATUS_TPM_DECRYPT_ERROR NTStatus = 0xC0290021 + STATUS_TPM_INVALID_AUTHHANDLE NTStatus = 0xC0290022 + STATUS_TPM_NO_ENDORSEMENT NTStatus = 0xC0290023 + STATUS_TPM_INVALID_KEYUSAGE NTStatus = 0xC0290024 + STATUS_TPM_WRONG_ENTITYTYPE NTStatus = 0xC0290025 + STATUS_TPM_INVALID_POSTINIT NTStatus = 0xC0290026 + STATUS_TPM_INAPPROPRIATE_SIG NTStatus = 0xC0290027 + STATUS_TPM_BAD_KEY_PROPERTY NTStatus = 0xC0290028 + STATUS_TPM_BAD_MIGRATION NTStatus = 0xC0290029 + STATUS_TPM_BAD_SCHEME NTStatus = 0xC029002A + STATUS_TPM_BAD_DATASIZE NTStatus = 0xC029002B + STATUS_TPM_BAD_MODE NTStatus = 0xC029002C + STATUS_TPM_BAD_PRESENCE NTStatus = 0xC029002D + STATUS_TPM_BAD_VERSION NTStatus = 0xC029002E + STATUS_TPM_NO_WRAP_TRANSPORT NTStatus = 0xC029002F + STATUS_TPM_AUDITFAIL_UNSUCCESSFUL NTStatus = 0xC0290030 + STATUS_TPM_AUDITFAIL_SUCCESSFUL NTStatus = 0xC0290031 + STATUS_TPM_NOTRESETABLE NTStatus = 0xC0290032 + STATUS_TPM_NOTLOCAL NTStatus = 0xC0290033 + STATUS_TPM_BAD_TYPE NTStatus = 0xC0290034 + STATUS_TPM_INVALID_RESOURCE NTStatus = 0xC0290035 + STATUS_TPM_NOTFIPS NTStatus = 0xC0290036 + STATUS_TPM_INVALID_FAMILY NTStatus = 0xC0290037 + STATUS_TPM_NO_NV_PERMISSION NTStatus = 0xC0290038 + STATUS_TPM_REQUIRES_SIGN NTStatus = 0xC0290039 + STATUS_TPM_KEY_NOTSUPPORTED NTStatus = 0xC029003A + STATUS_TPM_AUTH_CONFLICT NTStatus = 0xC029003B + STATUS_TPM_AREA_LOCKED NTStatus = 0xC029003C + STATUS_TPM_BAD_LOCALITY NTStatus = 0xC029003D + STATUS_TPM_READ_ONLY NTStatus = 0xC029003E + STATUS_TPM_PER_NOWRITE NTStatus = 0xC029003F + STATUS_TPM_FAMILYCOUNT NTStatus = 0xC0290040 + STATUS_TPM_WRITE_LOCKED NTStatus = 0xC0290041 + STATUS_TPM_BAD_ATTRIBUTES NTStatus = 0xC0290042 + STATUS_TPM_INVALID_STRUCTURE NTStatus = 0xC0290043 + STATUS_TPM_KEY_OWNER_CONTROL NTStatus = 0xC0290044 + STATUS_TPM_BAD_COUNTER NTStatus = 0xC0290045 + STATUS_TPM_NOT_FULLWRITE NTStatus = 0xC0290046 + STATUS_TPM_CONTEXT_GAP NTStatus = 0xC0290047 + STATUS_TPM_MAXNVWRITES NTStatus = 0xC0290048 + STATUS_TPM_NOOPERATOR NTStatus = 0xC0290049 + STATUS_TPM_RESOURCEMISSING NTStatus = 0xC029004A + STATUS_TPM_DELEGATE_LOCK NTStatus = 0xC029004B + STATUS_TPM_DELEGATE_FAMILY NTStatus = 0xC029004C + STATUS_TPM_DELEGATE_ADMIN NTStatus = 0xC029004D + STATUS_TPM_TRANSPORT_NOTEXCLUSIVE NTStatus = 0xC029004E + STATUS_TPM_OWNER_CONTROL NTStatus = 0xC029004F + STATUS_TPM_DAA_RESOURCES NTStatus = 0xC0290050 + STATUS_TPM_DAA_INPUT_DATA0 NTStatus = 0xC0290051 + STATUS_TPM_DAA_INPUT_DATA1 NTStatus = 0xC0290052 + STATUS_TPM_DAA_ISSUER_SETTINGS NTStatus = 0xC0290053 + STATUS_TPM_DAA_TPM_SETTINGS NTStatus = 0xC0290054 + STATUS_TPM_DAA_STAGE NTStatus = 0xC0290055 + STATUS_TPM_DAA_ISSUER_VALIDITY NTStatus = 0xC0290056 + STATUS_TPM_DAA_WRONG_W NTStatus = 0xC0290057 + STATUS_TPM_BAD_HANDLE NTStatus = 0xC0290058 + STATUS_TPM_BAD_DELEGATE NTStatus = 0xC0290059 + STATUS_TPM_BADCONTEXT NTStatus = 0xC029005A + STATUS_TPM_TOOMANYCONTEXTS NTStatus = 0xC029005B + STATUS_TPM_MA_TICKET_SIGNATURE NTStatus = 0xC029005C + STATUS_TPM_MA_DESTINATION NTStatus = 0xC029005D + STATUS_TPM_MA_SOURCE NTStatus = 0xC029005E + STATUS_TPM_MA_AUTHORITY NTStatus = 0xC029005F + STATUS_TPM_PERMANENTEK NTStatus = 0xC0290061 + STATUS_TPM_BAD_SIGNATURE NTStatus = 0xC0290062 + STATUS_TPM_NOCONTEXTSPACE NTStatus = 0xC0290063 + STATUS_TPM_20_E_ASYMMETRIC NTStatus = 0xC0290081 + STATUS_TPM_20_E_ATTRIBUTES NTStatus = 0xC0290082 + STATUS_TPM_20_E_HASH NTStatus = 0xC0290083 + STATUS_TPM_20_E_VALUE NTStatus = 0xC0290084 + STATUS_TPM_20_E_HIERARCHY NTStatus = 0xC0290085 + STATUS_TPM_20_E_KEY_SIZE NTStatus = 0xC0290087 + STATUS_TPM_20_E_MGF NTStatus = 0xC0290088 + STATUS_TPM_20_E_MODE NTStatus = 0xC0290089 + STATUS_TPM_20_E_TYPE NTStatus = 0xC029008A + STATUS_TPM_20_E_HANDLE NTStatus = 0xC029008B + STATUS_TPM_20_E_KDF NTStatus = 0xC029008C + STATUS_TPM_20_E_RANGE NTStatus = 0xC029008D + STATUS_TPM_20_E_AUTH_FAIL NTStatus = 0xC029008E + STATUS_TPM_20_E_NONCE NTStatus = 0xC029008F + STATUS_TPM_20_E_PP NTStatus = 0xC0290090 + STATUS_TPM_20_E_SCHEME NTStatus = 0xC0290092 + STATUS_TPM_20_E_SIZE NTStatus = 0xC0290095 + STATUS_TPM_20_E_SYMMETRIC NTStatus = 0xC0290096 + STATUS_TPM_20_E_TAG NTStatus = 0xC0290097 + STATUS_TPM_20_E_SELECTOR NTStatus = 0xC0290098 + STATUS_TPM_20_E_INSUFFICIENT NTStatus = 0xC029009A + STATUS_TPM_20_E_SIGNATURE NTStatus = 0xC029009B + STATUS_TPM_20_E_KEY NTStatus = 0xC029009C + STATUS_TPM_20_E_POLICY_FAIL NTStatus = 0xC029009D + STATUS_TPM_20_E_INTEGRITY NTStatus = 0xC029009F + STATUS_TPM_20_E_TICKET NTStatus = 0xC02900A0 + STATUS_TPM_20_E_RESERVED_BITS NTStatus = 0xC02900A1 + STATUS_TPM_20_E_BAD_AUTH NTStatus = 0xC02900A2 + STATUS_TPM_20_E_EXPIRED NTStatus = 0xC02900A3 + STATUS_TPM_20_E_POLICY_CC NTStatus = 0xC02900A4 + STATUS_TPM_20_E_BINDING NTStatus = 0xC02900A5 + STATUS_TPM_20_E_CURVE NTStatus = 0xC02900A6 + STATUS_TPM_20_E_ECC_POINT NTStatus = 0xC02900A7 + STATUS_TPM_20_E_INITIALIZE NTStatus = 0xC0290100 + STATUS_TPM_20_E_FAILURE NTStatus = 0xC0290101 + STATUS_TPM_20_E_SEQUENCE NTStatus = 0xC0290103 + STATUS_TPM_20_E_PRIVATE NTStatus = 0xC029010B + STATUS_TPM_20_E_HMAC NTStatus = 0xC0290119 + STATUS_TPM_20_E_DISABLED NTStatus = 0xC0290120 + STATUS_TPM_20_E_EXCLUSIVE NTStatus = 0xC0290121 + STATUS_TPM_20_E_ECC_CURVE NTStatus = 0xC0290123 + STATUS_TPM_20_E_AUTH_TYPE NTStatus = 0xC0290124 + STATUS_TPM_20_E_AUTH_MISSING NTStatus = 0xC0290125 + STATUS_TPM_20_E_POLICY NTStatus = 0xC0290126 + STATUS_TPM_20_E_PCR NTStatus = 0xC0290127 + STATUS_TPM_20_E_PCR_CHANGED NTStatus = 0xC0290128 + STATUS_TPM_20_E_UPGRADE NTStatus = 0xC029012D + STATUS_TPM_20_E_TOO_MANY_CONTEXTS NTStatus = 0xC029012E + STATUS_TPM_20_E_AUTH_UNAVAILABLE NTStatus = 0xC029012F + STATUS_TPM_20_E_REBOOT NTStatus = 0xC0290130 + STATUS_TPM_20_E_UNBALANCED NTStatus = 0xC0290131 + STATUS_TPM_20_E_COMMAND_SIZE NTStatus = 0xC0290142 + STATUS_TPM_20_E_COMMAND_CODE NTStatus = 0xC0290143 + STATUS_TPM_20_E_AUTHSIZE NTStatus = 0xC0290144 + STATUS_TPM_20_E_AUTH_CONTEXT NTStatus = 0xC0290145 + STATUS_TPM_20_E_NV_RANGE NTStatus = 0xC0290146 + STATUS_TPM_20_E_NV_SIZE NTStatus = 0xC0290147 + STATUS_TPM_20_E_NV_LOCKED NTStatus = 0xC0290148 + STATUS_TPM_20_E_NV_AUTHORIZATION NTStatus = 0xC0290149 + STATUS_TPM_20_E_NV_UNINITIALIZED NTStatus = 0xC029014A + STATUS_TPM_20_E_NV_SPACE NTStatus = 0xC029014B + STATUS_TPM_20_E_NV_DEFINED NTStatus = 0xC029014C + STATUS_TPM_20_E_BAD_CONTEXT NTStatus = 0xC0290150 + STATUS_TPM_20_E_CPHASH NTStatus = 0xC0290151 + STATUS_TPM_20_E_PARENT NTStatus = 0xC0290152 + STATUS_TPM_20_E_NEEDS_TEST NTStatus = 0xC0290153 + STATUS_TPM_20_E_NO_RESULT NTStatus = 0xC0290154 + STATUS_TPM_20_E_SENSITIVE NTStatus = 0xC0290155 + STATUS_TPM_COMMAND_BLOCKED NTStatus = 0xC0290400 + STATUS_TPM_INVALID_HANDLE NTStatus = 0xC0290401 + STATUS_TPM_DUPLICATE_VHANDLE NTStatus = 0xC0290402 + STATUS_TPM_EMBEDDED_COMMAND_BLOCKED NTStatus = 0xC0290403 + STATUS_TPM_EMBEDDED_COMMAND_UNSUPPORTED NTStatus = 0xC0290404 + STATUS_TPM_RETRY NTStatus = 0xC0290800 + STATUS_TPM_NEEDS_SELFTEST NTStatus = 0xC0290801 + STATUS_TPM_DOING_SELFTEST NTStatus = 0xC0290802 + STATUS_TPM_DEFEND_LOCK_RUNNING NTStatus = 0xC0290803 + STATUS_TPM_COMMAND_CANCELED NTStatus = 0xC0291001 + STATUS_TPM_TOO_MANY_CONTEXTS NTStatus = 0xC0291002 + STATUS_TPM_NOT_FOUND NTStatus = 0xC0291003 + STATUS_TPM_ACCESS_DENIED NTStatus = 0xC0291004 + STATUS_TPM_INSUFFICIENT_BUFFER NTStatus = 0xC0291005 + STATUS_TPM_PPI_FUNCTION_UNSUPPORTED NTStatus = 0xC0291006 + STATUS_PCP_ERROR_MASK NTStatus = 0xC0292000 + STATUS_PCP_DEVICE_NOT_READY NTStatus = 0xC0292001 + STATUS_PCP_INVALID_HANDLE NTStatus = 0xC0292002 + STATUS_PCP_INVALID_PARAMETER NTStatus = 0xC0292003 + STATUS_PCP_FLAG_NOT_SUPPORTED NTStatus = 0xC0292004 + STATUS_PCP_NOT_SUPPORTED NTStatus = 0xC0292005 + STATUS_PCP_BUFFER_TOO_SMALL NTStatus = 0xC0292006 + STATUS_PCP_INTERNAL_ERROR NTStatus = 0xC0292007 + STATUS_PCP_AUTHENTICATION_FAILED NTStatus = 0xC0292008 + STATUS_PCP_AUTHENTICATION_IGNORED NTStatus = 0xC0292009 + STATUS_PCP_POLICY_NOT_FOUND NTStatus = 0xC029200A + STATUS_PCP_PROFILE_NOT_FOUND NTStatus = 0xC029200B + STATUS_PCP_VALIDATION_FAILED NTStatus = 0xC029200C + STATUS_PCP_DEVICE_NOT_FOUND NTStatus = 0xC029200D + STATUS_PCP_WRONG_PARENT NTStatus = 0xC029200E + STATUS_PCP_KEY_NOT_LOADED NTStatus = 0xC029200F + STATUS_PCP_NO_KEY_CERTIFICATION NTStatus = 0xC0292010 + STATUS_PCP_KEY_NOT_FINALIZED NTStatus = 0xC0292011 + STATUS_PCP_ATTESTATION_CHALLENGE_NOT_SET NTStatus = 0xC0292012 + STATUS_PCP_NOT_PCR_BOUND NTStatus = 0xC0292013 + STATUS_PCP_KEY_ALREADY_FINALIZED NTStatus = 0xC0292014 + STATUS_PCP_KEY_USAGE_POLICY_NOT_SUPPORTED NTStatus = 0xC0292015 + STATUS_PCP_KEY_USAGE_POLICY_INVALID NTStatus = 0xC0292016 + STATUS_PCP_SOFT_KEY_ERROR NTStatus = 0xC0292017 + STATUS_PCP_KEY_NOT_AUTHENTICATED NTStatus = 0xC0292018 + STATUS_PCP_KEY_NOT_AIK NTStatus = 0xC0292019 + STATUS_PCP_KEY_NOT_SIGNING_KEY NTStatus = 0xC029201A + STATUS_PCP_LOCKED_OUT NTStatus = 0xC029201B + STATUS_PCP_CLAIM_TYPE_NOT_SUPPORTED NTStatus = 0xC029201C + STATUS_PCP_TPM_VERSION_NOT_SUPPORTED NTStatus = 0xC029201D + STATUS_PCP_BUFFER_LENGTH_MISMATCH NTStatus = 0xC029201E + STATUS_PCP_IFX_RSA_KEY_CREATION_BLOCKED NTStatus = 0xC029201F + STATUS_PCP_TICKET_MISSING NTStatus = 0xC0292020 + STATUS_PCP_RAW_POLICY_NOT_SUPPORTED NTStatus = 0xC0292021 + STATUS_PCP_KEY_HANDLE_INVALIDATED NTStatus = 0xC0292022 + STATUS_PCP_UNSUPPORTED_PSS_SALT NTStatus = 0x40292023 + STATUS_RTPM_CONTEXT_CONTINUE NTStatus = 0x00293000 + STATUS_RTPM_CONTEXT_COMPLETE NTStatus = 0x00293001 + STATUS_RTPM_NO_RESULT NTStatus = 0xC0293002 + STATUS_RTPM_PCR_READ_INCOMPLETE NTStatus = 0xC0293003 + STATUS_RTPM_INVALID_CONTEXT NTStatus = 0xC0293004 + STATUS_RTPM_UNSUPPORTED_CMD NTStatus = 0xC0293005 + STATUS_TPM_ZERO_EXHAUST_ENABLED NTStatus = 0xC0294000 + STATUS_HV_INVALID_HYPERCALL_CODE NTStatus = 0xC0350002 + STATUS_HV_INVALID_HYPERCALL_INPUT NTStatus = 0xC0350003 + STATUS_HV_INVALID_ALIGNMENT NTStatus = 0xC0350004 + STATUS_HV_INVALID_PARAMETER NTStatus = 0xC0350005 + STATUS_HV_ACCESS_DENIED NTStatus = 0xC0350006 + STATUS_HV_INVALID_PARTITION_STATE NTStatus = 0xC0350007 + STATUS_HV_OPERATION_DENIED NTStatus = 0xC0350008 + STATUS_HV_UNKNOWN_PROPERTY NTStatus = 0xC0350009 + STATUS_HV_PROPERTY_VALUE_OUT_OF_RANGE NTStatus = 0xC035000A + STATUS_HV_INSUFFICIENT_MEMORY NTStatus = 0xC035000B + STATUS_HV_PARTITION_TOO_DEEP NTStatus = 0xC035000C + STATUS_HV_INVALID_PARTITION_ID NTStatus = 0xC035000D + STATUS_HV_INVALID_VP_INDEX NTStatus = 0xC035000E + STATUS_HV_INVALID_PORT_ID NTStatus = 0xC0350011 + STATUS_HV_INVALID_CONNECTION_ID NTStatus = 0xC0350012 + STATUS_HV_INSUFFICIENT_BUFFERS NTStatus = 0xC0350013 + STATUS_HV_NOT_ACKNOWLEDGED NTStatus = 0xC0350014 + STATUS_HV_INVALID_VP_STATE NTStatus = 0xC0350015 + STATUS_HV_ACKNOWLEDGED NTStatus = 0xC0350016 + STATUS_HV_INVALID_SAVE_RESTORE_STATE NTStatus = 0xC0350017 + STATUS_HV_INVALID_SYNIC_STATE NTStatus = 0xC0350018 + STATUS_HV_OBJECT_IN_USE NTStatus = 0xC0350019 + STATUS_HV_INVALID_PROXIMITY_DOMAIN_INFO NTStatus = 0xC035001A + STATUS_HV_NO_DATA NTStatus = 0xC035001B + STATUS_HV_INACTIVE NTStatus = 0xC035001C + STATUS_HV_NO_RESOURCES NTStatus = 0xC035001D + STATUS_HV_FEATURE_UNAVAILABLE NTStatus = 0xC035001E + STATUS_HV_INSUFFICIENT_BUFFER NTStatus = 0xC0350033 + STATUS_HV_INSUFFICIENT_DEVICE_DOMAINS NTStatus = 0xC0350038 + STATUS_HV_CPUID_FEATURE_VALIDATION_ERROR NTStatus = 0xC035003C + STATUS_HV_CPUID_XSAVE_FEATURE_VALIDATION_ERROR NTStatus = 0xC035003D + STATUS_HV_PROCESSOR_STARTUP_TIMEOUT NTStatus = 0xC035003E + STATUS_HV_SMX_ENABLED NTStatus = 0xC035003F + STATUS_HV_INVALID_LP_INDEX NTStatus = 0xC0350041 + STATUS_HV_INVALID_REGISTER_VALUE NTStatus = 0xC0350050 + STATUS_HV_INVALID_VTL_STATE NTStatus = 0xC0350051 + STATUS_HV_NX_NOT_DETECTED NTStatus = 0xC0350055 + STATUS_HV_INVALID_DEVICE_ID NTStatus = 0xC0350057 + STATUS_HV_INVALID_DEVICE_STATE NTStatus = 0xC0350058 + STATUS_HV_PENDING_PAGE_REQUESTS NTStatus = 0x00350059 + STATUS_HV_PAGE_REQUEST_INVALID NTStatus = 0xC0350060 + STATUS_HV_INVALID_CPU_GROUP_ID NTStatus = 0xC035006F + STATUS_HV_INVALID_CPU_GROUP_STATE NTStatus = 0xC0350070 + STATUS_HV_OPERATION_FAILED NTStatus = 0xC0350071 + STATUS_HV_NOT_ALLOWED_WITH_NESTED_VIRT_ACTIVE NTStatus = 0xC0350072 + STATUS_HV_INSUFFICIENT_ROOT_MEMORY NTStatus = 0xC0350073 + STATUS_HV_NOT_PRESENT NTStatus = 0xC0351000 + STATUS_VID_DUPLICATE_HANDLER NTStatus = 0xC0370001 + STATUS_VID_TOO_MANY_HANDLERS NTStatus = 0xC0370002 + STATUS_VID_QUEUE_FULL NTStatus = 0xC0370003 + STATUS_VID_HANDLER_NOT_PRESENT NTStatus = 0xC0370004 + STATUS_VID_INVALID_OBJECT_NAME NTStatus = 0xC0370005 + STATUS_VID_PARTITION_NAME_TOO_LONG NTStatus = 0xC0370006 + STATUS_VID_MESSAGE_QUEUE_NAME_TOO_LONG NTStatus = 0xC0370007 + STATUS_VID_PARTITION_ALREADY_EXISTS NTStatus = 0xC0370008 + STATUS_VID_PARTITION_DOES_NOT_EXIST NTStatus = 0xC0370009 + STATUS_VID_PARTITION_NAME_NOT_FOUND NTStatus = 0xC037000A + STATUS_VID_MESSAGE_QUEUE_ALREADY_EXISTS NTStatus = 0xC037000B + STATUS_VID_EXCEEDED_MBP_ENTRY_MAP_LIMIT NTStatus = 0xC037000C + STATUS_VID_MB_STILL_REFERENCED NTStatus = 0xC037000D + STATUS_VID_CHILD_GPA_PAGE_SET_CORRUPTED NTStatus = 0xC037000E + STATUS_VID_INVALID_NUMA_SETTINGS NTStatus = 0xC037000F + STATUS_VID_INVALID_NUMA_NODE_INDEX NTStatus = 0xC0370010 + STATUS_VID_NOTIFICATION_QUEUE_ALREADY_ASSOCIATED NTStatus = 0xC0370011 + STATUS_VID_INVALID_MEMORY_BLOCK_HANDLE NTStatus = 0xC0370012 + STATUS_VID_PAGE_RANGE_OVERFLOW NTStatus = 0xC0370013 + STATUS_VID_INVALID_MESSAGE_QUEUE_HANDLE NTStatus = 0xC0370014 + STATUS_VID_INVALID_GPA_RANGE_HANDLE NTStatus = 0xC0370015 + STATUS_VID_NO_MEMORY_BLOCK_NOTIFICATION_QUEUE NTStatus = 0xC0370016 + STATUS_VID_MEMORY_BLOCK_LOCK_COUNT_EXCEEDED NTStatus = 0xC0370017 + STATUS_VID_INVALID_PPM_HANDLE NTStatus = 0xC0370018 + STATUS_VID_MBPS_ARE_LOCKED NTStatus = 0xC0370019 + STATUS_VID_MESSAGE_QUEUE_CLOSED NTStatus = 0xC037001A + STATUS_VID_VIRTUAL_PROCESSOR_LIMIT_EXCEEDED NTStatus = 0xC037001B + STATUS_VID_STOP_PENDING NTStatus = 0xC037001C + STATUS_VID_INVALID_PROCESSOR_STATE NTStatus = 0xC037001D + STATUS_VID_EXCEEDED_KM_CONTEXT_COUNT_LIMIT NTStatus = 0xC037001E + STATUS_VID_KM_INTERFACE_ALREADY_INITIALIZED NTStatus = 0xC037001F + STATUS_VID_MB_PROPERTY_ALREADY_SET_RESET NTStatus = 0xC0370020 + STATUS_VID_MMIO_RANGE_DESTROYED NTStatus = 0xC0370021 + STATUS_VID_INVALID_CHILD_GPA_PAGE_SET NTStatus = 0xC0370022 + STATUS_VID_RESERVE_PAGE_SET_IS_BEING_USED NTStatus = 0xC0370023 + STATUS_VID_RESERVE_PAGE_SET_TOO_SMALL NTStatus = 0xC0370024 + STATUS_VID_MBP_ALREADY_LOCKED_USING_RESERVED_PAGE NTStatus = 0xC0370025 + STATUS_VID_MBP_COUNT_EXCEEDED_LIMIT NTStatus = 0xC0370026 + STATUS_VID_SAVED_STATE_CORRUPT NTStatus = 0xC0370027 + STATUS_VID_SAVED_STATE_UNRECOGNIZED_ITEM NTStatus = 0xC0370028 + STATUS_VID_SAVED_STATE_INCOMPATIBLE NTStatus = 0xC0370029 + STATUS_VID_VTL_ACCESS_DENIED NTStatus = 0xC037002A + STATUS_VID_REMOTE_NODE_PARENT_GPA_PAGES_USED NTStatus = 0x80370001 + STATUS_IPSEC_BAD_SPI NTStatus = 0xC0360001 + STATUS_IPSEC_SA_LIFETIME_EXPIRED NTStatus = 0xC0360002 + STATUS_IPSEC_WRONG_SA NTStatus = 0xC0360003 + STATUS_IPSEC_REPLAY_CHECK_FAILED NTStatus = 0xC0360004 + STATUS_IPSEC_INVALID_PACKET NTStatus = 0xC0360005 + STATUS_IPSEC_INTEGRITY_CHECK_FAILED NTStatus = 0xC0360006 + STATUS_IPSEC_CLEAR_TEXT_DROP NTStatus = 0xC0360007 + STATUS_IPSEC_AUTH_FIREWALL_DROP NTStatus = 0xC0360008 + STATUS_IPSEC_THROTTLE_DROP NTStatus = 0xC0360009 + STATUS_IPSEC_DOSP_BLOCK NTStatus = 0xC0368000 + STATUS_IPSEC_DOSP_RECEIVED_MULTICAST NTStatus = 0xC0368001 + STATUS_IPSEC_DOSP_INVALID_PACKET NTStatus = 0xC0368002 + STATUS_IPSEC_DOSP_STATE_LOOKUP_FAILED NTStatus = 0xC0368003 + STATUS_IPSEC_DOSP_MAX_ENTRIES NTStatus = 0xC0368004 + STATUS_IPSEC_DOSP_KEYMOD_NOT_ALLOWED NTStatus = 0xC0368005 + STATUS_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES NTStatus = 0xC0368006 + STATUS_VOLMGR_INCOMPLETE_REGENERATION NTStatus = 0x80380001 + STATUS_VOLMGR_INCOMPLETE_DISK_MIGRATION NTStatus = 0x80380002 + STATUS_VOLMGR_DATABASE_FULL NTStatus = 0xC0380001 + STATUS_VOLMGR_DISK_CONFIGURATION_CORRUPTED NTStatus = 0xC0380002 + STATUS_VOLMGR_DISK_CONFIGURATION_NOT_IN_SYNC NTStatus = 0xC0380003 + STATUS_VOLMGR_PACK_CONFIG_UPDATE_FAILED NTStatus = 0xC0380004 + STATUS_VOLMGR_DISK_CONTAINS_NON_SIMPLE_VOLUME NTStatus = 0xC0380005 + STATUS_VOLMGR_DISK_DUPLICATE NTStatus = 0xC0380006 + STATUS_VOLMGR_DISK_DYNAMIC NTStatus = 0xC0380007 + STATUS_VOLMGR_DISK_ID_INVALID NTStatus = 0xC0380008 + STATUS_VOLMGR_DISK_INVALID NTStatus = 0xC0380009 + STATUS_VOLMGR_DISK_LAST_VOTER NTStatus = 0xC038000A + STATUS_VOLMGR_DISK_LAYOUT_INVALID NTStatus = 0xC038000B + STATUS_VOLMGR_DISK_LAYOUT_NON_BASIC_BETWEEN_BASIC_PARTITIONS NTStatus = 0xC038000C + STATUS_VOLMGR_DISK_LAYOUT_NOT_CYLINDER_ALIGNED NTStatus = 0xC038000D + STATUS_VOLMGR_DISK_LAYOUT_PARTITIONS_TOO_SMALL NTStatus = 0xC038000E + STATUS_VOLMGR_DISK_LAYOUT_PRIMARY_BETWEEN_LOGICAL_PARTITIONS NTStatus = 0xC038000F + STATUS_VOLMGR_DISK_LAYOUT_TOO_MANY_PARTITIONS NTStatus = 0xC0380010 + STATUS_VOLMGR_DISK_MISSING NTStatus = 0xC0380011 + STATUS_VOLMGR_DISK_NOT_EMPTY NTStatus = 0xC0380012 + STATUS_VOLMGR_DISK_NOT_ENOUGH_SPACE NTStatus = 0xC0380013 + STATUS_VOLMGR_DISK_REVECTORING_FAILED NTStatus = 0xC0380014 + STATUS_VOLMGR_DISK_SECTOR_SIZE_INVALID NTStatus = 0xC0380015 + STATUS_VOLMGR_DISK_SET_NOT_CONTAINED NTStatus = 0xC0380016 + STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_MEMBERS NTStatus = 0xC0380017 + STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_PLEXES NTStatus = 0xC0380018 + STATUS_VOLMGR_DYNAMIC_DISK_NOT_SUPPORTED NTStatus = 0xC0380019 + STATUS_VOLMGR_EXTENT_ALREADY_USED NTStatus = 0xC038001A + STATUS_VOLMGR_EXTENT_NOT_CONTIGUOUS NTStatus = 0xC038001B + STATUS_VOLMGR_EXTENT_NOT_IN_PUBLIC_REGION NTStatus = 0xC038001C + STATUS_VOLMGR_EXTENT_NOT_SECTOR_ALIGNED NTStatus = 0xC038001D + STATUS_VOLMGR_EXTENT_OVERLAPS_EBR_PARTITION NTStatus = 0xC038001E + STATUS_VOLMGR_EXTENT_VOLUME_LENGTHS_DO_NOT_MATCH NTStatus = 0xC038001F + STATUS_VOLMGR_FAULT_TOLERANT_NOT_SUPPORTED NTStatus = 0xC0380020 + STATUS_VOLMGR_INTERLEAVE_LENGTH_INVALID NTStatus = 0xC0380021 + STATUS_VOLMGR_MAXIMUM_REGISTERED_USERS NTStatus = 0xC0380022 + STATUS_VOLMGR_MEMBER_IN_SYNC NTStatus = 0xC0380023 + STATUS_VOLMGR_MEMBER_INDEX_DUPLICATE NTStatus = 0xC0380024 + STATUS_VOLMGR_MEMBER_INDEX_INVALID NTStatus = 0xC0380025 + STATUS_VOLMGR_MEMBER_MISSING NTStatus = 0xC0380026 + STATUS_VOLMGR_MEMBER_NOT_DETACHED NTStatus = 0xC0380027 + STATUS_VOLMGR_MEMBER_REGENERATING NTStatus = 0xC0380028 + STATUS_VOLMGR_ALL_DISKS_FAILED NTStatus = 0xC0380029 + STATUS_VOLMGR_NO_REGISTERED_USERS NTStatus = 0xC038002A + STATUS_VOLMGR_NO_SUCH_USER NTStatus = 0xC038002B + STATUS_VOLMGR_NOTIFICATION_RESET NTStatus = 0xC038002C + STATUS_VOLMGR_NUMBER_OF_MEMBERS_INVALID NTStatus = 0xC038002D + STATUS_VOLMGR_NUMBER_OF_PLEXES_INVALID NTStatus = 0xC038002E + STATUS_VOLMGR_PACK_DUPLICATE NTStatus = 0xC038002F + STATUS_VOLMGR_PACK_ID_INVALID NTStatus = 0xC0380030 + STATUS_VOLMGR_PACK_INVALID NTStatus = 0xC0380031 + STATUS_VOLMGR_PACK_NAME_INVALID NTStatus = 0xC0380032 + STATUS_VOLMGR_PACK_OFFLINE NTStatus = 0xC0380033 + STATUS_VOLMGR_PACK_HAS_QUORUM NTStatus = 0xC0380034 + STATUS_VOLMGR_PACK_WITHOUT_QUORUM NTStatus = 0xC0380035 + STATUS_VOLMGR_PARTITION_STYLE_INVALID NTStatus = 0xC0380036 + STATUS_VOLMGR_PARTITION_UPDATE_FAILED NTStatus = 0xC0380037 + STATUS_VOLMGR_PLEX_IN_SYNC NTStatus = 0xC0380038 + STATUS_VOLMGR_PLEX_INDEX_DUPLICATE NTStatus = 0xC0380039 + STATUS_VOLMGR_PLEX_INDEX_INVALID NTStatus = 0xC038003A + STATUS_VOLMGR_PLEX_LAST_ACTIVE NTStatus = 0xC038003B + STATUS_VOLMGR_PLEX_MISSING NTStatus = 0xC038003C + STATUS_VOLMGR_PLEX_REGENERATING NTStatus = 0xC038003D + STATUS_VOLMGR_PLEX_TYPE_INVALID NTStatus = 0xC038003E + STATUS_VOLMGR_PLEX_NOT_RAID5 NTStatus = 0xC038003F + STATUS_VOLMGR_PLEX_NOT_SIMPLE NTStatus = 0xC0380040 + STATUS_VOLMGR_STRUCTURE_SIZE_INVALID NTStatus = 0xC0380041 + STATUS_VOLMGR_TOO_MANY_NOTIFICATION_REQUESTS NTStatus = 0xC0380042 + STATUS_VOLMGR_TRANSACTION_IN_PROGRESS NTStatus = 0xC0380043 + STATUS_VOLMGR_UNEXPECTED_DISK_LAYOUT_CHANGE NTStatus = 0xC0380044 + STATUS_VOLMGR_VOLUME_CONTAINS_MISSING_DISK NTStatus = 0xC0380045 + STATUS_VOLMGR_VOLUME_ID_INVALID NTStatus = 0xC0380046 + STATUS_VOLMGR_VOLUME_LENGTH_INVALID NTStatus = 0xC0380047 + STATUS_VOLMGR_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE NTStatus = 0xC0380048 + STATUS_VOLMGR_VOLUME_NOT_MIRRORED NTStatus = 0xC0380049 + STATUS_VOLMGR_VOLUME_NOT_RETAINED NTStatus = 0xC038004A + STATUS_VOLMGR_VOLUME_OFFLINE NTStatus = 0xC038004B + STATUS_VOLMGR_VOLUME_RETAINED NTStatus = 0xC038004C + STATUS_VOLMGR_NUMBER_OF_EXTENTS_INVALID NTStatus = 0xC038004D + STATUS_VOLMGR_DIFFERENT_SECTOR_SIZE NTStatus = 0xC038004E + STATUS_VOLMGR_BAD_BOOT_DISK NTStatus = 0xC038004F + STATUS_VOLMGR_PACK_CONFIG_OFFLINE NTStatus = 0xC0380050 + STATUS_VOLMGR_PACK_CONFIG_ONLINE NTStatus = 0xC0380051 + STATUS_VOLMGR_NOT_PRIMARY_PACK NTStatus = 0xC0380052 + STATUS_VOLMGR_PACK_LOG_UPDATE_FAILED NTStatus = 0xC0380053 + STATUS_VOLMGR_NUMBER_OF_DISKS_IN_PLEX_INVALID NTStatus = 0xC0380054 + STATUS_VOLMGR_NUMBER_OF_DISKS_IN_MEMBER_INVALID NTStatus = 0xC0380055 + STATUS_VOLMGR_VOLUME_MIRRORED NTStatus = 0xC0380056 + STATUS_VOLMGR_PLEX_NOT_SIMPLE_SPANNED NTStatus = 0xC0380057 + STATUS_VOLMGR_NO_VALID_LOG_COPIES NTStatus = 0xC0380058 + STATUS_VOLMGR_PRIMARY_PACK_PRESENT NTStatus = 0xC0380059 + STATUS_VOLMGR_NUMBER_OF_DISKS_INVALID NTStatus = 0xC038005A + STATUS_VOLMGR_MIRROR_NOT_SUPPORTED NTStatus = 0xC038005B + STATUS_VOLMGR_RAID5_NOT_SUPPORTED NTStatus = 0xC038005C + STATUS_BCD_NOT_ALL_ENTRIES_IMPORTED NTStatus = 0x80390001 + STATUS_BCD_TOO_MANY_ELEMENTS NTStatus = 0xC0390002 + STATUS_BCD_NOT_ALL_ENTRIES_SYNCHRONIZED NTStatus = 0x80390003 + STATUS_VHD_DRIVE_FOOTER_MISSING NTStatus = 0xC03A0001 + STATUS_VHD_DRIVE_FOOTER_CHECKSUM_MISMATCH NTStatus = 0xC03A0002 + STATUS_VHD_DRIVE_FOOTER_CORRUPT NTStatus = 0xC03A0003 + STATUS_VHD_FORMAT_UNKNOWN NTStatus = 0xC03A0004 + STATUS_VHD_FORMAT_UNSUPPORTED_VERSION NTStatus = 0xC03A0005 + STATUS_VHD_SPARSE_HEADER_CHECKSUM_MISMATCH NTStatus = 0xC03A0006 + STATUS_VHD_SPARSE_HEADER_UNSUPPORTED_VERSION NTStatus = 0xC03A0007 + STATUS_VHD_SPARSE_HEADER_CORRUPT NTStatus = 0xC03A0008 + STATUS_VHD_BLOCK_ALLOCATION_FAILURE NTStatus = 0xC03A0009 + STATUS_VHD_BLOCK_ALLOCATION_TABLE_CORRUPT NTStatus = 0xC03A000A + STATUS_VHD_INVALID_BLOCK_SIZE NTStatus = 0xC03A000B + STATUS_VHD_BITMAP_MISMATCH NTStatus = 0xC03A000C + STATUS_VHD_PARENT_VHD_NOT_FOUND NTStatus = 0xC03A000D + STATUS_VHD_CHILD_PARENT_ID_MISMATCH NTStatus = 0xC03A000E + STATUS_VHD_CHILD_PARENT_TIMESTAMP_MISMATCH NTStatus = 0xC03A000F + STATUS_VHD_METADATA_READ_FAILURE NTStatus = 0xC03A0010 + STATUS_VHD_METADATA_WRITE_FAILURE NTStatus = 0xC03A0011 + STATUS_VHD_INVALID_SIZE NTStatus = 0xC03A0012 + STATUS_VHD_INVALID_FILE_SIZE NTStatus = 0xC03A0013 + STATUS_VIRTDISK_PROVIDER_NOT_FOUND NTStatus = 0xC03A0014 + STATUS_VIRTDISK_NOT_VIRTUAL_DISK NTStatus = 0xC03A0015 + STATUS_VHD_PARENT_VHD_ACCESS_DENIED NTStatus = 0xC03A0016 + STATUS_VHD_CHILD_PARENT_SIZE_MISMATCH NTStatus = 0xC03A0017 + STATUS_VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED NTStatus = 0xC03A0018 + STATUS_VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT NTStatus = 0xC03A0019 + STATUS_VIRTUAL_DISK_LIMITATION NTStatus = 0xC03A001A + STATUS_VHD_INVALID_TYPE NTStatus = 0xC03A001B + STATUS_VHD_INVALID_STATE NTStatus = 0xC03A001C + STATUS_VIRTDISK_UNSUPPORTED_DISK_SECTOR_SIZE NTStatus = 0xC03A001D + STATUS_VIRTDISK_DISK_ALREADY_OWNED NTStatus = 0xC03A001E + STATUS_VIRTDISK_DISK_ONLINE_AND_WRITABLE NTStatus = 0xC03A001F + STATUS_CTLOG_TRACKING_NOT_INITIALIZED NTStatus = 0xC03A0020 + STATUS_CTLOG_LOGFILE_SIZE_EXCEEDED_MAXSIZE NTStatus = 0xC03A0021 + STATUS_CTLOG_VHD_CHANGED_OFFLINE NTStatus = 0xC03A0022 + STATUS_CTLOG_INVALID_TRACKING_STATE NTStatus = 0xC03A0023 + STATUS_CTLOG_INCONSISTENT_TRACKING_FILE NTStatus = 0xC03A0024 + STATUS_VHD_METADATA_FULL NTStatus = 0xC03A0028 + STATUS_VHD_INVALID_CHANGE_TRACKING_ID NTStatus = 0xC03A0029 + STATUS_VHD_CHANGE_TRACKING_DISABLED NTStatus = 0xC03A002A + STATUS_VHD_MISSING_CHANGE_TRACKING_INFORMATION NTStatus = 0xC03A0030 + STATUS_VHD_RESIZE_WOULD_TRUNCATE_DATA NTStatus = 0xC03A0031 + STATUS_VHD_COULD_NOT_COMPUTE_MINIMUM_VIRTUAL_SIZE NTStatus = 0xC03A0032 + STATUS_VHD_ALREADY_AT_OR_BELOW_MINIMUM_VIRTUAL_SIZE NTStatus = 0xC03A0033 + STATUS_QUERY_STORAGE_ERROR NTStatus = 0x803A0001 + STATUS_GDI_HANDLE_LEAK NTStatus = 0x803F0001 + STATUS_RKF_KEY_NOT_FOUND NTStatus = 0xC0400001 + STATUS_RKF_DUPLICATE_KEY NTStatus = 0xC0400002 + STATUS_RKF_BLOB_FULL NTStatus = 0xC0400003 + STATUS_RKF_STORE_FULL NTStatus = 0xC0400004 + STATUS_RKF_FILE_BLOCKED NTStatus = 0xC0400005 + STATUS_RKF_ACTIVE_KEY NTStatus = 0xC0400006 + STATUS_RDBSS_RESTART_OPERATION NTStatus = 0xC0410001 + STATUS_RDBSS_CONTINUE_OPERATION NTStatus = 0xC0410002 + STATUS_RDBSS_POST_OPERATION NTStatus = 0xC0410003 + STATUS_RDBSS_RETRY_LOOKUP NTStatus = 0xC0410004 + STATUS_BTH_ATT_INVALID_HANDLE NTStatus = 0xC0420001 + STATUS_BTH_ATT_READ_NOT_PERMITTED NTStatus = 0xC0420002 + STATUS_BTH_ATT_WRITE_NOT_PERMITTED NTStatus = 0xC0420003 + STATUS_BTH_ATT_INVALID_PDU NTStatus = 0xC0420004 + STATUS_BTH_ATT_INSUFFICIENT_AUTHENTICATION NTStatus = 0xC0420005 + STATUS_BTH_ATT_REQUEST_NOT_SUPPORTED NTStatus = 0xC0420006 + STATUS_BTH_ATT_INVALID_OFFSET NTStatus = 0xC0420007 + STATUS_BTH_ATT_INSUFFICIENT_AUTHORIZATION NTStatus = 0xC0420008 + STATUS_BTH_ATT_PREPARE_QUEUE_FULL NTStatus = 0xC0420009 + STATUS_BTH_ATT_ATTRIBUTE_NOT_FOUND NTStatus = 0xC042000A + STATUS_BTH_ATT_ATTRIBUTE_NOT_LONG NTStatus = 0xC042000B + STATUS_BTH_ATT_INSUFFICIENT_ENCRYPTION_KEY_SIZE NTStatus = 0xC042000C + STATUS_BTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH NTStatus = 0xC042000D + STATUS_BTH_ATT_UNLIKELY NTStatus = 0xC042000E + STATUS_BTH_ATT_INSUFFICIENT_ENCRYPTION NTStatus = 0xC042000F + STATUS_BTH_ATT_UNSUPPORTED_GROUP_TYPE NTStatus = 0xC0420010 + STATUS_BTH_ATT_INSUFFICIENT_RESOURCES NTStatus = 0xC0420011 + STATUS_BTH_ATT_UNKNOWN_ERROR NTStatus = 0xC0421000 + STATUS_SECUREBOOT_ROLLBACK_DETECTED NTStatus = 0xC0430001 + STATUS_SECUREBOOT_POLICY_VIOLATION NTStatus = 0xC0430002 + STATUS_SECUREBOOT_INVALID_POLICY NTStatus = 0xC0430003 + STATUS_SECUREBOOT_POLICY_PUBLISHER_NOT_FOUND NTStatus = 0xC0430004 + STATUS_SECUREBOOT_POLICY_NOT_SIGNED NTStatus = 0xC0430005 + STATUS_SECUREBOOT_NOT_ENABLED NTStatus = 0x80430006 + STATUS_SECUREBOOT_FILE_REPLACED NTStatus = 0xC0430007 + STATUS_SECUREBOOT_POLICY_NOT_AUTHORIZED NTStatus = 0xC0430008 + STATUS_SECUREBOOT_POLICY_UNKNOWN NTStatus = 0xC0430009 + STATUS_SECUREBOOT_POLICY_MISSING_ANTIROLLBACKVERSION NTStatus = 0xC043000A + STATUS_SECUREBOOT_PLATFORM_ID_MISMATCH NTStatus = 0xC043000B + STATUS_SECUREBOOT_POLICY_ROLLBACK_DETECTED NTStatus = 0xC043000C + STATUS_SECUREBOOT_POLICY_UPGRADE_MISMATCH NTStatus = 0xC043000D + STATUS_SECUREBOOT_REQUIRED_POLICY_FILE_MISSING NTStatus = 0xC043000E + STATUS_SECUREBOOT_NOT_BASE_POLICY NTStatus = 0xC043000F + STATUS_SECUREBOOT_NOT_SUPPLEMENTAL_POLICY NTStatus = 0xC0430010 + STATUS_PLATFORM_MANIFEST_NOT_AUTHORIZED NTStatus = 0xC0EB0001 + STATUS_PLATFORM_MANIFEST_INVALID NTStatus = 0xC0EB0002 + STATUS_PLATFORM_MANIFEST_FILE_NOT_AUTHORIZED NTStatus = 0xC0EB0003 + STATUS_PLATFORM_MANIFEST_CATALOG_NOT_AUTHORIZED NTStatus = 0xC0EB0004 + STATUS_PLATFORM_MANIFEST_BINARY_ID_NOT_FOUND NTStatus = 0xC0EB0005 + STATUS_PLATFORM_MANIFEST_NOT_ACTIVE NTStatus = 0xC0EB0006 + STATUS_PLATFORM_MANIFEST_NOT_SIGNED NTStatus = 0xC0EB0007 + STATUS_SYSTEM_INTEGRITY_ROLLBACK_DETECTED NTStatus = 0xC0E90001 + STATUS_SYSTEM_INTEGRITY_POLICY_VIOLATION NTStatus = 0xC0E90002 + STATUS_SYSTEM_INTEGRITY_INVALID_POLICY NTStatus = 0xC0E90003 + STATUS_SYSTEM_INTEGRITY_POLICY_NOT_SIGNED NTStatus = 0xC0E90004 + STATUS_SYSTEM_INTEGRITY_TOO_MANY_POLICIES NTStatus = 0xC0E90005 + STATUS_SYSTEM_INTEGRITY_SUPPLEMENTAL_POLICY_NOT_AUTHORIZED NTStatus = 0xC0E90006 + STATUS_NO_APPLICABLE_APP_LICENSES_FOUND NTStatus = 0xC0EA0001 + STATUS_CLIP_LICENSE_NOT_FOUND NTStatus = 0xC0EA0002 + STATUS_CLIP_DEVICE_LICENSE_MISSING NTStatus = 0xC0EA0003 + STATUS_CLIP_LICENSE_INVALID_SIGNATURE NTStatus = 0xC0EA0004 + STATUS_CLIP_KEYHOLDER_LICENSE_MISSING_OR_INVALID NTStatus = 0xC0EA0005 + STATUS_CLIP_LICENSE_EXPIRED NTStatus = 0xC0EA0006 + STATUS_CLIP_LICENSE_SIGNED_BY_UNKNOWN_SOURCE NTStatus = 0xC0EA0007 + STATUS_CLIP_LICENSE_NOT_SIGNED NTStatus = 0xC0EA0008 + STATUS_CLIP_LICENSE_HARDWARE_ID_OUT_OF_TOLERANCE NTStatus = 0xC0EA0009 + STATUS_CLIP_LICENSE_DEVICE_ID_MISMATCH NTStatus = 0xC0EA000A + STATUS_AUDIO_ENGINE_NODE_NOT_FOUND NTStatus = 0xC0440001 + STATUS_HDAUDIO_EMPTY_CONNECTION_LIST NTStatus = 0xC0440002 + STATUS_HDAUDIO_CONNECTION_LIST_NOT_SUPPORTED NTStatus = 0xC0440003 + STATUS_HDAUDIO_NO_LOGICAL_DEVICES_CREATED NTStatus = 0xC0440004 + STATUS_HDAUDIO_NULL_LINKED_LIST_ENTRY NTStatus = 0xC0440005 + STATUS_SPACES_REPAIRED NTStatus = 0x00E70000 + STATUS_SPACES_PAUSE NTStatus = 0x00E70001 + STATUS_SPACES_COMPLETE NTStatus = 0x00E70002 + STATUS_SPACES_REDIRECT NTStatus = 0x00E70003 + STATUS_SPACES_FAULT_DOMAIN_TYPE_INVALID NTStatus = 0xC0E70001 + STATUS_SPACES_RESILIENCY_TYPE_INVALID NTStatus = 0xC0E70003 + STATUS_SPACES_DRIVE_SECTOR_SIZE_INVALID NTStatus = 0xC0E70004 + STATUS_SPACES_DRIVE_REDUNDANCY_INVALID NTStatus = 0xC0E70006 + STATUS_SPACES_NUMBER_OF_DATA_COPIES_INVALID NTStatus = 0xC0E70007 + STATUS_SPACES_INTERLEAVE_LENGTH_INVALID NTStatus = 0xC0E70009 + STATUS_SPACES_NUMBER_OF_COLUMNS_INVALID NTStatus = 0xC0E7000A + STATUS_SPACES_NOT_ENOUGH_DRIVES NTStatus = 0xC0E7000B + STATUS_SPACES_EXTENDED_ERROR NTStatus = 0xC0E7000C + STATUS_SPACES_PROVISIONING_TYPE_INVALID NTStatus = 0xC0E7000D + STATUS_SPACES_ALLOCATION_SIZE_INVALID NTStatus = 0xC0E7000E + STATUS_SPACES_ENCLOSURE_AWARE_INVALID NTStatus = 0xC0E7000F + STATUS_SPACES_WRITE_CACHE_SIZE_INVALID NTStatus = 0xC0E70010 + STATUS_SPACES_NUMBER_OF_GROUPS_INVALID NTStatus = 0xC0E70011 + STATUS_SPACES_DRIVE_OPERATIONAL_STATE_INVALID NTStatus = 0xC0E70012 + STATUS_SPACES_UPDATE_COLUMN_STATE NTStatus = 0xC0E70013 + STATUS_SPACES_MAP_REQUIRED NTStatus = 0xC0E70014 + STATUS_SPACES_UNSUPPORTED_VERSION NTStatus = 0xC0E70015 + STATUS_SPACES_CORRUPT_METADATA NTStatus = 0xC0E70016 + STATUS_SPACES_DRT_FULL NTStatus = 0xC0E70017 + STATUS_SPACES_INCONSISTENCY NTStatus = 0xC0E70018 + STATUS_SPACES_LOG_NOT_READY NTStatus = 0xC0E70019 + STATUS_SPACES_NO_REDUNDANCY NTStatus = 0xC0E7001A + STATUS_SPACES_DRIVE_NOT_READY NTStatus = 0xC0E7001B + STATUS_SPACES_DRIVE_SPLIT NTStatus = 0xC0E7001C + STATUS_SPACES_DRIVE_LOST_DATA NTStatus = 0xC0E7001D + STATUS_SPACES_ENTRY_INCOMPLETE NTStatus = 0xC0E7001E + STATUS_SPACES_ENTRY_INVALID NTStatus = 0xC0E7001F + STATUS_SPACES_MARK_DIRTY NTStatus = 0xC0E70020 + STATUS_VOLSNAP_BOOTFILE_NOT_VALID NTStatus = 0xC0500003 + STATUS_VOLSNAP_ACTIVATION_TIMEOUT NTStatus = 0xC0500004 + STATUS_IO_PREEMPTED NTStatus = 0xC0510001 + STATUS_SVHDX_ERROR_STORED NTStatus = 0xC05C0000 + STATUS_SVHDX_ERROR_NOT_AVAILABLE NTStatus = 0xC05CFF00 + STATUS_SVHDX_UNIT_ATTENTION_AVAILABLE NTStatus = 0xC05CFF01 + STATUS_SVHDX_UNIT_ATTENTION_CAPACITY_DATA_CHANGED NTStatus = 0xC05CFF02 + STATUS_SVHDX_UNIT_ATTENTION_RESERVATIONS_PREEMPTED NTStatus = 0xC05CFF03 + STATUS_SVHDX_UNIT_ATTENTION_RESERVATIONS_RELEASED NTStatus = 0xC05CFF04 + STATUS_SVHDX_UNIT_ATTENTION_REGISTRATIONS_PREEMPTED NTStatus = 0xC05CFF05 + STATUS_SVHDX_UNIT_ATTENTION_OPERATING_DEFINITION_CHANGED NTStatus = 0xC05CFF06 + STATUS_SVHDX_RESERVATION_CONFLICT NTStatus = 0xC05CFF07 + STATUS_SVHDX_WRONG_FILE_TYPE NTStatus = 0xC05CFF08 + STATUS_SVHDX_VERSION_MISMATCH NTStatus = 0xC05CFF09 + STATUS_VHD_SHARED NTStatus = 0xC05CFF0A + STATUS_SVHDX_NO_INITIATOR NTStatus = 0xC05CFF0B + STATUS_VHDSET_BACKING_STORAGE_NOT_FOUND NTStatus = 0xC05CFF0C + STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP NTStatus = 0xC05D0000 + STATUS_SMB_BAD_CLUSTER_DIALECT NTStatus = 0xC05D0001 + STATUS_SMB_GUEST_LOGON_BLOCKED NTStatus = 0xC05D0002 + STATUS_SECCORE_INVALID_COMMAND NTStatus = 0xC0E80000 + STATUS_VSM_NOT_INITIALIZED NTStatus = 0xC0450000 + STATUS_VSM_DMA_PROTECTION_NOT_IN_USE NTStatus = 0xC0450001 + STATUS_APPEXEC_CONDITION_NOT_SATISFIED NTStatus = 0xC0EC0000 + STATUS_APPEXEC_HANDLE_INVALIDATED NTStatus = 0xC0EC0001 + STATUS_APPEXEC_INVALID_HOST_GENERATION NTStatus = 0xC0EC0002 + STATUS_APPEXEC_UNEXPECTED_PROCESS_REGISTRATION NTStatus = 0xC0EC0003 + STATUS_APPEXEC_INVALID_HOST_STATE NTStatus = 0xC0EC0004 + STATUS_APPEXEC_NO_DONOR NTStatus = 0xC0EC0005 + STATUS_APPEXEC_HOST_ID_MISMATCH NTStatus = 0xC0EC0006 + STATUS_APPEXEC_UNKNOWN_USER NTStatus = 0xC0EC0007 +) diff --git a/vendor/golang.org/x/sys/windows/zknownfolderids_windows.go b/vendor/golang.org/x/sys/windows/zknownfolderids_windows.go new file mode 100644 index 0000000..6048ac6 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/zknownfolderids_windows.go @@ -0,0 +1,149 @@ +// Code generated by 'mkknownfolderids.bash'; DO NOT EDIT. + +package windows + +type KNOWNFOLDERID GUID + +var ( + FOLDERID_NetworkFolder = &KNOWNFOLDERID{0xd20beec4, 0x5ca8, 0x4905, [8]byte{0xae, 0x3b, 0xbf, 0x25, 0x1e, 0xa0, 0x9b, 0x53}} + FOLDERID_ComputerFolder = &KNOWNFOLDERID{0x0ac0837c, 0xbbf8, 0x452a, [8]byte{0x85, 0x0d, 0x79, 0xd0, 0x8e, 0x66, 0x7c, 0xa7}} + FOLDERID_InternetFolder = &KNOWNFOLDERID{0x4d9f7874, 0x4e0c, 0x4904, [8]byte{0x96, 0x7b, 0x40, 0xb0, 0xd2, 0x0c, 0x3e, 0x4b}} + FOLDERID_ControlPanelFolder = &KNOWNFOLDERID{0x82a74aeb, 0xaeb4, 0x465c, [8]byte{0xa0, 0x14, 0xd0, 0x97, 0xee, 0x34, 0x6d, 0x63}} + FOLDERID_PrintersFolder = &KNOWNFOLDERID{0x76fc4e2d, 0xd6ad, 0x4519, [8]byte{0xa6, 0x63, 0x37, 0xbd, 0x56, 0x06, 0x81, 0x85}} + FOLDERID_SyncManagerFolder = &KNOWNFOLDERID{0x43668bf8, 0xc14e, 0x49b2, [8]byte{0x97, 0xc9, 0x74, 0x77, 0x84, 0xd7, 0x84, 0xb7}} + FOLDERID_SyncSetupFolder = &KNOWNFOLDERID{0x0f214138, 0xb1d3, 0x4a90, [8]byte{0xbb, 0xa9, 0x27, 0xcb, 0xc0, 0xc5, 0x38, 0x9a}} + FOLDERID_ConflictFolder = &KNOWNFOLDERID{0x4bfefb45, 0x347d, 0x4006, [8]byte{0xa5, 0xbe, 0xac, 0x0c, 0xb0, 0x56, 0x71, 0x92}} + FOLDERID_SyncResultsFolder = &KNOWNFOLDERID{0x289a9a43, 0xbe44, 0x4057, [8]byte{0xa4, 0x1b, 0x58, 0x7a, 0x76, 0xd7, 0xe7, 0xf9}} + FOLDERID_RecycleBinFolder = &KNOWNFOLDERID{0xb7534046, 0x3ecb, 0x4c18, [8]byte{0xbe, 0x4e, 0x64, 0xcd, 0x4c, 0xb7, 0xd6, 0xac}} + FOLDERID_ConnectionsFolder = &KNOWNFOLDERID{0x6f0cd92b, 0x2e97, 0x45d1, [8]byte{0x88, 0xff, 0xb0, 0xd1, 0x86, 0xb8, 0xde, 0xdd}} + FOLDERID_Fonts = &KNOWNFOLDERID{0xfd228cb7, 0xae11, 0x4ae3, [8]byte{0x86, 0x4c, 0x16, 0xf3, 0x91, 0x0a, 0xb8, 0xfe}} + FOLDERID_Desktop = &KNOWNFOLDERID{0xb4bfcc3a, 0xdb2c, 0x424c, [8]byte{0xb0, 0x29, 0x7f, 0xe9, 0x9a, 0x87, 0xc6, 0x41}} + FOLDERID_Startup = &KNOWNFOLDERID{0xb97d20bb, 0xf46a, 0x4c97, [8]byte{0xba, 0x10, 0x5e, 0x36, 0x08, 0x43, 0x08, 0x54}} + FOLDERID_Programs = &KNOWNFOLDERID{0xa77f5d77, 0x2e2b, 0x44c3, [8]byte{0xa6, 0xa2, 0xab, 0xa6, 0x01, 0x05, 0x4a, 0x51}} + FOLDERID_StartMenu = &KNOWNFOLDERID{0x625b53c3, 0xab48, 0x4ec1, [8]byte{0xba, 0x1f, 0xa1, 0xef, 0x41, 0x46, 0xfc, 0x19}} + FOLDERID_Recent = &KNOWNFOLDERID{0xae50c081, 0xebd2, 0x438a, [8]byte{0x86, 0x55, 0x8a, 0x09, 0x2e, 0x34, 0x98, 0x7a}} + FOLDERID_SendTo = &KNOWNFOLDERID{0x8983036c, 0x27c0, 0x404b, [8]byte{0x8f, 0x08, 0x10, 0x2d, 0x10, 0xdc, 0xfd, 0x74}} + FOLDERID_Documents = &KNOWNFOLDERID{0xfdd39ad0, 0x238f, 0x46af, [8]byte{0xad, 0xb4, 0x6c, 0x85, 0x48, 0x03, 0x69, 0xc7}} + FOLDERID_Favorites = &KNOWNFOLDERID{0x1777f761, 0x68ad, 0x4d8a, [8]byte{0x87, 0xbd, 0x30, 0xb7, 0x59, 0xfa, 0x33, 0xdd}} + FOLDERID_NetHood = &KNOWNFOLDERID{0xc5abbf53, 0xe17f, 0x4121, [8]byte{0x89, 0x00, 0x86, 0x62, 0x6f, 0xc2, 0xc9, 0x73}} + FOLDERID_PrintHood = &KNOWNFOLDERID{0x9274bd8d, 0xcfd1, 0x41c3, [8]byte{0xb3, 0x5e, 0xb1, 0x3f, 0x55, 0xa7, 0x58, 0xf4}} + FOLDERID_Templates = &KNOWNFOLDERID{0xa63293e8, 0x664e, 0x48db, [8]byte{0xa0, 0x79, 0xdf, 0x75, 0x9e, 0x05, 0x09, 0xf7}} + FOLDERID_CommonStartup = &KNOWNFOLDERID{0x82a5ea35, 0xd9cd, 0x47c5, [8]byte{0x96, 0x29, 0xe1, 0x5d, 0x2f, 0x71, 0x4e, 0x6e}} + FOLDERID_CommonPrograms = &KNOWNFOLDERID{0x0139d44e, 0x6afe, 0x49f2, [8]byte{0x86, 0x90, 0x3d, 0xaf, 0xca, 0xe6, 0xff, 0xb8}} + FOLDERID_CommonStartMenu = &KNOWNFOLDERID{0xa4115719, 0xd62e, 0x491d, [8]byte{0xaa, 0x7c, 0xe7, 0x4b, 0x8b, 0xe3, 0xb0, 0x67}} + FOLDERID_PublicDesktop = &KNOWNFOLDERID{0xc4aa340d, 0xf20f, 0x4863, [8]byte{0xaf, 0xef, 0xf8, 0x7e, 0xf2, 0xe6, 0xba, 0x25}} + FOLDERID_ProgramData = &KNOWNFOLDERID{0x62ab5d82, 0xfdc1, 0x4dc3, [8]byte{0xa9, 0xdd, 0x07, 0x0d, 0x1d, 0x49, 0x5d, 0x97}} + FOLDERID_CommonTemplates = &KNOWNFOLDERID{0xb94237e7, 0x57ac, 0x4347, [8]byte{0x91, 0x51, 0xb0, 0x8c, 0x6c, 0x32, 0xd1, 0xf7}} + FOLDERID_PublicDocuments = &KNOWNFOLDERID{0xed4824af, 0xdce4, 0x45a8, [8]byte{0x81, 0xe2, 0xfc, 0x79, 0x65, 0x08, 0x36, 0x34}} + FOLDERID_RoamingAppData = &KNOWNFOLDERID{0x3eb685db, 0x65f9, 0x4cf6, [8]byte{0xa0, 0x3a, 0xe3, 0xef, 0x65, 0x72, 0x9f, 0x3d}} + FOLDERID_LocalAppData = &KNOWNFOLDERID{0xf1b32785, 0x6fba, 0x4fcf, [8]byte{0x9d, 0x55, 0x7b, 0x8e, 0x7f, 0x15, 0x70, 0x91}} + FOLDERID_LocalAppDataLow = &KNOWNFOLDERID{0xa520a1a4, 0x1780, 0x4ff6, [8]byte{0xbd, 0x18, 0x16, 0x73, 0x43, 0xc5, 0xaf, 0x16}} + FOLDERID_InternetCache = &KNOWNFOLDERID{0x352481e8, 0x33be, 0x4251, [8]byte{0xba, 0x85, 0x60, 0x07, 0xca, 0xed, 0xcf, 0x9d}} + FOLDERID_Cookies = &KNOWNFOLDERID{0x2b0f765d, 0xc0e9, 0x4171, [8]byte{0x90, 0x8e, 0x08, 0xa6, 0x11, 0xb8, 0x4f, 0xf6}} + FOLDERID_History = &KNOWNFOLDERID{0xd9dc8a3b, 0xb784, 0x432e, [8]byte{0xa7, 0x81, 0x5a, 0x11, 0x30, 0xa7, 0x59, 0x63}} + FOLDERID_System = &KNOWNFOLDERID{0x1ac14e77, 0x02e7, 0x4e5d, [8]byte{0xb7, 0x44, 0x2e, 0xb1, 0xae, 0x51, 0x98, 0xb7}} + FOLDERID_SystemX86 = &KNOWNFOLDERID{0xd65231b0, 0xb2f1, 0x4857, [8]byte{0xa4, 0xce, 0xa8, 0xe7, 0xc6, 0xea, 0x7d, 0x27}} + FOLDERID_Windows = &KNOWNFOLDERID{0xf38bf404, 0x1d43, 0x42f2, [8]byte{0x93, 0x05, 0x67, 0xde, 0x0b, 0x28, 0xfc, 0x23}} + FOLDERID_Profile = &KNOWNFOLDERID{0x5e6c858f, 0x0e22, 0x4760, [8]byte{0x9a, 0xfe, 0xea, 0x33, 0x17, 0xb6, 0x71, 0x73}} + FOLDERID_Pictures = &KNOWNFOLDERID{0x33e28130, 0x4e1e, 0x4676, [8]byte{0x83, 0x5a, 0x98, 0x39, 0x5c, 0x3b, 0xc3, 0xbb}} + FOLDERID_ProgramFilesX86 = &KNOWNFOLDERID{0x7c5a40ef, 0xa0fb, 0x4bfc, [8]byte{0x87, 0x4a, 0xc0, 0xf2, 0xe0, 0xb9, 0xfa, 0x8e}} + FOLDERID_ProgramFilesCommonX86 = &KNOWNFOLDERID{0xde974d24, 0xd9c6, 0x4d3e, [8]byte{0xbf, 0x91, 0xf4, 0x45, 0x51, 0x20, 0xb9, 0x17}} + FOLDERID_ProgramFilesX64 = &KNOWNFOLDERID{0x6d809377, 0x6af0, 0x444b, [8]byte{0x89, 0x57, 0xa3, 0x77, 0x3f, 0x02, 0x20, 0x0e}} + FOLDERID_ProgramFilesCommonX64 = &KNOWNFOLDERID{0x6365d5a7, 0x0f0d, 0x45e5, [8]byte{0x87, 0xf6, 0x0d, 0xa5, 0x6b, 0x6a, 0x4f, 0x7d}} + FOLDERID_ProgramFiles = &KNOWNFOLDERID{0x905e63b6, 0xc1bf, 0x494e, [8]byte{0xb2, 0x9c, 0x65, 0xb7, 0x32, 0xd3, 0xd2, 0x1a}} + FOLDERID_ProgramFilesCommon = &KNOWNFOLDERID{0xf7f1ed05, 0x9f6d, 0x47a2, [8]byte{0xaa, 0xae, 0x29, 0xd3, 0x17, 0xc6, 0xf0, 0x66}} + FOLDERID_UserProgramFiles = &KNOWNFOLDERID{0x5cd7aee2, 0x2219, 0x4a67, [8]byte{0xb8, 0x5d, 0x6c, 0x9c, 0xe1, 0x56, 0x60, 0xcb}} + FOLDERID_UserProgramFilesCommon = &KNOWNFOLDERID{0xbcbd3057, 0xca5c, 0x4622, [8]byte{0xb4, 0x2d, 0xbc, 0x56, 0xdb, 0x0a, 0xe5, 0x16}} + FOLDERID_AdminTools = &KNOWNFOLDERID{0x724ef170, 0xa42d, 0x4fef, [8]byte{0x9f, 0x26, 0xb6, 0x0e, 0x84, 0x6f, 0xba, 0x4f}} + FOLDERID_CommonAdminTools = &KNOWNFOLDERID{0xd0384e7d, 0xbac3, 0x4797, [8]byte{0x8f, 0x14, 0xcb, 0xa2, 0x29, 0xb3, 0x92, 0xb5}} + FOLDERID_Music = &KNOWNFOLDERID{0x4bd8d571, 0x6d19, 0x48d3, [8]byte{0xbe, 0x97, 0x42, 0x22, 0x20, 0x08, 0x0e, 0x43}} + FOLDERID_Videos = &KNOWNFOLDERID{0x18989b1d, 0x99b5, 0x455b, [8]byte{0x84, 0x1c, 0xab, 0x7c, 0x74, 0xe4, 0xdd, 0xfc}} + FOLDERID_Ringtones = &KNOWNFOLDERID{0xc870044b, 0xf49e, 0x4126, [8]byte{0xa9, 0xc3, 0xb5, 0x2a, 0x1f, 0xf4, 0x11, 0xe8}} + FOLDERID_PublicPictures = &KNOWNFOLDERID{0xb6ebfb86, 0x6907, 0x413c, [8]byte{0x9a, 0xf7, 0x4f, 0xc2, 0xab, 0xf0, 0x7c, 0xc5}} + FOLDERID_PublicMusic = &KNOWNFOLDERID{0x3214fab5, 0x9757, 0x4298, [8]byte{0xbb, 0x61, 0x92, 0xa9, 0xde, 0xaa, 0x44, 0xff}} + FOLDERID_PublicVideos = &KNOWNFOLDERID{0x2400183a, 0x6185, 0x49fb, [8]byte{0xa2, 0xd8, 0x4a, 0x39, 0x2a, 0x60, 0x2b, 0xa3}} + FOLDERID_PublicRingtones = &KNOWNFOLDERID{0xe555ab60, 0x153b, 0x4d17, [8]byte{0x9f, 0x04, 0xa5, 0xfe, 0x99, 0xfc, 0x15, 0xec}} + FOLDERID_ResourceDir = &KNOWNFOLDERID{0x8ad10c31, 0x2adb, 0x4296, [8]byte{0xa8, 0xf7, 0xe4, 0x70, 0x12, 0x32, 0xc9, 0x72}} + FOLDERID_LocalizedResourcesDir = &KNOWNFOLDERID{0x2a00375e, 0x224c, 0x49de, [8]byte{0xb8, 0xd1, 0x44, 0x0d, 0xf7, 0xef, 0x3d, 0xdc}} + FOLDERID_CommonOEMLinks = &KNOWNFOLDERID{0xc1bae2d0, 0x10df, 0x4334, [8]byte{0xbe, 0xdd, 0x7a, 0xa2, 0x0b, 0x22, 0x7a, 0x9d}} + FOLDERID_CDBurning = &KNOWNFOLDERID{0x9e52ab10, 0xf80d, 0x49df, [8]byte{0xac, 0xb8, 0x43, 0x30, 0xf5, 0x68, 0x78, 0x55}} + FOLDERID_UserProfiles = &KNOWNFOLDERID{0x0762d272, 0xc50a, 0x4bb0, [8]byte{0xa3, 0x82, 0x69, 0x7d, 0xcd, 0x72, 0x9b, 0x80}} + FOLDERID_Playlists = &KNOWNFOLDERID{0xde92c1c7, 0x837f, 0x4f69, [8]byte{0xa3, 0xbb, 0x86, 0xe6, 0x31, 0x20, 0x4a, 0x23}} + FOLDERID_SamplePlaylists = &KNOWNFOLDERID{0x15ca69b3, 0x30ee, 0x49c1, [8]byte{0xac, 0xe1, 0x6b, 0x5e, 0xc3, 0x72, 0xaf, 0xb5}} + FOLDERID_SampleMusic = &KNOWNFOLDERID{0xb250c668, 0xf57d, 0x4ee1, [8]byte{0xa6, 0x3c, 0x29, 0x0e, 0xe7, 0xd1, 0xaa, 0x1f}} + FOLDERID_SamplePictures = &KNOWNFOLDERID{0xc4900540, 0x2379, 0x4c75, [8]byte{0x84, 0x4b, 0x64, 0xe6, 0xfa, 0xf8, 0x71, 0x6b}} + FOLDERID_SampleVideos = &KNOWNFOLDERID{0x859ead94, 0x2e85, 0x48ad, [8]byte{0xa7, 0x1a, 0x09, 0x69, 0xcb, 0x56, 0xa6, 0xcd}} + FOLDERID_PhotoAlbums = &KNOWNFOLDERID{0x69d2cf90, 0xfc33, 0x4fb7, [8]byte{0x9a, 0x0c, 0xeb, 0xb0, 0xf0, 0xfc, 0xb4, 0x3c}} + FOLDERID_Public = &KNOWNFOLDERID{0xdfdf76a2, 0xc82a, 0x4d63, [8]byte{0x90, 0x6a, 0x56, 0x44, 0xac, 0x45, 0x73, 0x85}} + FOLDERID_ChangeRemovePrograms = &KNOWNFOLDERID{0xdf7266ac, 0x9274, 0x4867, [8]byte{0x8d, 0x55, 0x3b, 0xd6, 0x61, 0xde, 0x87, 0x2d}} + FOLDERID_AppUpdates = &KNOWNFOLDERID{0xa305ce99, 0xf527, 0x492b, [8]byte{0x8b, 0x1a, 0x7e, 0x76, 0xfa, 0x98, 0xd6, 0xe4}} + FOLDERID_AddNewPrograms = &KNOWNFOLDERID{0xde61d971, 0x5ebc, 0x4f02, [8]byte{0xa3, 0xa9, 0x6c, 0x82, 0x89, 0x5e, 0x5c, 0x04}} + FOLDERID_Downloads = &KNOWNFOLDERID{0x374de290, 0x123f, 0x4565, [8]byte{0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b}} + FOLDERID_PublicDownloads = &KNOWNFOLDERID{0x3d644c9b, 0x1fb8, 0x4f30, [8]byte{0x9b, 0x45, 0xf6, 0x70, 0x23, 0x5f, 0x79, 0xc0}} + FOLDERID_SavedSearches = &KNOWNFOLDERID{0x7d1d3a04, 0xdebb, 0x4115, [8]byte{0x95, 0xcf, 0x2f, 0x29, 0xda, 0x29, 0x20, 0xda}} + FOLDERID_QuickLaunch = &KNOWNFOLDERID{0x52a4f021, 0x7b75, 0x48a9, [8]byte{0x9f, 0x6b, 0x4b, 0x87, 0xa2, 0x10, 0xbc, 0x8f}} + FOLDERID_Contacts = &KNOWNFOLDERID{0x56784854, 0xc6cb, 0x462b, [8]byte{0x81, 0x69, 0x88, 0xe3, 0x50, 0xac, 0xb8, 0x82}} + FOLDERID_SidebarParts = &KNOWNFOLDERID{0xa75d362e, 0x50fc, 0x4fb7, [8]byte{0xac, 0x2c, 0xa8, 0xbe, 0xaa, 0x31, 0x44, 0x93}} + FOLDERID_SidebarDefaultParts = &KNOWNFOLDERID{0x7b396e54, 0x9ec5, 0x4300, [8]byte{0xbe, 0x0a, 0x24, 0x82, 0xeb, 0xae, 0x1a, 0x26}} + FOLDERID_PublicGameTasks = &KNOWNFOLDERID{0xdebf2536, 0xe1a8, 0x4c59, [8]byte{0xb6, 0xa2, 0x41, 0x45, 0x86, 0x47, 0x6a, 0xea}} + FOLDERID_GameTasks = &KNOWNFOLDERID{0x054fae61, 0x4dd8, 0x4787, [8]byte{0x80, 0xb6, 0x09, 0x02, 0x20, 0xc4, 0xb7, 0x00}} + FOLDERID_SavedGames = &KNOWNFOLDERID{0x4c5c32ff, 0xbb9d, 0x43b0, [8]byte{0xb5, 0xb4, 0x2d, 0x72, 0xe5, 0x4e, 0xaa, 0xa4}} + FOLDERID_Games = &KNOWNFOLDERID{0xcac52c1a, 0xb53d, 0x4edc, [8]byte{0x92, 0xd7, 0x6b, 0x2e, 0x8a, 0xc1, 0x94, 0x34}} + FOLDERID_SEARCH_MAPI = &KNOWNFOLDERID{0x98ec0e18, 0x2098, 0x4d44, [8]byte{0x86, 0x44, 0x66, 0x97, 0x93, 0x15, 0xa2, 0x81}} + FOLDERID_SEARCH_CSC = &KNOWNFOLDERID{0xee32e446, 0x31ca, 0x4aba, [8]byte{0x81, 0x4f, 0xa5, 0xeb, 0xd2, 0xfd, 0x6d, 0x5e}} + FOLDERID_Links = &KNOWNFOLDERID{0xbfb9d5e0, 0xc6a9, 0x404c, [8]byte{0xb2, 0xb2, 0xae, 0x6d, 0xb6, 0xaf, 0x49, 0x68}} + FOLDERID_UsersFiles = &KNOWNFOLDERID{0xf3ce0f7c, 0x4901, 0x4acc, [8]byte{0x86, 0x48, 0xd5, 0xd4, 0x4b, 0x04, 0xef, 0x8f}} + FOLDERID_UsersLibraries = &KNOWNFOLDERID{0xa302545d, 0xdeff, 0x464b, [8]byte{0xab, 0xe8, 0x61, 0xc8, 0x64, 0x8d, 0x93, 0x9b}} + FOLDERID_SearchHome = &KNOWNFOLDERID{0x190337d1, 0xb8ca, 0x4121, [8]byte{0xa6, 0x39, 0x6d, 0x47, 0x2d, 0x16, 0x97, 0x2a}} + FOLDERID_OriginalImages = &KNOWNFOLDERID{0x2c36c0aa, 0x5812, 0x4b87, [8]byte{0xbf, 0xd0, 0x4c, 0xd0, 0xdf, 0xb1, 0x9b, 0x39}} + FOLDERID_DocumentsLibrary = &KNOWNFOLDERID{0x7b0db17d, 0x9cd2, 0x4a93, [8]byte{0x97, 0x33, 0x46, 0xcc, 0x89, 0x02, 0x2e, 0x7c}} + FOLDERID_MusicLibrary = &KNOWNFOLDERID{0x2112ab0a, 0xc86a, 0x4ffe, [8]byte{0xa3, 0x68, 0x0d, 0xe9, 0x6e, 0x47, 0x01, 0x2e}} + FOLDERID_PicturesLibrary = &KNOWNFOLDERID{0xa990ae9f, 0xa03b, 0x4e80, [8]byte{0x94, 0xbc, 0x99, 0x12, 0xd7, 0x50, 0x41, 0x04}} + FOLDERID_VideosLibrary = &KNOWNFOLDERID{0x491e922f, 0x5643, 0x4af4, [8]byte{0xa7, 0xeb, 0x4e, 0x7a, 0x13, 0x8d, 0x81, 0x74}} + FOLDERID_RecordedTVLibrary = &KNOWNFOLDERID{0x1a6fdba2, 0xf42d, 0x4358, [8]byte{0xa7, 0x98, 0xb7, 0x4d, 0x74, 0x59, 0x26, 0xc5}} + FOLDERID_HomeGroup = &KNOWNFOLDERID{0x52528a6b, 0xb9e3, 0x4add, [8]byte{0xb6, 0x0d, 0x58, 0x8c, 0x2d, 0xba, 0x84, 0x2d}} + FOLDERID_HomeGroupCurrentUser = &KNOWNFOLDERID{0x9b74b6a3, 0x0dfd, 0x4f11, [8]byte{0x9e, 0x78, 0x5f, 0x78, 0x00, 0xf2, 0xe7, 0x72}} + FOLDERID_DeviceMetadataStore = &KNOWNFOLDERID{0x5ce4a5e9, 0xe4eb, 0x479d, [8]byte{0xb8, 0x9f, 0x13, 0x0c, 0x02, 0x88, 0x61, 0x55}} + FOLDERID_Libraries = &KNOWNFOLDERID{0x1b3ea5dc, 0xb587, 0x4786, [8]byte{0xb4, 0xef, 0xbd, 0x1d, 0xc3, 0x32, 0xae, 0xae}} + FOLDERID_PublicLibraries = &KNOWNFOLDERID{0x48daf80b, 0xe6cf, 0x4f4e, [8]byte{0xb8, 0x00, 0x0e, 0x69, 0xd8, 0x4e, 0xe3, 0x84}} + FOLDERID_UserPinned = &KNOWNFOLDERID{0x9e3995ab, 0x1f9c, 0x4f13, [8]byte{0xb8, 0x27, 0x48, 0xb2, 0x4b, 0x6c, 0x71, 0x74}} + FOLDERID_ImplicitAppShortcuts = &KNOWNFOLDERID{0xbcb5256f, 0x79f6, 0x4cee, [8]byte{0xb7, 0x25, 0xdc, 0x34, 0xe4, 0x02, 0xfd, 0x46}} + FOLDERID_AccountPictures = &KNOWNFOLDERID{0x008ca0b1, 0x55b4, 0x4c56, [8]byte{0xb8, 0xa8, 0x4d, 0xe4, 0xb2, 0x99, 0xd3, 0xbe}} + FOLDERID_PublicUserTiles = &KNOWNFOLDERID{0x0482af6c, 0x08f1, 0x4c34, [8]byte{0x8c, 0x90, 0xe1, 0x7e, 0xc9, 0x8b, 0x1e, 0x17}} + FOLDERID_AppsFolder = &KNOWNFOLDERID{0x1e87508d, 0x89c2, 0x42f0, [8]byte{0x8a, 0x7e, 0x64, 0x5a, 0x0f, 0x50, 0xca, 0x58}} + FOLDERID_StartMenuAllPrograms = &KNOWNFOLDERID{0xf26305ef, 0x6948, 0x40b9, [8]byte{0xb2, 0x55, 0x81, 0x45, 0x3d, 0x09, 0xc7, 0x85}} + FOLDERID_CommonStartMenuPlaces = &KNOWNFOLDERID{0xa440879f, 0x87a0, 0x4f7d, [8]byte{0xb7, 0x00, 0x02, 0x07, 0xb9, 0x66, 0x19, 0x4a}} + FOLDERID_ApplicationShortcuts = &KNOWNFOLDERID{0xa3918781, 0xe5f2, 0x4890, [8]byte{0xb3, 0xd9, 0xa7, 0xe5, 0x43, 0x32, 0x32, 0x8c}} + FOLDERID_RoamingTiles = &KNOWNFOLDERID{0x00bcfc5a, 0xed94, 0x4e48, [8]byte{0x96, 0xa1, 0x3f, 0x62, 0x17, 0xf2, 0x19, 0x90}} + FOLDERID_RoamedTileImages = &KNOWNFOLDERID{0xaaa8d5a5, 0xf1d6, 0x4259, [8]byte{0xba, 0xa8, 0x78, 0xe7, 0xef, 0x60, 0x83, 0x5e}} + FOLDERID_Screenshots = &KNOWNFOLDERID{0xb7bede81, 0xdf94, 0x4682, [8]byte{0xa7, 0xd8, 0x57, 0xa5, 0x26, 0x20, 0xb8, 0x6f}} + FOLDERID_CameraRoll = &KNOWNFOLDERID{0xab5fb87b, 0x7ce2, 0x4f83, [8]byte{0x91, 0x5d, 0x55, 0x08, 0x46, 0xc9, 0x53, 0x7b}} + FOLDERID_SkyDrive = &KNOWNFOLDERID{0xa52bba46, 0xe9e1, 0x435f, [8]byte{0xb3, 0xd9, 0x28, 0xda, 0xa6, 0x48, 0xc0, 0xf6}} + FOLDERID_OneDrive = &KNOWNFOLDERID{0xa52bba46, 0xe9e1, 0x435f, [8]byte{0xb3, 0xd9, 0x28, 0xda, 0xa6, 0x48, 0xc0, 0xf6}} + FOLDERID_SkyDriveDocuments = &KNOWNFOLDERID{0x24d89e24, 0x2f19, 0x4534, [8]byte{0x9d, 0xde, 0x6a, 0x66, 0x71, 0xfb, 0xb8, 0xfe}} + FOLDERID_SkyDrivePictures = &KNOWNFOLDERID{0x339719b5, 0x8c47, 0x4894, [8]byte{0x94, 0xc2, 0xd8, 0xf7, 0x7a, 0xdd, 0x44, 0xa6}} + FOLDERID_SkyDriveMusic = &KNOWNFOLDERID{0xc3f2459e, 0x80d6, 0x45dc, [8]byte{0xbf, 0xef, 0x1f, 0x76, 0x9f, 0x2b, 0xe7, 0x30}} + FOLDERID_SkyDriveCameraRoll = &KNOWNFOLDERID{0x767e6811, 0x49cb, 0x4273, [8]byte{0x87, 0xc2, 0x20, 0xf3, 0x55, 0xe1, 0x08, 0x5b}} + FOLDERID_SearchHistory = &KNOWNFOLDERID{0x0d4c3db6, 0x03a3, 0x462f, [8]byte{0xa0, 0xe6, 0x08, 0x92, 0x4c, 0x41, 0xb5, 0xd4}} + FOLDERID_SearchTemplates = &KNOWNFOLDERID{0x7e636bfe, 0xdfa9, 0x4d5e, [8]byte{0xb4, 0x56, 0xd7, 0xb3, 0x98, 0x51, 0xd8, 0xa9}} + FOLDERID_CameraRollLibrary = &KNOWNFOLDERID{0x2b20df75, 0x1eda, 0x4039, [8]byte{0x80, 0x97, 0x38, 0x79, 0x82, 0x27, 0xd5, 0xb7}} + FOLDERID_SavedPictures = &KNOWNFOLDERID{0x3b193882, 0xd3ad, 0x4eab, [8]byte{0x96, 0x5a, 0x69, 0x82, 0x9d, 0x1f, 0xb5, 0x9f}} + FOLDERID_SavedPicturesLibrary = &KNOWNFOLDERID{0xe25b5812, 0xbe88, 0x4bd9, [8]byte{0x94, 0xb0, 0x29, 0x23, 0x34, 0x77, 0xb6, 0xc3}} + FOLDERID_RetailDemo = &KNOWNFOLDERID{0x12d4c69e, 0x24ad, 0x4923, [8]byte{0xbe, 0x19, 0x31, 0x32, 0x1c, 0x43, 0xa7, 0x67}} + FOLDERID_Device = &KNOWNFOLDERID{0x1c2ac1dc, 0x4358, 0x4b6c, [8]byte{0x97, 0x33, 0xaf, 0x21, 0x15, 0x65, 0x76, 0xf0}} + FOLDERID_DevelopmentFiles = &KNOWNFOLDERID{0xdbe8e08e, 0x3053, 0x4bbc, [8]byte{0xb1, 0x83, 0x2a, 0x7b, 0x2b, 0x19, 0x1e, 0x59}} + FOLDERID_Objects3D = &KNOWNFOLDERID{0x31c0dd25, 0x9439, 0x4f12, [8]byte{0xbf, 0x41, 0x7f, 0xf4, 0xed, 0xa3, 0x87, 0x22}} + FOLDERID_AppCaptures = &KNOWNFOLDERID{0xedc0fe71, 0x98d8, 0x4f4a, [8]byte{0xb9, 0x20, 0xc8, 0xdc, 0x13, 0x3c, 0xb1, 0x65}} + FOLDERID_LocalDocuments = &KNOWNFOLDERID{0xf42ee2d3, 0x909f, 0x4907, [8]byte{0x88, 0x71, 0x4c, 0x22, 0xfc, 0x0b, 0xf7, 0x56}} + FOLDERID_LocalPictures = &KNOWNFOLDERID{0x0ddd015d, 0xb06c, 0x45d5, [8]byte{0x8c, 0x4c, 0xf5, 0x97, 0x13, 0x85, 0x46, 0x39}} + FOLDERID_LocalVideos = &KNOWNFOLDERID{0x35286a68, 0x3c57, 0x41a1, [8]byte{0xbb, 0xb1, 0x0e, 0xae, 0x73, 0xd7, 0x6c, 0x95}} + FOLDERID_LocalMusic = &KNOWNFOLDERID{0xa0c69a99, 0x21c8, 0x4671, [8]byte{0x87, 0x03, 0x79, 0x34, 0x16, 0x2f, 0xcf, 0x1d}} + FOLDERID_LocalDownloads = &KNOWNFOLDERID{0x7d83ee9b, 0x2244, 0x4e70, [8]byte{0xb1, 0xf5, 0x53, 0x93, 0x04, 0x2a, 0xf1, 0xe4}} + FOLDERID_RecordedCalls = &KNOWNFOLDERID{0x2f8b40c2, 0x83ed, 0x48ee, [8]byte{0xb3, 0x83, 0xa1, 0xf1, 0x57, 0xec, 0x6f, 0x9a}} + FOLDERID_AllAppMods = &KNOWNFOLDERID{0x7ad67899, 0x66af, 0x43ba, [8]byte{0x91, 0x56, 0x6a, 0xad, 0x42, 0xe6, 0xc5, 0x96}} + FOLDERID_CurrentAppMods = &KNOWNFOLDERID{0x3db40b20, 0x2a30, 0x4dbe, [8]byte{0x91, 0x7e, 0x77, 0x1d, 0xd2, 0x1d, 0xd0, 0x99}} + FOLDERID_AppDataDesktop = &KNOWNFOLDERID{0xb2c5e279, 0x7add, 0x439f, [8]byte{0xb2, 0x8c, 0xc4, 0x1f, 0xe1, 0xbb, 0xf6, 0x72}} + FOLDERID_AppDataDocuments = &KNOWNFOLDERID{0x7be16610, 0x1f7f, 0x44ac, [8]byte{0xbf, 0xf0, 0x83, 0xe1, 0x5f, 0x2f, 0xfc, 0xa1}} + FOLDERID_AppDataFavorites = &KNOWNFOLDERID{0x7cfbefbc, 0xde1f, 0x45aa, [8]byte{0xb8, 0x43, 0xa5, 0x42, 0xac, 0x53, 0x6c, 0xc9}} + FOLDERID_AppDataProgramData = &KNOWNFOLDERID{0x559d40a3, 0xa036, 0x40fa, [8]byte{0xaf, 0x61, 0x84, 0xcb, 0x43, 0x0a, 0x4d, 0x34}} +) diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go new file mode 100644 index 0000000..192d193 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -0,0 +1,4828 @@ +// Code generated by 'go generate'; DO NOT EDIT. + +package windows + +import ( + "syscall" + "unsafe" +) + +var _ unsafe.Pointer + +// Do the interface allocations only once for common +// Errno values. +const ( + errnoERROR_IO_PENDING = 997 +) + +var ( + errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return errERROR_EINVAL + case errnoERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} + +var ( + modCfgMgr32 = NewLazySystemDLL("CfgMgr32.dll") + modadvapi32 = NewLazySystemDLL("advapi32.dll") + modcrypt32 = NewLazySystemDLL("crypt32.dll") + moddnsapi = NewLazySystemDLL("dnsapi.dll") + moddwmapi = NewLazySystemDLL("dwmapi.dll") + modiphlpapi = NewLazySystemDLL("iphlpapi.dll") + modkernel32 = NewLazySystemDLL("kernel32.dll") + modmswsock = NewLazySystemDLL("mswsock.dll") + modnetapi32 = NewLazySystemDLL("netapi32.dll") + modntdll = NewLazySystemDLL("ntdll.dll") + modole32 = NewLazySystemDLL("ole32.dll") + modpsapi = NewLazySystemDLL("psapi.dll") + modsechost = NewLazySystemDLL("sechost.dll") + modsecur32 = NewLazySystemDLL("secur32.dll") + modsetupapi = NewLazySystemDLL("setupapi.dll") + modshell32 = NewLazySystemDLL("shell32.dll") + moduser32 = NewLazySystemDLL("user32.dll") + moduserenv = NewLazySystemDLL("userenv.dll") + modversion = NewLazySystemDLL("version.dll") + modwinmm = NewLazySystemDLL("winmm.dll") + modwintrust = NewLazySystemDLL("wintrust.dll") + modws2_32 = NewLazySystemDLL("ws2_32.dll") + modwtsapi32 = NewLazySystemDLL("wtsapi32.dll") + + procCM_Get_DevNode_Status = modCfgMgr32.NewProc("CM_Get_DevNode_Status") + procCM_Get_Device_Interface_ListW = modCfgMgr32.NewProc("CM_Get_Device_Interface_ListW") + procCM_Get_Device_Interface_List_SizeW = modCfgMgr32.NewProc("CM_Get_Device_Interface_List_SizeW") + procCM_MapCrToWin32Err = modCfgMgr32.NewProc("CM_MapCrToWin32Err") + procAdjustTokenGroups = modadvapi32.NewProc("AdjustTokenGroups") + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procAllocateAndInitializeSid = modadvapi32.NewProc("AllocateAndInitializeSid") + procBuildSecurityDescriptorW = modadvapi32.NewProc("BuildSecurityDescriptorW") + procChangeServiceConfig2W = modadvapi32.NewProc("ChangeServiceConfig2W") + procChangeServiceConfigW = modadvapi32.NewProc("ChangeServiceConfigW") + procCheckTokenMembership = modadvapi32.NewProc("CheckTokenMembership") + procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle") + procControlService = modadvapi32.NewProc("ControlService") + procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW") + procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") + procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW") + procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW") + procCopySid = modadvapi32.NewProc("CopySid") + procCreateProcessAsUserW = modadvapi32.NewProc("CreateProcessAsUserW") + procCreateServiceW = modadvapi32.NewProc("CreateServiceW") + procCreateWellKnownSid = modadvapi32.NewProc("CreateWellKnownSid") + procCryptAcquireContextW = modadvapi32.NewProc("CryptAcquireContextW") + procCryptGenRandom = modadvapi32.NewProc("CryptGenRandom") + procCryptReleaseContext = modadvapi32.NewProc("CryptReleaseContext") + procDeleteService = modadvapi32.NewProc("DeleteService") + procDeregisterEventSource = modadvapi32.NewProc("DeregisterEventSource") + procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") + procEnumDependentServicesW = modadvapi32.NewProc("EnumDependentServicesW") + procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW") + procEqualSid = modadvapi32.NewProc("EqualSid") + procFreeSid = modadvapi32.NewProc("FreeSid") + procGetAce = modadvapi32.NewProc("GetAce") + procGetLengthSid = modadvapi32.NewProc("GetLengthSid") + procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW") + procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl") + procGetSecurityDescriptorDacl = modadvapi32.NewProc("GetSecurityDescriptorDacl") + procGetSecurityDescriptorGroup = modadvapi32.NewProc("GetSecurityDescriptorGroup") + procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength") + procGetSecurityDescriptorOwner = modadvapi32.NewProc("GetSecurityDescriptorOwner") + procGetSecurityDescriptorRMControl = modadvapi32.NewProc("GetSecurityDescriptorRMControl") + procGetSecurityDescriptorSacl = modadvapi32.NewProc("GetSecurityDescriptorSacl") + procGetSecurityInfo = modadvapi32.NewProc("GetSecurityInfo") + procGetSidIdentifierAuthority = modadvapi32.NewProc("GetSidIdentifierAuthority") + procGetSidSubAuthority = modadvapi32.NewProc("GetSidSubAuthority") + procGetSidSubAuthorityCount = modadvapi32.NewProc("GetSidSubAuthorityCount") + procGetTokenInformation = modadvapi32.NewProc("GetTokenInformation") + procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") + procInitializeSecurityDescriptor = modadvapi32.NewProc("InitializeSecurityDescriptor") + procInitiateSystemShutdownExW = modadvapi32.NewProc("InitiateSystemShutdownExW") + procIsTokenRestricted = modadvapi32.NewProc("IsTokenRestricted") + procIsValidSecurityDescriptor = modadvapi32.NewProc("IsValidSecurityDescriptor") + procIsValidSid = modadvapi32.NewProc("IsValidSid") + procIsWellKnownSid = modadvapi32.NewProc("IsWellKnownSid") + procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") + procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW") + procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") + procMakeAbsoluteSD = modadvapi32.NewProc("MakeAbsoluteSD") + procMakeSelfRelativeSD = modadvapi32.NewProc("MakeSelfRelativeSD") + procNotifyServiceStatusChangeW = modadvapi32.NewProc("NotifyServiceStatusChangeW") + procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken") + procOpenSCManagerW = modadvapi32.NewProc("OpenSCManagerW") + procOpenServiceW = modadvapi32.NewProc("OpenServiceW") + procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") + procQueryServiceConfig2W = modadvapi32.NewProc("QueryServiceConfig2W") + procQueryServiceConfigW = modadvapi32.NewProc("QueryServiceConfigW") + procQueryServiceDynamicInformation = modadvapi32.NewProc("QueryServiceDynamicInformation") + procQueryServiceLockStatusW = modadvapi32.NewProc("QueryServiceLockStatusW") + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procQueryServiceStatusEx = modadvapi32.NewProc("QueryServiceStatusEx") + procRegCloseKey = modadvapi32.NewProc("RegCloseKey") + procRegEnumKeyExW = modadvapi32.NewProc("RegEnumKeyExW") + procRegNotifyChangeKeyValue = modadvapi32.NewProc("RegNotifyChangeKeyValue") + procRegOpenKeyExW = modadvapi32.NewProc("RegOpenKeyExW") + procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW") + procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW") + procRegisterEventSourceW = modadvapi32.NewProc("RegisterEventSourceW") + procRegisterServiceCtrlHandlerExW = modadvapi32.NewProc("RegisterServiceCtrlHandlerExW") + procReportEventW = modadvapi32.NewProc("ReportEventW") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetEntriesInAclW = modadvapi32.NewProc("SetEntriesInAclW") + procSetKernelObjectSecurity = modadvapi32.NewProc("SetKernelObjectSecurity") + procSetNamedSecurityInfoW = modadvapi32.NewProc("SetNamedSecurityInfoW") + procSetSecurityDescriptorControl = modadvapi32.NewProc("SetSecurityDescriptorControl") + procSetSecurityDescriptorDacl = modadvapi32.NewProc("SetSecurityDescriptorDacl") + procSetSecurityDescriptorGroup = modadvapi32.NewProc("SetSecurityDescriptorGroup") + procSetSecurityDescriptorOwner = modadvapi32.NewProc("SetSecurityDescriptorOwner") + procSetSecurityDescriptorRMControl = modadvapi32.NewProc("SetSecurityDescriptorRMControl") + procSetSecurityDescriptorSacl = modadvapi32.NewProc("SetSecurityDescriptorSacl") + procSetSecurityInfo = modadvapi32.NewProc("SetSecurityInfo") + procSetServiceStatus = modadvapi32.NewProc("SetServiceStatus") + procSetThreadToken = modadvapi32.NewProc("SetThreadToken") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") + procStartServiceCtrlDispatcherW = modadvapi32.NewProc("StartServiceCtrlDispatcherW") + procStartServiceW = modadvapi32.NewProc("StartServiceW") + procCertAddCertificateContextToStore = modcrypt32.NewProc("CertAddCertificateContextToStore") + procCertCloseStore = modcrypt32.NewProc("CertCloseStore") + procCertCreateCertificateContext = modcrypt32.NewProc("CertCreateCertificateContext") + procCertDeleteCertificateFromStore = modcrypt32.NewProc("CertDeleteCertificateFromStore") + procCertDuplicateCertificateContext = modcrypt32.NewProc("CertDuplicateCertificateContext") + procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore") + procCertFindCertificateInStore = modcrypt32.NewProc("CertFindCertificateInStore") + procCertFindChainInStore = modcrypt32.NewProc("CertFindChainInStore") + procCertFindExtension = modcrypt32.NewProc("CertFindExtension") + procCertFreeCertificateChain = modcrypt32.NewProc("CertFreeCertificateChain") + procCertFreeCertificateContext = modcrypt32.NewProc("CertFreeCertificateContext") + procCertGetCertificateChain = modcrypt32.NewProc("CertGetCertificateChain") + procCertGetNameStringW = modcrypt32.NewProc("CertGetNameStringW") + procCertOpenStore = modcrypt32.NewProc("CertOpenStore") + procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW") + procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy") + procCryptAcquireCertificatePrivateKey = modcrypt32.NewProc("CryptAcquireCertificatePrivateKey") + procCryptDecodeObject = modcrypt32.NewProc("CryptDecodeObject") + procCryptProtectData = modcrypt32.NewProc("CryptProtectData") + procCryptQueryObject = modcrypt32.NewProc("CryptQueryObject") + procCryptUnprotectData = modcrypt32.NewProc("CryptUnprotectData") + procPFXImportCertStore = modcrypt32.NewProc("PFXImportCertStore") + procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W") + procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W") + procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree") + procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute") + procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") + procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2") + procFreeMibTable = modiphlpapi.NewProc("FreeMibTable") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") + procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx") + procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") + procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex") + procGetIfTable2Ex = modiphlpapi.NewProc("GetIfTable2Ex") + procGetIpForwardEntry2 = modiphlpapi.NewProc("GetIpForwardEntry2") + procGetIpForwardTable2 = modiphlpapi.NewProc("GetIpForwardTable2") + procGetIpInterfaceEntry = modiphlpapi.NewProc("GetIpInterfaceEntry") + procGetIpInterfaceTable = modiphlpapi.NewProc("GetIpInterfaceTable") + procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry") + procGetUnicastIpAddressTable = modiphlpapi.NewProc("GetUnicastIpAddressTable") + procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange") + procNotifyRouteChange2 = modiphlpapi.NewProc("NotifyRouteChange2") + procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange") + procAddDllDirectory = modkernel32.NewProc("AddDllDirectory") + procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") + procCancelIo = modkernel32.NewProc("CancelIo") + procCancelIoEx = modkernel32.NewProc("CancelIoEx") + procClearCommBreak = modkernel32.NewProc("ClearCommBreak") + procClearCommError = modkernel32.NewProc("ClearCommError") + procCloseHandle = modkernel32.NewProc("CloseHandle") + procClosePseudoConsole = modkernel32.NewProc("ClosePseudoConsole") + procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") + procCreateDirectoryW = modkernel32.NewProc("CreateDirectoryW") + procCreateEventExW = modkernel32.NewProc("CreateEventExW") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW") + procCreateFileW = modkernel32.NewProc("CreateFileW") + procCreateHardLinkW = modkernel32.NewProc("CreateHardLinkW") + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") + procCreateJobObjectW = modkernel32.NewProc("CreateJobObjectW") + procCreateMutexExW = modkernel32.NewProc("CreateMutexExW") + procCreateMutexW = modkernel32.NewProc("CreateMutexW") + procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW") + procCreatePipe = modkernel32.NewProc("CreatePipe") + procCreateProcessW = modkernel32.NewProc("CreateProcessW") + procCreatePseudoConsole = modkernel32.NewProc("CreatePseudoConsole") + procCreateSymbolicLinkW = modkernel32.NewProc("CreateSymbolicLinkW") + procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") + procDefineDosDeviceW = modkernel32.NewProc("DefineDosDeviceW") + procDeleteFileW = modkernel32.NewProc("DeleteFileW") + procDeleteProcThreadAttributeList = modkernel32.NewProc("DeleteProcThreadAttributeList") + procDeleteVolumeMountPointW = modkernel32.NewProc("DeleteVolumeMountPointW") + procDeviceIoControl = modkernel32.NewProc("DeviceIoControl") + procDisconnectNamedPipe = modkernel32.NewProc("DisconnectNamedPipe") + procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") + procEscapeCommFunction = modkernel32.NewProc("EscapeCommFunction") + procExitProcess = modkernel32.NewProc("ExitProcess") + procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW") + procFindClose = modkernel32.NewProc("FindClose") + procFindCloseChangeNotification = modkernel32.NewProc("FindCloseChangeNotification") + procFindFirstChangeNotificationW = modkernel32.NewProc("FindFirstChangeNotificationW") + procFindFirstFileW = modkernel32.NewProc("FindFirstFileW") + procFindFirstVolumeMountPointW = modkernel32.NewProc("FindFirstVolumeMountPointW") + procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW") + procFindNextChangeNotification = modkernel32.NewProc("FindNextChangeNotification") + procFindNextFileW = modkernel32.NewProc("FindNextFileW") + procFindNextVolumeMountPointW = modkernel32.NewProc("FindNextVolumeMountPointW") + procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW") + procFindResourceW = modkernel32.NewProc("FindResourceW") + procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") + procFindVolumeMountPointClose = modkernel32.NewProc("FindVolumeMountPointClose") + procFlushConsoleInputBuffer = modkernel32.NewProc("FlushConsoleInputBuffer") + procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers") + procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile") + procFormatMessageW = modkernel32.NewProc("FormatMessageW") + procFreeEnvironmentStringsW = modkernel32.NewProc("FreeEnvironmentStringsW") + procFreeLibrary = modkernel32.NewProc("FreeLibrary") + procGenerateConsoleCtrlEvent = modkernel32.NewProc("GenerateConsoleCtrlEvent") + procGetACP = modkernel32.NewProc("GetACP") + procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount") + procGetCommModemStatus = modkernel32.NewProc("GetCommModemStatus") + procGetCommState = modkernel32.NewProc("GetCommState") + procGetCommTimeouts = modkernel32.NewProc("GetCommTimeouts") + procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") + procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") + procGetComputerNameW = modkernel32.NewProc("GetComputerNameW") + procGetConsoleCP = modkernel32.NewProc("GetConsoleCP") + procGetConsoleMode = modkernel32.NewProc("GetConsoleMode") + procGetConsoleOutputCP = modkernel32.NewProc("GetConsoleOutputCP") + procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") + procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW") + procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") + procGetCurrentThreadId = modkernel32.NewProc("GetCurrentThreadId") + procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW") + procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") + procGetEnvironmentStringsW = modkernel32.NewProc("GetEnvironmentStringsW") + procGetEnvironmentVariableW = modkernel32.NewProc("GetEnvironmentVariableW") + procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") + procGetFileAttributesExW = modkernel32.NewProc("GetFileAttributesExW") + procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW") + procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle") + procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx") + procGetFileTime = modkernel32.NewProc("GetFileTime") + procGetFileType = modkernel32.NewProc("GetFileType") + procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW") + procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW") + procGetLargePageMinimum = modkernel32.NewProc("GetLargePageMinimum") + procGetLastError = modkernel32.NewProc("GetLastError") + procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") + procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives") + procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW") + procGetMaximumProcessorCount = modkernel32.NewProc("GetMaximumProcessorCount") + procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW") + procGetModuleHandleExW = modkernel32.NewProc("GetModuleHandleExW") + procGetNamedPipeClientProcessId = modkernel32.NewProc("GetNamedPipeClientProcessId") + procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") + procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") + procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId") + procGetNumberOfConsoleInputEvents = modkernel32.NewProc("GetNumberOfConsoleInputEvents") + procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") + procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") + procGetProcAddress = modkernel32.NewProc("GetProcAddress") + procGetProcessId = modkernel32.NewProc("GetProcessId") + procGetProcessPreferredUILanguages = modkernel32.NewProc("GetProcessPreferredUILanguages") + procGetProcessShutdownParameters = modkernel32.NewProc("GetProcessShutdownParameters") + procGetProcessTimes = modkernel32.NewProc("GetProcessTimes") + procGetProcessWorkingSetSizeEx = modkernel32.NewProc("GetProcessWorkingSetSizeEx") + procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") + procGetShortPathNameW = modkernel32.NewProc("GetShortPathNameW") + procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW") + procGetStdHandle = modkernel32.NewProc("GetStdHandle") + procGetSystemDirectoryW = modkernel32.NewProc("GetSystemDirectoryW") + procGetSystemPreferredUILanguages = modkernel32.NewProc("GetSystemPreferredUILanguages") + procGetSystemTimeAsFileTime = modkernel32.NewProc("GetSystemTimeAsFileTime") + procGetSystemTimePreciseAsFileTime = modkernel32.NewProc("GetSystemTimePreciseAsFileTime") + procGetSystemWindowsDirectoryW = modkernel32.NewProc("GetSystemWindowsDirectoryW") + procGetTempPathW = modkernel32.NewProc("GetTempPathW") + procGetThreadPreferredUILanguages = modkernel32.NewProc("GetThreadPreferredUILanguages") + procGetTickCount64 = modkernel32.NewProc("GetTickCount64") + procGetTimeZoneInformation = modkernel32.NewProc("GetTimeZoneInformation") + procGetUserPreferredUILanguages = modkernel32.NewProc("GetUserPreferredUILanguages") + procGetVersion = modkernel32.NewProc("GetVersion") + procGetVolumeInformationByHandleW = modkernel32.NewProc("GetVolumeInformationByHandleW") + procGetVolumeInformationW = modkernel32.NewProc("GetVolumeInformationW") + procGetVolumeNameForVolumeMountPointW = modkernel32.NewProc("GetVolumeNameForVolumeMountPointW") + procGetVolumePathNameW = modkernel32.NewProc("GetVolumePathNameW") + procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW") + procGetWindowsDirectoryW = modkernel32.NewProc("GetWindowsDirectoryW") + procInitializeProcThreadAttributeList = modkernel32.NewProc("InitializeProcThreadAttributeList") + procIsProcessorFeaturePresent = modkernel32.NewProc("IsProcessorFeaturePresent") + procIsWow64Process = modkernel32.NewProc("IsWow64Process") + procIsWow64Process2 = modkernel32.NewProc("IsWow64Process2") + procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW") + procLoadLibraryW = modkernel32.NewProc("LoadLibraryW") + procLoadResource = modkernel32.NewProc("LoadResource") + procLocalAlloc = modkernel32.NewProc("LocalAlloc") + procLocalFree = modkernel32.NewProc("LocalFree") + procLockFileEx = modkernel32.NewProc("LockFileEx") + procLockResource = modkernel32.NewProc("LockResource") + procMapViewOfFile = modkernel32.NewProc("MapViewOfFile") + procModule32FirstW = modkernel32.NewProc("Module32FirstW") + procModule32NextW = modkernel32.NewProc("Module32NextW") + procMoveFileExW = modkernel32.NewProc("MoveFileExW") + procMoveFileW = modkernel32.NewProc("MoveFileW") + procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar") + procOpenEventW = modkernel32.NewProc("OpenEventW") + procOpenMutexW = modkernel32.NewProc("OpenMutexW") + procOpenProcess = modkernel32.NewProc("OpenProcess") + procOpenThread = modkernel32.NewProc("OpenThread") + procPostQueuedCompletionStatus = modkernel32.NewProc("PostQueuedCompletionStatus") + procProcess32FirstW = modkernel32.NewProc("Process32FirstW") + procProcess32NextW = modkernel32.NewProc("Process32NextW") + procProcessIdToSessionId = modkernel32.NewProc("ProcessIdToSessionId") + procPulseEvent = modkernel32.NewProc("PulseEvent") + procPurgeComm = modkernel32.NewProc("PurgeComm") + procQueryDosDeviceW = modkernel32.NewProc("QueryDosDeviceW") + procQueryFullProcessImageNameW = modkernel32.NewProc("QueryFullProcessImageNameW") + procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject") + procReadConsoleW = modkernel32.NewProc("ReadConsoleW") + procReadDirectoryChangesW = modkernel32.NewProc("ReadDirectoryChangesW") + procReadFile = modkernel32.NewProc("ReadFile") + procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory") + procReleaseMutex = modkernel32.NewProc("ReleaseMutex") + procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW") + procRemoveDllDirectory = modkernel32.NewProc("RemoveDllDirectory") + procResetEvent = modkernel32.NewProc("ResetEvent") + procResizePseudoConsole = modkernel32.NewProc("ResizePseudoConsole") + procResumeThread = modkernel32.NewProc("ResumeThread") + procSetCommBreak = modkernel32.NewProc("SetCommBreak") + procSetCommMask = modkernel32.NewProc("SetCommMask") + procSetCommState = modkernel32.NewProc("SetCommState") + procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts") + procSetConsoleCP = modkernel32.NewProc("SetConsoleCP") + procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition") + procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") + procSetConsoleOutputCP = modkernel32.NewProc("SetConsoleOutputCP") + procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW") + procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories") + procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW") + procSetEndOfFile = modkernel32.NewProc("SetEndOfFile") + procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW") + procSetErrorMode = modkernel32.NewProc("SetErrorMode") + procSetEvent = modkernel32.NewProc("SetEvent") + procSetFileAttributesW = modkernel32.NewProc("SetFileAttributesW") + procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") + procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle") + procSetFilePointer = modkernel32.NewProc("SetFilePointer") + procSetFileTime = modkernel32.NewProc("SetFileTime") + procSetFileValidData = modkernel32.NewProc("SetFileValidData") + procSetHandleInformation = modkernel32.NewProc("SetHandleInformation") + procSetInformationJobObject = modkernel32.NewProc("SetInformationJobObject") + procSetNamedPipeHandleState = modkernel32.NewProc("SetNamedPipeHandleState") + procSetPriorityClass = modkernel32.NewProc("SetPriorityClass") + procSetProcessPriorityBoost = modkernel32.NewProc("SetProcessPriorityBoost") + procSetProcessShutdownParameters = modkernel32.NewProc("SetProcessShutdownParameters") + procSetProcessWorkingSetSizeEx = modkernel32.NewProc("SetProcessWorkingSetSizeEx") + procSetStdHandle = modkernel32.NewProc("SetStdHandle") + procSetVolumeLabelW = modkernel32.NewProc("SetVolumeLabelW") + procSetVolumeMountPointW = modkernel32.NewProc("SetVolumeMountPointW") + procSetupComm = modkernel32.NewProc("SetupComm") + procSizeofResource = modkernel32.NewProc("SizeofResource") + procSleepEx = modkernel32.NewProc("SleepEx") + procTerminateJobObject = modkernel32.NewProc("TerminateJobObject") + procTerminateProcess = modkernel32.NewProc("TerminateProcess") + procThread32First = modkernel32.NewProc("Thread32First") + procThread32Next = modkernel32.NewProc("Thread32Next") + procUnlockFileEx = modkernel32.NewProc("UnlockFileEx") + procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile") + procUpdateProcThreadAttribute = modkernel32.NewProc("UpdateProcThreadAttribute") + procVirtualAlloc = modkernel32.NewProc("VirtualAlloc") + procVirtualFree = modkernel32.NewProc("VirtualFree") + procVirtualLock = modkernel32.NewProc("VirtualLock") + procVirtualProtect = modkernel32.NewProc("VirtualProtect") + procVirtualProtectEx = modkernel32.NewProc("VirtualProtectEx") + procVirtualQuery = modkernel32.NewProc("VirtualQuery") + procVirtualQueryEx = modkernel32.NewProc("VirtualQueryEx") + procVirtualUnlock = modkernel32.NewProc("VirtualUnlock") + procWTSGetActiveConsoleSessionId = modkernel32.NewProc("WTSGetActiveConsoleSessionId") + procWaitCommEvent = modkernel32.NewProc("WaitCommEvent") + procWaitForMultipleObjects = modkernel32.NewProc("WaitForMultipleObjects") + procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") + procWriteConsoleW = modkernel32.NewProc("WriteConsoleW") + procWriteFile = modkernel32.NewProc("WriteFile") + procWriteProcessMemory = modkernel32.NewProc("WriteProcessMemory") + procAcceptEx = modmswsock.NewProc("AcceptEx") + procGetAcceptExSockaddrs = modmswsock.NewProc("GetAcceptExSockaddrs") + procTransmitFile = modmswsock.NewProc("TransmitFile") + procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree") + procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation") + procNetUserEnum = modnetapi32.NewProc("NetUserEnum") + procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo") + procNtCreateFile = modntdll.NewProc("NtCreateFile") + procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile") + procNtQueryEaFile = modntdll.NewProc("NtQueryEaFile") + procNtQueryInformationFile = modntdll.NewProc("NtQueryInformationFile") + procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess") + procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation") + procNtSetEaFile = modntdll.NewProc("NtSetEaFile") + procNtSetInformationFile = modntdll.NewProc("NtSetInformationFile") + procNtSetInformationProcess = modntdll.NewProc("NtSetInformationProcess") + procNtSetSystemInformation = modntdll.NewProc("NtSetSystemInformation") + procRtlAddFunctionTable = modntdll.NewProc("RtlAddFunctionTable") + procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl") + procRtlDeleteFunctionTable = modntdll.NewProc("RtlDeleteFunctionTable") + procRtlDosPathNameToNtPathName_U_WithStatus = modntdll.NewProc("RtlDosPathNameToNtPathName_U_WithStatus") + procRtlDosPathNameToRelativeNtPathName_U_WithStatus = modntdll.NewProc("RtlDosPathNameToRelativeNtPathName_U_WithStatus") + procRtlGetCurrentPeb = modntdll.NewProc("RtlGetCurrentPeb") + procRtlGetNtVersionNumbers = modntdll.NewProc("RtlGetNtVersionNumbers") + procRtlGetVersion = modntdll.NewProc("RtlGetVersion") + procRtlInitString = modntdll.NewProc("RtlInitString") + procRtlInitUnicodeString = modntdll.NewProc("RtlInitUnicodeString") + procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb") + procCLSIDFromString = modole32.NewProc("CLSIDFromString") + procCoCreateGuid = modole32.NewProc("CoCreateGuid") + procCoGetObject = modole32.NewProc("CoGetObject") + procCoInitializeEx = modole32.NewProc("CoInitializeEx") + procCoTaskMemFree = modole32.NewProc("CoTaskMemFree") + procCoUninitialize = modole32.NewProc("CoUninitialize") + procStringFromGUID2 = modole32.NewProc("StringFromGUID2") + procEnumProcessModules = modpsapi.NewProc("EnumProcessModules") + procEnumProcessModulesEx = modpsapi.NewProc("EnumProcessModulesEx") + procEnumProcesses = modpsapi.NewProc("EnumProcesses") + procGetModuleBaseNameW = modpsapi.NewProc("GetModuleBaseNameW") + procGetModuleFileNameExW = modpsapi.NewProc("GetModuleFileNameExW") + procGetModuleInformation = modpsapi.NewProc("GetModuleInformation") + procQueryWorkingSetEx = modpsapi.NewProc("QueryWorkingSetEx") + procSubscribeServiceChangeNotifications = modsechost.NewProc("SubscribeServiceChangeNotifications") + procUnsubscribeServiceChangeNotifications = modsechost.NewProc("UnsubscribeServiceChangeNotifications") + procGetUserNameExW = modsecur32.NewProc("GetUserNameExW") + procTranslateNameW = modsecur32.NewProc("TranslateNameW") + procSetupDiBuildDriverInfoList = modsetupapi.NewProc("SetupDiBuildDriverInfoList") + procSetupDiCallClassInstaller = modsetupapi.NewProc("SetupDiCallClassInstaller") + procSetupDiCancelDriverInfoSearch = modsetupapi.NewProc("SetupDiCancelDriverInfoSearch") + procSetupDiClassGuidsFromNameExW = modsetupapi.NewProc("SetupDiClassGuidsFromNameExW") + procSetupDiClassNameFromGuidExW = modsetupapi.NewProc("SetupDiClassNameFromGuidExW") + procSetupDiCreateDeviceInfoListExW = modsetupapi.NewProc("SetupDiCreateDeviceInfoListExW") + procSetupDiCreateDeviceInfoW = modsetupapi.NewProc("SetupDiCreateDeviceInfoW") + procSetupDiDestroyDeviceInfoList = modsetupapi.NewProc("SetupDiDestroyDeviceInfoList") + procSetupDiDestroyDriverInfoList = modsetupapi.NewProc("SetupDiDestroyDriverInfoList") + procSetupDiEnumDeviceInfo = modsetupapi.NewProc("SetupDiEnumDeviceInfo") + procSetupDiEnumDriverInfoW = modsetupapi.NewProc("SetupDiEnumDriverInfoW") + procSetupDiGetClassDevsExW = modsetupapi.NewProc("SetupDiGetClassDevsExW") + procSetupDiGetClassInstallParamsW = modsetupapi.NewProc("SetupDiGetClassInstallParamsW") + procSetupDiGetDeviceInfoListDetailW = modsetupapi.NewProc("SetupDiGetDeviceInfoListDetailW") + procSetupDiGetDeviceInstallParamsW = modsetupapi.NewProc("SetupDiGetDeviceInstallParamsW") + procSetupDiGetDeviceInstanceIdW = modsetupapi.NewProc("SetupDiGetDeviceInstanceIdW") + procSetupDiGetDevicePropertyW = modsetupapi.NewProc("SetupDiGetDevicePropertyW") + procSetupDiGetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiGetDeviceRegistryPropertyW") + procSetupDiGetDriverInfoDetailW = modsetupapi.NewProc("SetupDiGetDriverInfoDetailW") + procSetupDiGetSelectedDevice = modsetupapi.NewProc("SetupDiGetSelectedDevice") + procSetupDiGetSelectedDriverW = modsetupapi.NewProc("SetupDiGetSelectedDriverW") + procSetupDiOpenDevRegKey = modsetupapi.NewProc("SetupDiOpenDevRegKey") + procSetupDiSetClassInstallParamsW = modsetupapi.NewProc("SetupDiSetClassInstallParamsW") + procSetupDiSetDeviceInstallParamsW = modsetupapi.NewProc("SetupDiSetDeviceInstallParamsW") + procSetupDiSetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiSetDeviceRegistryPropertyW") + procSetupDiSetSelectedDevice = modsetupapi.NewProc("SetupDiSetSelectedDevice") + procSetupDiSetSelectedDriverW = modsetupapi.NewProc("SetupDiSetSelectedDriverW") + procSetupUninstallOEMInfW = modsetupapi.NewProc("SetupUninstallOEMInfW") + procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW") + procSHGetKnownFolderPath = modshell32.NewProc("SHGetKnownFolderPath") + procShellExecuteW = modshell32.NewProc("ShellExecuteW") + procEnumChildWindows = moduser32.NewProc("EnumChildWindows") + procEnumWindows = moduser32.NewProc("EnumWindows") + procExitWindowsEx = moduser32.NewProc("ExitWindowsEx") + procGetClassNameW = moduser32.NewProc("GetClassNameW") + procGetDesktopWindow = moduser32.NewProc("GetDesktopWindow") + procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow") + procGetGUIThreadInfo = moduser32.NewProc("GetGUIThreadInfo") + procGetKeyboardLayout = moduser32.NewProc("GetKeyboardLayout") + procGetShellWindow = moduser32.NewProc("GetShellWindow") + procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId") + procIsWindow = moduser32.NewProc("IsWindow") + procIsWindowUnicode = moduser32.NewProc("IsWindowUnicode") + procIsWindowVisible = moduser32.NewProc("IsWindowVisible") + procLoadKeyboardLayoutW = moduser32.NewProc("LoadKeyboardLayoutW") + procMessageBoxW = moduser32.NewProc("MessageBoxW") + procToUnicodeEx = moduser32.NewProc("ToUnicodeEx") + procUnloadKeyboardLayout = moduser32.NewProc("UnloadKeyboardLayout") + procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") + procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") + procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") + procGetFileVersionInfoSizeW = modversion.NewProc("GetFileVersionInfoSizeW") + procGetFileVersionInfoW = modversion.NewProc("GetFileVersionInfoW") + procVerQueryValueW = modversion.NewProc("VerQueryValueW") + proctimeBeginPeriod = modwinmm.NewProc("timeBeginPeriod") + proctimeEndPeriod = modwinmm.NewProc("timeEndPeriod") + procWinVerifyTrustEx = modwintrust.NewProc("WinVerifyTrustEx") + procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW") + procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW") + procWSACleanup = modws2_32.NewProc("WSACleanup") + procWSADuplicateSocketW = modws2_32.NewProc("WSADuplicateSocketW") + procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW") + procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult") + procWSAIoctl = modws2_32.NewProc("WSAIoctl") + procWSALookupServiceBeginW = modws2_32.NewProc("WSALookupServiceBeginW") + procWSALookupServiceEnd = modws2_32.NewProc("WSALookupServiceEnd") + procWSALookupServiceNextW = modws2_32.NewProc("WSALookupServiceNextW") + procWSARecv = modws2_32.NewProc("WSARecv") + procWSARecvFrom = modws2_32.NewProc("WSARecvFrom") + procWSASend = modws2_32.NewProc("WSASend") + procWSASendTo = modws2_32.NewProc("WSASendTo") + procWSASocketW = modws2_32.NewProc("WSASocketW") + procWSAStartup = modws2_32.NewProc("WSAStartup") + procbind = modws2_32.NewProc("bind") + procclosesocket = modws2_32.NewProc("closesocket") + procconnect = modws2_32.NewProc("connect") + procgethostbyname = modws2_32.NewProc("gethostbyname") + procgetpeername = modws2_32.NewProc("getpeername") + procgetprotobyname = modws2_32.NewProc("getprotobyname") + procgetservbyname = modws2_32.NewProc("getservbyname") + procgetsockname = modws2_32.NewProc("getsockname") + procgetsockopt = modws2_32.NewProc("getsockopt") + proclisten = modws2_32.NewProc("listen") + procntohs = modws2_32.NewProc("ntohs") + procrecvfrom = modws2_32.NewProc("recvfrom") + procsendto = modws2_32.NewProc("sendto") + procsetsockopt = modws2_32.NewProc("setsockopt") + procshutdown = modws2_32.NewProc("shutdown") + procsocket = modws2_32.NewProc("socket") + procWTSEnumerateSessionsW = modwtsapi32.NewProc("WTSEnumerateSessionsW") + procWTSFreeMemory = modwtsapi32.NewProc("WTSFreeMemory") + procWTSQueryUserToken = modwtsapi32.NewProc("WTSQueryUserToken") +) + +func cm_Get_DevNode_Status(status *uint32, problemNumber *uint32, devInst DEVINST, flags uint32) (ret CONFIGRET) { + r0, _, _ := syscall.SyscallN(procCM_Get_DevNode_Status.Addr(), uintptr(unsafe.Pointer(status)), uintptr(unsafe.Pointer(problemNumber)), uintptr(devInst), uintptr(flags)) + ret = CONFIGRET(r0) + return +} + +func cm_Get_Device_Interface_List(interfaceClass *GUID, deviceID *uint16, buffer *uint16, bufferLen uint32, flags uint32) (ret CONFIGRET) { + r0, _, _ := syscall.SyscallN(procCM_Get_Device_Interface_ListW.Addr(), uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferLen), uintptr(flags)) + ret = CONFIGRET(r0) + return +} + +func cm_Get_Device_Interface_List_Size(len *uint32, interfaceClass *GUID, deviceID *uint16, flags uint32) (ret CONFIGRET) { + r0, _, _ := syscall.SyscallN(procCM_Get_Device_Interface_List_SizeW.Addr(), uintptr(unsafe.Pointer(len)), uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(flags)) + ret = CONFIGRET(r0) + return +} + +func cm_MapCrToWin32Err(configRet CONFIGRET, defaultWin32Error Errno) (ret Errno) { + r0, _, _ := syscall.SyscallN(procCM_MapCrToWin32Err.Addr(), uintptr(configRet), uintptr(defaultWin32Error)) + ret = Errno(r0) + return +} + +func AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) { + var _p0 uint32 + if resetToDefault { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procAdjustTokenGroups.Addr(), uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) { + var _p0 uint32 + if disableAllPrivileges { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procAdjustTokenPrivileges.Addr(), uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) { + r1, _, e1 := syscall.SyscallN(procAllocateAndInitializeSid.Addr(), uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries uint32, accessEntries *EXPLICIT_ACCESS, countAuditEntries uint32, auditEntries *EXPLICIT_ACCESS, oldSecurityDescriptor *SECURITY_DESCRIPTOR, sizeNewSecurityDescriptor *uint32, newSecurityDescriptor **SECURITY_DESCRIPTOR) (ret error) { + r0, _, _ := syscall.SyscallN(procBuildSecurityDescriptorW.Addr(), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(countAccessEntries), uintptr(unsafe.Pointer(accessEntries)), uintptr(countAuditEntries), uintptr(unsafe.Pointer(auditEntries)), uintptr(unsafe.Pointer(oldSecurityDescriptor)), uintptr(unsafe.Pointer(sizeNewSecurityDescriptor)), uintptr(unsafe.Pointer(newSecurityDescriptor))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) { + r1, _, e1 := syscall.SyscallN(procChangeServiceConfig2W.Addr(), uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procChangeServiceConfigW.Addr(), uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) { + r1, _, e1 := syscall.SyscallN(procCheckTokenMembership.Addr(), uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CloseServiceHandle(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procCloseServiceHandle.Addr(), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.SyscallN(procControlService.Addr(), uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR, revision uint32, securityInformation SECURITY_INFORMATION, str **uint16, strLen *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(securityInformation), uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(strLen))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procConvertSidToStringSidW.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(str) + if err != nil { + return + } + return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size) +} + +func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) { + r1, _, e1 := syscall.SyscallN(procConvertStringSidToSidW.Addr(), uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) { + r1, _, e1 := syscall.SyscallN(procCopySid.Addr(), uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) { + var _p0 uint32 + if inheritHandles { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procCreateProcessAsUserW.Addr(), uintptr(token), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateServiceW.Addr(), uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password))) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procCreateWellKnownSid.Addr(), uintptr(sidType), uintptr(unsafe.Pointer(domainSid)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sizeSid))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procCryptAcquireContextW.Addr(), uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) { + r1, _, e1 := syscall.SyscallN(procCryptGenRandom.Addr(), uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CryptReleaseContext(provhandle Handle, flags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procCryptReleaseContext.Addr(), uintptr(provhandle), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func DeleteService(service Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procDeleteService.Addr(), uintptr(service)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func DeregisterEventSource(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procDeregisterEventSource.Addr(), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) { + r1, _, e1 := syscall.SyscallN(procDuplicateTokenEx.Addr(), uintptr(existingToken), uintptr(desiredAccess), uintptr(unsafe.Pointer(tokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(newToken))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func EnumDependentServices(service Handle, activityState uint32, services *ENUM_SERVICE_STATUS, buffSize uint32, bytesNeeded *uint32, servicesReturned *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procEnumDependentServicesW.Addr(), uintptr(service), uintptr(activityState), uintptr(unsafe.Pointer(services)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procEnumServicesStatusExW.Addr(), uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) { + r0, _, _ := syscall.SyscallN(procEqualSid.Addr(), uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2))) + isEqual = r0 != 0 + return +} + +func FreeSid(sid *SID) (err error) { + r1, _, e1 := syscall.SyscallN(procFreeSid.Addr(), uintptr(unsafe.Pointer(sid))) + if r1 != 0 { + err = errnoErr(e1) + } + return +} + +func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) { + r1, _, e1 := syscall.SyscallN(procGetAce.Addr(), uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetLengthSid(sid *SID) (len uint32) { + r0, _, _ := syscall.SyscallN(procGetLengthSid.Addr(), uintptr(unsafe.Pointer(sid))) + len = uint32(r0) + return +} + +func getNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { + var _p0 *uint16 + _p0, ret = syscall.UTF16PtrFromString(objectName) + if ret != nil { + return + } + return _getNamedSecurityInfo(_p0, objectType, securityInformation, owner, group, dacl, sacl, sd) +} + +func _getNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { + r0, _, _ := syscall.SyscallN(procGetNamedSecurityInfoW.Addr(), uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func getSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, control *SECURITY_DESCRIPTOR_CONTROL, revision *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(control)), uintptr(unsafe.Pointer(revision))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func getSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent *bool, dacl **ACL, daclDefaulted *bool) (err error) { + var _p0 uint32 + if *daclPresent { + _p0 = 1 + } + var _p1 uint32 + if *daclDefaulted { + _p1 = 1 + } + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorDacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(&_p1))) + *daclPresent = _p0 != 0 + *daclDefaulted = _p1 != 0 + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefaulted *bool) (err error) { + var _p0 uint32 + if *groupDefaulted { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorGroup.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(&_p0))) + *groupDefaulted = _p0 != 0 + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func getSecurityDescriptorLength(sd *SECURITY_DESCRIPTOR) (len uint32) { + r0, _, _ := syscall.SyscallN(procGetSecurityDescriptorLength.Addr(), uintptr(unsafe.Pointer(sd))) + len = uint32(r0) + return +} + +func getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefaulted *bool) (err error) { + var _p0 uint32 + if *ownerDefaulted { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorOwner.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(&_p0))) + *ownerDefaulted = _p0 != 0 + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func getSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) (ret error) { + r0, _, _ := syscall.SyscallN(procGetSecurityDescriptorRMControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl **ACL, saclDefaulted *bool) (err error) { + var _p0 uint32 + if *saclPresent { + _p0 = 1 + } + var _p1 uint32 + if *saclDefaulted { + _p1 = 1 + } + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorSacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(&_p1))) + *saclPresent = _p0 != 0 + *saclDefaulted = _p1 != 0 + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func getSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { + r0, _, _ := syscall.SyscallN(procGetSecurityInfo.Addr(), uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) { + r0, _, _ := syscall.SyscallN(procGetSidIdentifierAuthority.Addr(), uintptr(unsafe.Pointer(sid))) + authority = (*SidIdentifierAuthority)(unsafe.Pointer(r0)) + return +} + +func getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) { + r0, _, _ := syscall.SyscallN(procGetSidSubAuthority.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(index)) + subAuthority = (*uint32)(unsafe.Pointer(r0)) + return +} + +func getSidSubAuthorityCount(sid *SID) (count *uint8) { + r0, _, _ := syscall.SyscallN(procGetSidSubAuthorityCount.Addr(), uintptr(unsafe.Pointer(sid))) + count = (*uint8)(unsafe.Pointer(r0)) + return +} + +func GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetTokenInformation.Addr(), uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ImpersonateSelf(impersonationlevel uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procImpersonateSelf.Addr(), uintptr(impersonationlevel)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procInitializeSecurityDescriptor.Addr(), uintptr(unsafe.Pointer(absoluteSD)), uintptr(revision)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func InitiateSystemShutdownEx(machineName *uint16, message *uint16, timeout uint32, forceAppsClosed bool, rebootAfterShutdown bool, reason uint32) (err error) { + var _p0 uint32 + if forceAppsClosed { + _p0 = 1 + } + var _p1 uint32 + if rebootAfterShutdown { + _p1 = 1 + } + r1, _, e1 := syscall.SyscallN(procInitiateSystemShutdownExW.Addr(), uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(message)), uintptr(timeout), uintptr(_p0), uintptr(_p1), uintptr(reason)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func isTokenRestricted(tokenHandle Token) (ret bool, err error) { + r0, _, e1 := syscall.SyscallN(procIsTokenRestricted.Addr(), uintptr(tokenHandle)) + ret = r0 != 0 + if !ret { + err = errnoErr(e1) + } + return +} + +func isValidSecurityDescriptor(sd *SECURITY_DESCRIPTOR) (isValid bool) { + r0, _, _ := syscall.SyscallN(procIsValidSecurityDescriptor.Addr(), uintptr(unsafe.Pointer(sd))) + isValid = r0 != 0 + return +} + +func isValidSid(sid *SID) (isValid bool) { + r0, _, _ := syscall.SyscallN(procIsValidSid.Addr(), uintptr(unsafe.Pointer(sid))) + isValid = r0 != 0 + return +} + +func isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) { + r0, _, _ := syscall.SyscallN(procIsWellKnownSid.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(sidType)) + isWellKnown = r0 != 0 + return +} + +func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procLookupAccountNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procLookupAccountSidW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) { + r1, _, e1 := syscall.SyscallN(procLookupPrivilegeValueW.Addr(), uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func makeAbsoluteSD(selfRelativeSD *SECURITY_DESCRIPTOR, absoluteSD *SECURITY_DESCRIPTOR, absoluteSDSize *uint32, dacl *ACL, daclSize *uint32, sacl *ACL, saclSize *uint32, owner *SID, ownerSize *uint32, group *SID, groupSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procMakeAbsoluteSD.Addr(), uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(absoluteSDSize)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(daclSize)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(saclSize)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(ownerSize)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(groupSize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procMakeSelfRelativeSD.Addr(), uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(selfRelativeSDSize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) { + r0, _, _ := syscall.SyscallN(procNotifyServiceStatusChangeW.Addr(), uintptr(service), uintptr(notifyMask), uintptr(unsafe.Pointer(notifier))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func OpenProcessToken(process Handle, access uint32, token *Token) (err error) { + r1, _, e1 := syscall.SyscallN(procOpenProcessToken.Addr(), uintptr(process), uintptr(access), uintptr(unsafe.Pointer(token))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procOpenSCManagerW.Addr(), uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procOpenServiceW.Addr(), uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) { + var _p0 uint32 + if openAsSelf { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procOpenThreadToken.Addr(), uintptr(thread), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procQueryServiceConfig2W.Addr(), uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procQueryServiceConfigW.Addr(), uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func QueryServiceDynamicInformation(service Handle, infoLevel uint32, dynamicInfo unsafe.Pointer) (err error) { + err = procQueryServiceDynamicInformation.Find() + if err != nil { + return + } + r1, _, e1 := syscall.SyscallN(procQueryServiceDynamicInformation.Addr(), uintptr(service), uintptr(infoLevel), uintptr(dynamicInfo)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func QueryServiceLockStatus(mgr Handle, lockStatus *QUERY_SERVICE_LOCK_STATUS, bufSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procQueryServiceLockStatusW.Addr(), uintptr(mgr), uintptr(unsafe.Pointer(lockStatus)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.SyscallN(procQueryServiceStatus.Addr(), uintptr(service), uintptr(unsafe.Pointer(status))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procQueryServiceStatusEx.Addr(), uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func RegCloseKey(key Handle) (regerrno error) { + r0, _, _ := syscall.SyscallN(procRegCloseKey.Addr(), uintptr(key)) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) { + r0, _, _ := syscall.SyscallN(procRegEnumKeyExW.Addr(), uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime))) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, event Handle, asynchronous bool) (regerrno error) { + var _p0 uint32 + if watchSubtree { + _p0 = 1 + } + var _p1 uint32 + if asynchronous { + _p1 = 1 + } + r0, _, _ := syscall.SyscallN(procRegNotifyChangeKeyValue.Addr(), uintptr(key), uintptr(_p0), uintptr(notifyFilter), uintptr(event), uintptr(_p1)) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) { + r0, _, _ := syscall.SyscallN(procRegOpenKeyExW.Addr(), uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result))) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) { + r0, _, _ := syscall.SyscallN(procRegQueryInfoKeyW.Addr(), uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime))) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) { + r0, _, _ := syscall.SyscallN(procRegQueryValueExW.Addr(), uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen))) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procRegisterEventSourceW.Addr(), uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName))) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, context uintptr) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procRegisterServiceCtrlHandlerExW.Addr(), uintptr(unsafe.Pointer(serviceName)), uintptr(handlerProc), uintptr(context)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) { + r1, _, e1 := syscall.SyscallN(procReportEventW.Addr(), uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func RevertToSelf() (err error) { + r1, _, e1 := syscall.SyscallN(procRevertToSelf.Addr()) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) { + r0, _, _ := syscall.SyscallN(procSetEntriesInAclW.Addr(), uintptr(countExplicitEntries), uintptr(unsafe.Pointer(explicitEntries)), uintptr(unsafe.Pointer(oldACL)), uintptr(unsafe.Pointer(newACL))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) { + r1, _, e1 := syscall.SyscallN(procSetKernelObjectSecurity.Addr(), uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { + var _p0 *uint16 + _p0, ret = syscall.UTF16PtrFromString(objectName) + if ret != nil { + return + } + return _SetNamedSecurityInfo(_p0, objectType, securityInformation, owner, group, dacl, sacl) +} + +func _SetNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { + r0, _, _ := syscall.SyscallN(procSetNamedSecurityInfoW.Addr(), uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func setSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) (err error) { + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(controlBitsOfInterest), uintptr(controlBitsToSet)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent bool, dacl *ACL, daclDefaulted bool) (err error) { + var _p0 uint32 + if daclPresent { + _p0 = 1 + } + var _p1 uint32 + if daclDefaulted { + _p1 = 1 + } + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorDacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(dacl)), uintptr(_p1)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group *SID, groupDefaulted bool) (err error) { + var _p0 uint32 + if groupDefaulted { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorGroup.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(_p0)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaulted bool) (err error) { + var _p0 uint32 + if ownerDefaulted { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorOwner.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(_p0)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) { + syscall.SyscallN(procSetSecurityDescriptorRMControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl))) + return +} + +func setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl *ACL, saclDefaulted bool) (err error) { + var _p0 uint32 + if saclPresent { + _p0 = 1 + } + var _p1 uint32 + if saclDefaulted { + _p1 = 1 + } + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorSacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(sacl)), uintptr(_p1)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { + r0, _, _ := syscall.SyscallN(procSetSecurityInfo.Addr(), uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.SyscallN(procSetServiceStatus.Addr(), uintptr(service), uintptr(unsafe.Pointer(serviceStatus))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetThreadToken(thread *Handle, token Token) (err error) { + r1, _, e1 := syscall.SyscallN(procSetThreadToken.Addr(), uintptr(unsafe.Pointer(thread)), uintptr(token)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetTokenInformation.Addr(), uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) { + r1, _, e1 := syscall.SyscallN(procStartServiceCtrlDispatcherW.Addr(), uintptr(unsafe.Pointer(serviceTable))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procStartServiceW.Addr(), uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) { + r1, _, e1 := syscall.SyscallN(procCertAddCertificateContextToStore.Addr(), uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CertCloseStore(store Handle, flags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procCertCloseStore.Addr(), uintptr(store), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) { + r0, _, e1 := syscall.SyscallN(procCertCreateCertificateContext.Addr(), uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen)) + context = (*CertContext)(unsafe.Pointer(r0)) + if context == nil { + err = errnoErr(e1) + } + return +} + +func CertDeleteCertificateFromStore(certContext *CertContext) (err error) { + r1, _, e1 := syscall.SyscallN(procCertDeleteCertificateFromStore.Addr(), uintptr(unsafe.Pointer(certContext))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CertDuplicateCertificateContext(certContext *CertContext) (dupContext *CertContext) { + r0, _, _ := syscall.SyscallN(procCertDuplicateCertificateContext.Addr(), uintptr(unsafe.Pointer(certContext))) + dupContext = (*CertContext)(unsafe.Pointer(r0)) + return +} + +func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) { + r0, _, e1 := syscall.SyscallN(procCertEnumCertificatesInStore.Addr(), uintptr(store), uintptr(unsafe.Pointer(prevContext))) + context = (*CertContext)(unsafe.Pointer(r0)) + if context == nil { + err = errnoErr(e1) + } + return +} + +func CertFindCertificateInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevCertContext *CertContext) (cert *CertContext, err error) { + r0, _, e1 := syscall.SyscallN(procCertFindCertificateInStore.Addr(), uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevCertContext))) + cert = (*CertContext)(unsafe.Pointer(r0)) + if cert == nil { + err = errnoErr(e1) + } + return +} + +func CertFindChainInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevChainContext *CertChainContext) (certchain *CertChainContext, err error) { + r0, _, e1 := syscall.SyscallN(procCertFindChainInStore.Addr(), uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevChainContext))) + certchain = (*CertChainContext)(unsafe.Pointer(r0)) + if certchain == nil { + err = errnoErr(e1) + } + return +} + +func CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) { + r0, _, _ := syscall.SyscallN(procCertFindExtension.Addr(), uintptr(unsafe.Pointer(objId)), uintptr(countExtensions), uintptr(unsafe.Pointer(extensions))) + ret = (*CertExtension)(unsafe.Pointer(r0)) + return +} + +func CertFreeCertificateChain(ctx *CertChainContext) { + syscall.SyscallN(procCertFreeCertificateChain.Addr(), uintptr(unsafe.Pointer(ctx))) + return +} + +func CertFreeCertificateContext(ctx *CertContext) (err error) { + r1, _, e1 := syscall.SyscallN(procCertFreeCertificateContext.Addr(), uintptr(unsafe.Pointer(ctx))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) { + r1, _, e1 := syscall.SyscallN(procCertGetCertificateChain.Addr(), uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CertGetNameString(certContext *CertContext, nameType uint32, flags uint32, typePara unsafe.Pointer, name *uint16, size uint32) (chars uint32) { + r0, _, _ := syscall.SyscallN(procCertGetNameStringW.Addr(), uintptr(unsafe.Pointer(certContext)), uintptr(nameType), uintptr(flags), uintptr(typePara), uintptr(unsafe.Pointer(name)), uintptr(size)) + chars = uint32(r0) + return +} + +func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCertOpenStore.Addr(), uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCertOpenSystemStoreW.Addr(), uintptr(hprov), uintptr(unsafe.Pointer(name))) + store = Handle(r0) + if store == 0 { + err = errnoErr(e1) + } + return +} + +func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) { + r1, _, e1 := syscall.SyscallN(procCertVerifyCertificateChainPolicy.Addr(), uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CryptAcquireCertificatePrivateKey(cert *CertContext, flags uint32, parameters unsafe.Pointer, cryptProvOrNCryptKey *Handle, keySpec *uint32, callerFreeProvOrNCryptKey *bool) (err error) { + var _p0 uint32 + if *callerFreeProvOrNCryptKey { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procCryptAcquireCertificatePrivateKey.Addr(), uintptr(unsafe.Pointer(cert)), uintptr(flags), uintptr(parameters), uintptr(unsafe.Pointer(cryptProvOrNCryptKey)), uintptr(unsafe.Pointer(keySpec)), uintptr(unsafe.Pointer(&_p0))) + *callerFreeProvOrNCryptKey = _p0 != 0 + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte, lenEncodedBytes uint32, flags uint32, decoded unsafe.Pointer, decodedLen *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procCryptDecodeObject.Addr(), uintptr(encodingType), uintptr(unsafe.Pointer(structType)), uintptr(unsafe.Pointer(encodedBytes)), uintptr(lenEncodedBytes), uintptr(flags), uintptr(decoded), uintptr(unsafe.Pointer(decodedLen))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) { + r1, _, e1 := syscall.SyscallN(procCryptProtectData.Addr(), uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) { + r1, _, e1 := syscall.SyscallN(procCryptQueryObject.Addr(), uintptr(objectType), uintptr(object), uintptr(expectedContentTypeFlags), uintptr(expectedFormatTypeFlags), uintptr(flags), uintptr(unsafe.Pointer(msgAndCertEncodingType)), uintptr(unsafe.Pointer(contentType)), uintptr(unsafe.Pointer(formatType)), uintptr(unsafe.Pointer(certStore)), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(context))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) { + r1, _, e1 := syscall.SyscallN(procCryptUnprotectData.Addr(), uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) { + r0, _, e1 := syscall.SyscallN(procPFXImportCertStore.Addr(), uintptr(unsafe.Pointer(pfx)), uintptr(unsafe.Pointer(password)), uintptr(flags)) + store = Handle(r0) + if store == 0 { + err = errnoErr(e1) + } + return +} + +func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) { + r0, _, _ := syscall.SyscallN(procDnsNameCompare_W.Addr(), uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2))) + same = r0 != 0 + return +} + +func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { + var _p0 *uint16 + _p0, status = syscall.UTF16PtrFromString(name) + if status != nil { + return + } + return _DnsQuery(_p0, qtype, options, extra, qrs, pr) +} + +func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { + r0, _, _ := syscall.SyscallN(procDnsQuery_W.Addr(), uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr))) + if r0 != 0 { + status = syscall.Errno(r0) + } + return +} + +func DnsRecordListFree(rl *DNSRecord, freetype uint32) { + syscall.SyscallN(procDnsRecordListFree.Addr(), uintptr(unsafe.Pointer(rl)), uintptr(freetype)) + return +} + +func DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) { + r0, _, _ := syscall.SyscallN(procDwmGetWindowAttribute.Addr(), uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size)) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) { + r0, _, _ := syscall.SyscallN(procDwmSetWindowAttribute.Addr(), uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size)) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) { + r0, _, _ := syscall.SyscallN(procCancelMibChangeNotify2.Addr(), uintptr(notificationHandle)) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func FreeMibTable(memory unsafe.Pointer) { + syscall.SyscallN(procFreeMibTable.Addr(), uintptr(memory)) + return +} + +func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetAdaptersAddresses.Addr(), uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetAdaptersInfo.Addr(), uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetBestInterfaceEx.Addr(), uintptr(sockaddr), uintptr(unsafe.Pointer(pdwBestIfIndex))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIfEntry(pIfRow *MibIfRow) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIfEntry.Addr(), uintptr(unsafe.Pointer(pIfRow))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIfEntry2Ex.Addr(), uintptr(level), uintptr(unsafe.Pointer(row))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIfTable2Ex(level uint32, table **MibIfTable2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIfTable2Ex.Addr(), uintptr(level), uintptr(unsafe.Pointer(table))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpForwardEntry2.Addr(), uintptr(unsafe.Pointer(row))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpForwardTable2.Addr(), uintptr(family), uintptr(unsafe.Pointer(table))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIpInterfaceEntry(row *MibIpInterfaceRow) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpInterfaceEntry.Addr(), uintptr(unsafe.Pointer(row))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIpInterfaceTable(family uint16, table **MibIpInterfaceTable) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpInterfaceTable.Addr(), uintptr(family), uintptr(unsafe.Pointer(table))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetUnicastIpAddressEntry.Addr(), uintptr(unsafe.Pointer(row))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetUnicastIpAddressTable(family uint16, table **MibUnicastIpAddressTable) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetUnicastIpAddressTable.Addr(), uintptr(family), uintptr(unsafe.Pointer(table))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { + var _p0 uint32 + if initialNotification { + _p0 = 1 + } + r0, _, _ := syscall.SyscallN(procNotifyIpInterfaceChange.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { + var _p0 uint32 + if initialNotification { + _p0 = 1 + } + r0, _, _ := syscall.SyscallN(procNotifyRouteChange2.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { + var _p0 uint32 + if initialNotification { + _p0 = 1 + } + r0, _, _ := syscall.SyscallN(procNotifyUnicastIpAddressChange.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func AddDllDirectory(path *uint16) (cookie uintptr, err error) { + r0, _, e1 := syscall.SyscallN(procAddDllDirectory.Addr(), uintptr(unsafe.Pointer(path))) + cookie = uintptr(r0) + if cookie == 0 { + err = errnoErr(e1) + } + return +} + +func AssignProcessToJobObject(job Handle, process Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procAssignProcessToJobObject.Addr(), uintptr(job), uintptr(process)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CancelIo(s Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procCancelIo.Addr(), uintptr(s)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CancelIoEx(s Handle, o *Overlapped) (err error) { + r1, _, e1 := syscall.SyscallN(procCancelIoEx.Addr(), uintptr(s), uintptr(unsafe.Pointer(o))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ClearCommBreak(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procClearCommBreak.Addr(), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error) { + r1, _, e1 := syscall.SyscallN(procClearCommError.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpErrors)), uintptr(unsafe.Pointer(lpStat))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CloseHandle(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procCloseHandle.Addr(), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ClosePseudoConsole(console Handle) { + syscall.SyscallN(procClosePseudoConsole.Addr(), uintptr(console)) + return +} + +func ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.SyscallN(procConnectNamedPipe.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(overlapped))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) { + r1, _, e1 := syscall.SyscallN(procCreateDirectoryW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateEventExW.Addr(), uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess)) + handle = Handle(r0) + if handle == 0 || e1 == ERROR_ALREADY_EXISTS { + err = errnoErr(e1) + } + return +} + +func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateEventW.Addr(), uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 || e1 == ERROR_ALREADY_EXISTS { + err = errnoErr(e1) + } + return +} + +func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateFileMappingW.Addr(), uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 || e1 == ERROR_ALREADY_EXISTS { + err = errnoErr(e1) + } + return +} + +func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateFileW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile)) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) + } + return +} + +func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procCreateHardLinkW.Addr(), uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved)) + if r1&0xff == 0 { + err = errnoErr(e1) + } + return +} + +func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uintptr, threadcnt uint32) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateIoCompletionPort.Addr(), uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func CreateJobObject(jobAttr *SecurityAttributes, name *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateJobObjectW.Addr(), uintptr(unsafe.Pointer(jobAttr)), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func CreateMutexEx(mutexAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateMutexExW.Addr(), uintptr(unsafe.Pointer(mutexAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess)) + handle = Handle(r0) + if handle == 0 || e1 == ERROR_ALREADY_EXISTS { + err = errnoErr(e1) + } + return +} + +func CreateMutex(mutexAttrs *SecurityAttributes, initialOwner bool, name *uint16) (handle Handle, err error) { + var _p0 uint32 + if initialOwner { + _p0 = 1 + } + r0, _, e1 := syscall.SyscallN(procCreateMutexW.Addr(), uintptr(unsafe.Pointer(mutexAttrs)), uintptr(_p0), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 || e1 == ERROR_ALREADY_EXISTS { + err = errnoErr(e1) + } + return +} + +func CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateNamedPipeW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa))) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) + } + return +} + +func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procCreatePipe.Addr(), uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) { + var _p0 uint32 + if inheritHandles { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procCreateProcessW.Addr(), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pconsole *Handle) (hr error) { + r0, _, _ := syscall.SyscallN(procCreatePseudoConsole.Addr(), uintptr(size), uintptr(in), uintptr(out), uintptr(flags), uintptr(unsafe.Pointer(pconsole))) + if r0 != 0 { + hr = syscall.Errno(r0) + } + return +} + +func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procCreateSymbolicLinkW.Addr(), uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags)) + if r1&0xff == 0 { + err = errnoErr(e1) + } + return +} + +func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateToolhelp32Snapshot.Addr(), uintptr(flags), uintptr(processId)) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) + } + return +} + +func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procDefineDosDeviceW.Addr(), uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func DeleteFile(path *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procDeleteFileW.Addr(), uintptr(unsafe.Pointer(path))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func deleteProcThreadAttributeList(attrlist *ProcThreadAttributeList) { + syscall.SyscallN(procDeleteProcThreadAttributeList.Addr(), uintptr(unsafe.Pointer(attrlist))) + return +} + +func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procDeleteVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(volumeMountPoint))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.SyscallN(procDeviceIoControl.Addr(), uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func DisconnectNamedPipe(pipe Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procDisconnectNamedPipe.Addr(), uintptr(pipe)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) { + var _p0 uint32 + if bInheritHandle { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procDuplicateHandle.Addr(), uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func EscapeCommFunction(handle Handle, dwFunc uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procEscapeCommFunction.Addr(), uintptr(handle), uintptr(dwFunc)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ExitProcess(exitcode uint32) { + syscall.SyscallN(procExitProcess.Addr(), uintptr(exitcode)) + return +} + +func ExpandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procExpandEnvironmentStringsW.Addr(), uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func FindClose(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFindClose.Addr(), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FindCloseChangeNotification(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFindCloseChangeNotification.Addr(), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FindFirstChangeNotification(path string, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(path) + if err != nil { + return + } + return _FindFirstChangeNotification(_p0, watchSubtree, notifyFilter) +} + +func _FindFirstChangeNotification(path *uint16, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) { + var _p1 uint32 + if watchSubtree { + _p1 = 1 + } + r0, _, e1 := syscall.SyscallN(procFindFirstChangeNotificationW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(_p1), uintptr(notifyFilter)) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) + } + return +} + +func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procFindFirstFileW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data))) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) + } + return +} + +func FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procFindFirstVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) + } + return +} + +func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procFindFirstVolumeW.Addr(), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) + } + return +} + +func FindNextChangeNotification(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFindNextChangeNotification.Addr(), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func findNextFile1(handle Handle, data *win32finddata1) (err error) { + r1, _, e1 := syscall.SyscallN(procFindNextFileW.Addr(), uintptr(handle), uintptr(unsafe.Pointer(data))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procFindNextVolumeMountPointW.Addr(), uintptr(findVolumeMountPoint), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procFindNextVolumeW.Addr(), uintptr(findVolume), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func findResource(module Handle, name uintptr, resType uintptr) (resInfo Handle, err error) { + r0, _, e1 := syscall.SyscallN(procFindResourceW.Addr(), uintptr(module), uintptr(name), uintptr(resType)) + resInfo = Handle(r0) + if resInfo == 0 { + err = errnoErr(e1) + } + return +} + +func FindVolumeClose(findVolume Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFindVolumeClose.Addr(), uintptr(findVolume)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFindVolumeMountPointClose.Addr(), uintptr(findVolumeMountPoint)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FlushConsoleInputBuffer(console Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFlushConsoleInputBuffer.Addr(), uintptr(console)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FlushFileBuffers(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFlushFileBuffers.Addr(), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FlushViewOfFile(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procFlushViewOfFile.Addr(), uintptr(addr), uintptr(length)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) { + var _p0 *uint16 + if len(buf) > 0 { + _p0 = &buf[0] + } + r0, _, e1 := syscall.SyscallN(procFormatMessageW.Addr(), uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args))) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func FreeEnvironmentStrings(envs *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procFreeEnvironmentStringsW.Addr(), uintptr(unsafe.Pointer(envs))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FreeLibrary(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFreeLibrary.Addr(), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGenerateConsoleCtrlEvent.Addr(), uintptr(ctrlEvent), uintptr(processGroupID)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetACP() (acp uint32) { + r0, _, _ := syscall.SyscallN(procGetACP.Addr()) + acp = uint32(r0) + return +} + +func GetActiveProcessorCount(groupNumber uint16) (ret uint32) { + r0, _, _ := syscall.SyscallN(procGetActiveProcessorCount.Addr(), uintptr(groupNumber)) + ret = uint32(r0) + return +} + +func GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetCommModemStatus.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpModemStat))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetCommState(handle Handle, lpDCB *DCB) (err error) { + r1, _, e1 := syscall.SyscallN(procGetCommState.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpDCB))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { + r1, _, e1 := syscall.SyscallN(procGetCommTimeouts.Addr(), uintptr(handle), uintptr(unsafe.Pointer(timeouts))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetCommandLine() (cmd *uint16) { + r0, _, _ := syscall.SyscallN(procGetCommandLineW.Addr()) + cmd = (*uint16)(unsafe.Pointer(r0)) + return +} + +func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetComputerNameExW.Addr(), uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetComputerName(buf *uint16, n *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetComputerNameW.Addr(), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetConsoleCP() (cp uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetConsoleCP.Addr()) + cp = uint32(r0) + if cp == 0 { + err = errnoErr(e1) + } + return +} + +func GetConsoleMode(console Handle, mode *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetConsoleMode.Addr(), uintptr(console), uintptr(unsafe.Pointer(mode))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetConsoleOutputCP() (cp uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetConsoleOutputCP.Addr()) + cp = uint32(r0) + if cp == 0 { + err = errnoErr(e1) + } + return +} + +func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { + r1, _, e1 := syscall.SyscallN(procGetConsoleScreenBufferInfo.Addr(), uintptr(console), uintptr(unsafe.Pointer(info))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetCurrentDirectoryW.Addr(), uintptr(buflen), uintptr(unsafe.Pointer(buf))) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func GetCurrentProcessId() (pid uint32) { + r0, _, _ := syscall.SyscallN(procGetCurrentProcessId.Addr()) + pid = uint32(r0) + return +} + +func GetCurrentThreadId() (id uint32) { + r0, _, _ := syscall.SyscallN(procGetCurrentThreadId.Addr()) + id = uint32(r0) + return +} + +func GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { + r1, _, e1 := syscall.SyscallN(procGetDiskFreeSpaceExW.Addr(), uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailableToCaller)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetDriveType(rootPathName *uint16) (driveType uint32) { + r0, _, _ := syscall.SyscallN(procGetDriveTypeW.Addr(), uintptr(unsafe.Pointer(rootPathName))) + driveType = uint32(r0) + return +} + +func GetEnvironmentStrings() (envs *uint16, err error) { + r0, _, e1 := syscall.SyscallN(procGetEnvironmentStringsW.Addr()) + envs = (*uint16)(unsafe.Pointer(r0)) + if envs == nil { + err = errnoErr(e1) + } + return +} + +func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetEnvironmentVariableW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetExitCodeProcess.Addr(), uintptr(handle), uintptr(unsafe.Pointer(exitcode))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) { + r1, _, e1 := syscall.SyscallN(procGetFileAttributesExW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetFileAttributes(name *uint16) (attrs uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetFileAttributesW.Addr(), uintptr(unsafe.Pointer(name))) + attrs = uint32(r0) + if attrs == INVALID_FILE_ATTRIBUTES { + err = errnoErr(e1) + } + return +} + +func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) { + r1, _, e1 := syscall.SyscallN(procGetFileInformationByHandle.Addr(), uintptr(handle), uintptr(unsafe.Pointer(data))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte, outBufferLen uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetFileInformationByHandleEx.Addr(), uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferLen)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { + r1, _, e1 := syscall.SyscallN(procGetFileTime.Addr(), uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetFileType(filehandle Handle) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetFileType.Addr(), uintptr(filehandle)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func GetFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetFinalPathNameByHandleW.Addr(), uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetFullPathNameW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname))) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func GetLargePageMinimum() (size uintptr) { + r0, _, _ := syscall.SyscallN(procGetLargePageMinimum.Addr()) + size = uintptr(r0) + return +} + +func GetLastError() (lasterr error) { + r0, _, _ := syscall.SyscallN(procGetLastError.Addr()) + if r0 != 0 { + lasterr = syscall.Errno(r0) + } + return +} + +func GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetLogicalDriveStringsW.Addr(), uintptr(bufferLength), uintptr(unsafe.Pointer(buffer))) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func GetLogicalDrives() (drivesBitMask uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetLogicalDrives.Addr()) + drivesBitMask = uint32(r0) + if drivesBitMask == 0 { + err = errnoErr(e1) + } + return +} + +func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetLongPathNameW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func GetMaximumProcessorCount(groupNumber uint16) (ret uint32) { + r0, _, _ := syscall.SyscallN(procGetMaximumProcessorCount.Addr(), uintptr(groupNumber)) + ret = uint32(r0) + return +} + +func GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetModuleFileNameW.Addr(), uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procGetModuleHandleExW.Addr(), uintptr(flags), uintptr(unsafe.Pointer(moduleName)), uintptr(unsafe.Pointer(module))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetNamedPipeClientProcessId.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(clientProcessID))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetNamedPipeHandleStateW.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetNamedPipeInfo.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetNamedPipeServerProcessId.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(serverProcessID))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetNumberOfConsoleInputEvents.Addr(), uintptr(console), uintptr(unsafe.Pointer(numevents))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) { + var _p0 uint32 + if wait { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procGetOverlappedResult.Addr(), uintptr(handle), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(done)), uintptr(_p0)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetPriorityClass(process Handle) (ret uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetPriorityClass.Addr(), uintptr(process)) + ret = uint32(r0) + if ret == 0 { + err = errnoErr(e1) + } + return +} + +func GetProcAddress(module Handle, procname string) (proc uintptr, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(procname) + if err != nil { + return + } + return _GetProcAddress(module, _p0) +} + +func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) { + r0, _, e1 := syscall.SyscallN(procGetProcAddress.Addr(), uintptr(module), uintptr(unsafe.Pointer(procname))) + proc = uintptr(r0) + if proc == 0 { + err = errnoErr(e1) + } + return +} + +func GetProcessId(process Handle) (id uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetProcessId.Addr(), uintptr(process)) + id = uint32(r0) + if id == 0 { + err = errnoErr(e1) + } + return +} + +func getProcessPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetProcessPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetProcessShutdownParameters(level *uint32, flags *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetProcessShutdownParameters.Addr(), uintptr(unsafe.Pointer(level)), uintptr(unsafe.Pointer(flags))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) { + r1, _, e1 := syscall.SyscallN(procGetProcessTimes.Addr(), uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32) { + syscall.SyscallN(procGetProcessWorkingSetSizeEx.Addr(), uintptr(hProcess), uintptr(unsafe.Pointer(lpMinimumWorkingSetSize)), uintptr(unsafe.Pointer(lpMaximumWorkingSetSize)), uintptr(unsafe.Pointer(flags))) + return +} + +func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uintptr, overlapped **Overlapped, timeout uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetQueuedCompletionStatus.Addr(), uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetShortPathNameW.Addr(), uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func getStartupInfo(startupInfo *StartupInfo) { + syscall.SyscallN(procGetStartupInfoW.Addr(), uintptr(unsafe.Pointer(startupInfo))) + return +} + +func GetStdHandle(stdhandle uint32) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procGetStdHandle.Addr(), uintptr(stdhandle)) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) + } + return +} + +func getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetSystemDirectoryW.Addr(), uintptr(unsafe.Pointer(dir)), uintptr(dirLen)) + len = uint32(r0) + if len == 0 { + err = errnoErr(e1) + } + return +} + +func getSystemPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetSystemPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetSystemTimeAsFileTime(time *Filetime) { + syscall.SyscallN(procGetSystemTimeAsFileTime.Addr(), uintptr(unsafe.Pointer(time))) + return +} + +func GetSystemTimePreciseAsFileTime(time *Filetime) { + syscall.SyscallN(procGetSystemTimePreciseAsFileTime.Addr(), uintptr(unsafe.Pointer(time))) + return +} + +func getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetSystemWindowsDirectoryW.Addr(), uintptr(unsafe.Pointer(dir)), uintptr(dirLen)) + len = uint32(r0) + if len == 0 { + err = errnoErr(e1) + } + return +} + +func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetTempPathW.Addr(), uintptr(buflen), uintptr(unsafe.Pointer(buf))) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func getThreadPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetThreadPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func getTickCount64() (ms uint64) { + r0, _, _ := syscall.SyscallN(procGetTickCount64.Addr()) + ms = uint64(r0) + return +} + +func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetTimeZoneInformation.Addr(), uintptr(unsafe.Pointer(tzi))) + rc = uint32(r0) + if rc == 0xffffffff { + err = errnoErr(e1) + } + return +} + +func getUserPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetUserPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetVersion() (ver uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetVersion.Addr()) + ver = uint32(r0) + if ver == 0 { + err = errnoErr(e1) + } + return +} + +func GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetVolumeInformationByHandleW.Addr(), uintptr(file), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetVolumeInformationW.Addr(), uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetVolumeNameForVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferlength)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetVolumePathNameW.Addr(), uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(volumePathName)), uintptr(bufferLength)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetVolumePathNamesForVolumeNameW.Addr(), uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(volumePathNames)), uintptr(bufferLength), uintptr(unsafe.Pointer(returnLength))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetWindowsDirectoryW.Addr(), uintptr(unsafe.Pointer(dir)), uintptr(dirLen)) + len = uint32(r0) + if len == 0 { + err = errnoErr(e1) + } + return +} + +func initializeProcThreadAttributeList(attrlist *ProcThreadAttributeList, attrcount uint32, flags uint32, size *uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procInitializeProcThreadAttributeList.Addr(), uintptr(unsafe.Pointer(attrlist)), uintptr(attrcount), uintptr(flags), uintptr(unsafe.Pointer(size))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func IsProcessorFeaturePresent(ProcessorFeature uint32) (ret bool) { + r0, _, _ := syscall.SyscallN(procIsProcessorFeaturePresent.Addr(), uintptr(ProcessorFeature)) + ret = r0 != 0 + return +} + +func IsWow64Process(handle Handle, isWow64 *bool) (err error) { + var _p0 uint32 + if *isWow64 { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procIsWow64Process.Addr(), uintptr(handle), uintptr(unsafe.Pointer(&_p0))) + *isWow64 = _p0 != 0 + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func IsWow64Process2(handle Handle, processMachine *uint16, nativeMachine *uint16) (err error) { + err = procIsWow64Process2.Find() + if err != nil { + return + } + r1, _, e1 := syscall.SyscallN(procIsWow64Process2.Addr(), uintptr(handle), uintptr(unsafe.Pointer(processMachine)), uintptr(unsafe.Pointer(nativeMachine))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(libname) + if err != nil { + return + } + return _LoadLibraryEx(_p0, zero, flags) +} + +func _LoadLibraryEx(libname *uint16, zero Handle, flags uintptr) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procLoadLibraryExW.Addr(), uintptr(unsafe.Pointer(libname)), uintptr(zero), uintptr(flags)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func LoadLibrary(libname string) (handle Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(libname) + if err != nil { + return + } + return _LoadLibrary(_p0) +} + +func _LoadLibrary(libname *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procLoadLibraryW.Addr(), uintptr(unsafe.Pointer(libname))) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func LoadResource(module Handle, resInfo Handle) (resData Handle, err error) { + r0, _, e1 := syscall.SyscallN(procLoadResource.Addr(), uintptr(module), uintptr(resInfo)) + resData = Handle(r0) + if resData == 0 { + err = errnoErr(e1) + } + return +} + +func LocalAlloc(flags uint32, length uint32) (ptr uintptr, err error) { + r0, _, e1 := syscall.SyscallN(procLocalAlloc.Addr(), uintptr(flags), uintptr(length)) + ptr = uintptr(r0) + if ptr == 0 { + err = errnoErr(e1) + } + return +} + +func LocalFree(hmem Handle) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procLocalFree.Addr(), uintptr(hmem)) + handle = Handle(r0) + if handle != 0 { + err = errnoErr(e1) + } + return +} + +func LockFileEx(file Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.SyscallN(procLockFileEx.Addr(), uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func LockResource(resData Handle) (addr uintptr, err error) { + r0, _, e1 := syscall.SyscallN(procLockResource.Addr(), uintptr(resData)) + addr = uintptr(r0) + if addr == 0 { + err = errnoErr(e1) + } + return +} + +func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) { + r0, _, e1 := syscall.SyscallN(procMapViewOfFile.Addr(), uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length)) + addr = uintptr(r0) + if addr == 0 { + err = errnoErr(e1) + } + return +} + +func Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) { + r1, _, e1 := syscall.SyscallN(procModule32FirstW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func Module32Next(snapshot Handle, moduleEntry *ModuleEntry32) (err error) { + r1, _, e1 := syscall.SyscallN(procModule32NextW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procMoveFileExW.Addr(), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func MoveFile(from *uint16, to *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procMoveFileW.Addr(), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { + r0, _, e1 := syscall.SyscallN(procMultiByteToWideChar.Addr(), uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) + nwrite = int32(r0) + if nwrite == 0 { + err = errnoErr(e1) + } + return +} + +func OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } + r0, _, e1 := syscall.SyscallN(procOpenEventW.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func OpenMutex(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } + r0, _, e1 := syscall.SyscallN(procOpenMutexW.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } + r0, _, e1 := syscall.SyscallN(procOpenProcess.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(processId)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } + r0, _, e1 := syscall.SyscallN(procOpenThread.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(threadId)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + +func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uintptr, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.SyscallN(procPostQueuedCompletionStatus.Addr(), uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) { + r1, _, e1 := syscall.SyscallN(procProcess32FirstW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(procEntry))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) { + r1, _, e1 := syscall.SyscallN(procProcess32NextW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(procEntry))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procProcessIdToSessionId.Addr(), uintptr(pid), uintptr(unsafe.Pointer(sessionid))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func PulseEvent(event Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procPulseEvent.Addr(), uintptr(event)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func PurgeComm(handle Handle, dwFlags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procPurgeComm.Addr(), uintptr(handle), uintptr(dwFlags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) { + r0, _, e1 := syscall.SyscallN(procQueryDosDeviceW.Addr(), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } + return +} + +func QueryFullProcessImageName(proc Handle, flags uint32, exeName *uint16, size *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procQueryFullProcessImageNameW.Addr(), uintptr(proc), uintptr(flags), uintptr(unsafe.Pointer(exeName)), uintptr(unsafe.Pointer(size))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procQueryInformationJobObject.Addr(), uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), uintptr(unsafe.Pointer(retlen))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) { + r1, _, e1 := syscall.SyscallN(procReadConsoleW.Addr(), uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { + var _p0 uint32 + if watchSubTree { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procReadDirectoryChangesW.Addr(), uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } + r1, _, e1 := syscall.SyscallN(procReadFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ReadProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesRead *uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procReadProcessMemory.Addr(), uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesRead))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ReleaseMutex(mutex Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procReleaseMutex.Addr(), uintptr(mutex)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func RemoveDirectory(path *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procRemoveDirectoryW.Addr(), uintptr(unsafe.Pointer(path))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func RemoveDllDirectory(cookie uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procRemoveDllDirectory.Addr(), uintptr(cookie)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ResetEvent(event Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procResetEvent.Addr(), uintptr(event)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func resizePseudoConsole(pconsole Handle, size uint32) (hr error) { + r0, _, _ := syscall.SyscallN(procResizePseudoConsole.Addr(), uintptr(pconsole), uintptr(size)) + if r0 != 0 { + hr = syscall.Errno(r0) + } + return +} + +func ResumeThread(thread Handle) (ret uint32, err error) { + r0, _, e1 := syscall.SyscallN(procResumeThread.Addr(), uintptr(thread)) + ret = uint32(r0) + if ret == 0xffffffff { + err = errnoErr(e1) + } + return +} + +func SetCommBreak(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procSetCommBreak.Addr(), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetCommMask(handle Handle, dwEvtMask uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetCommMask.Addr(), uintptr(handle), uintptr(dwEvtMask)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetCommState(handle Handle, lpDCB *DCB) (err error) { + r1, _, e1 := syscall.SyscallN(procSetCommState.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpDCB))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { + r1, _, e1 := syscall.SyscallN(procSetCommTimeouts.Addr(), uintptr(handle), uintptr(unsafe.Pointer(timeouts))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetConsoleCP(cp uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetConsoleCP.Addr(), uintptr(cp)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setConsoleCursorPosition(console Handle, position uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetConsoleCursorPosition.Addr(), uintptr(console), uintptr(position)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetConsoleMode(console Handle, mode uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetConsoleMode.Addr(), uintptr(console), uintptr(mode)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetConsoleOutputCP(cp uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetConsoleOutputCP.Addr(), uintptr(cp)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetCurrentDirectory(path *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procSetCurrentDirectoryW.Addr(), uintptr(unsafe.Pointer(path))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetDefaultDllDirectories(directoryFlags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetDefaultDllDirectories.Addr(), uintptr(directoryFlags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetDllDirectory(path string) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(path) + if err != nil { + return + } + return _SetDllDirectory(_p0) +} + +func _SetDllDirectory(path *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procSetDllDirectoryW.Addr(), uintptr(unsafe.Pointer(path))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetEndOfFile(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procSetEndOfFile.Addr(), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procSetEnvironmentVariableW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetErrorMode(mode uint32) (ret uint32) { + r0, _, _ := syscall.SyscallN(procSetErrorMode.Addr(), uintptr(mode)) + ret = uint32(r0) + return +} + +func SetEvent(event Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procSetEvent.Addr(), uintptr(event)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetFileAttributes(name *uint16, attrs uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetFileAttributesW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(attrs)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) { + r1, _, e1 := syscall.SyscallN(procSetFileCompletionNotificationModes.Addr(), uintptr(handle), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetFileInformationByHandle(handle Handle, class uint32, inBuffer *byte, inBufferLen uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetFileInformationByHandle.Addr(), uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) { + r0, _, e1 := syscall.SyscallN(procSetFilePointer.Addr(), uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence)) + newlowoffset = uint32(r0) + if newlowoffset == 0xffffffff { + err = errnoErr(e1) + } + return +} + +func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { + r1, _, e1 := syscall.SyscallN(procSetFileTime.Addr(), uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetFileValidData(handle Handle, validDataLength int64) (err error) { + r1, _, e1 := syscall.SyscallN(procSetFileValidData.Addr(), uintptr(handle), uintptr(validDataLength)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetHandleInformation.Addr(), uintptr(handle), uintptr(mask), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error) { + r0, _, e1 := syscall.SyscallN(procSetInformationJobObject.Addr(), uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength)) + ret = int(r0) + if ret == 0 { + err = errnoErr(e1) + } + return +} + +func SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetNamedPipeHandleState.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetPriorityClass(process Handle, priorityClass uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetPriorityClass.Addr(), uintptr(process), uintptr(priorityClass)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetProcessPriorityBoost(process Handle, disable bool) (err error) { + var _p0 uint32 + if disable { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procSetProcessPriorityBoost.Addr(), uintptr(process), uintptr(_p0)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetProcessShutdownParameters(level uint32, flags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetProcessShutdownParameters.Addr(), uintptr(level), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetProcessWorkingSetSizeEx.Addr(), uintptr(hProcess), uintptr(dwMinimumWorkingSetSize), uintptr(dwMaximumWorkingSetSize), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetStdHandle(stdhandle uint32, handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procSetStdHandle.Addr(), uintptr(stdhandle), uintptr(handle)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procSetVolumeLabelW.Addr(), uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procSetVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupComm.Addr(), uintptr(handle), uintptr(dwInQueue), uintptr(dwOutQueue)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SizeofResource(module Handle, resInfo Handle) (size uint32, err error) { + r0, _, e1 := syscall.SyscallN(procSizeofResource.Addr(), uintptr(module), uintptr(resInfo)) + size = uint32(r0) + if size == 0 { + err = errnoErr(e1) + } + return +} + +func SleepEx(milliseconds uint32, alertable bool) (ret uint32) { + var _p0 uint32 + if alertable { + _p0 = 1 + } + r0, _, _ := syscall.SyscallN(procSleepEx.Addr(), uintptr(milliseconds), uintptr(_p0)) + ret = uint32(r0) + return +} + +func TerminateJobObject(job Handle, exitCode uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procTerminateJobObject.Addr(), uintptr(job), uintptr(exitCode)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func TerminateProcess(handle Handle, exitcode uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procTerminateProcess.Addr(), uintptr(handle), uintptr(exitcode)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func Thread32First(snapshot Handle, threadEntry *ThreadEntry32) (err error) { + r1, _, e1 := syscall.SyscallN(procThread32First.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func Thread32Next(snapshot Handle, threadEntry *ThreadEntry32) (err error) { + r1, _, e1 := syscall.SyscallN(procThread32Next.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func UnlockFileEx(file Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.SyscallN(procUnlockFileEx.Addr(), uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func UnmapViewOfFile(addr uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procUnmapViewOfFile.Addr(), uintptr(addr)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procUpdateProcThreadAttribute.Addr(), uintptr(unsafe.Pointer(attrlist)), uintptr(flags), uintptr(attr), uintptr(value), uintptr(size), uintptr(prevvalue), uintptr(unsafe.Pointer(returnedsize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) { + r0, _, e1 := syscall.SyscallN(procVirtualAlloc.Addr(), uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect)) + value = uintptr(r0) + if value == 0 { + err = errnoErr(e1) + } + return +} + +func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procVirtualFree.Addr(), uintptr(address), uintptr(size), uintptr(freetype)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func VirtualLock(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procVirtualLock.Addr(), uintptr(addr), uintptr(length)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procVirtualProtect.Addr(), uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func VirtualProtectEx(process Handle, address uintptr, size uintptr, newProtect uint32, oldProtect *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procVirtualProtectEx.Addr(), uintptr(process), uintptr(address), uintptr(size), uintptr(newProtect), uintptr(unsafe.Pointer(oldProtect))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procVirtualQuery.Addr(), uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func VirtualQueryEx(process Handle, address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procVirtualQueryEx.Addr(), uintptr(process), uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func VirtualUnlock(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procVirtualUnlock.Addr(), uintptr(addr), uintptr(length)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func WTSGetActiveConsoleSessionId() (sessionID uint32) { + r0, _, _ := syscall.SyscallN(procWTSGetActiveConsoleSessionId.Addr()) + sessionID = uint32(r0) + return +} + +func WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error) { + r1, _, e1 := syscall.SyscallN(procWaitCommEvent.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpEvtMask)), uintptr(unsafe.Pointer(lpOverlapped))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMilliseconds uint32) (event uint32, err error) { + var _p0 uint32 + if waitAll { + _p0 = 1 + } + r0, _, e1 := syscall.SyscallN(procWaitForMultipleObjects.Addr(), uintptr(count), uintptr(handles), uintptr(_p0), uintptr(waitMilliseconds)) + event = uint32(r0) + if event == 0xffffffff { + err = errnoErr(e1) + } + return +} + +func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) { + r0, _, e1 := syscall.SyscallN(procWaitForSingleObject.Addr(), uintptr(handle), uintptr(waitMilliseconds)) + event = uint32(r0) + if event == 0xffffffff { + err = errnoErr(e1) + } + return +} + +func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) { + r1, _, e1 := syscall.SyscallN(procWriteConsoleW.Addr(), uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } + r1, _, e1 := syscall.SyscallN(procWriteFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func WriteProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesWritten *uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procWriteProcessMemory.Addr(), uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesWritten))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.SyscallN(procAcceptEx.Addr(), uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) { + syscall.SyscallN(procGetAcceptExSockaddrs.Addr(), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen))) + return +} + +func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procTransmitFile.Addr(), uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func NetApiBufferFree(buf *byte) (neterr error) { + r0, _, _ := syscall.SyscallN(procNetApiBufferFree.Addr(), uintptr(unsafe.Pointer(buf))) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + +func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) { + r0, _, _ := syscall.SyscallN(procNetGetJoinInformation.Addr(), uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType))) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + +func NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) { + r0, _, _ := syscall.SyscallN(procNetUserEnum.Addr(), uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(filter), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), uintptr(unsafe.Pointer(resumeHandle))) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + +func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) { + r0, _, _ := syscall.SyscallN(procNetUserGetInfo.Addr(), uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf))) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + +func NtCreateFile(handle *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, allocationSize *int64, attributes uint32, share uint32, disposition uint32, options uint32, eabuffer uintptr, ealength uint32) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procNtCreateFile.Addr(), uintptr(unsafe.Pointer(handle)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(attributes), uintptr(share), uintptr(disposition), uintptr(options), uintptr(eabuffer), uintptr(ealength)) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func NtCreateNamedPipeFile(pipe *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procNtCreateNamedPipeFile.Addr(), uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout))) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func NtQueryEaFile(handle Handle, iosb *IO_STATUS_BLOCK, outBuffer *byte, outBufferLen uint32, returnSingleEntry bool, eaList *byte, eaListLen uint32, eaIndex *uint32, restartScan bool) (ntstatus error) { + var _p0 uint32 + if returnSingleEntry { + _p0 = 1 + } + var _p1 uint32 + if restartScan { + _p1 = 1 + } + r0, _, _ := syscall.SyscallN(procNtQueryEaFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferLen), uintptr(_p0), uintptr(unsafe.Pointer(eaList)), uintptr(eaListLen), uintptr(unsafe.Pointer(eaIndex)), uintptr(_p1)) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func NtQueryInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, outBuffer *byte, outBufferLen uint32, class uint32) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procNtQueryInformationFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferLen), uintptr(class)) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32, retLen *uint32) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procNtQueryInformationProcess.Addr(), uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), uintptr(unsafe.Pointer(retLen))) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func NtQuerySystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32, retLen *uint32) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procNtQuerySystemInformation.Addr(), uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen), uintptr(unsafe.Pointer(retLen))) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func NtSetEaFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, inBufferLen uint32) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procNtSetEaFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen)) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func NtSetInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, inBufferLen uint32, class uint32) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procNtSetInformationFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen), uintptr(class)) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procNtSetInformationProcess.Addr(), uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen)) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func NtSetSystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procNtSetSystemInformation.Addr(), uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen)) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func RtlAddFunctionTable(functionTable *RUNTIME_FUNCTION, entryCount uint32, baseAddress uintptr) (ret bool) { + r0, _, _ := syscall.SyscallN(procRtlAddFunctionTable.Addr(), uintptr(unsafe.Pointer(functionTable)), uintptr(entryCount), uintptr(baseAddress)) + ret = r0 != 0 + return +} + +func RtlDefaultNpAcl(acl **ACL) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procRtlDefaultNpAcl.Addr(), uintptr(unsafe.Pointer(acl))) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func RtlDeleteFunctionTable(functionTable *RUNTIME_FUNCTION) (ret bool) { + r0, _, _ := syscall.SyscallN(procRtlDeleteFunctionTable.Addr(), uintptr(unsafe.Pointer(functionTable))) + ret = r0 != 0 + return +} + +func RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procRtlDosPathNameToNtPathName_U_WithStatus.Addr(), uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName))) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func RtlDosPathNameToRelativeNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procRtlDosPathNameToRelativeNtPathName_U_WithStatus.Addr(), uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName))) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func RtlGetCurrentPeb() (peb *PEB) { + r0, _, _ := syscall.SyscallN(procRtlGetCurrentPeb.Addr()) + peb = (*PEB)(unsafe.Pointer(r0)) + return +} + +func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { + syscall.SyscallN(procRtlGetNtVersionNumbers.Addr(), uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber))) + return +} + +func rtlGetVersion(info *OsVersionInfoEx) (ntstatus error) { + r0, _, _ := syscall.SyscallN(procRtlGetVersion.Addr(), uintptr(unsafe.Pointer(info))) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func RtlInitString(destinationString *NTString, sourceString *byte) { + syscall.SyscallN(procRtlInitString.Addr(), uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString))) + return +} + +func RtlInitUnicodeString(destinationString *NTUnicodeString, sourceString *uint16) { + syscall.SyscallN(procRtlInitUnicodeString.Addr(), uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString))) + return +} + +func rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) { + r0, _, _ := syscall.SyscallN(procRtlNtStatusToDosErrorNoTeb.Addr(), uintptr(ntstatus)) + ret = syscall.Errno(r0) + return +} + +func clsidFromString(lpsz *uint16, pclsid *GUID) (ret error) { + r0, _, _ := syscall.SyscallN(procCLSIDFromString.Addr(), uintptr(unsafe.Pointer(lpsz)), uintptr(unsafe.Pointer(pclsid))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func coCreateGuid(pguid *GUID) (ret error) { + r0, _, _ := syscall.SyscallN(procCoCreateGuid.Addr(), uintptr(unsafe.Pointer(pguid))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func CoGetObject(name *uint16, bindOpts *BIND_OPTS3, guid *GUID, functionTable **uintptr) (ret error) { + r0, _, _ := syscall.SyscallN(procCoGetObject.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bindOpts)), uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(functionTable))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func CoInitializeEx(reserved uintptr, coInit uint32) (ret error) { + r0, _, _ := syscall.SyscallN(procCoInitializeEx.Addr(), uintptr(reserved), uintptr(coInit)) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func CoTaskMemFree(address unsafe.Pointer) { + syscall.SyscallN(procCoTaskMemFree.Addr(), uintptr(address)) + return +} + +func CoUninitialize() { + syscall.SyscallN(procCoUninitialize.Addr()) + return +} + +func stringFromGUID2(rguid *GUID, lpsz *uint16, cchMax int32) (chars int32) { + r0, _, _ := syscall.SyscallN(procStringFromGUID2.Addr(), uintptr(unsafe.Pointer(rguid)), uintptr(unsafe.Pointer(lpsz)), uintptr(cchMax)) + chars = int32(r0) + return +} + +func EnumProcessModules(process Handle, module *Handle, cb uint32, cbNeeded *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procEnumProcessModules.Addr(), uintptr(process), uintptr(unsafe.Pointer(module)), uintptr(cb), uintptr(unsafe.Pointer(cbNeeded))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func EnumProcessModulesEx(process Handle, module *Handle, cb uint32, cbNeeded *uint32, filterFlag uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procEnumProcessModulesEx.Addr(), uintptr(process), uintptr(unsafe.Pointer(module)), uintptr(cb), uintptr(unsafe.Pointer(cbNeeded)), uintptr(filterFlag)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func enumProcesses(processIds *uint32, nSize uint32, bytesReturned *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procEnumProcesses.Addr(), uintptr(unsafe.Pointer(processIds)), uintptr(nSize), uintptr(unsafe.Pointer(bytesReturned))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetModuleBaseName(process Handle, module Handle, baseName *uint16, size uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetModuleBaseNameW.Addr(), uintptr(process), uintptr(module), uintptr(unsafe.Pointer(baseName)), uintptr(size)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetModuleFileNameEx(process Handle, module Handle, filename *uint16, size uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetModuleFileNameExW.Addr(), uintptr(process), uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetModuleInformation.Addr(), uintptr(process), uintptr(module), uintptr(unsafe.Pointer(modinfo)), uintptr(cb)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func QueryWorkingSetEx(process Handle, pv uintptr, cb uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procQueryWorkingSetEx.Addr(), uintptr(process), uintptr(pv), uintptr(cb)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SubscribeServiceChangeNotifications(service Handle, eventType uint32, callback uintptr, callbackCtx uintptr, subscription *uintptr) (ret error) { + ret = procSubscribeServiceChangeNotifications.Find() + if ret != nil { + return + } + r0, _, _ := syscall.SyscallN(procSubscribeServiceChangeNotifications.Addr(), uintptr(service), uintptr(eventType), uintptr(callback), uintptr(callbackCtx), uintptr(unsafe.Pointer(subscription))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func UnsubscribeServiceChangeNotifications(subscription uintptr) (err error) { + err = procUnsubscribeServiceChangeNotifications.Find() + if err != nil { + return + } + syscall.SyscallN(procUnsubscribeServiceChangeNotifications.Addr(), uintptr(subscription)) + return +} + +func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetUserNameExW.Addr(), uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize))) + if r1&0xff == 0 { + err = errnoErr(e1) + } + return +} + +func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procTranslateNameW.Addr(), uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize))) + if r1&0xff == 0 { + err = errnoErr(e1) + } + return +} + +func SetupDiBuildDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiBuildDriverInfoList.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetupDiCallClassInstaller(installFunction DI_FUNCTION, deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiCallClassInstaller.Addr(), uintptr(installFunction), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetupDiCancelDriverInfoSearch(deviceInfoSet DevInfo) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiCancelDriverInfoSearch.Addr(), uintptr(deviceInfoSet)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiClassGuidsFromNameEx(className *uint16, classGuidList *GUID, classGuidListSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiClassGuidsFromNameExW.Addr(), uintptr(unsafe.Pointer(className)), uintptr(unsafe.Pointer(classGuidList)), uintptr(classGuidListSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiClassNameFromGuidEx(classGUID *GUID, className *uint16, classNameSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiClassNameFromGuidExW.Addr(), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(className)), uintptr(classNameSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiCreateDeviceInfoListEx(classGUID *GUID, hwndParent uintptr, machineName *uint16, reserved uintptr) (handle DevInfo, err error) { + r0, _, e1 := syscall.SyscallN(procSetupDiCreateDeviceInfoListExW.Addr(), uintptr(unsafe.Pointer(classGUID)), uintptr(hwndParent), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) + handle = DevInfo(r0) + if handle == DevInfo(InvalidHandle) { + err = errnoErr(e1) + } + return +} + +func setupDiCreateDeviceInfo(deviceInfoSet DevInfo, DeviceName *uint16, classGUID *GUID, DeviceDescription *uint16, hwndParent uintptr, CreationFlags DICD, deviceInfoData *DevInfoData) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiCreateDeviceInfoW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(DeviceName)), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(DeviceDescription)), uintptr(hwndParent), uintptr(CreationFlags), uintptr(unsafe.Pointer(deviceInfoData))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetupDiDestroyDeviceInfoList(deviceInfoSet DevInfo) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiDestroyDeviceInfoList.Addr(), uintptr(deviceInfoSet)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetupDiDestroyDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiDestroyDriverInfoList.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex uint32, deviceInfoData *DevInfoData) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiEnumDeviceInfo.Addr(), uintptr(deviceInfoSet), uintptr(memberIndex), uintptr(unsafe.Pointer(deviceInfoData))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT, memberIndex uint32, driverInfoData *DrvInfoData) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiEnumDriverInfoW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType), uintptr(memberIndex), uintptr(unsafe.Pointer(driverInfoData))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiGetClassDevsEx(classGUID *GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, deviceInfoSet DevInfo, machineName *uint16, reserved uintptr) (handle DevInfo, err error) { + r0, _, e1 := syscall.SyscallN(procSetupDiGetClassDevsExW.Addr(), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(Enumerator)), uintptr(hwndParent), uintptr(Flags), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) + handle = DevInfo(r0) + if handle == DevInfo(InvalidHandle) { + err = errnoErr(e1) + } + return +} + +func SetupDiGetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiGetClassInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize), uintptr(unsafe.Pointer(requiredSize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo, deviceInfoSetDetailData *DevInfoListDetailData) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceInfoListDetailW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoSetDetailData))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, instanceId *uint16, instanceIdSize uint32, instanceIdRequiredSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceInstanceIdW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(instanceId)), uintptr(instanceIdSize), uintptr(unsafe.Pointer(instanceIdRequiredSize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiGetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, propertyKey *DEVPROPKEY, propertyType *DEVPROPTYPE, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32, flags uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiGetDevicePropertyW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(propertyKey)), uintptr(unsafe.Pointer(propertyType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyRegDataType *uint32, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceRegistryPropertyW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyRegDataType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(unsafe.Pointer(requiredSize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData, driverInfoDetailData *DrvInfoDetailData, driverInfoDetailDataSize uint32, requiredSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiGetDriverInfoDetailW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData)), uintptr(unsafe.Pointer(driverInfoDetailData)), uintptr(driverInfoDetailDataSize), uintptr(unsafe.Pointer(requiredSize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiGetSelectedDevice.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiGetSelectedDriverW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetupDiOpenDevRegKey(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (key Handle, err error) { + r0, _, e1 := syscall.SyscallN(procSetupDiOpenDevRegKey.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(Scope), uintptr(HwProfile), uintptr(KeyType), uintptr(samDesired)) + key = Handle(r0) + if key == InvalidHandle { + err = errnoErr(e1) + } + return +} + +func SetupDiSetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiSetClassInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetupDiSetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiSetDeviceInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyBuffer *byte, propertyBufferSize uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiSetDeviceRegistryPropertyW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetupDiSetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiSetSelectedDevice.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func SetupDiSetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupDiSetSelectedDriverW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func setupUninstallOEMInf(infFileName *uint16, flags SUOI, reserved uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procSetupUninstallOEMInfW.Addr(), uintptr(unsafe.Pointer(infFileName)), uintptr(flags), uintptr(reserved)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func commandLineToArgv(cmd *uint16, argc *int32) (argv **uint16, err error) { + r0, _, e1 := syscall.SyscallN(procCommandLineToArgvW.Addr(), uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc))) + argv = (**uint16)(unsafe.Pointer(r0)) + if argv == nil { + err = errnoErr(e1) + } + return +} + +func shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **uint16) (ret error) { + r0, _, _ := syscall.SyscallN(procSHGetKnownFolderPath.Addr(), uintptr(unsafe.Pointer(id)), uintptr(flags), uintptr(token), uintptr(unsafe.Pointer(path))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) { + r1, _, e1 := syscall.SyscallN(procShellExecuteW.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(verb)), uintptr(unsafe.Pointer(file)), uintptr(unsafe.Pointer(args)), uintptr(unsafe.Pointer(cwd)), uintptr(showCmd)) + if r1 <= 32 { + err = errnoErr(e1) + } + return +} + +func EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) { + syscall.SyscallN(procEnumChildWindows.Addr(), uintptr(hwnd), uintptr(enumFunc), uintptr(param)) + return +} + +func EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) { + r1, _, e1 := syscall.SyscallN(procEnumWindows.Addr(), uintptr(enumFunc), uintptr(param)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ExitWindowsEx(flags uint32, reason uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procExitWindowsEx.Addr(), uintptr(flags), uintptr(reason)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) { + r0, _, e1 := syscall.SyscallN(procGetClassNameW.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(className)), uintptr(maxCount)) + copied = int32(r0) + if copied == 0 { + err = errnoErr(e1) + } + return +} + +func GetDesktopWindow() (hwnd HWND) { + r0, _, _ := syscall.SyscallN(procGetDesktopWindow.Addr()) + hwnd = HWND(r0) + return +} + +func GetForegroundWindow() (hwnd HWND) { + r0, _, _ := syscall.SyscallN(procGetForegroundWindow.Addr()) + hwnd = HWND(r0) + return +} + +func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) { + r1, _, e1 := syscall.SyscallN(procGetGUIThreadInfo.Addr(), uintptr(thread), uintptr(unsafe.Pointer(info))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetKeyboardLayout(tid uint32) (hkl Handle) { + r0, _, _ := syscall.SyscallN(procGetKeyboardLayout.Addr(), uintptr(tid)) + hkl = Handle(r0) + return +} + +func GetShellWindow() (shellWindow HWND) { + r0, _, _ := syscall.SyscallN(procGetShellWindow.Addr()) + shellWindow = HWND(r0) + return +} + +func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetWindowThreadProcessId.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(pid))) + tid = uint32(r0) + if tid == 0 { + err = errnoErr(e1) + } + return +} + +func IsWindow(hwnd HWND) (isWindow bool) { + r0, _, _ := syscall.SyscallN(procIsWindow.Addr(), uintptr(hwnd)) + isWindow = r0 != 0 + return +} + +func IsWindowUnicode(hwnd HWND) (isUnicode bool) { + r0, _, _ := syscall.SyscallN(procIsWindowUnicode.Addr(), uintptr(hwnd)) + isUnicode = r0 != 0 + return +} + +func IsWindowVisible(hwnd HWND) (isVisible bool) { + r0, _, _ := syscall.SyscallN(procIsWindowVisible.Addr(), uintptr(hwnd)) + isVisible = r0 != 0 + return +} + +func LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) { + r0, _, e1 := syscall.SyscallN(procLoadKeyboardLayoutW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(flags)) + hkl = Handle(r0) + if hkl == 0 { + err = errnoErr(e1) + } + return +} + +func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) { + r0, _, e1 := syscall.SyscallN(procMessageBoxW.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype)) + ret = int32(r0) + if ret == 0 { + err = errnoErr(e1) + } + return +} + +func ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) { + r0, _, _ := syscall.SyscallN(procToUnicodeEx.Addr(), uintptr(vkey), uintptr(scancode), uintptr(unsafe.Pointer(keystate)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(flags), uintptr(hkl)) + ret = int32(r0) + return +} + +func UnloadKeyboardLayout(hkl Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procUnloadKeyboardLayout.Addr(), uintptr(hkl)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) { + var _p0 uint32 + if inheritExisting { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procCreateEnvironmentBlock.Addr(), uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func DestroyEnvironmentBlock(block *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procDestroyEnvironmentBlock.Addr(), uintptr(unsafe.Pointer(block))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetUserProfileDirectoryW.Addr(), uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetFileVersionInfoSize(filename string, zeroHandle *Handle) (bufSize uint32, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(filename) + if err != nil { + return + } + return _GetFileVersionInfoSize(_p0, zeroHandle) +} + +func _GetFileVersionInfoSize(filename *uint16, zeroHandle *Handle) (bufSize uint32, err error) { + r0, _, e1 := syscall.SyscallN(procGetFileVersionInfoSizeW.Addr(), uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(zeroHandle))) + bufSize = uint32(r0) + if bufSize == 0 { + err = errnoErr(e1) + } + return +} + +func GetFileVersionInfo(filename string, handle uint32, bufSize uint32, buffer unsafe.Pointer) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(filename) + if err != nil { + return + } + return _GetFileVersionInfo(_p0, handle, bufSize, buffer) +} + +func _GetFileVersionInfo(filename *uint16, handle uint32, bufSize uint32, buffer unsafe.Pointer) (err error) { + r1, _, e1 := syscall.SyscallN(procGetFileVersionInfoW.Addr(), uintptr(unsafe.Pointer(filename)), uintptr(handle), uintptr(bufSize), uintptr(buffer)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func VerQueryValue(block unsafe.Pointer, subBlock string, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(subBlock) + if err != nil { + return + } + return _VerQueryValue(block, _p0, pointerToBufferPointer, bufSize) +} + +func _VerQueryValue(block unsafe.Pointer, subBlock *uint16, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procVerQueryValueW.Addr(), uintptr(block), uintptr(unsafe.Pointer(subBlock)), uintptr(pointerToBufferPointer), uintptr(unsafe.Pointer(bufSize))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func TimeBeginPeriod(period uint32) (err error) { + r1, _, e1 := syscall.SyscallN(proctimeBeginPeriod.Addr(), uintptr(period)) + if r1 != 0 { + err = errnoErr(e1) + } + return +} + +func TimeEndPeriod(period uint32) (err error) { + r1, _, e1 := syscall.SyscallN(proctimeEndPeriod.Addr(), uintptr(period)) + if r1 != 0 { + err = errnoErr(e1) + } + return +} + +func WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) { + r0, _, _ := syscall.SyscallN(procWinVerifyTrustEx.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(actionId)), uintptr(unsafe.Pointer(data))) + if r0 != 0 { + ret = syscall.Errno(r0) + } + return +} + +func FreeAddrInfoW(addrinfo *AddrinfoW) { + syscall.SyscallN(procFreeAddrInfoW.Addr(), uintptr(unsafe.Pointer(addrinfo))) + return +} + +func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) { + r0, _, _ := syscall.SyscallN(procGetAddrInfoW.Addr(), uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result))) + if r0 != 0 { + sockerr = syscall.Errno(r0) + } + return +} + +func WSACleanup() (err error) { + r1, _, e1 := syscall.SyscallN(procWSACleanup.Addr()) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err error) { + r1, _, e1 := syscall.SyscallN(procWSADuplicateSocketW.Addr(), uintptr(s), uintptr(processID), uintptr(unsafe.Pointer(info))) + if r1 != 0 { + err = errnoErr(e1) + } + return +} + +func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) { + r0, _, e1 := syscall.SyscallN(procWSAEnumProtocolsW.Addr(), uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) + n = int32(r0) + if n == -1 { + err = errnoErr(e1) + } + return +} + +func WSAGetOverlappedResult(h Handle, o *Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) { + var _p0 uint32 + if wait { + _p0 = 1 + } + r1, _, e1 := syscall.SyscallN(procWSAGetOverlappedResult.Addr(), uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procWSAIoctl.Addr(), uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func WSALookupServiceBegin(querySet *WSAQUERYSET, flags uint32, handle *Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procWSALookupServiceBeginW.Addr(), uintptr(unsafe.Pointer(querySet)), uintptr(flags), uintptr(unsafe.Pointer(handle))) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func WSALookupServiceEnd(handle Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procWSALookupServiceEnd.Addr(), uintptr(handle)) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func WSALookupServiceNext(handle Handle, flags uint32, size *int32, querySet *WSAQUERYSET) (err error) { + r1, _, e1 := syscall.SyscallN(procWSALookupServiceNextW.Addr(), uintptr(handle), uintptr(flags), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(querySet))) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.SyscallN(procWSARecv.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.SyscallN(procWSARecvFrom.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.SyscallN(procWSASend.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.SyscallN(procWSASendTo.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procWSASocketW.Addr(), uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protoInfo)), uintptr(group), uintptr(flags)) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) + } + return +} + +func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { + r0, _, _ := syscall.SyscallN(procWSAStartup.Addr(), uintptr(verreq), uintptr(unsafe.Pointer(data))) + if r0 != 0 { + sockerr = syscall.Errno(r0) + } + return +} + +func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) { + r1, _, e1 := syscall.SyscallN(procbind.Addr(), uintptr(s), uintptr(name), uintptr(namelen)) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func Closesocket(s Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procclosesocket.Addr(), uintptr(s)) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) { + r1, _, e1 := syscall.SyscallN(procconnect.Addr(), uintptr(s), uintptr(name), uintptr(namelen)) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func GetHostByName(name string) (h *Hostent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return + } + return _GetHostByName(_p0) +} + +func _GetHostByName(name *byte) (h *Hostent, err error) { + r0, _, e1 := syscall.SyscallN(procgethostbyname.Addr(), uintptr(unsafe.Pointer(name))) + h = (*Hostent)(unsafe.Pointer(r0)) + if h == nil { + err = errnoErr(e1) + } + return +} + +func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { + r1, _, e1 := syscall.SyscallN(procgetpeername.Addr(), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func GetProtoByName(name string) (p *Protoent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return + } + return _GetProtoByName(_p0) +} + +func _GetProtoByName(name *byte) (p *Protoent, err error) { + r0, _, e1 := syscall.SyscallN(procgetprotobyname.Addr(), uintptr(unsafe.Pointer(name))) + p = (*Protoent)(unsafe.Pointer(r0)) + if p == nil { + err = errnoErr(e1) + } + return +} + +func GetServByName(name string, proto string) (s *Servent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return + } + var _p1 *byte + _p1, err = syscall.BytePtrFromString(proto) + if err != nil { + return + } + return _GetServByName(_p0, _p1) +} + +func _GetServByName(name *byte, proto *byte) (s *Servent, err error) { + r0, _, e1 := syscall.SyscallN(procgetservbyname.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto))) + s = (*Servent)(unsafe.Pointer(r0)) + if s == nil { + err = errnoErr(e1) + } + return +} + +func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { + r1, _, e1 := syscall.SyscallN(procgetsockname.Addr(), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) { + r1, _, e1 := syscall.SyscallN(procgetsockopt.Addr(), uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen))) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func listen(s Handle, backlog int32) (err error) { + r1, _, e1 := syscall.SyscallN(proclisten.Addr(), uintptr(s), uintptr(backlog)) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func Ntohs(netshort uint16) (u uint16) { + r0, _, _ := syscall.SyscallN(procntohs.Addr(), uintptr(netshort)) + u = uint16(r0) + return +} + +func recvfrom(s Handle, buf []byte, flags int32, from *RawSockaddrAny, fromlen *int32) (n int32, err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } + r0, _, e1 := syscall.SyscallN(procrecvfrom.Addr(), uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) + n = int32(r0) + if n == -1 { + err = errnoErr(e1) + } + return +} + +func sendto(s Handle, buf []byte, flags int32, to unsafe.Pointer, tolen int32) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } + r1, _, e1 := syscall.SyscallN(procsendto.Addr(), uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(tolen)) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) { + r1, _, e1 := syscall.SyscallN(procsetsockopt.Addr(), uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen)) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func shutdown(s Handle, how int32) (err error) { + r1, _, e1 := syscall.SyscallN(procshutdown.Addr(), uintptr(s), uintptr(how)) + if r1 == socket_error { + err = errnoErr(e1) + } + return +} + +func socket(af int32, typ int32, protocol int32) (handle Handle, err error) { + r0, _, e1 := syscall.SyscallN(procsocket.Addr(), uintptr(af), uintptr(typ), uintptr(protocol)) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) + } + return +} + +func WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procWTSEnumerateSessionsW.Addr(), uintptr(handle), uintptr(reserved), uintptr(version), uintptr(unsafe.Pointer(sessions)), uintptr(unsafe.Pointer(count))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func WTSFreeMemory(ptr uintptr) { + syscall.SyscallN(procWTSFreeMemory.Addr(), uintptr(ptr)) + return +} + +func WTSQueryUserToken(session uint32, token *Token) (err error) { + r1, _, e1 := syscall.SyscallN(procWTSQueryUserToken.Addr(), uintptr(session), uintptr(unsafe.Pointer(token))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/telemetry/.dockerignore b/vendor/golang.org/x/telemetry/.dockerignore new file mode 100644 index 0000000..416ae44 --- /dev/null +++ b/vendor/golang.org/x/telemetry/.dockerignore @@ -0,0 +1,17 @@ +.git +.localstorage +node_modules +devtools +.eslint* +.gitignore +.prettier* +.stylelint* +CONTRIBUTING.md +LICENSE +npm +npx +package-lock.json +package.json +PATENTS +README.md +tsconfig.json \ No newline at end of file diff --git a/vendor/golang.org/x/telemetry/.eslintrc.json b/vendor/golang.org/x/telemetry/.eslintrc.json new file mode 100644 index 0000000..ba5e242 --- /dev/null +++ b/vendor/golang.org/x/telemetry/.eslintrc.json @@ -0,0 +1,11 @@ +{ + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "root": true, + "ignorePatterns": ["*.min.js"] +} diff --git a/vendor/golang.org/x/telemetry/.gitattributes b/vendor/golang.org/x/telemetry/.gitattributes new file mode 100644 index 0000000..f529a11 --- /dev/null +++ b/vendor/golang.org/x/telemetry/.gitattributes @@ -0,0 +1,14 @@ +# Treat all files in the repo as binary, with no git magic updating +# line endings. This produces predictable results in different environments. +# +# Windows users contributing to Go will need to use a modern version +# of git and editors capable of LF line endings. +# +# Windows .bat files are known to have multiple bugs when run with LF +# endings. So if they are checked in with CRLF endings, there should +# be a test like the one in test/winbatch.go in the go repository. +# (See golang.org/issue/37791.) +# +# See golang.org/issue/9281. + +* -text diff --git a/vendor/golang.org/x/telemetry/.gitignore b/vendor/golang.org/x/telemetry/.gitignore new file mode 100644 index 0000000..46770c4 --- /dev/null +++ b/vendor/golang.org/x/telemetry/.gitignore @@ -0,0 +1,2 @@ +node_modules +.localstorage \ No newline at end of file diff --git a/vendor/golang.org/x/telemetry/.prettierrc.json b/vendor/golang.org/x/telemetry/.prettierrc.json new file mode 100644 index 0000000..91c0b94 --- /dev/null +++ b/vendor/golang.org/x/telemetry/.prettierrc.json @@ -0,0 +1 @@ +{"proseWrap": "always"} diff --git a/vendor/golang.org/x/telemetry/.stylelintrc.json b/vendor/golang.org/x/telemetry/.stylelintrc.json new file mode 100644 index 0000000..adccf47 --- /dev/null +++ b/vendor/golang.org/x/telemetry/.stylelintrc.json @@ -0,0 +1,11 @@ +{ + "extends": ["stylelint-config-standard"], + "rules": { + "declaration-property-value-allowed-list": { + "/color/": ["/^var\\(--/", "transparent"] + }, + "unit-disallowed-list": ["px"], + "selector-class-pattern": "^[a-zA-Z\\-]+$" + }, + "ignoreFiles": ["**/*.min.css"] +} diff --git a/vendor/golang.org/x/telemetry/CONTRIBUTING.md b/vendor/golang.org/x/telemetry/CONTRIBUTING.md new file mode 100644 index 0000000..e913373 --- /dev/null +++ b/vendor/golang.org/x/telemetry/CONTRIBUTING.md @@ -0,0 +1,30 @@ +# Contributing to Go + +Go is an open source project. + +It is the work of hundreds of contributors. We appreciate your help! + +## Filing issues + +When [filing an issue](https://golang.org/issue/new), make sure to answer these +five questions: + +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? + +General questions should go to the +[golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead +of the issue tracker. The gophers there will answer or ask you to file an issue +if you've tripped over a bug. + +## Contributing code + +Please read the +[Contribution Guidelines](https://golang.org/doc/contribute.html) before sending +patches. + +Unless otherwise noted, the Go source files are distributed under the BSD-style +license found in the LICENSE file. diff --git a/vendor/golang.org/x/telemetry/LICENSE b/vendor/golang.org/x/telemetry/LICENSE new file mode 100644 index 0000000..2a7cf70 --- /dev/null +++ b/vendor/golang.org/x/telemetry/LICENSE @@ -0,0 +1,27 @@ +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/telemetry/PATENTS b/vendor/golang.org/x/telemetry/PATENTS new file mode 100644 index 0000000..7330990 --- /dev/null +++ b/vendor/golang.org/x/telemetry/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/telemetry/README.md b/vendor/golang.org/x/telemetry/README.md new file mode 100644 index 0000000..81a1574 --- /dev/null +++ b/vendor/golang.org/x/telemetry/README.md @@ -0,0 +1,62 @@ +# Go Telemetry + +This repository holds the Go Telemetry server code and libraries, used for +hosting [telemetry.go.dev](https://telemetry.go.dev) and instrumenting Go +toolchain programs with opt-in telemetry. + +**Warning**: this repository is intended for use only in tools maintained by +the Go team, including tools in the Go distribution and auxiliary tools like +[gopls](https://pkg.go.dev/golang.org/x/tools/gopls) or +[govulncheck](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck). There are +no compatibility guarantees for any of the packages here: public APIs will +change in breaking ways as the telemetry integration is refined. + +## Notable Packages + +- The [x/telemetry/counter](https://pkg.go.dev/golang.org/x/telemetry/counter) + package provides a library for instrumenting programs with counters and stack + reports. +- The [x/telemetry/upload](https://pkg.go.dev/golang.org/x/telemetry/upload) + package provides a hook for Go toolchain programs to upload telemetry data, + if the user has opted in to telemetry uploading. +- The [x/telemetry/cmd/gotelemetry](https://pkg.go.dev/pkg/golang.org/x/telemetry/cmd/gotelemetry) + command is used for managing telemetry data and configuration. +- The [x/telemetry/config](https://pkg.go.dev/pkg/golang.org/x/telemetry/config) + package defines the subset of telemetry data that has been approved for + uploading by the telemetry proposal process. +- The [x/telemetry/godev](https://pkg.go.dev/pkg/golang.org/x/telemetry/godev) directory defines + the services running at [telemetry.go.dev](https://telemetry.go.dev). + +## Contributing + +This repository uses Gerrit for code changes. To learn how to submit changes to +this repository, see https://go.dev/doc/contribute. + +The git repository is https://go.googlesource.com/telemetry. + +The main issue tracker for the telemetry repository is located at +https://go.dev/issues. Prefix your issue with "x/telemetry:" in +the subject line, so it is easy to find. + +### Linting & Formatting + +This repository uses [eslint](https://eslint.org/) to format TS files, +[stylelint](https://stylelint.io/) to format CSS files, and +[prettier](https://prettier.io/) to format TS, CSS, Markdown, and YAML files. + +See the style guides: + +- [TypeScript](https://google.github.io/styleguide/tsguide.html) +- [CSS](https://go.dev/wiki/CSSStyleGuide) + +It is encouraged that all TS and CSS code be run through formatters before +submitting a change. However, it is not a strict requirement enforced by CI. + +### Installing npm Dependencies: + +1. Install [docker](https://docs.docker.com/get-docker/) +2. Run `./npm install` + +### Run ESLint, Stylelint, & Prettier + + ./npm run all diff --git a/vendor/golang.org/x/telemetry/codereview.cfg b/vendor/golang.org/x/telemetry/codereview.cfg new file mode 100644 index 0000000..3f8b14b --- /dev/null +++ b/vendor/golang.org/x/telemetry/codereview.cfg @@ -0,0 +1 @@ +issuerepo: golang/go diff --git a/vendor/golang.org/x/telemetry/counter/counter.go b/vendor/golang.org/x/telemetry/counter/counter.go new file mode 100644 index 0000000..fe2d0f6 --- /dev/null +++ b/vendor/golang.org/x/telemetry/counter/counter.go @@ -0,0 +1,146 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package counter + +// The implementation of this package and tests are located in +// internal/counter, which can be shared with the upload package. +// TODO(hyangah): use of type aliases prevents nice documentation +// rendering in go doc or pkgsite. Fix this either by avoiding +// type aliasing or restructuring the internal/counter package. +import ( + "flag" + "path" + "runtime/debug" + + "golang.org/x/telemetry/internal/counter" + "golang.org/x/telemetry/internal/telemetry" +) + +// Inc increments the counter with the given name. +func Inc(name string) { + New(name).Inc() +} + +// Add adds n to the counter with the given name. +func Add(name string, n int64) { + New(name).Add(n) +} + +// New returns a counter with the given name. +// New can be called in global initializers and will be compiled down to +// linker-initialized data. That is, calling New to initialize a global +// has no cost at program startup. +// +// See "Counter Naming" in the package doc for a description of counter naming +// conventions. +func New(name string) *Counter { + // Note: not calling DefaultFile.New in order to keep this + // function something the compiler can inline and convert + // into static data initializations, with no init-time footprint. + // TODO(hyangah): is it trivial enough for the compiler to inline? + return counter.New(name) +} + +// A Counter is a single named event counter. +// A Counter is safe for use by multiple goroutines simultaneously. +// +// Counters should typically be created using New +// and stored as global variables, like: +// +// package mypackage +// var errorCount = counter.New("mypackage/errors") +// +// (The initialization of errorCount in this example is handled +// entirely by the compiler and linker; this line executes no code +// at program startup.) +// +// Then code can call Add to increment the counter +// each time the corresponding event is observed. +// +// Although it is possible to use New to create +// a Counter each time a particular event needs to be recorded, +// that usage fails to amortize the construction cost over +// multiple calls to Add, so it is more expensive and not recommended. +type Counter = counter.Counter + +// A StackCounter is the in-memory knowledge about a stack counter. +// StackCounters are more expensive to use than regular Counters, +// requiring, at a minimum, a call to runtime.Callers. +type StackCounter = counter.StackCounter + +// NewStack returns a new stack counter with the given name and depth. +// +// See "Counter Naming" in the package doc for a description of counter naming +// conventions. +func NewStack(name string, depth int) *StackCounter { + return counter.NewStack(name, depth) +} + +// Open prepares telemetry counters for recording to the file system. +// +// If the telemetry mode is "off", Open is a no-op. Otherwise, it opens the +// counter file on disk and starts to mmap telemetry counters to the file. +// Open also persists any counters already created in the current process. +// +// Open should only be called from short-lived processes such as command line +// tools. If your process is long-running, use [OpenAndRotate]. +func Open() { + counter.Open(false) +} + +// OpenAndRotate is like [Open], but also schedules a rotation of the counter +// file when it expires. +// +// See golang/go#68497 for background on why [OpenAndRotate] is a separate API. +// +// TODO(rfindley): refactor Open and OpenAndRotate for Go 1.24. +func OpenAndRotate() { + counter.Open(true) +} + +// OpenDir prepares telemetry counters for recording to the file system, using +// the specified telemetry directory, if it is not the empty string. +// +// If the telemetry mode is "off", Open is a no-op. Otherwise, it opens the +// counter file on disk and starts to mmap telemetry counters to the file. +// Open also persists any counters already created in the current process. +func OpenDir(telemetryDir string) { + if telemetryDir != "" { + telemetry.Default = telemetry.NewDir(telemetryDir) + } + counter.Open(false) +} + +// CountFlags creates a counter for every flag that is set +// and increments the counter. The name of the counter is +// the concatenation of prefix and the flag name. +// +// For instance, CountFlags("gopls/flag:", *flag.CommandLine) +func CountFlags(prefix string, fs flag.FlagSet) { + fs.Visit(func(f *flag.Flag) { + New(prefix + f.Name).Inc() + }) +} + +// CountCommandLineFlags creates a counter for every flag +// that is set in the default flag.CommandLine FlagSet using +// the counter name binaryName+"/flag:"+flagName where +// binaryName is the base name of the Path embedded in the +// binary's build info. If the binary does not have embedded build +// info, the "flag:"+flagName counter will be incremented. +// +// CountCommandLineFlags must be called after flags are parsed +// with flag.Parse. +// +// For instance, if the -S flag is passed to cmd/compile and +// CountCommandLineFlags is called after flags are parsed, +// the "compile/flag:S" counter will be incremented. +func CountCommandLineFlags() { + prefix := "flag:" + if buildInfo, ok := debug.ReadBuildInfo(); ok && buildInfo.Path != "" { + prefix = path.Base(buildInfo.Path) + "/" + prefix + } + CountFlags(prefix, *flag.CommandLine) +} diff --git a/vendor/golang.org/x/telemetry/counter/doc.go b/vendor/golang.org/x/telemetry/counter/doc.go new file mode 100644 index 0000000..639e9ea --- /dev/null +++ b/vendor/golang.org/x/telemetry/counter/doc.go @@ -0,0 +1,58 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package counter implements a simple counter system for collecting +// totally public telemetry data. +// +// There are two kinds of counters, basic counters and stack counters. +// Basic counters are created by [New]. +// Stack counters are created by [NewStack]. +// Both are incremented by calling Inc(). +// +// Basic counters are very cheap. Stack counters are more expensive, as they +// require parsing the stack. (Stack counters are implemented as basic counters +// whose names are the concatenation of the name and the stack trace. There is +// an upper limit on the size of this name, about 4K bytes. If the name is too +// long the stack will be truncated and "truncated" appended.) +// +// When counter files expire they are turned into reports by the upload +// package. The first time any counter file is created for a user, a random day +// of the week is selected on which counter files will expire. For the first +// week, that day is more than 7 days (but not more than two weeks) in the +// future. After that the counter files expire weekly on the same day of the +// week. +// +// # Counter Naming +// +// Counter names passed to [New] and [NewStack] should follow these +// conventions: +// +// - Names cannot contain whitespace or newlines. +// +// - Names must be valid unicode, with no unprintable characters. +// +// - Names may contain at most one ':'. In the counter "foo:bar", we refer to +// "foo" as the "chart name" and "bar" as the "bucket name". +// +// - The '/' character should partition counter names into a hierarchy. The +// root of this hierarchy should identify the logical entity that "owns" +// the counter. This could be an application, such as "gopls" in the case +// of "gopls/client:vscode", or a shared library, such as "crash" in the +// case of the "crash/crash" counter owned by the crashmonitor library. If +// the entity name itself contains a '/', that's ok: "cmd/go/flag" is fine. +// +// - Words should be '-' separated, as in "gopls/completion/errors-latency" +// +// - Histograms should use bucket names identifying upper bounds with '<'. +// For example given two counters "gopls/completion/latency:<50ms" and +// "gopls/completion/latency:<100ms", the "<100ms" bucket counts events +// with latency in the half-open interval [50ms, 100ms). +// +// # Debugging +// +// The GODEBUG environment variable can enable printing of additional debug +// information for counters. Adding GODEBUG=countertrace=1 to the environment +// of a process using counters causes the x/telemetry/counter package to log +// counter information to stderr. +package counter diff --git a/vendor/golang.org/x/telemetry/dir.go b/vendor/golang.org/x/telemetry/dir.go new file mode 100644 index 0000000..5931669 --- /dev/null +++ b/vendor/golang.org/x/telemetry/dir.go @@ -0,0 +1,12 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package telemetry + +import "golang.org/x/telemetry/internal/telemetry" + +// Dir returns the telemetry directory. +func Dir() string { + return telemetry.Default.Dir() +} diff --git a/vendor/golang.org/x/telemetry/doc.go b/vendor/golang.org/x/telemetry/doc.go new file mode 100644 index 0000000..073f40d --- /dev/null +++ b/vendor/golang.org/x/telemetry/doc.go @@ -0,0 +1 @@ +package telemetry diff --git a/vendor/golang.org/x/telemetry/internal/config/config.go b/vendor/golang.org/x/telemetry/internal/config/config.go new file mode 100644 index 0000000..533a889 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/config/config.go @@ -0,0 +1,140 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// package config provides methods for loading and querying a +// telemetry upload config file. +package config + +import ( + "encoding/json" + "os" + "strings" + + "golang.org/x/telemetry/internal/telemetry" +) + +// Config is a wrapper around telemetry.UploadConfig that provides some +// convenience methods for checking the contents of a report. +type Config struct { + *telemetry.UploadConfig + program map[string]bool + goos map[string]bool + goarch map[string]bool + goversion map[string]bool + pgversion map[pgkey]bool + pgcounter map[pgkey]bool + pgcounterprefix map[pgkey]bool + pgstack map[pgkey]bool + rate map[pgkey]float64 +} + +type pgkey struct { + program, key string +} + +func ReadConfig(file string) (*Config, error) { + data, err := os.ReadFile(file) + if err != nil { + return nil, err + } + var cfg telemetry.UploadConfig + if err := json.Unmarshal(data, &cfg); err != nil { + return nil, err + } + return NewConfig(&cfg), nil +} + +func NewConfig(cfg *telemetry.UploadConfig) *Config { + ucfg := Config{UploadConfig: cfg} + ucfg.goos = set(ucfg.GOOS) + ucfg.goarch = set(ucfg.GOARCH) + ucfg.goversion = set(ucfg.GoVersion) + ucfg.program = make(map[string]bool, len(ucfg.Programs)) + ucfg.pgversion = make(map[pgkey]bool, len(ucfg.Programs)) + ucfg.pgcounter = make(map[pgkey]bool, len(ucfg.Programs)) + ucfg.pgcounterprefix = make(map[pgkey]bool, len(ucfg.Programs)) + ucfg.pgstack = make(map[pgkey]bool, len(ucfg.Programs)) + ucfg.rate = make(map[pgkey]float64) + for _, p := range ucfg.Programs { + ucfg.program[p.Name] = true + for _, v := range p.Versions { + ucfg.pgversion[pgkey{p.Name, v}] = true + } + for _, c := range p.Counters { + for _, e := range Expand(c.Name) { + ucfg.pgcounter[pgkey{p.Name, e}] = true + ucfg.rate[pgkey{p.Name, e}] = c.Rate + } + prefix, _, found := strings.Cut(c.Name, ":") + if found { + ucfg.pgcounterprefix[pgkey{p.Name, prefix}] = true + } + } + for _, s := range p.Stacks { + ucfg.pgstack[pgkey{p.Name, s.Name}] = true + ucfg.rate[pgkey{p.Name, s.Name}] = s.Rate + } + } + return &ucfg +} + +func (r *Config) HasProgram(s string) bool { + return r.program[s] +} + +func (r *Config) HasGOOS(s string) bool { + return r.goos[s] +} + +func (r *Config) HasGOARCH(s string) bool { + return r.goarch[s] +} + +func (r *Config) HasGoVersion(s string) bool { + return r.goversion[s] +} + +func (r *Config) HasVersion(program, version string) bool { + return r.pgversion[pgkey{program, version}] +} + +func (r *Config) HasCounter(program, counter string) bool { + return r.pgcounter[pgkey{program, counter}] +} + +func (r *Config) HasCounterPrefix(program, prefix string) bool { + return r.pgcounterprefix[pgkey{program, prefix}] +} + +func (r *Config) HasStack(program, stack string) bool { + return r.pgstack[pgkey{program, stack}] +} + +func (r *Config) Rate(program, name string) float64 { + return r.rate[pgkey{program, name}] +} + +func set(slice []string) map[string]bool { + s := make(map[string]bool, len(slice)) + for _, v := range slice { + s[v] = true + } + return s +} + +// Expand takes a counter defined with buckets and expands it into distinct +// strings for each bucket. +func Expand(counter string) []string { + prefix, rest, hasBuckets := strings.Cut(counter, "{") + var counters []string + if hasBuckets { + buckets := strings.Split(strings.TrimSuffix(rest, "}"), ",") + for _, b := range buckets { + counters = append(counters, prefix+b) + } + } else { + counters = append(counters, prefix) + } + return counters +} diff --git a/vendor/golang.org/x/telemetry/internal/configstore/download.go b/vendor/golang.org/x/telemetry/internal/configstore/download.go new file mode 100644 index 0000000..e60ab7e --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/configstore/download.go @@ -0,0 +1,86 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package configstore abstracts interaction with the telemetry config server. +// Telemetry config (golang.org/x/telemetry/config) is distributed as a go +// module containing go.mod and config.json. Programs that upload collected +// counters download the latest config using `go mod download`. This provides +// verification of downloaded configuration and cacheability. +package configstore + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "os/exec" + "path/filepath" + "sync/atomic" + + "golang.org/x/telemetry/internal/telemetry" +) + +const ( + ModulePath = "golang.org/x/telemetry/config" + configFileName = "config.json" +) + +// needNoConsole is used on windows to set the windows.CREATE_NO_WINDOW +// creation flag. +var needNoConsole = func(cmd *exec.Cmd) {} + +var downloads int64 + +// Downloads reports, for testing purposes, the number of times [Download] has +// been called. +func Downloads() int64 { + return atomic.LoadInt64(&downloads) +} + +// Download fetches the requested telemetry UploadConfig using "go mod +// download". If envOverlay is provided, it is appended to the environment used +// for invoking the go command. +// +// The second result is the canonical version of the requested configuration. +func Download(version string, envOverlay []string) (*telemetry.UploadConfig, string, error) { + atomic.AddInt64(&downloads, 1) + + if version == "" { + version = "latest" + } + modVer := ModulePath + "@" + version + var stdout, stderr bytes.Buffer + cmd := exec.Command("go", "mod", "download", "-json", modVer) + needNoConsole(cmd) + cmd.Env = append(os.Environ(), envOverlay...) + cmd.Stdout = &stdout + cmd.Stderr = &stderr + if err := cmd.Run(); err != nil { + var info struct { + Error string + } + if err := json.Unmarshal(stdout.Bytes(), &info); err == nil && info.Error != "" { + return nil, "", fmt.Errorf("failed to download config module: %v", info.Error) + } + return nil, "", fmt.Errorf("failed to download config module: %w\n%s", err, &stderr) + } + + var info struct { + Dir string + Version string + Error string + } + if err := json.Unmarshal(stdout.Bytes(), &info); err != nil || info.Dir == "" { + return nil, "", fmt.Errorf("failed to download config module (invalid JSON): %w", err) + } + data, err := os.ReadFile(filepath.Join(info.Dir, configFileName)) + if err != nil { + return nil, "", fmt.Errorf("invalid config module: %w", err) + } + cfg := new(telemetry.UploadConfig) + if err := json.Unmarshal(data, cfg); err != nil { + return nil, "", fmt.Errorf("invalid config: %w", err) + } + return cfg, info.Version, nil +} diff --git a/vendor/golang.org/x/telemetry/internal/configstore/download_windows.go b/vendor/golang.org/x/telemetry/internal/configstore/download_windows.go new file mode 100644 index 0000000..1368de1 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/configstore/download_windows.go @@ -0,0 +1,33 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows + +package configstore + +import ( + "os/exec" + "syscall" + + "golang.org/x/sys/windows" +) + +func init() { + needNoConsole = needNoConsoleWindows +} + +func needNoConsoleWindows(cmd *exec.Cmd) { + // The uploader main process is likely a daemonized process with no console. + // (see x/telemetry/start_windows.go) The console creation behavior when + // a parent is a console process without console is not clearly documented + // but empirically we observed the new console is created and attached to the + // subprocess in the default setup. + // + // Ensure no new console is attached to the subprocess by setting CREATE_NO_WINDOW. + // https://learn.microsoft.com/en-us/windows/console/creation-of-a-console + // https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags + cmd.SysProcAttr = &syscall.SysProcAttr{ + CreationFlags: windows.CREATE_NO_WINDOW, + } +} diff --git a/vendor/golang.org/x/telemetry/internal/counter/counter.go b/vendor/golang.org/x/telemetry/internal/counter/counter.go new file mode 100644 index 0000000..c08115e --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/counter/counter.go @@ -0,0 +1,401 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package internal/counter implements the internals of the public counter package. +// In addition to the public API, this package also includes APIs to parse and +// manage the counter files, needed by the upload package. +package counter + +import ( + "fmt" + "os" + "runtime" + "strings" + "sync/atomic" +) + +var ( + // Note: not using internal/godebug, so that internal/godebug can use + // internal/counter. + debugCounter = strings.Contains(os.Getenv("GODEBUG"), "countertrace=1") + CrashOnBugs = false // for testing; if set, exit on fatal log messages +) + +// debugPrintf formats a debug message if GODEBUG=countertrace=1. +func debugPrintf(format string, args ...any) { + if debugCounter { + if len(format) == 0 || format[len(format)-1] != '\n' { + format += "\n" + } + fmt.Fprintf(os.Stderr, "counter: "+format, args...) + } +} + +// debugFatalf logs a fatal error if GODEBUG=countertrace=1. +func debugFatalf(format string, args ...any) { + if debugCounter || CrashOnBugs { + if len(format) == 0 || format[len(format)-1] != '\n' { + format += "\n" + } + fmt.Fprintf(os.Stderr, "counter bug: "+format, args...) + os.Exit(1) + } +} + +// A Counter is a single named event counter. +// A Counter is safe for use by multiple goroutines simultaneously. +// +// Counters should typically be created using New +// and stored as global variables, like: +// +// package mypackage +// var errorCount = counter.New("mypackage/errors") +// +// (The initialization of errorCount in this example is handled +// entirely by the compiler and linker; this line executes no code +// at program startup.) +// +// Then code can call Add to increment the counter +// each time the corresponding event is observed. +// +// Although it is possible to use New to create +// a Counter each time a particular event needs to be recorded, +// that usage fails to amortize the construction cost over +// multiple calls to Add, so it is more expensive and not recommended. +type Counter struct { + name string + file *file + + next atomic.Pointer[Counter] + state counterState + ptr counterPtr +} + +func (c *Counter) Name() string { + return c.name +} + +type counterPtr struct { + m *mappedFile + count *atomic.Uint64 +} + +type counterState struct { + bits atomic.Uint64 +} + +func (s *counterState) load() counterStateBits { + return counterStateBits(s.bits.Load()) +} + +func (s *counterState) update(old *counterStateBits, new counterStateBits) bool { + if s.bits.CompareAndSwap(uint64(*old), uint64(new)) { + *old = new + return true + } + return false +} + +type counterStateBits uint64 + +const ( + stateReaders counterStateBits = 1<<30 - 1 + stateLocked counterStateBits = stateReaders + stateHavePtr counterStateBits = 1 << 30 + stateExtraShift = 31 + stateExtra counterStateBits = 1<<64 - 1<> stateExtraShift } + +func (b counterStateBits) incReader() counterStateBits { return b + 1 } +func (b counterStateBits) decReader() counterStateBits { return b - 1 } +func (b counterStateBits) setLocked() counterStateBits { return b | stateLocked } +func (b counterStateBits) clearLocked() counterStateBits { return b &^ stateLocked } +func (b counterStateBits) setHavePtr() counterStateBits { return b | stateHavePtr } +func (b counterStateBits) clearHavePtr() counterStateBits { return b &^ stateHavePtr } +func (b counterStateBits) clearExtra() counterStateBits { return b &^ stateExtra } +func (b counterStateBits) addExtra(n uint64) counterStateBits { + const maxExtra = uint64(stateExtra) >> stateExtraShift // 0x1ffffffff + x := b.extra() + if x+n < x || x+n > maxExtra { + x = maxExtra + } else { + x += n + } + return b.clearExtra() | counterStateBits(x)< count=%d\n", c.name, extra, sum) + } + + // Took care of refreshing ptr and flushing extra. + // Now we can release the lock, unless of course + // another goroutine cleared havePtr or added to extra, + // in which case we go around again. + if !c.state.update(&state, state.clearLocked()) { + continue + } + debugPrintf("releaseLock %s: unlocked\n", c.name) + return + } +} + +// add wraps the atomic.Uint64.Add operation to handle integer overflow. +func (c *Counter) add(n uint64) uint64 { + count := c.ptr.count + for { + old := count.Load() + sum := old + n + if sum < old { + sum = ^uint64(0) + } + if count.CompareAndSwap(old, sum) { + runtime.KeepAlive(c.ptr.m) + return sum + } + } +} + +func (c *Counter) invalidate() { + for { + state := c.state.load() + if !state.havePtr() { + debugPrintf("invalidate %s: no ptr\n", c.name) + return + } + if c.state.update(&state, state.clearHavePtr()) { + debugPrintf("invalidate %s: cleared havePtr\n", c.name) + return + } + } +} + +func (c *Counter) refresh() { + for { + state := c.state.load() + if state.havePtr() || state.readers() > 0 || state.extra() == 0 { + debugPrintf("refresh %s: havePtr=%v readers=%d extra=%d\n", c.name, state.havePtr(), state.readers(), state.extra()) + return + } + if c.state.update(&state, state.setLocked()) { + debugPrintf("refresh %s: locked havePtr=%v readers=%d extra=%d\n", c.name, state.havePtr(), state.readers(), state.extra()) + c.releaseLock(state) + return + } + } +} + +// Read reads the given counter. +// This is the implementation of x/telemetry/counter/countertest.ReadCounter. +func Read(c *Counter) (uint64, error) { + if c.file.current.Load() == nil { + return c.state.load().extra(), nil + } + pf, err := readFile(c.file) + if err != nil { + return 0, err + } + v, ok := pf.Count[DecodeStack(c.Name())] + if !ok { + return v, fmt.Errorf("not found:%q", DecodeStack(c.Name())) + } + return v, nil +} + +func readFile(f *file) (*File, error) { + if f == nil { + debugPrintf("No file") + return nil, fmt.Errorf("counter is not initialized - was Open called?") + } + + // Note: don't call f.rotate here as this will enqueue a follow-up rotation. + f.rotate1() + + if f.err != nil { + return nil, fmt.Errorf("failed to rotate mapped file - %v", f.err) + } + current := f.current.Load() + if current == nil { + return nil, fmt.Errorf("counter has no mapped file") + } + name := current.f.Name() + data, err := ReadMapped(name) + if err != nil { + return nil, fmt.Errorf("failed to read from file: %v", err) + } + pf, err := Parse(name, data) + if err != nil { + return nil, fmt.Errorf("failed to parse: %v", err) + } + return pf, nil +} + +// ReadFile reads the counters and stack counters from the given file. +// This is the implementation of x/telemetry/counter/countertest.ReadFile. +func ReadFile(name string) (counters, stackCounters map[string]uint64, _ error) { + // TODO: Document the format of the stackCounters names. + + data, err := ReadMapped(name) + if err != nil { + return nil, nil, fmt.Errorf("failed to read from file: %v", err) + } + pf, err := Parse(name, data) + if err != nil { + return nil, nil, fmt.Errorf("failed to parse: %v", err) + } + counters = make(map[string]uint64) + stackCounters = make(map[string]uint64) + for k, v := range pf.Count { + if IsStackCounter(k) { + stackCounters[DecodeStack(k)] = v + } else { + counters[k] = v + } + } + return counters, stackCounters, nil +} + +// ReadMapped reads the contents of the given file by memory mapping. +// +// This avoids file synchronization issues. +func ReadMapped(name string) ([]byte, error) { + f, err := os.OpenFile(name, os.O_RDWR, 0666) + if err != nil { + return nil, err + } + defer f.Close() + fi, err := f.Stat() + if err != nil { + return nil, err + } + mapping, err := memmap(f) + if err != nil { + return nil, err + } + data := make([]byte, fi.Size()) + copy(data, mapping.Data) + munmap(mapping) + return data, nil +} diff --git a/vendor/golang.org/x/telemetry/internal/counter/file.go b/vendor/golang.org/x/telemetry/internal/counter/file.go new file mode 100644 index 0000000..872a6f6 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/counter/file.go @@ -0,0 +1,814 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package counter + +import ( + "bytes" + "errors" + "fmt" + "math/rand" + "os" + "path" + "path/filepath" + "runtime" + "runtime/debug" + "sync" + "sync/atomic" + "time" + "unsafe" + + "golang.org/x/telemetry/internal/mmap" + "golang.org/x/telemetry/internal/telemetry" +) + +// A file is a counter file. +type file struct { + // Linked list of all known counters. + // (Linked list insertion is easy to make lock-free, + // and we don't want the initial counters incremented + // by a program to cause significant contention.) + counters atomic.Pointer[Counter] // head of list + end Counter // list ends at &end instead of nil + + mu sync.Mutex + buildInfo *debug.BuildInfo + timeBegin, timeEnd time.Time + err error + // current holds the current file mapping, which may change when the file is + // rotated or extended. + // + // current may be read without holding mu, but may be nil. + // + // The cleanup logic for file mappings is complicated, because invalidating + // counter pointers is reentrant: [file.invalidateCounters] may call + // [file.lookup], which acquires mu. Therefore, writing current must be done + // as follows: + // 1. record the previous value of current + // 2. Store a new value in current + // 3. unlock mu + // 4. call invalidateCounters + // 5. close the previous mapped value from (1) + // TODO(rfindley): simplify + current atomic.Pointer[mappedFile] +} + +var defaultFile file + +// register ensures that the counter c is registered with the file. +func (f *file) register(c *Counter) { + debugPrintf("register %s %p\n", c.Name(), c) + + // If counter is not registered with file, register it. + // Doing this lazily avoids init-time work + // as well as any execution cost at all for counters + // that are not used in a given program. + wroteNext := false + for wroteNext || c.next.Load() == nil { + head := f.counters.Load() + next := head + if next == nil { + next = &f.end + } + debugPrintf("register %s next %p\n", c.Name(), next) + if !wroteNext { + if !c.next.CompareAndSwap(nil, next) { + debugPrintf("register %s cas failed %p\n", c.Name(), c.next.Load()) + continue + } + wroteNext = true + } else { + c.next.Store(next) + } + if f.counters.CompareAndSwap(head, c) { + debugPrintf("registered %s %p\n", c.Name(), f.counters.Load()) + return + } + debugPrintf("register %s cas2 failed %p %p\n", c.Name(), f.counters.Load(), head) + } +} + +// invalidateCounters marks as invalid all the pointers +// held by f's counters and then refreshes them. +// +// invalidateCounters cannot be called while holding f.mu, +// because a counter refresh may call f.lookup. +func (f *file) invalidateCounters() { + // Mark every counter as needing to refresh its count pointer. + if head := f.counters.Load(); head != nil { + for c := head; c != &f.end; c = c.next.Load() { + c.invalidate() + } + for c := head; c != &f.end; c = c.next.Load() { + c.refresh() + } + } +} + +// lookup looks up the counter with the given name in the file, +// allocating it if needed, and returns a pointer to the atomic.Uint64 +// containing the counter data. +// If the file has not been opened yet, lookup returns nil. +func (f *file) lookup(name string) counterPtr { + current := f.current.Load() + if current == nil { + debugPrintf("lookup %s - no mapped file\n", name) + return counterPtr{} + } + ptr := f.newCounter(name) + if ptr == nil { + return counterPtr{} + } + return counterPtr{current, ptr} +} + +// ErrDisabled is the error returned when telemetry is disabled. +var ErrDisabled = errors.New("counter: disabled as Go telemetry is off") + +var ( + errNoBuildInfo = errors.New("counter: missing build info") + errCorrupt = errors.New("counter: corrupt counter file") +) + +// weekEnd returns the day of the week on which uploads occur (and therefore +// counters expire). +// +// Reads the weekends file, creating one if none exists. +func weekEnd() (time.Weekday, error) { + // If there is no 'weekends' file create it and initialize it + // to a random day of the week. There is a short interval for + // a race. + weekends := filepath.Join(telemetry.Default.LocalDir(), "weekends") + day := fmt.Sprintf("%d\n", rand.Intn(7)) + if _, err := os.ReadFile(weekends); err != nil { + if err := os.MkdirAll(telemetry.Default.LocalDir(), 0777); err != nil { + debugPrintf("%v: could not create telemetry.LocalDir %s", err, telemetry.Default.LocalDir()) + return 0, err + } + if err = os.WriteFile(weekends, []byte(day), 0666); err != nil { + return 0, err + } + } + + // race is over, read the file + buf, err := os.ReadFile(weekends) + // There is no reasonable way of recovering from errors + // so we just fail + if err != nil { + return 0, err + } + buf = bytes.TrimSpace(buf) + if len(buf) == 0 { + return 0, fmt.Errorf("empty weekends file") + } + weekend := time.Weekday(buf[0] - '0') // 0 is Sunday + // paranoia to make sure the value is legal + weekend %= 7 + if weekend < 0 { + weekend += 7 + } + return weekend, nil +} + +// rotate checks to see whether the file f needs to be rotated, +// meaning to start a new counter file with a different date in the name. +// rotate is also used to open the file initially, meaning f.current can be nil. +// In general rotate should be called just once for each file. +// rotate will arrange a timer to call itself again when necessary. +func (f *file) rotate() { + expiry := f.rotate1() + if !expiry.IsZero() { + delay := time.Until(expiry) + // Some tests set CounterTime to a time in the past, causing delay to be + // negative. Avoid infinite loops by delaying at least a short interval. + // + // TODO(rfindley): instead, just also mock AfterFunc. + const minDelay = 1 * time.Minute + if delay < minDelay { + delay = minDelay + } + // TODO(rsc): Does this do the right thing for laptops closing? + time.AfterFunc(delay, f.rotate) + } +} + +func nop() {} + +// CounterTime returns the current UTC time. +// Mutable for testing. +var CounterTime = func() time.Time { + return time.Now().UTC() +} + +// counterSpan returns the current time span for a counter file, as determined +// by [CounterTime] and the [weekEnd]. +func counterSpan() (begin, end time.Time, _ error) { + year, month, day := CounterTime().Date() + begin = time.Date(year, month, day, 0, 0, 0, 0, time.UTC) + // files always begin today, but expire on the next day of the week + // from the 'weekends' file. + weekend, err := weekEnd() + if err != nil { + return time.Time{}, time.Time{}, err + } + incr := int(weekend - begin.Weekday()) + if incr <= 0 { + incr += 7 // ensure that end is later than begin + } + end = time.Date(year, month, day+incr, 0, 0, 0, 0, time.UTC) + return begin, end, nil +} + +// rotate1 rotates the current counter file, returning its expiry, or the zero +// time if rotation failed. +func (f *file) rotate1() time.Time { + // Cleanup must be performed while unlocked, since invalidateCounters may + // involve calls to f.lookup. + var previous *mappedFile // read below while holding the f.mu. + defer func() { + // Counters must be invalidated whenever the mapped file changes. + if next := f.current.Load(); next != previous { + f.invalidateCounters() + // Ensure that the previous counter mapped file is closed. + if previous != nil { + previous.close() // safe to call multiple times + } + } + }() + + f.mu.Lock() + defer f.mu.Unlock() + + previous = f.current.Load() + + if f.err != nil { + return time.Time{} // already in failed state; nothing to do + } + + fail := func(err error) { + debugPrintf("rotate: %v", err) + f.err = err + f.current.Store(nil) + } + + if mode, _ := telemetry.Default.Mode(); mode == "off" { + // TODO(rfindley): do we ever want to make ErrDisabled recoverable? + // Specifically, if f.err is ErrDisabled, should we check again during when + // rotating? + fail(ErrDisabled) + return time.Time{} + } + + if f.buildInfo == nil { + bi, ok := debug.ReadBuildInfo() + if !ok { + fail(errNoBuildInfo) + return time.Time{} + } + f.buildInfo = bi + } + + begin, end, err := counterSpan() + if err != nil { + fail(err) + return time.Time{} + } + if f.timeBegin.Equal(begin) && f.timeEnd.Equal(end) { + return f.timeEnd // nothing to do + } + f.timeBegin, f.timeEnd = begin, end + + goVers, progPath, progVers := telemetry.ProgramInfo(f.buildInfo) + meta := fmt.Sprintf("TimeBegin: %s\nTimeEnd: %s\nProgram: %s\nVersion: %s\nGoVersion: %s\nGOOS: %s\nGOARCH: %s\n\n", + f.timeBegin.Format(time.RFC3339), f.timeEnd.Format(time.RFC3339), + progPath, progVers, goVers, runtime.GOOS, runtime.GOARCH) + if len(meta) > maxMetaLen { // should be impossible for our use + fail(fmt.Errorf("metadata too long")) + return time.Time{} + } + + if progVers != "" { + progVers = "@" + progVers + } + baseName := fmt.Sprintf("%s%s-%s-%s-%s-%s.%s.count", + path.Base(progPath), + progVers, + goVers, + runtime.GOOS, + runtime.GOARCH, + f.timeBegin.Format(telemetry.DateOnly), + FileVersion, + ) + dir := telemetry.Default.LocalDir() + if err := os.MkdirAll(dir, 0777); err != nil { + fail(fmt.Errorf("making local dir: %v", err)) + return time.Time{} + } + name := filepath.Join(dir, baseName) + + m, err := openMapped(name, meta) + if err != nil { + // Mapping failed: + // If there used to be a mapped file, after cleanup + // incrementing counters will only change their internal state. + // (before cleanup the existing mapped file would be updated) + fail(fmt.Errorf("openMapped: %v", err)) + return time.Time{} + } + + debugPrintf("using %v", m.f.Name()) + f.current.Store(m) + return f.timeEnd +} + +func (f *file) newCounter(name string) *atomic.Uint64 { + v, cleanup := f.newCounter1(name) + cleanup() + return v +} + +func (f *file) newCounter1(name string) (v *atomic.Uint64, cleanup func()) { + f.mu.Lock() + defer f.mu.Unlock() + + current := f.current.Load() + if current == nil { + return nil, nop + } + debugPrintf("newCounter %s in %s\n", name, current.f.Name()) + if v, _, _, _ := current.lookup(name); v != nil { + return v, nop + } + v, newM, err := current.newCounter(name) + if err != nil { + debugPrintf("newCounter %s: %v\n", name, err) + return nil, nop + } + + cleanup = nop + if newM != nil { + f.current.Store(newM) + cleanup = func() { + f.invalidateCounters() + current.close() + } + } + return v, cleanup +} + +var ( + openOnce sync.Once + // rotating reports whether the call to Open had rotate = true. + // + // In golang/go#68497, we observed that file rotation can break runtime + // deadlock detection. To minimize the fix for 1.23, we are splitting the + // Open API into one version that rotates the counter file, and another that + // does not. The rotating variable guards against use of both APIs from the + // same process. + rotating bool +) + +// Open associates counting with the defaultFile. +// The returned function is for testing only, and should +// be called after all Inc()s are finished, but before +// any reports are generated. +// (Otherwise expired count files will not be deleted on Windows.) +func Open(rotate bool) func() { + if telemetry.DisabledOnPlatform { + return func() {} + } + close := func() {} + openOnce.Do(func() { + rotating = rotate + if mode, _ := telemetry.Default.Mode(); mode == "off" { + // Don't open the file when telemetry is off. + defaultFile.err = ErrDisabled + // No need to clean up. + return + } + debugPrintf("Open(%v)", rotate) + if rotate { + defaultFile.rotate() // calls rotate1 and schedules a rotation + } else { + defaultFile.rotate1() + } + close = func() { + // Once this has been called, the defaultFile is no longer usable. + mf := defaultFile.current.Load() + if mf == nil { + // telemetry might have been off + return + } + mf.close() + } + }) + if rotating != rotate { + panic("BUG: Open called with inconsistent values for 'rotate'") + } + return close +} + +const ( + FileVersion = "v1" + hdrPrefix = "# telemetry/counter file " + FileVersion + "\n" + recordUnit = 32 + maxMetaLen = 512 + numHash = 512 // 2kB for hash table + maxNameLen = 4 * 1024 + limitOff = 0 + hashOff = 4 + pageSize = 16 * 1024 + minFileLen = 16 * 1024 +) + +// A mappedFile is a counter file mmapped into memory. +// +// The file layout for a mappedFile m is as follows: +// +// offset, byte size: description +// ------------------ ----------- +// 0, hdrLen: header, containing metadata; see [mappedHeader] +// hdrLen+limitOff, 4: uint32 allocation limit (byte offset of the end of counter records) +// hdrLen+hashOff, 4*numHash: hash table, stores uint32 heads of a linked list of records, keyed by name hash +// hdrLen+hashOff+4*numHash to limit: counter records: see record syntax below +// +// The record layout is as follows: +// +// offset, byte size: description +// ------------------ ----------- +// 0, 8: uint64 counter value +// 8, 12: uint32 name length +// 12, 16: uint32 offset of next record in linked list +// 16, name length: counter name +type mappedFile struct { + meta string + hdrLen uint32 + zero [4]byte + closeOnce sync.Once + f *os.File + mapping *mmap.Data +} + +// openMapped opens and memory maps a file. +// +// name is the path to the file. +// +// meta is the file metadata, which must match the metadata of the file on disk +// exactly. +// +// existing should be nil the first time this is called for a file, +// and when remapping, should be the previous mappedFile. +func openMapped(name, meta string) (_ *mappedFile, err error) { + hdr, err := mappedHeader(meta) + if err != nil { + return nil, err + } + + f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE, 0666) + if err != nil { + return nil, err + } + // Note: using local variable m here, not return value, + // so that return nil, err does not set m = nil and break the code in the defer. + m := &mappedFile{ + f: f, + meta: meta, + } + + defer func() { + if err != nil { + m.close() + } + }() + + info, err := f.Stat() + if err != nil { + return nil, err + } + + // Establish file header and initial data area if not already present. + if info.Size() < minFileLen { + if _, err := f.WriteAt(hdr, 0); err != nil { + return nil, err + } + // Write zeros at the end of the file to extend it to minFileLen. + if _, err := f.WriteAt(m.zero[:], int64(minFileLen-len(m.zero))); err != nil { + return nil, err + } + info, err = f.Stat() + if err != nil { + return nil, err + } + if info.Size() < minFileLen { + return nil, fmt.Errorf("counter: writing file did not extend it") + } + } + + // Map into memory. + mapping, err := memmap(f) + if err != nil { + return nil, err + } + m.mapping = mapping + if !bytes.HasPrefix(m.mapping.Data, hdr) { + // TODO(rfindley): we can and should do better here, reading the mapped + // header length and comparing headers exactly. + return nil, fmt.Errorf("counter: header mismatch") + } + m.hdrLen = uint32(len(hdr)) + + return m, nil +} + +func mappedHeader(meta string) ([]byte, error) { + if len(meta) > maxMetaLen { + return nil, fmt.Errorf("counter: metadata too large") + } + np := round(len(hdrPrefix), 4) + n := round(np+4+len(meta), 32) + hdr := make([]byte, n) + copy(hdr, hdrPrefix) + *(*uint32)(unsafe.Pointer(&hdr[np])) = uint32(n) + copy(hdr[np+4:], meta) + return hdr, nil +} + +func (m *mappedFile) place(limit uint32, name string) (start, end uint32) { + if limit == 0 { + // first record in file + limit = m.hdrLen + hashOff + 4*numHash + } + n := round(uint32(16+len(name)), recordUnit) + start = round(limit, recordUnit) // should already be rounded but just in case + // Note: Checking for crossing a page boundary would be + // start/pageSize != (start+n-1)/pageSize, + // but we are checking for reaching the page end, so no -1. + // The page end is reserved for use by extend. + // See the comment in m.extend. + if start/pageSize != (start+n)/pageSize { + // bump start to next page + start = round(limit, pageSize) + } + return start, start + n +} + +var memmap = mmap.Mmap +var munmap = mmap.Munmap + +func (m *mappedFile) close() { + m.closeOnce.Do(func() { + if m.mapping != nil { + munmap(m.mapping) + m.mapping = nil + } + if m.f != nil { + m.f.Close() // best effort + m.f = nil + } + }) +} + +// hash returns the hash code for name. +// The implementation is FNV-1a. +// This hash function is a fixed detail of the file format. +// It cannot be changed without also changing the file format version. +func hash(name string) uint32 { + const ( + offset32 = 2166136261 + prime32 = 16777619 + ) + h := uint32(offset32) + for i := 0; i < len(name); i++ { + c := name[i] + h = (h ^ uint32(c)) * prime32 + } + return (h ^ (h >> 16)) % numHash +} + +func (m *mappedFile) load32(off uint32) uint32 { + if int64(off) >= int64(len(m.mapping.Data)) { + return 0 + } + return (*atomic.Uint32)(unsafe.Pointer(&m.mapping.Data[off])).Load() +} + +func (m *mappedFile) cas32(off, old, new uint32) bool { + if int64(off) >= int64(len(m.mapping.Data)) { + panic("bad cas32") // return false would probably loop + } + return (*atomic.Uint32)(unsafe.Pointer(&m.mapping.Data[off])).CompareAndSwap(old, new) +} + +// entryAt reads a counter record at the given byte offset. +// +// See the documentation for [mappedFile] for a description of the counter record layout. +func (m *mappedFile) entryAt(off uint32) (name []byte, next uint32, v *atomic.Uint64, ok bool) { + if off < m.hdrLen+hashOff || int64(off)+16 > int64(len(m.mapping.Data)) { + return nil, 0, nil, false + } + nameLen := m.load32(off+8) & 0x00ffffff + if nameLen == 0 || int64(off)+16+int64(nameLen) > int64(len(m.mapping.Data)) { + return nil, 0, nil, false + } + name = m.mapping.Data[off+16 : off+16+nameLen] + next = m.load32(off + 12) + v = (*atomic.Uint64)(unsafe.Pointer(&m.mapping.Data[off])) + return name, next, v, true +} + +// writeEntryAt writes a new counter record at the given offset. +// +// See the documentation for [mappedFile] for a description of the counter record layout. +// +// writeEntryAt only returns false in the presence of some form of corruption: +// an offset outside the bounds of the record region in the mapped file. +func (m *mappedFile) writeEntryAt(off uint32, name string) (next *atomic.Uint32, v *atomic.Uint64, ok bool) { + // TODO(rfindley): shouldn't this first condition be off < m.hdrLen+hashOff+4*numHash? + if off < m.hdrLen+hashOff || int64(off)+16+int64(len(name)) > int64(len(m.mapping.Data)) { + return nil, nil, false + } + copy(m.mapping.Data[off+16:], name) + atomic.StoreUint32((*uint32)(unsafe.Pointer(&m.mapping.Data[off+8])), uint32(len(name))|0xff000000) + next = (*atomic.Uint32)(unsafe.Pointer(&m.mapping.Data[off+12])) + v = (*atomic.Uint64)(unsafe.Pointer(&m.mapping.Data[off])) + return next, v, true +} + +// lookup searches the mapped file for a counter record with the given name, returning: +// - v: the mapped counter value +// - headOff: the offset of the head pointer (see [mappedFile]) +// - head: the value of the head pointer +// - ok: whether lookup succeeded +func (m *mappedFile) lookup(name string) (v *atomic.Uint64, headOff, head uint32, ok bool) { + h := hash(name) + headOff = m.hdrLen + hashOff + h*4 + head = m.load32(headOff) + off := head + for off != 0 { + ename, next, v, ok := m.entryAt(off) + if !ok { + return nil, 0, 0, false + } + if string(ename) == name { + return v, headOff, head, true + } + off = next + } + return nil, headOff, head, true +} + +// newCounter allocates and writes a new counter record with the given name. +// +// If name is already recorded in the file, newCounter returns the existing counter. +func (m *mappedFile) newCounter(name string) (v *atomic.Uint64, m1 *mappedFile, err error) { + if len(name) > maxNameLen { + return nil, nil, fmt.Errorf("counter name too long") + } + orig := m + defer func() { + if m != orig { + if err != nil { + m.close() + } else { + m1 = m + } + } + }() + + v, headOff, head, ok := m.lookup(name) + for tries := 0; !ok; tries++ { + if tries >= 10 { + debugFatalf("corrupt: failed to remap after 10 tries") + return nil, nil, errCorrupt + } + // Lookup found an invalid pointer, + // perhaps because the file has grown larger than the mapping. + limit := m.load32(m.hdrLen + limitOff) + if limit, datalen := int64(limit), int64(len(m.mapping.Data)); limit <= datalen { + // Mapping doesn't need to grow, so lookup found actual corruption, + // in the form of an entry pointer that exceeds the recorded allocation + // limit. This should never happen, unless the actual file contents are + // corrupt. + debugFatalf("corrupt: limit %d is within mapping length %d", limit, datalen) + return nil, nil, errCorrupt + } + // That the recorded limit is greater than the mapped data indicates that + // an external process has extended the file. Re-map to pick up this extension. + newM, err := openMapped(m.f.Name(), m.meta) + if err != nil { + return nil, nil, err + } + if limit, datalen := int64(limit), int64(len(newM.mapping.Data)); limit > datalen { + // We've re-mapped, yet limit still exceeds the data length. This + // indicates that the underlying file was somehow truncated, or the + // recorded limit is corrupt. + debugFatalf("corrupt: limit %d exceeds file size %d", limit, datalen) + return nil, nil, errCorrupt + } + // If m != orig, this is at least the second time around the loop + // trying to open the mapping. Close the previous attempt. + if m != orig { + m.close() + } + m = newM + v, headOff, head, ok = m.lookup(name) + } + if v != nil { + return v, nil, nil + } + + // Reserve space for new record. + // We are competing against other programs using the same file, + // so we use a compare-and-swap on the allocation limit in the header. + var start, end uint32 + for { + // Determine where record should end, and grow file if needed. + limit := m.load32(m.hdrLen + limitOff) + start, end = m.place(limit, name) + debugPrintf("place %s at %#x-%#x\n", name, start, end) + if int64(end) > int64(len(m.mapping.Data)) { + newM, err := m.extend(end) + if err != nil { + return nil, nil, err + } + if m != orig { + m.close() + } + m = newM + continue + } + + // Attempt to reserve that space for our record. + if m.cas32(m.hdrLen+limitOff, limit, end) { + break + } + } + + // Write record. + next, v, ok := m.writeEntryAt(start, name) + if !ok { + debugFatalf("corrupt: failed to write entry: %#x+%d vs %#x\n", start, len(name), len(m.mapping.Data)) + return nil, nil, errCorrupt // more likely our math is wrong + } + + // Link record into hash chain, making sure not to introduce a duplicate. + // We know name does not appear in the chain starting at head. + for { + next.Store(head) + if m.cas32(headOff, head, start) { + return v, nil, nil + } + + // Check new elements in chain for duplicates. + old := head + head = m.load32(headOff) + for off := head; off != old; { + ename, enext, v, ok := m.entryAt(off) + if !ok { + return nil, nil, errCorrupt + } + if string(ename) == name { + next.Store(^uint32(0)) // mark ours as dead + return v, nil, nil + } + off = enext + } + } +} + +func (m *mappedFile) extend(end uint32) (*mappedFile, error) { + end = round(end, pageSize) + info, err := m.f.Stat() + if err != nil { + return nil, err + } + if info.Size() < int64(end) { + // Note: multiple processes could be calling extend at the same time, + // but this write only writes the last 4 bytes of the page. + // The last 4 bytes of the page are reserved for this purpose and hold no data. + // (In m.place, if a new record would extend to the very end of the page, + // it is placed in the next page instead.) + // So it is fine if multiple processes extend at the same time. + if _, err := m.f.WriteAt(m.zero[:], int64(end)-int64(len(m.zero))); err != nil { + return nil, err + } + } + newM, err := openMapped(m.f.Name(), m.meta) + if err != nil { + return nil, err + } + if int64(len(newM.mapping.Data)) < int64(end) { + // File system or logic bug: new file is somehow not extended. + // See go.dev/issue/68311, where this appears to have been happening. + newM.close() + return nil, errCorrupt + } + return newM, err +} + +// round returns x rounded up to the next multiple of unit, +// which must be a power of two. +func round[T int | uint32](x T, unit T) T { + return (x + unit - 1) &^ (unit - 1) +} diff --git a/vendor/golang.org/x/telemetry/internal/counter/parse.go b/vendor/golang.org/x/telemetry/internal/counter/parse.go new file mode 100644 index 0000000..a42a351 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/counter/parse.go @@ -0,0 +1,82 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package counter + +import ( + "bytes" + "fmt" + "strings" + "unsafe" + + "golang.org/x/telemetry/internal/mmap" +) + +type File struct { + Meta map[string]string + Count map[string]uint64 +} + +func Parse(filename string, data []byte) (*File, error) { + if !bytes.HasPrefix(data, []byte(hdrPrefix)) || len(data) < pageSize { + if len(data) < pageSize { + return nil, fmt.Errorf("%s: file too short (%d<%d)", filename, len(data), pageSize) + } + return nil, fmt.Errorf("%s: wrong hdr (not %q)", filename, hdrPrefix) + } + corrupt := func() (*File, error) { + // TODO(rfindley): return a useful error message. + return nil, fmt.Errorf("%s: corrupt counter file", filename) + } + + f := &File{ + Meta: make(map[string]string), + Count: make(map[string]uint64), + } + np := round(len(hdrPrefix), 4) + hdrLen := *(*uint32)(unsafe.Pointer(&data[np])) + if hdrLen > pageSize { + return corrupt() + } + meta := data[np+4 : hdrLen] + if i := bytes.IndexByte(meta, 0); i >= 0 { + meta = meta[:i] + } + m := &mappedFile{ + meta: string(meta), + hdrLen: hdrLen, + mapping: &mmap.Data{Data: data}, + } + + lines := strings.Split(m.meta, "\n") + for _, line := range lines { + if line == "" { + continue + } + k, v, ok := strings.Cut(line, ": ") + if !ok { + return corrupt() + } + f.Meta[k] = v + } + + for i := uint32(0); i < numHash; i++ { + headOff := hdrLen + hashOff + i*4 + head := m.load32(headOff) + off := head + for off != 0 { + ename, next, v, ok := m.entryAt(off) + if !ok { + return corrupt() + } + if _, ok := f.Count[string(ename)]; ok { + return corrupt() + } + ctrName := DecodeStack(string(ename)) + f.Count[ctrName] = v.Load() + off = next + } + } + return f, nil +} diff --git a/vendor/golang.org/x/telemetry/internal/counter/stackcounter.go b/vendor/golang.org/x/telemetry/internal/counter/stackcounter.go new file mode 100644 index 0000000..3e7ffde --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/counter/stackcounter.go @@ -0,0 +1,212 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package counter + +import ( + "fmt" + "runtime" + "strings" + "sync" +) + +// On the disk, and upstream, stack counters look like sets of +// regular counters with names that include newlines. + +// a StackCounter is the in-memory knowledge about a stack counter. +// StackCounters are more expensive to use than regular Counters, +// requiring, at a minimum, a call to runtime.Callers. +type StackCounter struct { + name string + depth int + file *file + + mu sync.Mutex + // as this is a detail of the implementation, it could be replaced + // by a more efficient mechanism + stacks []stack +} + +type stack struct { + pcs []uintptr + counter *Counter +} + +func NewStack(name string, depth int) *StackCounter { + return &StackCounter{name: name, depth: depth, file: &defaultFile} +} + +// Inc increments a stack counter. It computes the caller's stack and +// looks up the corresponding counter. It then increments that counter, +// creating it if necessary. +func (c *StackCounter) Inc() { + pcs := make([]uintptr, c.depth) + n := runtime.Callers(2, pcs) // caller of Inc + pcs = pcs[:n] + + c.mu.Lock() + defer c.mu.Unlock() + + // Existing counter? + var ctr *Counter + for _, s := range c.stacks { + if eq(s.pcs, pcs) { + if s.counter != nil { + ctr = s.counter + break + } + } + } + + if ctr == nil { + // Create new counter. + ctr = &Counter{ + name: EncodeStack(pcs, c.name), + file: c.file, + } + c.stacks = append(c.stacks, stack{pcs: pcs, counter: ctr}) + } + + ctr.Inc() +} + +// EncodeStack returns the name of the counter to +// use for the given stack of program counters. +// The name encodes the stack. +func EncodeStack(pcs []uintptr, prefix string) string { + var locs []string + lastImport := "" + frs := runtime.CallersFrames(pcs) + for { + fr, more := frs.Next() + // TODO(adonovan): this CutLast(".") operation isn't + // appropriate for generic function symbols. + path, fname := cutLastDot(fr.Function) + if path == lastImport { + path = `"` // (a ditto mark) + } else { + lastImport = path + } + var loc string + if fr.Func != nil { + // Use function-relative line numbering. + // f:+2 means two lines into function f. + // f:-1 should never happen, but be conservative. + // + // An inlined call is replaced by a NOP instruction + // with the correct pclntab information. + _, entryLine := fr.Func.FileLine(fr.Entry) + loc = fmt.Sprintf("%s.%s:%+d,+0x%x", path, fname, fr.Line-entryLine, fr.PC-fr.Entry) + } else { + // The function is non-Go code or is fully inlined: + // use absolute line number within enclosing file. + // + // For inlined calls, the PC and Entry values + // both refer to the enclosing combined function. + // For example, both these PCs are relative to "caller": + // + // callee:=1,+0x12 ('=' means inlined) + // caller:+2,+0x34 + loc = fmt.Sprintf("%s.%s:=%d,+0x%x", path, fname, fr.Line, fr.PC-fr.Entry) + } + locs = append(locs, loc) + if !more { + break + } + } + + name := prefix + "\n" + strings.Join(locs, "\n") + if len(name) > maxNameLen { + const bad = "\ntruncated\n" + name = name[:maxNameLen-len(bad)] + bad + } + return name +} + +// DecodeStack expands the (compressed) stack encoded in the counter name. +func DecodeStack(ename string) string { + if !strings.Contains(ename, "\n") { + return ename // not a stack counter + } + lines := strings.Split(ename, "\n") + var lastPath string // empty or ends with . + for i, line := range lines { + path, rest := cutLastDot(line) + if len(path) == 0 { + continue // unchanged + } + if len(path) == 1 && path[0] == '"' { + lines[i] = lastPath + rest + } else { + lastPath = path + "." + // line unchanged + } + } + return strings.Join(lines, "\n") // trailing \n? +} + +// input is . +// output is (import path, function name) +func cutLastDot(x string) (before, after string) { + i := strings.LastIndex(x, ".") + if i < 0 { + return "", x + } + return x[:i], x[i+1:] +} + +// Names reports all the counter names associated with a StackCounter. +func (c *StackCounter) Names() []string { + c.mu.Lock() + defer c.mu.Unlock() + names := make([]string, len(c.stacks)) + for i, s := range c.stacks { + names[i] = s.counter.Name() + } + return names +} + +// Counters returns the known Counters for a StackCounter. +// There may be more in the count file. +func (c *StackCounter) Counters() []*Counter { + c.mu.Lock() + defer c.mu.Unlock() + counters := make([]*Counter, len(c.stacks)) + for i, s := range c.stacks { + counters[i] = s.counter + } + return counters +} + +func eq(a, b []uintptr) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} + +// ReadStack reads the given stack counter. +// This is the implementation of +// golang.org/x/telemetry/counter/countertest.ReadStackCounter. +func ReadStack(c *StackCounter) (map[string]uint64, error) { + ret := map[string]uint64{} + for _, ctr := range c.Counters() { + v, err := Read(ctr) + if err != nil { + return nil, err + } + ret[DecodeStack(ctr.Name())] = v + } + return ret, nil +} + +// IsStackCounter reports whether the counter name is for a stack counter. +func IsStackCounter(name string) bool { + return strings.Contains(name, "\n") +} diff --git a/vendor/golang.org/x/telemetry/internal/crashmonitor/monitor.go b/vendor/golang.org/x/telemetry/internal/crashmonitor/monitor.go new file mode 100644 index 0000000..f6e6c70 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/crashmonitor/monitor.go @@ -0,0 +1,367 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package crashmonitor + +// This file defines a monitor that reports arbitrary Go runtime +// crashes to telemetry. + +import ( + "bytes" + "fmt" + "io" + "log" + "os" + "reflect" + "runtime/debug" + "strconv" + "strings" + + "golang.org/x/telemetry/internal/counter" +) + +// Parent sets up the parent side of the crashmonitor. It requires +// exclusive use of a writable pipe connected to the child process's stdin. +func Parent(pipe *os.File) { + writeSentinel(pipe) + // Ensure that we get pc=0x%x values in the traceback. + debug.SetTraceback("system") + debug.SetCrashOutput(pipe, debug.CrashOptions{}) // ignore error +} + +// Child runs the part of the crashmonitor that runs in the child process. +// It expects its stdin to be connected via a pipe to the parent which has +// run Parent. +func Child() { + // Wait for parent process's dying gasp. + // If the parent dies for any reason this read will return. + data, err := io.ReadAll(os.Stdin) + if err != nil { + log.Fatalf("failed to read from input pipe: %v", err) + } + + // If the only line is the sentinel, it wasn't a crash. + if bytes.Count(data, []byte("\n")) < 2 { + childExitHook() + os.Exit(0) // parent exited without crash report + } + + log.Printf("parent reported crash:\n%s", data) + + // Parse the stack out of the crash report + // and record a telemetry count for it. + name, err := telemetryCounterName(data) + if err != nil { + // Keep count of how often this happens + // so that we can investigate if necessary. + incrementCounter("crash/malformed") + + // Something went wrong. + // Save the crash securely in the file system. + f, err := os.CreateTemp(os.TempDir(), "*.crash") + if err != nil { + log.Fatal(err) + } + if _, err := f.Write(data); err != nil { + log.Fatal(err) + } + if err := f.Close(); err != nil { + log.Fatal(err) + } + log.Printf("failed to report crash to telemetry: %v", err) + log.Fatalf("crash report saved at %s", f.Name()) + } + + incrementCounter(name) + + childExitHook() + log.Fatalf("telemetry crash recorded") +} + +// (stubbed by test) +var ( + incrementCounter = func(name string) { counter.New(name).Inc() } + childExitHook = func() {} +) + +// The sentinel function returns its address. The difference between +// this value as observed by calls in two different processes of the +// same executable tells us the relative offset of their text segments. +// +// It would be nice if SetCrashOutput took care of this as it's fiddly +// and likely to confuse every user at first. +func sentinel() uint64 { + return uint64(reflect.ValueOf(sentinel).Pointer()) +} + +func writeSentinel(out io.Writer) { + fmt.Fprintf(out, "sentinel %x\n", sentinel()) +} + +// telemetryCounterName parses a crash report produced by the Go +// runtime, extracts the stack of the first runnable goroutine, +// converts each line into telemetry form ("symbol:relative-line"), +// and returns this as the name of a counter. +func telemetryCounterName(crash []byte) (string, error) { + pcs, err := parseStackPCs(string(crash)) + if err != nil { + return "", err + } + + // Limit the number of frames we request. + pcs = pcs[:min(len(pcs), 16)] + + if len(pcs) == 0 { + // This can occur if all goroutines are idle, as when + // caught in a deadlock, or killed by an async signal + // while blocked. + // + // TODO(adonovan): consider how to report such + // situations. Reporting a goroutine in [sleep] or + // [select] state could be quite confusing without + // further information about the nature of the crash, + // as the problem is not local to the code location. + // + // For now, we keep count of this situation so that we + // can access whether it needs a more involved solution. + return "crash/no-running-goroutine", nil + } + + // This string appears at the start of all + // crashmonitor-generated counter names. + // + // It is tempting to expose this as a parameter of Start, but + // it is not without risk. What value should most programs + // provide? There's no point giving the name of the executable + // as this is already recorded by telemetry. What if the + // application runs in multiple modes? Then it might be useful + // to record the mode. The problem is that an application with + // multiple modes probably doesn't know its mode by line 1 of + // main.main: it might require flag or argument parsing, or + // even validation of an environment variable, and we really + // want to steer users aware from any logic before Start. The + // flags and arguments will be wrong in the child process, and + // every extra conditional branch creates a risk that the + // recursively executed child program will behave not like the + // monitor but like the application. If the child process + // exits before calling Start, then the parent application + // will not have a monitor, and its crash reports will be + // discarded (written in to a pipe that is never read). + // + // So for now, we use this constant string. + const prefix = "crash/crash" + return counter.EncodeStack(pcs, prefix), nil +} + +// parseStackPCs parses the parent process's program counters for the +// first running goroutine out of a GOTRACEBACK=system traceback, +// adjusting them so that they are valid for the child process's text +// segment. +// +// This function returns only program counter values, ensuring that +// there is no possibility of strings from the crash report (which may +// contain PII) leaking into the telemetry system. +func parseStackPCs(crash string) ([]uintptr, error) { + // getSymbol parses the symbol name out of a line of the form: + // SYMBOL(ARGS) + // + // Note: SYMBOL may contain parens "pkg.(*T).method". However, type + // parameters are always replaced with ..., so they cannot introduce + // more parens. e.g., "pkg.(*T[...]).method". + // + // ARGS can contain parens. We want the first paren that is not + // immediately preceded by a ".". + // + // TODO(prattmic): This is mildly complicated and is only used to find + // runtime.sigpanic, so perhaps simplify this by checking explicitly + // for sigpanic. + getSymbol := func(line string) (string, error) { + var prev rune + for i, c := range line { + if line[i] != '(' { + prev = c + continue + } + if prev == '.' { + prev = c + continue + } + return line[:i], nil + } + return "", fmt.Errorf("no symbol for stack frame: %s", line) + } + + // getPC parses the PC out of a line of the form: + // \tFILE:LINE +0xRELPC sp=... fp=... pc=... + getPC := func(line string) (uint64, error) { + _, pcstr, ok := strings.Cut(line, " pc=") // e.g. pc=0x%x + if !ok { + return 0, fmt.Errorf("no pc= for stack frame: %s", line) + } + return strconv.ParseUint(pcstr, 0, 64) // 0 => allow 0x prefix + } + + type goroutine struct { + id uint64 + pcs []uintptr + system bool // stack starts with runtime.systemstack_switch + } + + var ( + glist []*goroutine + parentSentinel uint64 + childSentinel = sentinel() + lines = strings.Split(crash, "\n") + + // Parsing state for the current goroutine. + g *goroutine + symLine = true // a symbol (not a filename) is expected on this line + currSymbol string + prevSymbol string + ) + + for _, line := range lines { + // Read sentinel value. + if parentSentinel == 0 && strings.HasPrefix(line, "sentinel ") { + _, err := fmt.Sscanf(line, "sentinel %x", &parentSentinel) + if err != nil { + return nil, fmt.Errorf("can't read sentinel line") + } + continue + } + + // Check for a "goroutine GID [STATUS]" header. + if strings.HasPrefix(line, "goroutine ") { + if parentSentinel == 0 { + return nil, fmt.Errorf("no sentinel value in crash report") + } + isG0 := strings.HasPrefix(line, "goroutine 0 ") + isRunning := strings.Contains(line, " [running]:") + if isG0 || isRunning { + var id uint64 + if parts := strings.Fields(line); len(parts) > 1 { + id, _ = strconv.ParseUint(parts[1], 10, 64) + } + g = &goroutine{id: id} + glist = append(glist, g) + symLine = true + currSymbol = "" + prevSymbol = "" + } else { + g = nil + } + continue + } + + if g == nil { + continue + } + + // A blank line or "created by " marks the end of the goroutine stack. + if line == "" || strings.HasPrefix(line, "created by ") { + g = nil + continue + } + + // Expect a pair of lines: + // SYMBOL(ARGS) + // \tFILE:LINE +0xRELPC sp=0x%x fp=0x%x pc=0x%x + // Note: SYMBOL may contain parens "pkg.(*T).method" + // The RELPC is sometimes missing. + + if symLine { + var err error + currSymbol, err = getSymbol(line) + if err != nil { + return nil, fmt.Errorf("error extracting symbol: %v", err) + } + + symLine = false // Next line is FILE:LINE. + } else { + // Parse the PC, and correct for the parent and child's + // different mappings of the text section. + pc, err := getPC(line) + if err != nil { + // Inlined frame, perhaps; skip it. + + // Done with this frame. Next line is a new frame. + // + // Don't update prevSymbol; we only want to + // track frames with a PC. + currSymbol = "" + symLine = true + continue + } + + pc = pc - parentSentinel + childSentinel + + // If the previous frame was sigpanic, then this frame + // was a trap (e.g., SIGSEGV). + // + // Typically all middle frames are calls, and report + // the "return PC". That is, the instruction following + // the CALL where the callee will eventually return to. + // + // runtime.CallersFrames is aware of this property and + // will decrement each PC by 1 to "back up" to the + // location of the CALL, which is the actual line + // number the user expects. + // + // This does not work for traps, as a trap is not a + // call, so the reported PC is not the return PC, but + // the actual PC of the trap. + // + // runtime.Callers is aware of this and will + // intentionally increment trap PCs in order to correct + // for the decrement performed by + // runtime.CallersFrames. See runtime.tracebackPCs and + // runtume.(*unwinder).symPC. + // + // We must emulate the same behavior, otherwise we will + // report the location of the instruction immediately + // prior to the trap, which may be on a different line, + // or even a different inlined functions. + // + // TODO(prattmic): The runtime applies the same trap + // behavior for other "injected calls", see injectCall + // in runtime.(*unwinder).next. Do we want to handle + // those as well? I don't believe we'd ever see + // runtime.asyncPreempt or runtime.debugCallV2 in a + // typical crash. + if prevSymbol == "runtime.sigpanic" { + pc++ + } + + if len(g.pcs) == 0 && currSymbol == "runtime.systemstack_switch" { + g.system = true + } + g.pcs = append(g.pcs, uintptr(pc)) + + // Done with this frame. Next line is a new frame. + prevSymbol = currSymbol + currSymbol = "" + symLine = true + } + } + + if len(glist) == 0 { + return nil, nil + } + + // The first goroutine in the dump is the one that crashed. + firstG := glist[0] + + // If the first goroutine is g0 (the system stack), we want to find the user + // goroutine that called it, which will start with systemstack_switch. + if firstG.id == 0 { + for _, g := range glist[1:] { + if g.system && len(g.pcs) > 0 { + // Stitch the g0 stack and user stack (skipping systemstack_switch). + return append(firstG.pcs, g.pcs[1:]...), nil + } + } + } + + return firstG.pcs, nil +} diff --git a/vendor/golang.org/x/telemetry/internal/mmap/mmap.go b/vendor/golang.org/x/telemetry/internal/mmap/mmap.go new file mode 100644 index 0000000..2febe3e --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/mmap/mmap.go @@ -0,0 +1,36 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This package is a lightly modified version of the mmap code +// in github.com/google/codesearch/index. + +// The mmap package provides an abstraction for memory mapping files +// on different platforms. +package mmap + +import ( + "os" +) + +// The backing file is never closed, so Data +// remains valid for the lifetime of the process. +type Data struct { + // TODO(pjw): might be better to define versions of Data + // for the 3 specializations + f *os.File + Data []byte + // Some windows magic + Windows interface{} +} + +// Mmap maps the given file into memory. +// When remapping a file, pass the most recently returned Data. +func Mmap(f *os.File) (*Data, error) { + return mmapFile(f) +} + +// Munmap unmaps the given file from memory. +func Munmap(d *Data) error { + return munmapFile(d) +} diff --git a/vendor/golang.org/x/telemetry/internal/mmap/mmap_other.go b/vendor/golang.org/x/telemetry/internal/mmap/mmap_other.go new file mode 100644 index 0000000..610ab1a --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/mmap/mmap_other.go @@ -0,0 +1,25 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build (js && wasm) || wasip1 || plan9 + +package mmap + +import ( + "io" + "os" +) + +// mmapFile on other systems doesn't mmap the file. It just reads everything. +func mmapFile(f *os.File) (*Data, error) { + b, err := io.ReadAll(f) + if err != nil { + return nil, err + } + return &Data{f, b, nil}, nil +} + +func munmapFile(_ *Data) error { + return nil +} diff --git a/vendor/golang.org/x/telemetry/internal/mmap/mmap_unix.go b/vendor/golang.org/x/telemetry/internal/mmap/mmap_unix.go new file mode 100644 index 0000000..72ad91d --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/mmap/mmap_unix.go @@ -0,0 +1,47 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build unix + +package mmap + +import ( + "fmt" + "io/fs" + "os" + "syscall" +) + +func mmapFile(f *os.File) (*Data, error) { + st, err := f.Stat() + if err != nil { + return nil, err + } + size := st.Size() + pagesize := int64(os.Getpagesize()) + if int64(int(size+(pagesize-1))) != size+(pagesize-1) { + return nil, fmt.Errorf("%s: too large for mmap", f.Name()) + } + n := int(size) + if n == 0 { + return &Data{f, nil, nil}, nil + } + mmapLength := int(((size + pagesize - 1) / pagesize) * pagesize) // round up to page size + data, err := syscall.Mmap(int(f.Fd()), 0, mmapLength, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED) + if err != nil { + return nil, &fs.PathError{Op: "mmap", Path: f.Name(), Err: err} + } + return &Data{f, data[:n], nil}, nil +} + +func munmapFile(d *Data) error { + if len(d.Data) == 0 { + return nil + } + err := syscall.Munmap(d.Data) + if err != nil { + return &fs.PathError{Op: "munmap", Path: d.f.Name(), Err: err} + } + return nil +} diff --git a/vendor/golang.org/x/telemetry/internal/mmap/mmap_windows.go b/vendor/golang.org/x/telemetry/internal/mmap/mmap_windows.go new file mode 100644 index 0000000..2e8dfbe --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/mmap/mmap_windows.go @@ -0,0 +1,52 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mmap + +import ( + "fmt" + "os" + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +func mmapFile(f *os.File) (*Data, error) { + st, err := f.Stat() + if err != nil { + return nil, err + } + size := st.Size() + if size == 0 { + return &Data{f, nil, nil}, nil + } + // set the min and max sizes to zero to map the whole file, as described in + // https://learn.microsoft.com/en-us/windows/win32/memory/creating-a-file-mapping-object#file-mapping-size + h, err := windows.CreateFileMapping(windows.Handle(f.Fd()), nil, syscall.PAGE_READWRITE, 0, 0, nil) + if err != nil { + return nil, fmt.Errorf("CreateFileMapping %s: %w", f.Name(), err) + } + // the mapping extends from zero to the end of the file mapping + // https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile + addr, err := windows.MapViewOfFile(h, syscall.FILE_MAP_READ|syscall.FILE_MAP_WRITE, 0, 0, 0) + if err != nil { + return nil, fmt.Errorf("MapViewOfFile %s: %w", f.Name(), err) + } + // Note: previously, we called windows.VirtualQuery here to get the exact + // size of the memory mapped region, but VirtualQuery reported sizes smaller + // than the actual file size (hypothesis: VirtualQuery only reports pages in + // a certain state, and newly written pages may not be counted). + return &Data{f, unsafe.Slice((*byte)(unsafe.Pointer(addr)), size), h}, nil +} + +func munmapFile(d *Data) error { + err := windows.UnmapViewOfFile(uintptr(unsafe.Pointer(&d.Data[0]))) + x, ok := d.Windows.(windows.Handle) + if ok { + windows.CloseHandle(x) + } + d.f.Close() + return err +} diff --git a/vendor/golang.org/x/telemetry/internal/telemetry/dateonly.go b/vendor/golang.org/x/telemetry/internal/telemetry/dateonly.go new file mode 100644 index 0000000..7195301 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/telemetry/dateonly.go @@ -0,0 +1,9 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package telemetry + +// TODO(rfindley): replace uses of DateOnly with time.DateOnly once we no +// longer support building gopls with go 1.19. +const DateOnly = "2006-01-02" diff --git a/vendor/golang.org/x/telemetry/internal/telemetry/dir.go b/vendor/golang.org/x/telemetry/internal/telemetry/dir.go new file mode 100644 index 0000000..0673be5 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/telemetry/dir.go @@ -0,0 +1,163 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package telemetry manages the telemetry mode file. +package telemetry + +import ( + "fmt" + "os" + "path/filepath" + "runtime" + "strings" + "time" +) + +// Default is the default directory containing Go telemetry configuration and +// data. +// +// If Default is uninitialized, Default.Mode will be "off". As a consequence, +// no data should be written to the directory, and so the path values of +// LocalDir, UploadDir, etc. must not matter. +// +// Default is a global for convenience and testing, but should not be mutated +// outside of tests. +// +// TODO(rfindley): it would be nice to completely eliminate this global state, +// or at least push it in the golang.org/x/telemetry package +var Default Dir + +// A Dir holds paths to telemetry data inside a directory. +type Dir struct { + dir, local, upload, debug, modefile string +} + +// NewDir creates a new Dir encapsulating paths in the given dir. +// +// NewDir does not create any new directories or files--it merely encapsulates +// the telemetry directory layout. +func NewDir(dir string) Dir { + return Dir{ + dir: dir, + local: filepath.Join(dir, "local"), + upload: filepath.Join(dir, "upload"), + debug: filepath.Join(dir, "debug"), + modefile: filepath.Join(dir, "mode"), + } +} + +func init() { + cfgDir, err := os.UserConfigDir() + if err != nil { + return + } + Default = NewDir(filepath.Join(cfgDir, "go", "telemetry")) +} + +func (d Dir) Dir() string { + return d.dir +} + +func (d Dir) LocalDir() string { + return d.local +} + +func (d Dir) UploadDir() string { + return d.upload +} + +func (d Dir) DebugDir() string { + return d.debug +} + +func (d Dir) ModeFile() string { + return d.modefile +} + +// SetMode updates the telemetry mode with the given mode. +// Acceptable values for mode are "on", "off", or "local". +// +// SetMode always writes the mode file, and explicitly records the date at +// which the modefile was updated. This means that calling SetMode with "on" +// effectively resets the timeout before the next telemetry report is uploaded. +func (d Dir) SetMode(mode string) error { + return d.SetModeAsOf(mode, time.Now()) +} + +// SetModeAsOf is like SetMode, but accepts an explicit time to use to +// back-date the mode state. This exists only for testing purposes. +func (d Dir) SetModeAsOf(mode string, asofTime time.Time) error { + mode = strings.TrimSpace(mode) + switch mode { + case "on", "off", "local": + default: + return fmt.Errorf("invalid telemetry mode: %q", mode) + } + if d.modefile == "" { + return fmt.Errorf("cannot determine telemetry mode file name") + } + // TODO(rfindley): why is this not 777, consistent with the use of 666 below? + if err := os.MkdirAll(filepath.Dir(d.modefile), 0755); err != nil { + return fmt.Errorf("cannot create a telemetry mode file: %w", err) + } + + asof := asofTime.UTC().Format(DateOnly) + // Defensively guarantee that we can parse the asof time. + if _, err := time.Parse(DateOnly, asof); err != nil { + return fmt.Errorf("internal error: invalid mode date %q: %v", asof, err) + } + + data := []byte(mode + " " + asof) + return os.WriteFile(d.modefile, data, 0666) +} + +// Mode returns the current telemetry mode, as well as the time that the mode +// was effective. +// +// If there is no effective time, the second result is the zero time. +// +// If Mode is "off", no data should be written to the telemetry directory, and +// the other paths values referenced by Dir should be considered undefined. +// This accounts for the case where initializing [Default] fails, and therefore +// local telemetry paths are unknown. +func (d Dir) Mode() (string, time.Time) { + if d.modefile == "" { + return "off", time.Time{} // it's likely LocalDir/UploadDir are empty too. Turn off telemetry. + } + data, err := os.ReadFile(d.modefile) + if err != nil { + return "local", time.Time{} // default + } + mode := string(data) + mode = strings.TrimSpace(mode) + + // Forward compatibility for https://go.dev/issue/63142#issuecomment-1734025130 + // + // If the modefile contains a date, return it. + if idx := strings.Index(mode, " "); idx >= 0 { + d, err := time.Parse(DateOnly, mode[idx+1:]) + if err != nil { + d = time.Time{} + } + return mode[:idx], d + } + + return mode, time.Time{} +} + +// DisabledOnPlatform indicates whether telemetry is disabled +// due to bugs in the current platform. +// +// TODO(rfindley): move to a more appropriate file. +const DisabledOnPlatform = false || + // The following platforms could potentially be supported in the future: + runtime.GOOS == "openbsd" || // #60614 + runtime.GOOS == "solaris" || // #60968 #60970 + runtime.GOOS == "android" || // #60967 + runtime.GOOS == "illumos" || // #65544 + // These platforms fundamentally can't be supported: + runtime.GOOS == "js" || // #60971 + runtime.GOOS == "wasip1" || // #60971 + runtime.GOOS == "plan9" || // https://github.com/golang/go/issues/57540#issuecomment-1470766639 + runtime.GOARCH == "mips" || runtime.GOARCH == "mipsle" // mips lacks cross-process 64-bit atomics diff --git a/vendor/golang.org/x/telemetry/internal/telemetry/proginfo.go b/vendor/golang.org/x/telemetry/internal/telemetry/proginfo.go new file mode 100644 index 0000000..5ff7d34 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/telemetry/proginfo.go @@ -0,0 +1,57 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package telemetry + +import ( + "go/version" + "os" + "path/filepath" + "runtime/debug" + "strings" +) + +// IsToolchainProgram reports whether a program with the given path is a Go +// toolchain program. +func IsToolchainProgram(progPath string) bool { + return strings.HasPrefix(progPath, "cmd/") +} + +// ProgramInfo extracts the go version, program package path, and program +// version to use for counter files. +// +// For programs in the Go toolchain, the program version will be the same as +// the Go version, and will typically be of the form "go1.2.3", not a semantic +// version of the form "v1.2.3". Go versions may also include spaces and +// special characters. +func ProgramInfo(info *debug.BuildInfo) (goVers, progPath, progVers string) { + goVers = info.GoVersion + if strings.Contains(goVers, "devel") || strings.Contains(goVers, "-") || !version.IsValid(goVers) { + goVers = "devel" + } + + progPath = info.Path + if progPath == "" { + progPath = strings.TrimSuffix(filepath.Base(os.Args[0]), ".exe") + } + + // Main module version information is not populated for the cmd module, but + // we can re-use the Go version here. + if IsToolchainProgram(progPath) { + progVers = goVers + } else { + progVers = info.Main.Version + if strings.Contains(progVers, "devel") || strings.Count(progVers, "-") > 1 { + // Heuristically mark all pseudo-version-like version strings as "devel" + // to avoid creating too many counter files. + // We should not use regexp that pulls in large dependencies. + // Pseudo-versions have at least three parts (https://go.dev/ref/mod#pseudo-versions). + // This heuristic still allows use to track prerelease + // versions (e.g. gopls@v0.16.0-pre.1, vscgo@v0.42.0-rc.1). + progVers = "devel" + } + } + + return goVers, progPath, progVers +} diff --git a/vendor/golang.org/x/telemetry/internal/telemetry/types.go b/vendor/golang.org/x/telemetry/internal/telemetry/types.go new file mode 100644 index 0000000..0fd61f8 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/telemetry/types.go @@ -0,0 +1,51 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package telemetry + +// Common types and directories used by multiple packages. + +// An UploadConfig controls what data is uploaded. +type UploadConfig struct { + GOOS []string + GOARCH []string + GoVersion []string + SampleRate float64 + Programs []*ProgramConfig +} + +type ProgramConfig struct { + // the counter names may have to be + // repeated for each program. (e.g., if the counters are in a package + // that is used in more than one program.) + Name string + Versions []string // versions present in a counterconfig + Counters []CounterConfig `json:",omitempty"` + Stacks []CounterConfig `json:",omitempty"` +} + +type CounterConfig struct { + Name string // The "collapsed" counter: :{,,...} + Rate float64 // If X <= Rate, report this counter + Depth int `json:",omitempty"` // for stack counters +} + +// A Report is the weekly aggregate of counters. +type Report struct { + Week string // End day this report covers (YYYY-MM-DD) + LastWeek string // Week field from latest previous report uploaded + X float64 // A random probability used to determine which counters are uploaded + Programs []*ProgramReport + Config string // version of UploadConfig used +} + +type ProgramReport struct { + Program string // Package path of the program. + Version string // Program version. Go version if the program is part of the go distribution. Module version, otherwise. + GoVersion string // Go version used to build the program. + GOOS string + GOARCH string + Counters map[string]int64 + Stacks map[string]int64 +} diff --git a/vendor/golang.org/x/telemetry/internal/upload/Doc.txt b/vendor/golang.org/x/telemetry/internal/upload/Doc.txt new file mode 100644 index 0000000..45601e6 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/upload/Doc.txt @@ -0,0 +1,45 @@ +The upload process converts count files into reports, and +uploads reports. There will be only one report, named YYYY-MM-DD.json, +for a given day. + +First phase. Look at the localdir (os.UserConfigdir()/go/telemetry/local) +and find all .count and .json files. Find the count files that are no +longer active by looking at their metadata. + +Second phase. Group the inactive count files by their expiry date, and +for each date generate the local report and the upload report. (The upload +report only contains the counters in the upload configuration.) The upload +report is saved in the local directory with a name like YYYY-MM-DD.json, if +there is no file already existing with that name. +If the local report is different, it is saved in the local directory +with a name like local.YYYY-MM-DD.json. The new upload report is +added to the list of .json files from the first phase. At this point +the count files are no longer needed and can be deleted. + +Third phase. Look at the .json files in the list from the first phase. +If the name starts with local, skip it. If there is a file with the +identical name in the upload directory, remove the one in the local directory. +Otherwise try to upload the one in the local directory, +If the upload succeeds, move the file to the uploaded directory. + + +There are various error conditions. +1. Several processes could look at localdir and see work to do. +1A. They could see different sets of expired count files for some day. + This could happen if another process is removing count files. In this + case there is already a YYYY-MM-DD.json file either in localdir + or updatedir, so the process seeing fewer count files will not generate + a report. +1B. They could see the same count files, and no report in either directory. + They will both generate (in memory) reports and check to see if there + is a YYYY-MM-DD.json file in either directory. They could both then + write two files with the same name, but different X values, but + otherwise the same contents. The X values are very close to the front + of the file. Assuming reasonable file system semantics one version of + the file will be written. To minimize this, just before writing reports + the code checks again to see if they exist. +1C. Once there is an existing well-formed file YYYY-MM-DD.json in localdir + eventually the upload will succeed, and the file will be moved to updatedir. + It is possible that other processes will not see the file in updatedir and + upload it again and also move it to uploaddir. This is harmless as all + the uploaded files are identical. diff --git a/vendor/golang.org/x/telemetry/internal/upload/date.go b/vendor/golang.org/x/telemetry/internal/upload/date.go new file mode 100644 index 0000000..d6d67a1 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/upload/date.go @@ -0,0 +1,85 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package upload + +import ( + "fmt" + "os" + "sync" + "time" + + "golang.org/x/telemetry/internal/counter" + "golang.org/x/telemetry/internal/telemetry" +) + +// time and date handling + +var distantPast = 21 * 24 * time.Hour + +// reports that are too old (21 days) are not uploaded +func (u *uploader) tooOld(date string, uploadStartTime time.Time) bool { + t, err := time.Parse(telemetry.DateOnly, date) + if err != nil { + u.logger.Printf("tooOld: %v", err) + return false + } + age := uploadStartTime.Sub(t) + return age > distantPast +} + +// counterDateSpan parses the counter file named fname and returns the (begin, +// end) span recorded in its metadata, or an error if this data could not be +// extracted. +func (u *uploader) counterDateSpan(fname string) (begin, end time.Time, _ error) { + parsed, err := u.parseCountFile(fname) + if err != nil { + return time.Time{}, time.Time{}, err + } + timeBegin, ok := parsed.Meta["TimeBegin"] + if !ok { + return time.Time{}, time.Time{}, fmt.Errorf("missing counter metadata for TimeBegin") + } + begin, err = time.Parse(time.RFC3339, timeBegin) + if err != nil { + return time.Time{}, time.Time{}, fmt.Errorf("failed to parse TimeBegin: %v", err) + } + timeEnd, ok := parsed.Meta["TimeEnd"] + if !ok { + return time.Time{}, time.Time{}, fmt.Errorf("missing counter metadata for TimeEnd") + } + end, err = time.Parse(time.RFC3339, timeEnd) + if err != nil { + return time.Time{}, time.Time{}, fmt.Errorf("failed to parse TimeEnd: %v", err) + } + return begin, end, nil +} + +// avoid parsing count files multiple times +type parsedCache struct { + mu sync.Mutex + m map[string]*counter.File +} + +func (u *uploader) parseCountFile(fname string) (*counter.File, error) { + u.cache.mu.Lock() + defer u.cache.mu.Unlock() + if u.cache.m == nil { + u.cache.m = make(map[string]*counter.File) + } + if f, ok := u.cache.m[fname]; ok { + return f, nil + } + buf, err := os.ReadFile(fname) + if err != nil { + return nil, fmt.Errorf("parse ReadFile: %v for %s", err, fname) + } + f, err := counter.Parse(fname, buf) + if err != nil { + + return nil, fmt.Errorf("parse Parse: %v for %s", err, fname) + } + u.cache.m[fname] = f + return f, nil +} diff --git a/vendor/golang.org/x/telemetry/internal/upload/findwork.go b/vendor/golang.org/x/telemetry/internal/upload/findwork.go new file mode 100644 index 0000000..2b165be --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/upload/findwork.go @@ -0,0 +1,102 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package upload + +import ( + "os" + "path/filepath" + "strings" +) + +// files to handle +type work struct { + // absolute file names + countfiles []string // count files to process + readyfiles []string // old reports to upload + // relative names + uploaded map[string]bool // reports that have been uploaded +} + +// find all the files that look like counter files or reports +// that need to be uploaded. (There may be unexpected leftover files +// and uploading is supposed to be idempotent.) +func (u *uploader) findWork() work { + localdir, uploaddir := u.dir.LocalDir(), u.dir.UploadDir() + var ans work + fis, err := os.ReadDir(localdir) + if err != nil { + u.logger.Printf("Could not find work: failed to read local dir %s: %v", localdir, err) + return ans + } + + mode, asof := u.dir.Mode() + u.logger.Printf("Finding work: mode %s asof %s", mode, asof) + + // count files end in .v1.count + // reports end in .json. If they are not to be uploaded they + // start with local. + for _, fi := range fis { + if strings.HasSuffix(fi.Name(), ".v1.count") { + fname := filepath.Join(localdir, fi.Name()) + _, expiry, err := u.counterDateSpan(fname) + switch { + case err != nil: + u.logger.Printf("Error reading expiry for count file %s: %v", fi.Name(), err) + case expiry.After(u.startTime): + u.logger.Printf("Skipping count file %s: still active", fi.Name()) + default: + u.logger.Printf("Collecting count file %s", fi.Name()) + ans.countfiles = append(ans.countfiles, fname) + } + } else if strings.HasPrefix(fi.Name(), "local.") { + // skip + } else if strings.HasSuffix(fi.Name(), ".json") && mode == "on" { + // Collect reports that are ready for upload. + reportDate := u.uploadReportDate(fi.Name()) + if !asof.IsZero() && !reportDate.IsZero() { + // If both the mode asof date and the report date are present, do the + // right thing... + // + // (see https://github.com/golang/go/issues/63142#issuecomment-1734025130) + if asof.Before(reportDate) { + // Note: since this report was created after telemetry was enabled, + // we can only assume that the process that created it checked that + // the counter data contained therein was all from after the asof + // date. + // + // TODO(rfindley): store the begin date in reports, so that we can + // verify this assumption. + u.logger.Printf("Uploadable: %s", fi.Name()) + ans.readyfiles = append(ans.readyfiles, filepath.Join(localdir, fi.Name())) + } + } else { + // ...otherwise fall back on the old behavior of uploading all + // unuploaded files. + // + // TODO(rfindley): invert this logic following more testing. We + // should only upload if we know both the asof date and the report + // date, and they are acceptable. + u.logger.Printf("Uploadable (missing date): %s", fi.Name()) + ans.readyfiles = append(ans.readyfiles, filepath.Join(localdir, fi.Name())) + } + } + } + + fis, err = os.ReadDir(uploaddir) + if err != nil { + os.MkdirAll(uploaddir, 0777) + return ans + } + // There should be only one of these per day; maybe sometime + // we'll want to clean the directory. + ans.uploaded = make(map[string]bool) + for _, fi := range fis { + if strings.HasSuffix(fi.Name(), ".json") { + u.logger.Printf("Already uploaded: %s", fi.Name()) + ans.uploaded[fi.Name()] = true + } + } + return ans +} diff --git a/vendor/golang.org/x/telemetry/internal/upload/reports.go b/vendor/golang.org/x/telemetry/internal/upload/reports.go new file mode 100644 index 0000000..34bb29d --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/upload/reports.go @@ -0,0 +1,344 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package upload + +import ( + "crypto/rand" + "encoding/binary" + "encoding/json" + "fmt" + "math" + "os" + "path/filepath" + "strings" + "time" + + "golang.org/x/telemetry/internal/config" + "golang.org/x/telemetry/internal/counter" + "golang.org/x/telemetry/internal/telemetry" +) + +// reports generates reports from inactive count files +func (u *uploader) reports(todo *work) ([]string, error) { + if mode, _ := u.dir.Mode(); mode == "off" { + return nil, nil // no reports + } + thisInstant := u.startTime + today := thisInstant.Format(telemetry.DateOnly) + lastWeek := latestReport(todo.uploaded) + if lastWeek >= today { //should never happen + lastWeek = "" + } + u.logger.Printf("Last week: %s, today: %s", lastWeek, today) + countFiles := make(map[string][]string) // expiry date string->filenames + earliest := make(map[string]time.Time) // earliest begin time for any counter + for _, f := range todo.countfiles { + begin, end, err := u.counterDateSpan(f) + if err != nil { + // This shouldn't happen: we should have already skipped count files that + // don't contain valid start or end times. + u.logger.Printf("BUG: failed to parse expiry for collected count file: %v", err) + continue + } + + if end.Before(thisInstant) { + expiry := end.Format(dateFormat) + countFiles[expiry] = append(countFiles[expiry], f) + if earliest[expiry].IsZero() || earliest[expiry].After(begin) { + earliest[expiry] = begin + } + } + } + for expiry, files := range countFiles { + if notNeeded(expiry, *todo) { + u.logger.Printf("Files for %s not needed, deleting %v", expiry, files) + // The report already exists. + // There's another check in createReport. + u.deleteFiles(files) + continue + } + fname, err := u.createReport(earliest[expiry], expiry, files, lastWeek) + if err != nil { + u.logger.Printf("Failed to create report for %s: %v", expiry, err) + continue + } + if fname != "" { + u.logger.Printf("Ready to upload: %s", filepath.Base(fname)) + todo.readyfiles = append(todo.readyfiles, fname) + } + } + return todo.readyfiles, nil +} + +// latestReport returns the YYYY-MM-DD of the last report uploaded +// or the empty string if there are no reports. +func latestReport(uploaded map[string]bool) string { + var latest string + for name := range uploaded { + if strings.HasSuffix(name, ".json") { + if name > latest { + latest = name + } + } + } + if latest == "" { + return "" + } + // strip off the .json + return latest[:len(latest)-len(".json")] +} + +// notNeeded returns true if the report for date has already been created +func notNeeded(date string, todo work) bool { + if todo.uploaded != nil && todo.uploaded[date+".json"] { + return true + } + // maybe the report is already in todo.readyfiles + for _, f := range todo.readyfiles { + if strings.Contains(f, date) { + return true + } + } + return false +} + +func (u *uploader) deleteFiles(files []string) { + for _, f := range files { + if err := os.Remove(f); err != nil { + // this could be a race condition. + // conversely, on Windows, err may be nil and + // the file not deleted if anyone has it open. + u.logger.Printf("%v failed to remove %s", err, f) + } + } +} + +// createReport creates local and upload report files by +// combining all the count files for the expiryDate, and +// returns the upload report file's path. +// It may delete the count files once local and upload report +// files are successfully created. +func (u *uploader) createReport(start time.Time, expiryDate string, countFiles []string, lastWeek string) (string, error) { + uploadOK := true + mode, asof := u.dir.Mode() + if mode != "on" { + u.logger.Printf("No upload config or mode %q is not 'on'", mode) + uploadOK = false // no config, nothing to upload + } + if u.tooOld(expiryDate, u.startTime) { + u.logger.Printf("Expiry date %s is too old", expiryDate) + uploadOK = false + } + // If the mode is recorded with an asof date, don't upload if the report + // includes any data on or before the asof date. + if !asof.IsZero() && !asof.Before(start) { + u.logger.Printf("As-of date %s is not before start %s", asof, start) + uploadOK = false + } + // TODO(rfindley): check that all the x.Meta are consistent for GOOS, GOARCH, etc. + report := &telemetry.Report{ + Config: u.configVersion, + X: computeRandom(), // json encodes all the bits + Week: expiryDate, + LastWeek: lastWeek, + } + if report.X > u.config.SampleRate && u.config.SampleRate > 0 { + u.logger.Printf("X: %f > SampleRate:%f, not uploadable", report.X, u.config.SampleRate) + uploadOK = false + } + var succeeded bool + for _, f := range countFiles { + fok := false + x, err := u.parseCountFile(f) + if err != nil { + u.logger.Printf("Unparseable count file %s: %v", filepath.Base(f), err) + continue + } + prog := findProgReport(x.Meta, report) + for k, v := range x.Count { + if counter.IsStackCounter(k) { + // stack + prog.Stacks[k] += int64(v) + } else { + // counter + prog.Counters[k] += int64(v) + } + succeeded = true + fok = true + } + if !fok { + u.logger.Printf("no counters found in %s", f) + } + } + if !succeeded { + return "", fmt.Errorf("none of the %d count files for %s contained counters", len(countFiles), expiryDate) + } + // 1. generate the local report + localContents, err := json.MarshalIndent(report, "", " ") + if err != nil { + return "", fmt.Errorf("failed to marshal report for %s: %v", expiryDate, err) + } + // check that the report can be read back + // TODO(pjw): remove for production? + var report2 telemetry.Report + if err := json.Unmarshal(localContents, &report2); err != nil { + return "", fmt.Errorf("failed to unmarshal local report for %s: %v", expiryDate, err) + } + + var uploadContents []byte + if uploadOK { + // 2. create the uploadable version + cfg := config.NewConfig(u.config) + upload := &telemetry.Report{ + Week: report.Week, + LastWeek: report.LastWeek, + X: report.X, + Config: report.Config, + } + for _, p := range report.Programs { + // does the uploadConfig want this program? + // if so, copy over the Stacks and Counters + // that the uploadConfig mentions. + if !cfg.HasGoVersion(p.GoVersion) || !cfg.HasProgram(p.Program) || !cfg.HasVersion(p.Program, p.Version) { + continue + } + x := &telemetry.ProgramReport{ + Program: p.Program, + Version: p.Version, + GOOS: p.GOOS, + GOARCH: p.GOARCH, + GoVersion: p.GoVersion, + Counters: make(map[string]int64), + Stacks: make(map[string]int64), + } + upload.Programs = append(upload.Programs, x) + for k, v := range p.Counters { + if cfg.HasCounter(p.Program, k) && report.X <= cfg.Rate(p.Program, k) { + x.Counters[k] = v + } + } + // and the same for Stacks + // this can be made more efficient, when it matters + for k, v := range p.Stacks { + before, _, _ := strings.Cut(k, "\n") + if cfg.HasStack(p.Program, before) && report.X <= cfg.Rate(p.Program, before) { + x.Stacks[k] = v + } + } + } + + uploadContents, err = json.MarshalIndent(upload, "", " ") + if err != nil { + return "", fmt.Errorf("failed to marshal upload report for %s: %v", expiryDate, err) + } + } + localFileName := filepath.Join(u.dir.LocalDir(), "local."+expiryDate+".json") + uploadFileName := filepath.Join(u.dir.LocalDir(), expiryDate+".json") + + /* Prepare to write files */ + // if either file exists, someone has been here ahead of us + // (there is still a race, but this check shortens the open window) + if _, err := os.Stat(localFileName); err == nil { + u.deleteFiles(countFiles) + return "", fmt.Errorf("local report %s already exists", localFileName) + } + if _, err := os.Stat(uploadFileName); err == nil { + u.deleteFiles(countFiles) + return "", fmt.Errorf("report %s already exists", uploadFileName) + } + // write the uploadable file + var errUpload, errLocal error + if uploadOK { + _, errUpload = exclusiveWrite(uploadFileName, uploadContents) + } + // write the local file + _, errLocal = exclusiveWrite(localFileName, localContents) + /* Wrote the files */ + + // even though these errors won't occur, what should happen + // if errUpload == nil and it is ok to upload, and errLocal != nil? + if errLocal != nil { + return "", fmt.Errorf("failed to write local file %s (%v)", localFileName, errLocal) + } + if errUpload != nil { + return "", fmt.Errorf("failed to write upload file %s (%v)", uploadFileName, errUpload) + } + u.logger.Printf("Created %s, deleting %d count files", filepath.Base(uploadFileName), len(countFiles)) + u.deleteFiles(countFiles) + if uploadOK { + return uploadFileName, nil + } + return "", nil +} + +// exclusiveWrite attempts to create filename exclusively, and if successful, +// writes content to the resulting file handle. +// +// It returns a boolean indicating whether the exclusive handle was acquired, +// and an error indicating whether the operation succeeded. +// If the file already exists, exclusiveWrite returns (false, nil). +func exclusiveWrite(filename string, content []byte) (_ bool, rerr error) { + f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644) + if err != nil { + if os.IsExist(err) { + return false, nil + } + return false, err + } + defer func() { + if err := f.Close(); err != nil && rerr == nil { + rerr = err + } + }() + if _, err := f.Write(content); err != nil { + return false, err + } + return true, nil +} + +// return an existing ProgremReport, or create anew +func findProgReport(meta map[string]string, report *telemetry.Report) *telemetry.ProgramReport { + for _, prog := range report.Programs { + if prog.Program == meta["Program"] && prog.Version == meta["Version"] && + prog.GoVersion == meta["GoVersion"] && prog.GOOS == meta["GOOS"] && + prog.GOARCH == meta["GOARCH"] { + return prog + } + } + prog := telemetry.ProgramReport{ + Program: meta["Program"], + Version: meta["Version"], + GoVersion: meta["GoVersion"], + GOOS: meta["GOOS"], + GOARCH: meta["GOARCH"], + Counters: make(map[string]int64), + Stacks: make(map[string]int64), + } + report.Programs = append(report.Programs, &prog) + return &prog +} + +// computeRandom returns a cryptographic random float64 in the range [0, 1], +// with 52 bits of precision. +func computeRandom() float64 { + for { + b := make([]byte, 8) + _, err := rand.Read(b) + if err != nil { + panic(fmt.Sprintf("rand.Read failed: %v", err)) + } + // and turn it into a float64 + x := math.Float64frombits(binary.LittleEndian.Uint64(b)) + if math.IsNaN(x) || math.IsInf(x, 0) { + continue + } + x = math.Abs(x) + if x < 0x1p-1000 { // avoid underflow patterns + continue + } + frac, _ := math.Frexp(x) // 52 bits of randomness + return frac*2 - 1 + } +} diff --git a/vendor/golang.org/x/telemetry/internal/upload/run.go b/vendor/golang.org/x/telemetry/internal/upload/run.go new file mode 100644 index 0000000..e9c8dc2 --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/upload/run.go @@ -0,0 +1,226 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package upload + +import ( + "fmt" + "io" + "log" + "os" + "path" + "path/filepath" + "runtime/debug" + "strings" + "time" + + "golang.org/x/telemetry/internal/configstore" + "golang.org/x/telemetry/internal/telemetry" +) + +// RunConfig configures non-default behavior of a call to Run. +// +// All fields are optional, for testing or observability. +type RunConfig struct { + TelemetryDir string // if set, overrides the telemetry data directory + UploadURL string // if set, overrides the telemetry upload endpoint + LogWriter io.Writer // if set, used for detailed logging of the upload process + Env []string // if set, appended to the config download environment + StartTime time.Time // if set, overrides the upload start time +} + +// Run generates and uploads reports, as allowed by the mode file. +func Run(config RunConfig) error { + defer func() { + if err := recover(); err != nil { + log.Printf("upload recover: %v", err) + } + }() + uploader, err := newUploader(config) + if err != nil { + return err + } + defer uploader.Close() + return uploader.Run() +} + +// uploader encapsulates a single upload operation, carrying parameters and +// shared state. +type uploader struct { + // config is used to select counters to upload. + config *telemetry.UploadConfig // + configVersion string // version of the config + dir telemetry.Dir // the telemetry dir to process + + uploadServerURL string + startTime time.Time + + cache parsedCache + + logFile *os.File + logger *log.Logger +} + +// newUploader creates a new uploader to use for running the upload for the +// given config. +// +// Uploaders should only be used for one call to [uploader.Run]. +func newUploader(rcfg RunConfig) (*uploader, error) { + // Determine the upload directory. + var dir telemetry.Dir + if rcfg.TelemetryDir != "" { + dir = telemetry.NewDir(rcfg.TelemetryDir) + } else { + dir = telemetry.Default + } + + // Determine the upload URL. + uploadURL := rcfg.UploadURL + if uploadURL == "" { + uploadURL = "https://telemetry.go.dev/upload" + } + + // Determine the upload logger. + // + // This depends on the provided rcfg.LogWriter and the presence of + // dir.DebugDir, as follows: + // 1. If LogWriter is present, log to it. + // 2. If DebugDir is present, log to a file within it. + // 3. If both LogWriter and DebugDir are present, log to a multi writer. + // 4. If neither LogWriter nor DebugDir are present, log to a noop logger. + var logWriters []io.Writer + logFile, err := debugLogFile(dir.DebugDir()) + if err != nil { + logFile = nil + } + if logFile != nil { + logWriters = append(logWriters, logFile) + } + if rcfg.LogWriter != nil { + logWriters = append(logWriters, rcfg.LogWriter) + } + var logWriter io.Writer + switch len(logWriters) { + case 0: + logWriter = io.Discard + case 1: + logWriter = logWriters[0] + default: + logWriter = io.MultiWriter(logWriters...) + } + logger := log.New(logWriter, "", log.Ltime|log.Lmicroseconds|log.Lshortfile) + + // Fetch the upload config, if it is not provided. + var ( + config *telemetry.UploadConfig + configVersion string + ) + + if mode, _ := dir.Mode(); mode == "on" { + // golang/go#68946: only download the upload config if it will be used. + // + // TODO(rfindley): This is a narrow change aimed at minimally fixing the + // associated bug. In the future, we should read the mode only once during + // the upload process. + config, configVersion, err = configstore.Download("latest", rcfg.Env) + if err != nil { + return nil, err + } + } else { + config = &telemetry.UploadConfig{} + configVersion = "v0.0.0-0" + } + + // Set the start time, if it is not provided. + startTime := time.Now().UTC() + if !rcfg.StartTime.IsZero() { + startTime = rcfg.StartTime + } + + return &uploader{ + config: config, + configVersion: configVersion, + dir: dir, + uploadServerURL: uploadURL, + startTime: startTime, + + logFile: logFile, + logger: logger, + }, nil +} + +// Close cleans up any resources associated with the uploader. +func (u *uploader) Close() error { + if u.logFile == nil { + return nil + } + return u.logFile.Close() +} + +// Run generates and uploads reports +func (u *uploader) Run() error { + if telemetry.DisabledOnPlatform { + return nil + } + todo := u.findWork() + ready, err := u.reports(&todo) + if err != nil { + u.logger.Printf("Error building reports: %v", err) + return fmt.Errorf("reports failed: %v", err) + } + u.logger.Printf("Uploading %d reports", len(ready)) + for _, f := range ready { + u.uploadReport(f) + } + return nil +} + +// debugLogFile arranges to write a log file in the given debug directory, if +// it exists. +func debugLogFile(debugDir string) (*os.File, error) { + fd, err := os.Stat(debugDir) + if os.IsNotExist(err) { + return nil, nil + } + if err != nil { + return nil, err + } + if !fd.IsDir() { + return nil, fmt.Errorf("debug path %q is not a directory", debugDir) + } + info, ok := debug.ReadBuildInfo() + if !ok { + return nil, fmt.Errorf("no build info") + } + year, month, day := time.Now().UTC().Date() + goVers := info.GoVersion + // E.g., goVers:"go1.22-20240109-RC01 cl/597041403 +dcbe772469 X:loopvar" + words := strings.Fields(goVers) + goVers = words[0] + progPkgPath := info.Path + if progPkgPath == "" { + progPkgPath = strings.TrimSuffix(filepath.Base(os.Args[0]), ".exe") + } + prog := path.Base(progPkgPath) + progVers := info.Main.Version + if progVers == "(devel)" { // avoid special characters in created file names + progVers = "devel" + } + logBase := strings.ReplaceAll( + fmt.Sprintf("%s-%s-%s-%4d%02d%02d-%d.log", prog, progVers, goVers, year, month, day, os.Getpid()), + " ", "") + fname := filepath.Join(debugDir, logBase) + if _, err := os.Stat(fname); err == nil { + // This process previously called upload.Run + return nil, nil + } + f, err := os.OpenFile(fname, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0666) + if err != nil { + if os.IsExist(err) { + return nil, nil // this process previously called upload.Run + } + return nil, err + } + return f, nil +} diff --git a/vendor/golang.org/x/telemetry/internal/upload/upload.go b/vendor/golang.org/x/telemetry/internal/upload/upload.go new file mode 100644 index 0000000..419745f --- /dev/null +++ b/vendor/golang.org/x/telemetry/internal/upload/upload.go @@ -0,0 +1,117 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package upload + +import ( + "bytes" + "net/http" + "os" + "path/filepath" + "regexp" + "strings" + "time" + + "golang.org/x/telemetry/internal/telemetry" +) + +var ( + dateRE = regexp.MustCompile(`(\d\d\d\d-\d\d-\d\d)[.]json$`) + dateFormat = telemetry.DateOnly + // TODO(rfindley): use dateFormat throughout. +) + +// uploadReportDate returns the date component of the upload file name, or "" if the +// date was unmatched. +func (u *uploader) uploadReportDate(fname string) time.Time { + match := dateRE.FindStringSubmatch(fname) + if match == nil || len(match) < 2 { + u.logger.Printf("malformed report name: missing date: %q", filepath.Base(fname)) + return time.Time{} + } + d, err := time.Parse(dateFormat, match[1]) + if err != nil { + u.logger.Printf("malformed report name: bad date: %q", filepath.Base(fname)) + return time.Time{} + } + return d +} + +func (u *uploader) uploadReport(fname string) { + thisInstant := u.startTime + // TODO(rfindley): use uploadReportDate here, once we've done a gopls release. + + // first make sure it is not in the future + today := thisInstant.Format(telemetry.DateOnly) + match := dateRE.FindStringSubmatch(fname) + if match == nil || len(match) < 2 { + u.logger.Printf("Report name %q missing date", filepath.Base(fname)) + } else if match[1] > today { + u.logger.Printf("Report date for %q is later than today (%s)", filepath.Base(fname), today) + return // report is in the future, which shouldn't happen + } + buf, err := os.ReadFile(fname) + if err != nil { + u.logger.Printf("%v reading %s", err, fname) + return + } + if u.uploadReportContents(fname, buf) { + // anything left to do? + } +} + +// try to upload the report, 'true' if successful +func (u *uploader) uploadReportContents(fname string, buf []byte) bool { + fdate := strings.TrimSuffix(filepath.Base(fname), ".json") + fdate = fdate[len(fdate)-len(telemetry.DateOnly):] + + newname := filepath.Join(u.dir.UploadDir(), fdate+".json") + + // Lock the upload, to prevent duplicate uploads. + { + lockname := newname + ".lock" + lockfile, err := os.OpenFile(lockname, os.O_CREATE|os.O_EXCL, 0666) + if err != nil { + u.logger.Printf("Failed to acquire lock %s: %v", lockname, err) + return false + } + _ = lockfile.Close() + defer os.Remove(lockname) + } + + if _, err := os.Stat(newname); err == nil { + // Another process uploaded but failed to clean up (or hasn't yet cleaned + // up). Ensure that cleanup occurs. + u.logger.Printf("After acquire: report already uploaded") + _ = os.Remove(fname) + return false + } + + endpoint := u.uploadServerURL + "/" + fdate + b := bytes.NewReader(buf) + resp, err := http.Post(endpoint, "application/json", b) + if err != nil { + u.logger.Printf("Error upload %s to %s: %v", filepath.Base(fname), endpoint, err) + return false + } + // hope for a 200, remove file on a 4xx, otherwise it will be retried by another process + if resp.StatusCode != 200 { + u.logger.Printf("Failed to upload %s to %s: %s", filepath.Base(fname), endpoint, resp.Status) + if resp.StatusCode >= 400 && resp.StatusCode < 500 { + err := os.Remove(fname) + if err == nil { + u.logger.Printf("Removed local/%s", filepath.Base(fname)) + } else { + u.logger.Printf("Error removing local/%s: %v", filepath.Base(fname), err) + } + } + return false + } + // Store a copy of the uploaded report in the uploaded directory. + if err := os.WriteFile(newname, buf, 0644); err == nil { + os.Remove(fname) // if it exists + } + u.logger.Printf("Uploaded %s to %q", fdate+".json", endpoint) + return true +} diff --git a/vendor/golang.org/x/telemetry/mode.go b/vendor/golang.org/x/telemetry/mode.go new file mode 100644 index 0000000..8cdcd13 --- /dev/null +++ b/vendor/golang.org/x/telemetry/mode.go @@ -0,0 +1,38 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package telemetry + +import "golang.org/x/telemetry/internal/telemetry" + +// Mode returns the current telemetry mode. +// +// The telemetry mode is a global value that controls both the local collection +// and uploading of telemetry data. Possible mode values are: +// - "on": both collection and uploading is enabled +// - "local": collection is enabled, but uploading is disabled +// - "off": both collection and uploading are disabled +// +// When mode is "on", or "local", telemetry data is written to the local file +// system and may be inspected with the [gotelemetry] command. +// +// If an error occurs while reading the telemetry mode from the file system, +// Mode returns the default value "local". +// +// [gotelemetry]: https://pkg.go.dev/golang.org/x/telemetry/cmd/gotelemetry +func Mode() string { + mode, _ := telemetry.Default.Mode() + return mode +} + +// SetMode sets the global telemetry mode to the given value. +// +// See the documentation of [Mode] for a description of the supported mode +// values. +// +// An error is returned if the provided mode value is invalid, or if an error +// occurs while persisting the mode value to the file system. +func SetMode(mode string) error { + return telemetry.Default.SetMode(mode) +} diff --git a/vendor/golang.org/x/telemetry/npm b/vendor/golang.org/x/telemetry/npm new file mode 100644 index 0000000..a5455cf --- /dev/null +++ b/vendor/golang.org/x/telemetry/npm @@ -0,0 +1,13 @@ +#!/bin/bash +# Copyright 2022 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +docker run \ + --rm \ + --volume $(pwd):/workspace \ + --workdir /workspace \ + --env NODE_OPTIONS="--dns-result-order=ipv4first" \ + --entrypoint npm \ + node:18.16.0-slim \ + $@ diff --git a/vendor/golang.org/x/telemetry/npx b/vendor/golang.org/x/telemetry/npx new file mode 100644 index 0000000..47bb38b --- /dev/null +++ b/vendor/golang.org/x/telemetry/npx @@ -0,0 +1,13 @@ +#!/bin/bash +# Copyright 2022 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +docker run \ + --rm \ + --volume $(pwd):/workspace \ + --workdir /workspace \ + --env NODE_OPTIONS="--dns-result-order=ipv4first" \ + --entrypoint npx \ + node:18.16.0-slim \ + $@ diff --git a/vendor/golang.org/x/telemetry/package-lock.json b/vendor/golang.org/x/telemetry/package-lock.json new file mode 100644 index 0000000..9c86033 --- /dev/null +++ b/vendor/golang.org/x/telemetry/package-lock.json @@ -0,0 +1,4363 @@ +{ + "name": "workspace", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@observablehq/plot": "0.6.9", + "d3": "7.8.5" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "5.59.6", + "@typescript-eslint/parser": "5.59.6", + "eslint": "8.40.0", + "eslint-config-prettier": "8.8.0", + "npm-run-all": "4.1.5", + "prettier": "2.8.8", + "stylelint": "15.6.2", + "stylelint-config-standard": "33.0.0", + "typescript": "5.0.4" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.1.1.tgz", + "integrity": "sha512-viRnRh02AgO4mwIQb2xQNJju0i+Fh9roNgmbR5xEuG7J3TGgxjnE95HnBLgsFJOJOksvcfxOUCgODcft6Y07cA==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^2.1.1" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz", + "integrity": "sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.4.tgz", + "integrity": "sha512-GyYot6jHgcSDZZ+tLSnrzkR7aJhF2ZW6d+CXH66mjy5WpAQhZD4HDke2OQ36SivGRWlZJpAz7TzbW6OKlEpxAA==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.1.1", + "@csstools/css-tokenizer": "^2.1.1" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.2", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/@eslint/js": { + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@observablehq/plot": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/@observablehq/plot/-/plot-0.6.9.tgz", + "integrity": "sha512-vwV6bzQsGjv2XrPEpc3Voixcz2e5EVvCSzzcs/uW9KXO5ZM8GdMVXtNTaRwYXUOk98nbiYFCFwzMaIyRjrt9IA==", + "dependencies": { + "d3": "^7.8.0", + "interval-tree-1d": "^1.0.0", + "isoformat": "^0.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.6.tgz", + "integrity": "sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/type-utils": "5.59.6", + "@typescript-eslint/utils": "5.59.6", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.6.tgz", + "integrity": "sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/typescript-estree": "5.59.6", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.6.tgz", + "integrity": "sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/visitor-keys": "5.59.6" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.6.tgz", + "integrity": "sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.59.6", + "@typescript-eslint/utils": "5.59.6", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz", + "integrity": "sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz", + "integrity": "sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/visitor-keys": "5.59.6", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.6.tgz", + "integrity": "sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/typescript-estree": "5.59.6", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz", + "integrity": "sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.6", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "node_modules/binary-search-bounds": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-2.0.5.tgz", + "integrity": "sha512-H0ea4Fd3lS1+sTEB2TgcLoK21lLhwEJzlQv3IN47pJS976Gx4zoWe0ak3q+uYh60ppQxg9F16Ri4tS1sfD4+jA==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/brace-expansion/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", + "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==", + "dev": true, + "dependencies": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-functions-list": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.1.0.tgz", + "integrity": "sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==", + "dev": true, + "engines": { + "node": ">=12.22" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/d3": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz", + "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.3.tgz", + "integrity": "sha512-JRHwbQQ84XuAESWhvIPaUV4/1UYTBOLiOPGWqgFDHZS1D5QN9c57FbH3QpEnQMYiOXNzKUQyGTZf+EVO7RT5TQ==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delaunator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", + "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", + "dependencies": { + "robust-predicates": "^3.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.21.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", + "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.0", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/interval-tree-1d": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/interval-tree-1d/-/interval-tree-1d-1.0.4.tgz", + "integrity": "sha512-wY8QJH+6wNI0uh4pDQzMvl+478Qh7Rl4qLmqiluxALlNvl+I+o5x38Pw3/z7mDPTPS1dQalZJXsmbvxx5gclhQ==", + "dependencies": { + "binary-search-bounds": "^2.0.0" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isoformat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/isoformat/-/isoformat-0.2.1.tgz", + "integrity": "sha512-tFLRAygk9NqrRPhJSnNGh7g7oaVWDwR0wKh/GM2LgmPa50Eg4UfyaCO4I8k6EqJHl1/uh2RAD6g06n5ygEnrjQ==" + }, + "node_modules/js-sdsl": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", + "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/known-css-properties": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz", + "integrity": "sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==", + "dev": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-all/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/npm-run-all/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/npm-run-all/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/npm-run-all/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", + "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.1.tgz", + "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==" + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz", + "integrity": "sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", + "dev": true + }, + "node_modules/stylelint": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.6.2.tgz", + "integrity": "sha512-fjQWwcdUye4DU+0oIxNGwawIPC5DvG5kdObY5Sg4rc87untze3gC/5g/ikePqVjrAsBUZjwMN+pZsAYbDO6ArQ==", + "dev": true, + "dependencies": { + "@csstools/css-parser-algorithms": "^2.1.1", + "@csstools/css-tokenizer": "^2.1.1", + "@csstools/media-query-list-parser": "^2.0.4", + "@csstools/selector-specificity": "^2.2.0", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^8.1.3", + "css-functions-list": "^3.1.0", + "css-tree": "^2.3.1", + "debug": "^4.3.4", + "fast-glob": "^3.2.12", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^6.0.1", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^5.2.4", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.27.0", + "mathml-tag-names": "^2.1.3", + "meow": "^9.0.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.12", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^3.0.0", + "svg-tags": "^1.0.0", + "table": "^6.8.1", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-12.0.0.tgz", + "integrity": "sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ==", + "dev": true, + "peerDependencies": { + "stylelint": "^15.5.0" + } + }, + "node_modules/stylelint-config-standard": { + "version": "33.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-33.0.0.tgz", + "integrity": "sha512-eyxnLWoXImUn77+ODIuW9qXBDNM+ALN68L3wT1lN2oNspZ7D9NVGlNHb2QCUn4xDug6VZLsh0tF8NyoYzkgTzg==", + "dev": true, + "dependencies": { + "stylelint-config-recommended": "^12.0.0" + }, + "peerDependencies": { + "stylelint": "^15.5.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/vendor/golang.org/x/telemetry/package.json b/vendor/golang.org/x/telemetry/package.json new file mode 100644 index 0000000..3680ce2 --- /dev/null +++ b/vendor/golang.org/x/telemetry/package.json @@ -0,0 +1,23 @@ +{ + "scripts": { + "eslint": "eslint . --fix", + "stylelint": "stylelint '**/*.css' --fix", + "prettier": "prettier --write **/*.{css,ts,md,yaml} !**/*.min.css", + "all": "run-s --continue-on-error eslint stylelint prettier" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "5.59.6", + "@typescript-eslint/parser": "5.59.6", + "eslint": "8.40.0", + "eslint-config-prettier": "8.8.0", + "npm-run-all": "4.1.5", + "prettier": "2.8.8", + "stylelint": "15.6.2", + "stylelint-config-standard": "33.0.0", + "typescript": "5.0.4" + }, + "dependencies": { + "@observablehq/plot": "0.6.9", + "d3": "7.8.5" + } +} diff --git a/vendor/golang.org/x/telemetry/start.go b/vendor/golang.org/x/telemetry/start.go new file mode 100644 index 0000000..9c0519a --- /dev/null +++ b/vendor/golang.org/x/telemetry/start.go @@ -0,0 +1,354 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package telemetry + +import ( + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "sync" + "time" + + "golang.org/x/sync/errgroup" + "golang.org/x/telemetry/counter" + "golang.org/x/telemetry/internal/crashmonitor" + "golang.org/x/telemetry/internal/telemetry" + "golang.org/x/telemetry/internal/upload" +) + +// Config controls the behavior of [Start]. +type Config struct { + // ReportCrashes, if set, will enable crash reporting. + // ReportCrashes uses the [debug.SetCrashOutput] mechanism, which is a + // process-wide resource. + // Do not make other calls to that function within your application. + // ReportCrashes is a non-functional unless the program is built with go1.23+. + ReportCrashes bool + + // Upload causes this program to periodically upload approved counters + // from the local telemetry database to telemetry.go.dev. + // + // This option has no effect unless the user has given consent + // to enable data collection, for example by running + // cmd/gotelemetry or affirming the gopls dialog. + // + // (This feature is expected to be used only by gopls. + // Longer term, the go command may become the sole program + // responsible for uploading.) + Upload bool + + // TelemetryDir, if set, will specify an alternate telemetry + // directory to write data to. If not set, it uses the default + // directory. + // This field is intended to be used for isolating testing environments. + TelemetryDir string + + // UploadStartTime, if set, overrides the time used as the upload start time, + // which is the time used by the upload logic to determine whether counter + // file data should be uploaded. Only counter files that have expired before + // the start time are considered for upload. + // + // This field can be used to simulate a future upload that collects recently + // modified counters. + UploadStartTime time.Time + + // UploadURL, if set, overrides the URL used to receive uploaded reports. If + // unset, this URL defaults to https://telemetry.go.dev/upload. + UploadURL string +} + +// Start initializes telemetry using the specified configuration. +// +// Start opens the local telemetry database so that counter increment +// operations are durably recorded in the local file system. +// +// If [Config.Upload] is set, and the user has opted in to telemetry +// uploading, this process may attempt to upload approved counters +// to telemetry.go.dev. +// +// If [Config.ReportCrashes] is set, any fatal crash will be +// recorded by incrementing a counter named for the stack of the +// first running goroutine in the traceback. +// +// If either of these flags is set, Start re-executes the current +// executable as a child process, in a special mode in which it +// acts as a telemetry sidecar for the parent process (the application). +// In that mode, the call to Start will never return, so Start must +// be called immediately within main, even before such things as +// inspecting the command line. The application should avoid expensive +// steps or external side effects in init functions, as they will +// be executed twice (parent and child). +// +// Start returns a StartResult, which may be awaited via [StartResult.Wait] to +// wait for all work done by Start to complete. +func Start(config Config) *StartResult { + switch v := os.Getenv(telemetryChildVar); v { + case "": + // The subprocess started by parent has GO_TELEMETRY_CHILD=1. + return parent(config) + case "1": + child(config) // child will exit the process when it's done. + case "2": + // Do nothing: this was executed directly or indirectly by a child. + default: + log.Fatalf("unexpected value for %q: %q", telemetryChildVar, v) + } + + return &StartResult{} +} + +// MaybeChild executes the telemetry child logic if the calling program is +// the telemetry child process, and does nothing otherwise. It is meant to be +// called as the first thing in a program that uses telemetry.Start but cannot +// call telemetry.Start immediately when it starts. +func MaybeChild(config Config) { + if v := os.Getenv(telemetryChildVar); v == "1" { + child(config) // child will exit the process when it's done. + } + // other values of the telemetryChildVar environment variable + // will be handled by telemetry.Start. +} + +// A StartResult is a handle to the result of a call to [Start]. Call +// [StartResult.Wait] to wait for the completion of all work done on behalf of +// Start. +type StartResult struct { + wg sync.WaitGroup +} + +// Wait waits for the completion of all work initiated by [Start]. +func (res *StartResult) Wait() { + if res == nil { + return + } + res.wg.Wait() +} + +var daemonize = func(cmd *exec.Cmd) {} + +// If telemetryChildVar is set to "1" in the environment, this is the telemetry +// child. +// +// If telemetryChildVar is set to "2", this is a child of the child, and no +// further forking should occur. +const telemetryChildVar = "GO_TELEMETRY_CHILD" + +// If telemetryUploadVar is set to "1" in the environment, the upload token has been +// acquired by the parent, and the child should attempt an upload. +const telemetryUploadVar = "GO_TELEMETRY_CHILD_UPLOAD" + +func parent(config Config) *StartResult { + if config.TelemetryDir != "" { + telemetry.Default = telemetry.NewDir(config.TelemetryDir) + } + result := new(StartResult) + + mode, _ := telemetry.Default.Mode() + if mode == "off" { + // Telemetry is turned off. Crash reporting doesn't work without telemetry + // at least set to "local". The upload process runs in both "on" and "local" modes. + // In local mode the upload process builds local reports but does not do the upload. + return result + } + + counter.Open() + + if _, err := os.Stat(telemetry.Default.LocalDir()); err != nil { + // There was a problem statting LocalDir, which is needed for both + // crash monitoring and counter uploading. Most likely, there was an + // error creating telemetry.LocalDir in the counter.Open call above. + // Don't start the child. + return result + } + + childShouldUpload := config.Upload && acquireUploadToken() + reportCrashes := config.ReportCrashes + + if reportCrashes || childShouldUpload { + startChild(reportCrashes, childShouldUpload, result) + } + + return result +} + +func startChild(reportCrashes, upload bool, result *StartResult) { + // This process is the application (parent). + // Fork+exec the telemetry child. + exe, err := os.Executable() + if err != nil { + // There was an error getting os.Executable. It's possible + // for this to happen on AIX if os.Args[0] is not an absolute + // path and we can't find os.Args[0] in PATH. + log.Printf("failed to start telemetry sidecar: os.Executable: %v", err) + return + } + cmd := exec.Command(exe, "** telemetry **") // this unused arg is just for ps(1) + daemonize(cmd) + cmd.Env = append(os.Environ(), telemetryChildVar+"=1") + if upload { + cmd.Env = append(cmd.Env, telemetryUploadVar+"=1") + } + cmd.Dir = telemetry.Default.LocalDir() + + // The child process must write to a log file, not + // the stderr file it inherited from the parent, as + // the child may outlive the parent but should not prolong + // the life of any pipes created (by the grandparent) + // to gather the output of the parent. + // + // By default, we discard the child process's stderr, + // but in line with the uploader, log to a file in debug + // only if that directory was created by the user. + fd, err := os.Stat(telemetry.Default.DebugDir()) + if err != nil { + if !os.IsNotExist(err) { + log.Printf("failed to stat debug directory: %v", err) + return + } + } else if fd.IsDir() { + // local/debug exists and is a directory. Set stderr to a log file path + // in local/debug. + childLogPath := filepath.Join(telemetry.Default.DebugDir(), "sidecar.log") + childLog, err := os.OpenFile(childLogPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600) + if err != nil { + log.Printf("opening sidecar log file for child: %v", err) + return + } + defer childLog.Close() + cmd.Stderr = childLog + } + + var crashOutputFile *os.File + if reportCrashes { + pipe, err := cmd.StdinPipe() + if err != nil { + log.Printf("StdinPipe: %v", err) + return + } + + crashOutputFile = pipe.(*os.File) // (this conversion is safe) + } + + if err := cmd.Start(); err != nil { + // The child couldn't be started. Log the failure. + log.Printf("can't start telemetry child process: %v", err) + return + } + if reportCrashes { + crashmonitor.Parent(crashOutputFile) + } + result.wg.Add(1) + go func() { + cmd.Wait() // Release resources if cmd happens not to outlive this process. + result.wg.Done() + }() +} + +func child(config Config) { + log.SetPrefix(fmt.Sprintf("telemetry-sidecar (pid %v): ", os.Getpid())) + + if config.TelemetryDir != "" { + telemetry.Default = telemetry.NewDir(config.TelemetryDir) + } + + // golang/go#67211: be sure to set telemetryChildVar before running the + // child, because the child itself invokes the go command to download the + // upload config. If the telemetryChildVar variable is still set to "1", + // that delegated go command may think that it is itself a telemetry + // child. + // + // On the other hand, if telemetryChildVar were simply unset, then the + // delegated go commands would fork themselves recursively. Short-circuit + // this recursion. + os.Setenv(telemetryChildVar, "2") + upload := os.Getenv(telemetryUploadVar) == "1" + + // The crashmonitor and/or upload process may themselves record counters. + counter.Open() + + // Start crashmonitoring and uploading depending on what's requested + // and wait for the longer running child to complete before exiting: + // if we collected a crash before the upload finished, wait for the + // upload to finish before exiting + var g errgroup.Group + + if config.ReportCrashes { + g.Go(func() error { + crashmonitor.Child() + return nil + }) + } + if upload { + g.Go(func() error { + uploaderChild(config.UploadStartTime, config.UploadURL) + return nil + }) + } + g.Wait() + + os.Exit(0) +} + +func uploaderChild(asof time.Time, uploadURL string) { + if err := upload.Run(upload.RunConfig{ + UploadURL: uploadURL, + LogWriter: os.Stderr, + StartTime: asof, + }); err != nil { + log.Printf("upload failed: %v", err) + } +} + +// acquireUploadToken acquires a token permitting the caller to upload. +// To limit the frequency of uploads, only one token is issue per +// machine per time period. +// The boolean indicates whether the token was acquired. +func acquireUploadToken() bool { + if telemetry.Default.LocalDir() == "" { + // The telemetry dir wasn't initialized properly, probably because + // os.UserConfigDir did not complete successfully. In that case + // there are no counters to upload, so we should just do nothing. + return false + } + tokenfile := filepath.Join(telemetry.Default.LocalDir(), "upload.token") + const period = 24 * time.Hour + + // A process acquires a token by successfully creating a + // well-known file. If the file already exists and has an + // mtime age less then than the period, the process does + // not acquire the token. If the file is older than the + // period, the process is allowed to remove the file and + // try to re-create it. + fi, err := os.Stat(tokenfile) + if err == nil { + if time.Since(fi.ModTime()) < period { + return false + } + // There's a possible race here where two processes check the + // token file and see that it's older than the period, then the + // first one removes it and creates another, and then a second one + // removes the newly created file and creates yet another + // file. Then both processes would act as though they had the token. + // This is very rare, but it's also okay because we're only grabbing + // the token to do rate limiting, not for correctness. + _ = os.Remove(tokenfile) + } else if !os.IsNotExist(err) { + log.Printf("error acquiring upload taken: statting token file: %v", err) + return false + } + + f, err := os.OpenFile(tokenfile, os.O_CREATE|os.O_EXCL, 0666) + if err != nil { + if os.IsExist(err) { + return false + } + log.Printf("error acquiring upload token: creating token file: %v", err) + return false + } + _ = f.Close() + return true +} diff --git a/vendor/golang.org/x/telemetry/start_posix.go b/vendor/golang.org/x/telemetry/start_posix.go new file mode 100644 index 0000000..078b235 --- /dev/null +++ b/vendor/golang.org/x/telemetry/start_posix.go @@ -0,0 +1,22 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris + +package telemetry + +import ( + "os/exec" + "syscall" +) + +func init() { + daemonize = daemonizePosix +} + +func daemonizePosix(cmd *exec.Cmd) { + cmd.SysProcAttr = &syscall.SysProcAttr{ + Setsid: true, + } +} diff --git a/vendor/golang.org/x/telemetry/start_windows.go b/vendor/golang.org/x/telemetry/start_windows.go new file mode 100644 index 0000000..ceb2c02 --- /dev/null +++ b/vendor/golang.org/x/telemetry/start_windows.go @@ -0,0 +1,29 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows + +package telemetry + +import ( + "os/exec" + "syscall" + + "golang.org/x/sys/windows" +) + +func init() { + daemonize = daemonizeWindows +} + +func daemonizeWindows(cmd *exec.Cmd) { + // Set DETACHED_PROCESS creation flag so that closing + // the console window the parent process was run in + // does not kill the child. + // See documentation of creation flags in the Microsoft documentation: + // https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags + cmd.SysProcAttr = &syscall.SysProcAttr{ + CreationFlags: windows.DETACHED_PROCESS, + } +} diff --git a/vendor/golang.org/x/telemetry/tsconfig.json b/vendor/golang.org/x/telemetry/tsconfig.json new file mode 100644 index 0000000..7833e31 --- /dev/null +++ b/vendor/golang.org/x/telemetry/tsconfig.json @@ -0,0 +1,26 @@ +{ + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "node", + + "strict": true, + "allowUnusedLabels": false, + "allowUnreachableCode": false, + "exactOptionalPropertyTypes": true, + "noFallthroughCasesInSwitch": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + + "checkJs": true, + + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, +} \ No newline at end of file diff --git a/vendor/golang.org/x/telemetry/types_alias.go b/vendor/golang.org/x/telemetry/types_alias.go new file mode 100644 index 0000000..83ba7e0 --- /dev/null +++ b/vendor/golang.org/x/telemetry/types_alias.go @@ -0,0 +1,21 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package telemetry + +import "golang.org/x/telemetry/internal/telemetry" + +// Common types and directories used by multiple packages. + +// An UploadConfig controls what data is uploaded. +type UploadConfig = telemetry.UploadConfig + +type ProgramConfig = telemetry.ProgramConfig + +type CounterConfig = telemetry.CounterConfig + +// A Report is what's uploaded (or saved locally) +type Report = telemetry.Report + +type ProgramReport = telemetry.ProgramReport diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE new file mode 100644 index 0000000..2a7cf70 --- /dev/null +++ b/vendor/golang.org/x/tools/LICENSE @@ -0,0 +1,27 @@ +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS new file mode 100644 index 0000000..7330990 --- /dev/null +++ b/vendor/golang.org/x/tools/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/tools/cmd/deadcode/deadcode.go b/vendor/golang.org/x/tools/cmd/deadcode/deadcode.go new file mode 100644 index 0000000..780bbb3 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/deadcode/deadcode.go @@ -0,0 +1,634 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bytes" + _ "embed" + "encoding/json" + "flag" + "fmt" + "go/ast" + "go/token" + "go/types" + "io" + "log" + "maps" + "os" + "path/filepath" + "regexp" + "runtime" + "runtime/pprof" + "slices" + "sort" + "strings" + "text/template" + + "golang.org/x/telemetry" + "golang.org/x/tools/go/callgraph" + "golang.org/x/tools/go/callgraph/rta" + "golang.org/x/tools/go/packages" + "golang.org/x/tools/go/ssa" + "golang.org/x/tools/go/ssa/ssautil" + "golang.org/x/tools/internal/typesinternal" +) + +//go:embed doc.go +var doc string + +// flags +var ( + testFlag = flag.Bool("test", false, "include implicit test packages and executables") + tagsFlag = flag.String("tags", "", "comma-separated list of extra build tags (see: go help buildconstraint)") + + filterFlag = flag.String("filter", "", "report only packages matching this regular expression (default: module of first package)") + generatedFlag = flag.Bool("generated", false, "include dead functions in generated Go files") + whyLiveFlag = flag.String("whylive", "", "show a path from main to the named function") + formatFlag = flag.String("f", "", "format output records using template") + jsonFlag = flag.Bool("json", false, "output JSON records") + cpuProfile = flag.String("cpuprofile", "", "write CPU profile to this file") + memProfile = flag.String("memprofile", "", "write memory profile to this file") +) + +func usage() { + // Extract the content of the /* ... */ comment in doc.go. + _, after, _ := strings.Cut(doc, "/*\n") + doc, _, _ := strings.Cut(after, "*/") + io.WriteString(flag.CommandLine.Output(), doc+` +Flags: + +`) + flag.PrintDefaults() +} + +func main() { + telemetry.Start(telemetry.Config{ReportCrashes: true}) + + log.SetPrefix("deadcode: ") + log.SetFlags(0) // no time prefix + + flag.Usage = usage + flag.Parse() + if len(flag.Args()) == 0 { + usage() + os.Exit(2) + } + + if *cpuProfile != "" { + f, err := os.Create(*cpuProfile) + if err != nil { + log.Fatal(err) + } + if err := pprof.StartCPUProfile(f); err != nil { + log.Fatal(err) + } + // NB: profile won't be written in case of error. + defer pprof.StopCPUProfile() + } + + if *memProfile != "" { + f, err := os.Create(*memProfile) + if err != nil { + log.Fatal(err) + } + // NB: profile won't be written in case of error. + defer func() { + runtime.GC() // get up-to-date statistics + if err := pprof.WriteHeapProfile(f); err != nil { + log.Fatalf("Writing memory profile: %v", err) + } + f.Close() + }() + } + + // Reject bad output options early. + if *formatFlag != "" { + if *jsonFlag { + log.Fatalf("you cannot specify both -f=template and -json") + } + if _, err := template.New("deadcode").Parse(*formatFlag); err != nil { + log.Fatalf("invalid -f: %v", err) + } + } + + // Load, parse, and type-check the complete program(s). + cfg := &packages.Config{ + BuildFlags: []string{"-tags=" + *tagsFlag}, + Mode: packages.LoadAllSyntax | packages.NeedModule, + Tests: *testFlag, + } + initial, err := packages.Load(cfg, flag.Args()...) + if err != nil { + log.Fatalf("Load: %v", err) + } + if len(initial) == 0 { + log.Fatalf("no packages") + } + if packages.PrintErrors(initial) > 0 { + log.Fatalf("packages contain errors") + } + + // If -filter is unset, use first module (if available). + if *filterFlag == "" { + seen := make(map[string]bool) + var patterns []string + for _, pkg := range initial { + if pkg.Module != nil && pkg.Module.Path != "" && !seen[pkg.Module.Path] { + seen[pkg.Module.Path] = true + patterns = append(patterns, regexp.QuoteMeta(pkg.Module.Path)) + } + } + + if patterns != nil { + *filterFlag = "^(" + strings.Join(patterns, "|") + ")\\b" + } else { + *filterFlag = "" // match any + } + } + filter, err := regexp.Compile(*filterFlag) + if err != nil { + log.Fatalf("-filter: %v", err) + } + + // Create SSA-form program representation + // and find main packages. + prog, pkgs := ssautil.AllPackages(initial, ssa.InstantiateGenerics) + + mains := ssautil.MainPackages(pkgs) + if len(mains) == 0 { + log.Fatalf("no main packages") + } + var roots []*ssa.Function + for _, main := range mains { + roots = append(roots, main.Func("init"), main.Func("main")) + } + + // Gather all source-level functions, + // as the user interface is expressed in terms of them. + // + // We ignore synthetic wrappers, and nested functions. Literal + // functions passed as arguments to other functions are of + // course address-taken and there exists a dynamic call of + // that signature, so when they are unreachable, it is + // invariably because the parent is unreachable. + var ( + sourceFuncs []*ssa.Function + generated = make(map[string]bool) + interfaceTypes = make(map[*types.Package][]*types.Interface) + ) + packages.Visit(initial, nil, func(p *packages.Package) { + // Collect interfaces by package for marker method identification. + var interfaces []*types.Interface + scope := p.Types.Scope() + for _, name := range scope.Names() { + if typeName, ok := scope.Lookup(name).(*types.TypeName); ok && + types.IsInterface(typeName.Type()) { + interfaces = append(interfaces, typeName.Type().Underlying().(*types.Interface)) + } + } + interfaceTypes[p.Types] = interfaces + + for _, file := range p.Syntax { + for _, decl := range file.Decls { + if decl, ok := decl.(*ast.FuncDecl); ok { + obj := p.TypesInfo.Defs[decl.Name].(*types.Func) + fn := prog.FuncValue(obj) + sourceFuncs = append(sourceFuncs, fn) + } + } + + if ast.IsGenerated(file) { + generated[p.Fset.File(file.Pos()).Name()] = true + } + } + }) + + // Build function bodies only now: nothing below uses the + // syntax or type information of initial, so it can be + // freed as each package is built. Everything after this + // point works from the SSA program and its file set alone. + initial, pkgs = nil, nil // aid GC + prog.Build() + + // -- types.Info is now unused and may be reclaimed by GC -- + + fset := prog.Fset + prog = nil + + // Compute the reachabilty from main. + // (Build a call graph only for -whylive.) + res := rta.Analyze(roots, *whyLiveFlag != "") + + // Subtle: the -test flag causes us to analyze test variants + // such as "package p as compiled for p.test" or even "for q.test". + // This leads to multiple distinct ssa.Function instances that + // represent the same source declaration, and it is essentially + // impossible to discover this from the SSA representation + // (since it has lost the connection to go/packages.Package.ID). + // + // So, we de-duplicate such variants by position: + // if any one of them is live, we consider all of them live. + // (We use Position not Pos to avoid assuming that files common + // to packages "p" and "p [p.test]" were parsed only once.) + reachablePosn := make(map[token.Position]bool) + for fn := range res.Reachable { + if fn.Pos().IsValid() || fn.Name() == "init" { + reachablePosn[fset.Position(fn.Pos())] = true + } + } + + // The -whylive=fn flag causes deadcode to explain why a function + // is not dead, by showing a path to it from some root. + if *whyLiveFlag != "" { + targets := make(map[*ssa.Function]bool) + for _, fn := range sourceFuncs { + if prettyName(fn, true) == *whyLiveFlag { + targets[fn] = true + } + } + if len(targets) == 0 { + // Function is not part of the program. + // + // TODO(adonovan): improve the UX here in case + // of spelling or syntax mistakes. Some ideas: + // - a cmd/callgraph command to enumerate + // available functions. + // - a deadcode -live flag to compute the complement. + // - a syntax hint: example.com/pkg.Func or (example.com/pkg.Type).Method + // - report the element of AllFunctions with the smallest + // Levenshtein distance from *whyLiveFlag. + // - permit -whylive=regexp. But beware of spurious + // matches (e.g. fmt.Print matches fmt.Println) + // and the annoyance of having to quote parens (*T).f. + log.Fatalf("function %q not found in program", *whyLiveFlag) + } + + // Opt: remove the unreachable ones. + for fn := range targets { + if !reachablePosn[fset.Position(fn.Pos())] { + delete(targets, fn) + } + } + if len(targets) == 0 { + log.Fatalf("function %s is dead code", *whyLiveFlag) + } + + res.CallGraph.DeleteSyntheticNodes() // inline synthetic wrappers (except inits) + root, path := pathSearch(roots, res, targets) + if root == nil { + // RTA doesn't add callgraph edges for reflective calls. + log.Fatalf("%s is reachable only through reflection", *whyLiveFlag) + } + if len(path) == 0 { + // No edges => one of the targets is a root. + // Rather than (confusingly) print nothing, make this an error. + log.Fatalf("%s is a root", root.Func) + } + + // Build a list of jsonEdge records + // to print as -json or -f=template. + var edges []any + for _, edge := range path { + edges = append(edges, jsonEdge{ + Initial: cond(len(edges) == 0, prettyName(edge.Caller.Func, true), ""), + Kind: cond(isStaticCall(edge), "static", "dynamic"), + Position: toJSONPosition(fset.Position(edge.Pos())), + Callee: prettyName(edge.Callee.Func, true), + }) + } + format := `{{if .Initial}}{{printf "%19s%s\n" "" .Initial}}{{end}}{{printf "%8s@L%.4d --> %s" .Kind .Position.Line .Callee}}` + if *formatFlag != "" { + format = *formatFlag + } + printObjects(format, edges) + return + } + + // Group unreachable functions by package path. + byPkgPath := make(map[string]map[*ssa.Function]bool) + for _, fn := range sourceFuncs { + posn := fset.Position(fn.Pos()) + + if !reachablePosn[posn] { + reachablePosn[posn] = true // suppress dups with same pos + + pkgpath := fn.Pkg.Pkg.Path() + m, ok := byPkgPath[pkgpath] + if !ok { + m = make(map[*ssa.Function]bool) + byPkgPath[pkgpath] = m + } + m[fn] = true + } + } + + // Build array of jsonPackage objects. + var packages []any + for _, pkgpath := range slices.Sorted(maps.Keys(byPkgPath)) { + if !filter.MatchString(pkgpath) { + continue + } + + m := byPkgPath[pkgpath] + + // Print functions that appear within the same file in + // declaration order. This tends to keep related + // methods such as (T).Marshal and (*T).Unmarshal + // together better than sorting. + fns := slices.Collect(maps.Keys(m)) + sort.Slice(fns, func(i, j int) bool { + xposn := fset.Position(fns[i].Pos()) + yposn := fset.Position(fns[j].Pos()) + if xposn.Filename != yposn.Filename { + return xposn.Filename < yposn.Filename + } + return xposn.Line < yposn.Line + }) + + var functions []jsonFunction + for _, fn := range fns { + posn := fset.Position(fn.Pos()) + + // Without -generated, skip functions declared in + // generated Go files. + // (Functions called by them may still be reported.) + gen := generated[posn.Filename] + if gen && !*generatedFlag { + continue + } + + // Marker methods should not be reported + marker := isMarkerMethod(fn, interfaceTypes[fn.Pkg.Pkg]) + if marker { + continue + } + + functions = append(functions, jsonFunction{ + Name: prettyName(fn, false), + Position: toJSONPosition(posn), + Generated: gen, + Marker: marker, + }) + } + if len(functions) > 0 { + packages = append(packages, jsonPackage{ + Name: fns[0].Pkg.Pkg.Name(), + Path: pkgpath, + Funcs: functions, + }) + } + } + + // Default line-oriented format: "a/b/c.go:1:2: unreachable func: T.f" + format := `{{range .Funcs}}{{printf "%s: unreachable func: %s\n" .Position .Name}}{{end}}` + if *formatFlag != "" { + format = *formatFlag + } + printObjects(format, packages) +} + +// prettyName is a fork of Function.String designed to reduce +// go/ssa's fussy punctuation symbols, e.g. "(*pkg.T).F" -> "pkg.T.F". +// +// It only works for functions that remain after +// callgraph.Graph.DeleteSyntheticNodes: source-level named functions +// and methods, their anonymous functions, and synthetic package +// initializers. +func prettyName(fn *ssa.Function, qualified bool) string { + var buf strings.Builder + + // optional package qualifier + if qualified && fn.Pkg != nil { + fmt.Fprintf(&buf, "%s.", fn.Pkg.Pkg.Path()) + } + + var format func(*ssa.Function) + format = func(fn *ssa.Function) { + // anonymous? + if fn.Parent() != nil { + format(fn.Parent()) + i := slices.Index(fn.Parent().AnonFuncs, fn) + fmt.Fprintf(&buf, "$%d", i+1) + return + } + + // method receiver? + if obj, ok := fn.Object().(*types.Func); ok { + if _, named := typesinternal.RecvBase(obj); named != nil { + buf.WriteString(named.Obj().Name()) + buf.WriteByte('.') + } + } + + // function/method name + buf.WriteString(fn.Name()) + } + format(fn) + + return buf.String() +} + +// printObjects formats an array of objects, either as JSON or using a +// template, following the manner of 'go list (-json|-f=template)'. +func printObjects(format string, objects []any) { + if *jsonFlag { + out, err := json.MarshalIndent(objects, "", "\t") + if err != nil { + log.Fatalf("internal error: %v", err) + } + os.Stdout.Write(out) + return + } + + // -f=template. Parse can't fail: we checked it earlier. + tmpl := template.Must(template.New("deadcode").Parse(format)) + for _, object := range objects { + var buf bytes.Buffer + if err := tmpl.Execute(&buf, object); err != nil { + log.Fatal(err) + } + if n := buf.Len(); n == 0 || buf.Bytes()[n-1] != '\n' { + buf.WriteByte('\n') + } + os.Stdout.Write(buf.Bytes()) + } +} + +// pathSearch returns the shortest path from one of the roots to one +// of the targets (along with the root itself), or zero if no path was found. +func pathSearch(roots []*ssa.Function, res *rta.Result, targets map[*ssa.Function]bool) (*callgraph.Node, []*callgraph.Edge) { + // Search breadth-first (for shortest path) from the root. + // + // We don't use the virtual CallGraph.Root node as we wish to + // choose the order in which we search entrypoints: + // non-test packages before test packages, + // main functions before init functions. + + // Sort roots into preferred order. + importsTesting := func(fn *ssa.Function) bool { + isTesting := func(p *types.Package) bool { return p.Path() == "testing" } + return slices.ContainsFunc(fn.Pkg.Pkg.Imports(), isTesting) + } + sort.Slice(roots, func(i, j int) bool { + x, y := roots[i], roots[j] + xtest := importsTesting(x) + ytest := importsTesting(y) + if xtest != ytest { + return !xtest // non-tests before tests + } + xinit := x.Name() == "init" + yinit := y.Name() == "init" + if xinit != yinit { + return !xinit // mains before inits + } + return false + }) + + search := func(allowDynamic bool) (*callgraph.Node, []*callgraph.Edge) { + // seen maps each encountered node to its predecessor on the + // path to a root node, or to nil for root itself. + seen := make(map[*callgraph.Node]*callgraph.Edge) + bfs := func(root *callgraph.Node) []*callgraph.Edge { + queue := []*callgraph.Node{root} + seen[root] = nil + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] + + // found a path? + if targets[node.Func] { + path := []*callgraph.Edge{} // non-nil in case len(path)=0 + for { + edge := seen[node] + if edge == nil { + slices.Reverse(path) + return path + } + path = append(path, edge) + node = edge.Caller + } + } + + for _, edge := range node.Out { + if allowDynamic || isStaticCall(edge) { + if _, ok := seen[edge.Callee]; !ok { + seen[edge.Callee] = edge + queue = append(queue, edge.Callee) + } + } + } + } + return nil + } + for _, rootFn := range roots { + root := res.CallGraph.Nodes[rootFn] + if root == nil { + // Missing call graph node for root. + // TODO(adonovan): seems like a bug in rta. + continue + } + if path := bfs(root); path != nil { + return root, path + } + } + return nil, nil + } + + for _, allowDynamic := range []bool{false, true} { + if root, path := search(allowDynamic); path != nil { + return root, path + } + } + + return nil, nil +} + +// -- utilities -- + +func isStaticCall(edge *callgraph.Edge) bool { + return edge.Site != nil && edge.Site.Common().StaticCallee() != nil +} + +var cwd, _ = os.Getwd() + +func toJSONPosition(posn token.Position) jsonPosition { + // Use cwd-relative filename if possible. + filename := posn.Filename + if rel, err := filepath.Rel(cwd, filename); err == nil && !strings.HasPrefix(rel, "..") { + filename = rel + } + + return jsonPosition{filename, posn.Line, posn.Column} +} + +func cond[T any](cond bool, t, f T) T { + if cond { + return t + } else { + return f + } +} + +// isMarkerMethod reports whether fn is a marker method: +// an unexported, empty-bodied method with no parameters or results +// that implements some named interface type in the same package. +func isMarkerMethod(fn *ssa.Function, interfaceTypes []*types.Interface) bool { + // Is it an unexported method of no params/results? + if !(fn.Signature.Recv() != nil && + !ast.IsExported(fn.Name()) && + fn.Signature.Params() == nil && + fn.Signature.Results() == nil) { + return false + } + + // Does the method have an empty body? + body := fn.Syntax().(*ast.FuncDecl).Body + if body == nil || len(body.List) > 0 { + return false + } + + // Does it implement some named interface type in this package? + return slices.ContainsFunc(interfaceTypes, func(iface *types.Interface) bool { + return types.Implements(fn.Signature.Recv().Type(), iface) + }) +} + +// -- output protocol (for JSON or text/template) -- + +// Keep in sync with doc comment! + +type jsonFunction struct { + Name string // name (sans package qualifier) + Position jsonPosition // file/line/column of declaration + Generated bool // function is declared in a generated .go file + Marker bool // function is a marker interface method +} + +func (f jsonFunction) String() string { return f.Name } + +type jsonPackage struct { + Name string // declared name + Path string // full import path + Funcs []jsonFunction // non-empty list of package's dead functions +} + +func (p jsonPackage) String() string { return p.Path } + +// The Initial and Callee names are package-qualified. +type jsonEdge struct { + Initial string `json:",omitempty"` // initial entrypoint (main or init); first edge only + Kind string // = static | dynamic + Position jsonPosition + Callee string +} + +type jsonPosition struct { + File string + Line, Col int +} + +func (p jsonPosition) String() string { + return fmt.Sprintf("%s:%d:%d", p.File, p.Line, p.Col) +} diff --git a/vendor/golang.org/x/tools/cmd/deadcode/doc.go b/vendor/golang.org/x/tools/cmd/deadcode/doc.go new file mode 100644 index 0000000..aff22c6 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/deadcode/doc.go @@ -0,0 +1,146 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +The deadcode command reports unreachable functions in Go programs. + + Usage: deadcode [flags] package... + +The deadcode command loads a Go program from source then uses Rapid +Type Analysis (RTA) to build a call graph of all the functions +reachable from the program's main function. Any functions that are not +reachable are reported as dead code, grouped by package. + +Packages are expressed in the notation of 'go list' (or other +underlying build system if you are using an alternative +golang.org/x/go/packages driver). Only executable (main) packages are +considered starting points for the analysis. + +The -test flag causes it to analyze test executables too. Tests +sometimes make use of functions that would otherwise appear to be dead +code, and public API functions reported as dead with -test indicate +possible gaps in your test coverage. Bear in mind that an Example test +function without an "Output:" comment is merely documentation: +it is dead code, and does not contribute coverage. + +The -filter flag restricts results to packages that match the provided +regular expression; its default value matches the listed packages and any other +packages belonging to the same modules. Use -filter= to display all results. + +Example: show all dead code within the gopls module: + + $ deadcode -test golang.org/x/tools/gopls/... + +The analysis can soundly analyze dynamic calls though func values, +interface methods, and reflection. However, it does not currently +understand the aliasing created by //go:linkname directives, so it +will fail to recognize that calls to a linkname-annotated function +with no body in fact dispatch to the function named in the annotation. +This may result in the latter function being spuriously reported as dead. + +By default, the tool does not report dead functions in generated files, +as determined by the special comment described in +https://go.dev/s/generatedcode. Use the -generated flag to include them. + +The tool also does not report marker interface methods by default. +Marker interface methods are typically used to create compile-time constraints +to ensure that only specific types can implement a particular interface. +These methods have no other functionality (empty function body) and are never invoked. +Although marker interface methods are technically unreachable, removing them would break +the interface implementation. Hence, the tool excludes them from the report. + +In any case, just because a function is reported as dead does not mean +it is unconditionally safe to delete it. For example, a dead function +may be referenced by another dead function, and a dead method may be +required to satisfy an interface that is never called. +Some judgement is required. + +The analysis is valid only for a single GOOS/GOARCH/-tags configuration, +so a function reported as dead may be live in a different configuration. +Consider running the tool once for each configuration of interest. +Consider using a line-oriented output format (see below) to make it +easier to compute the intersection of results across all runs. + +# Output + +The command supports three output formats. + +With no flags, the command prints the name and location of each dead +function in the form of a typical compiler diagnostic, for example: + + $ deadcode -f='{{range .Funcs}}{{println .Position}}{{end}}' -test ./gopls/... + gopls/internal/protocol/command.go:1206:6: unreachable func: openClientEditor + gopls/internal/template/parse.go:414:18: unreachable func: Parsed.WriteNode + gopls/internal/template/parse.go:419:18: unreachable func: wrNode.writeNode + +With the -json flag, the command prints an array of Package +objects, as defined by the JSON schema (see below). + +With the -f=template flag, the command executes the specified template +on each Package record. So, this template shows dead functions grouped +by package: + + $ deadcode -f='{{println .Path}}{{range .Funcs}}{{printf "\t%s\n" .Name}}{{end}}{{println}}' -test ./gopls/... + golang.org/x/tools/gopls/internal/lsp + openClientEditor + + golang.org/x/tools/gopls/internal/template + Parsed.WriteNode + wrNode.writeNode + +# Why is a function not dead? + +The -whylive=function flag explain why the named function is not dead +by showing an arbitrary shortest path to it from one of the main functions. +(To enumerate the functions in a program, or for more sophisticated +call graph queries, use golang.org/x/tools/cmd/callgraph.) + +Fully static call paths are preferred over paths involving dynamic +edges, even if longer. Paths starting from a non-test package are +preferred over those from tests. Paths from main functions are +preferred over paths from init functions. + +The result is a list of Edge objects (see JSON schema below). +Again, the -json and -f=template flags may be used to control +the formatting of the list of Edge objects. +The default format shows, for each edge in the path, whether the call +is static or dynamic, and its source line number. For example: + + $ deadcode -whylive=bytes.Buffer.String -test ./cmd/deadcode/... + golang.org/x/tools/cmd/deadcode.main + static@L0117 --> golang.org/x/tools/go/packages.Load + static@L0262 --> golang.org/x/tools/go/packages.defaultDriver + static@L0305 --> golang.org/x/tools/go/packages.goListDriver + static@L0153 --> golang.org/x/tools/go/packages.goListDriver$1 + static@L0154 --> golang.org/x/tools/go/internal/packagesdriver.GetSizesForArgsGolist + static@L0044 --> bytes.Buffer.String + +# JSON schema + + type Package struct { + Name string // declared name + Path string // full import path + Funcs []Function // list of dead functions within it + } + + type Function struct { + Name string // name (sans package qualifier) + Position Position // file/line/column of function declaration + Generated bool // function is declared in a generated .go file + Marker bool // function is a marker interface method + } + + type Edge struct { + Initial string // initial entrypoint (main or init); first edge only + Kind string // = static | dynamic + Position Position // file/line/column of call site + Callee string // target of the call + } + + type Position struct { + File string // name of file + Line, Col int // line and byte index, both 1-based + } +*/ +package main diff --git a/vendor/golang.org/x/tools/cmd/goimports/doc.go b/vendor/golang.org/x/tools/cmd/goimports/doc.go new file mode 100644 index 0000000..18a3ad4 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/goimports/doc.go @@ -0,0 +1,50 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Command goimports updates your Go import lines, +adding missing ones and removing unreferenced ones. + + $ go install golang.org/x/tools/cmd/goimports@latest + +In addition to fixing imports, goimports also formats +your code in the same style as gofmt so it can be used +as a replacement for your editor's gofmt-on-save hook. + +For emacs, make sure you have the latest go-mode.el: + + https://github.com/dominikh/go-mode.el + +Then in your .emacs file: + + (setq gofmt-command "goimports") + (add-hook 'before-save-hook 'gofmt-before-save) + +For vim, set "gofmt_command" to "goimports": + + https://golang.org/change/39c724dd7f252 + https://golang.org/wiki/IDEsAndTextEditorPlugins + etc + +For GoSublime, follow the steps described here: + + http://michaelwhatcott.com/gosublime-goimports/ + +For other editors, you probably know what to do. + +To exclude directories in your $GOPATH from being scanned for Go +files, goimports respects a configuration file at +$GOPATH/src/.goimportsignore which may contain blank lines, comment +lines (beginning with '#'), or lines naming a directory relative to +the configuration file to ignore when scanning. No globbing or regex +patterns are allowed. Use the "-v" verbose flag to verify it's +working and see what goimports is doing. + +File bugs or feature requests at: + + https://golang.org/issues/new?title=x/tools/cmd/goimports:+ + +Happy hacking! +*/ +package main // import "golang.org/x/tools/cmd/goimports" diff --git a/vendor/golang.org/x/tools/cmd/goimports/goimports.go b/vendor/golang.org/x/tools/cmd/goimports/goimports.go new file mode 100644 index 0000000..84b9b9e --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/goimports/goimports.go @@ -0,0 +1,388 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bufio" + "bytes" + "errors" + "flag" + "fmt" + "go/scanner" + "io" + "io/fs" + "log" + "os" + "os/exec" + "path/filepath" + "runtime" + "runtime/pprof" + "strings" + "testing" + + "golang.org/x/telemetry/counter" + "golang.org/x/tools/internal/gocommand" + "golang.org/x/tools/internal/imports" +) + +var ( + // main operation modes + list = flag.Bool("l", false, "list files whose formatting differs from goimport's") + write = flag.Bool("w", false, "write result to (source) file instead of stdout") + doDiff = flag.Bool("d", false, "display diffs instead of rewriting files") + srcdir = flag.String("srcdir", "", "choose imports as if source code is from `dir`. When operating on a single file, dir may instead be the complete file name.") + + verbose bool // verbose logging + + cpuProfile = flag.String("cpuprofile", "", "CPU profile output") + memProfile = flag.String("memprofile", "", "memory profile output") + memProfileRate = flag.Int("memrate", 0, "if > 0, sets runtime.MemProfileRate") + + options = &imports.Options{ + TabWidth: 8, + TabIndent: true, + Comments: true, + Fragment: true, + Env: &imports.ProcessEnv{ + GocmdRunner: &gocommand.Runner{}, + }, + } + exitCode = 0 +) + +func init() { + flag.BoolVar(&options.AllErrors, "e", false, "report all errors (not just the first 10 on different lines)") + flag.StringVar(&options.LocalPrefix, "local", "", "put imports beginning with this string after 3rd-party packages; comma-separated list") + flag.BoolVar(&options.FormatOnly, "format-only", false, "if true, don't fix imports and only format. In this mode, goimports is effectively gofmt, with the addition that imports are grouped into sections.") +} + +func report(err error) { + scanner.PrintError(os.Stderr, err) + exitCode = 2 +} + +func usage() { + fmt.Fprintf(os.Stderr, "usage: goimports [flags] [path ...]\n") + flag.PrintDefaults() + os.Exit(2) +} + +func isGoFile(d fs.DirEntry) bool { + // ignore non-Go files + name := d.Name() + return !d.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") +} + +// argumentType is which mode goimports was invoked as. +type argumentType int + +const ( + // fromStdin means the user is piping their source into goimports. + fromStdin argumentType = iota + + // singleArg is the common case from editors, when goimports is run on + // a single file. + singleArg + + // multipleArg is when the user ran "goimports file1.go file2.go" + // or ran goimports on a directory tree. + multipleArg +) + +func processFile(filename string, in io.Reader, out io.Writer, argType argumentType) error { + opt := options + if argType == fromStdin { + nopt := *options + nopt.Fragment = true + opt = &nopt + } + + if in == nil { + f, err := os.Open(filename) + if err != nil { + return err + } + defer f.Close() + in = f + } + + src, err := io.ReadAll(in) + if err != nil { + return err + } + + target := filename + if *srcdir != "" { + // Determine whether the provided -srcdirc is a directory or file + // and then use it to override the target. + // + // See https://github.com/dominikh/go-mode.el/issues/146 + if isFile(*srcdir) { + if argType == multipleArg { + return errors.New("-srcdir value can't be a file when passing multiple arguments or when walking directories") + } + target = *srcdir + } else if argType == singleArg && strings.HasSuffix(*srcdir, ".go") && !isDir(*srcdir) { + // For a file which doesn't exist on disk yet, but might shortly. + // e.g. user in editor opens $DIR/newfile.go and newfile.go doesn't yet exist on disk. + // The goimports on-save hook writes the buffer to a temp file + // first and runs goimports before the actual save to newfile.go. + // The editor's buffer is named "newfile.go" so that is passed to goimports as: + // goimports -srcdir=/gopath/src/pkg/newfile.go /tmp/gofmtXXXXXXXX.go + // and then the editor reloads the result from the tmp file and writes + // it to newfile.go. + target = *srcdir + } else { + // Pretend that file is from *srcdir in order to decide + // visible imports correctly. + target = filepath.Join(*srcdir, filepath.Base(filename)) + } + } + + res, err := imports.Process(target, src, opt) + if err != nil { + return err + } + + if !bytes.Equal(src, res) { + // formatting has changed + if *list { + fmt.Fprintln(out, filename) + } + if *write { + if argType == fromStdin { + // filename is "" + return errors.New("can't use -w on stdin") + } + // On Windows, we need to re-set the permissions from the file. See golang/go#38225. + var perms os.FileMode + if fi, err := os.Stat(filename); err == nil { + perms = fi.Mode() & os.ModePerm + } + err = os.WriteFile(filename, res, perms) + if err != nil { + return err + } + } + if *doDiff { + if argType == fromStdin { + filename = "stdin.go" // because .orig looks silly + } + data, err := diff(src, res, filename) + if err != nil { + return fmt.Errorf("computing diff: %s", err) + } + fmt.Printf("diff -u %s %s\n", filepath.ToSlash(filename+".orig"), filepath.ToSlash(filename)) + out.Write(data) + } + } + + if !*list && !*write && !*doDiff { + _, err = out.Write(res) + } + + return err +} + +func visitFile(path string, d fs.DirEntry, err error) error { + if err == nil && isGoFile(d) { + err = processFile(path, nil, os.Stdout, multipleArg) + } + if err != nil { + report(err) + } + return nil +} + +func walkDir(path string) { + filepath.WalkDir(path, visitFile) +} + +func main() { + // Measure how many people still use goimports. + // (See https://go.dev/issue/78671 for one.) + counter.Open() + counter.Inc("tools/cmd:goimports") + runtime.GOMAXPROCS(runtime.NumCPU()) + + // call gofmtMain in a separate function + // so that it can use defer and have them + // run before the exit. + gofmtMain() + if !testing.Testing() { + os.Exit(exitCode) + } +} + +// parseFlags parses command line flags and returns the paths to process. +// It's a var so that custom implementations can replace it in other files. +var parseFlags = func() []string { + flag.BoolVar(&verbose, "v", false, "verbose logging") + + flag.Parse() + return flag.Args() +} + +func bufferedFileWriter(dest string) (w io.Writer, close func()) { + f, err := os.Create(dest) + if err != nil { + log.Fatal(err) + } + bw := bufio.NewWriter(f) + return bw, func() { + if err := bw.Flush(); err != nil { + log.Fatalf("error flushing %v: %v", dest, err) + } + if err := f.Close(); err != nil { + log.Fatal(err) + } + } +} + +func gofmtMain() { + flag.Usage = usage + paths := parseFlags() + + if *cpuProfile != "" { + bw, flush := bufferedFileWriter(*cpuProfile) + pprof.StartCPUProfile(bw) + defer flush() + defer pprof.StopCPUProfile() + } + // doTrace is a conditionally compiled wrapper around runtime/trace. It is + // used to allow goimports to compile under gccgo, which does not support + // runtime/trace. See https://golang.org/issue/15544. + defer doTrace()() + if *memProfileRate > 0 { + runtime.MemProfileRate = *memProfileRate + bw, flush := bufferedFileWriter(*memProfile) + defer func() { + runtime.GC() // materialize all statistics + if err := pprof.WriteHeapProfile(bw); err != nil { + log.Fatal(err) + } + flush() + }() + } + + if verbose { + log.SetFlags(log.LstdFlags | log.Lmicroseconds) + options.Env.Logf = log.Printf + } + if options.TabWidth < 0 { + fmt.Fprintf(os.Stderr, "negative tabwidth %d\n", options.TabWidth) + exitCode = 2 + return + } + + if len(paths) == 0 { + if err := processFile("", os.Stdin, os.Stdout, fromStdin); err != nil { + report(err) + } + return + } + + argType := singleArg + if len(paths) > 1 { + argType = multipleArg + } + + for _, path := range paths { + switch dir, err := os.Stat(path); { + case err != nil: + report(err) + case dir.IsDir(): + walkDir(path) + default: + if err := processFile(path, nil, os.Stdout, argType); err != nil { + report(err) + } + } + } +} + +func writeTempFile(dir, prefix string, data []byte) (string, error) { + file, err := os.CreateTemp(dir, prefix) + if err != nil { + return "", err + } + _, err = file.Write(data) + if err1 := file.Close(); err == nil { + err = err1 + } + if err != nil { + os.Remove(file.Name()) + return "", err + } + return file.Name(), nil +} + +func diff(b1, b2 []byte, filename string) (data []byte, err error) { + f1, err := writeTempFile("", "gofmt", b1) + if err != nil { + return + } + defer os.Remove(f1) + + f2, err := writeTempFile("", "gofmt", b2) + if err != nil { + return + } + defer os.Remove(f2) + + cmd := "diff" + if runtime.GOOS == "plan9" { + cmd = "/bin/ape/diff" + } + + data, err = exec.Command(cmd, "-u", f1, f2).CombinedOutput() + if len(data) > 0 { + // diff exits with a non-zero status when the files don't match. + // Ignore that failure as long as we get output. + return replaceTempFilename(data, filename) + } + return +} + +// replaceTempFilename replaces temporary filenames in diff with actual one. +// +// --- /tmp/gofmt316145376 2017-02-03 19:13:00.280468375 -0500 +// +++ /tmp/gofmt617882815 2017-02-03 19:13:00.280468375 -0500 +// ... +// -> +// --- path/to/file.go.orig 2017-02-03 19:13:00.280468375 -0500 +// +++ path/to/file.go 2017-02-03 19:13:00.280468375 -0500 +// ... +func replaceTempFilename(diff []byte, filename string) ([]byte, error) { + bs := bytes.SplitN(diff, []byte{'\n'}, 3) + if len(bs) < 3 { + return nil, fmt.Errorf("got unexpected diff for %s", filename) + } + // Preserve timestamps. + var t0, t1 []byte + if i := bytes.LastIndexByte(bs[0], '\t'); i != -1 { + t0 = bs[0][i:] + } + if i := bytes.LastIndexByte(bs[1], '\t'); i != -1 { + t1 = bs[1][i:] + } + // Always print filepath with slash separator. + f := filepath.ToSlash(filename) + bs[0] = fmt.Appendf(nil, "--- %s%s", f+".orig", t0) + bs[1] = fmt.Appendf(nil, "+++ %s%s", f, t1) + return bytes.Join(bs, []byte{'\n'}), nil +} + +// isFile reports whether name is a file. +func isFile(name string) bool { + fi, err := os.Stat(name) + return err == nil && fi.Mode().IsRegular() +} + +// isDir reports whether name is a directory. +func isDir(name string) bool { + fi, err := os.Stat(name) + return err == nil && fi.IsDir() +} diff --git a/vendor/golang.org/x/tools/cmd/goimports/goimports_gc.go b/vendor/golang.org/x/tools/cmd/goimports/goimports_gc.go new file mode 100644 index 0000000..3a88482 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/goimports/goimports_gc.go @@ -0,0 +1,26 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc + +package main + +import ( + "flag" + "runtime/trace" +) + +var traceProfile = flag.String("trace", "", "trace profile output") + +func doTrace() func() { + if *traceProfile != "" { + bw, flush := bufferedFileWriter(*traceProfile) + trace.Start(bw) + return func() { + trace.Stop() + flush() + } + } + return func() {} +} diff --git a/vendor/golang.org/x/tools/cmd/goimports/goimports_not_gc.go b/vendor/golang.org/x/tools/cmd/goimports/goimports_not_gc.go new file mode 100644 index 0000000..21dc779 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/goimports/goimports_not_gc.go @@ -0,0 +1,11 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !gc + +package main + +func doTrace() func() { + return func() {} +} diff --git a/vendor/golang.org/x/tools/go/analysis/analysis.go b/vendor/golang.org/x/tools/go/analysis/analysis.go new file mode 100644 index 0000000..786c29d --- /dev/null +++ b/vendor/golang.org/x/tools/go/analysis/analysis.go @@ -0,0 +1,269 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package analysis + +import ( + "flag" + "fmt" + "go/ast" + "go/token" + "go/types" + "reflect" + "time" +) + +// An Analyzer describes an analysis function and its options. +type Analyzer struct { + // The Name of the analyzer must be a valid Go identifier + // as it may appear in command-line flags, URLs, and so on. + Name string + + // Doc is the documentation for the analyzer. + // The part before the first "\n\n" is the title + // (no capital or period, max ~60 letters). + Doc string + + // URL holds an optional link to a web page with additional + // documentation for this analyzer. + URL string + + // Flags defines any flags accepted by the analyzer. + // The manner in which these flags are exposed to the user + // depends on the driver which runs the analyzer. + Flags flag.FlagSet + + // Run applies the analyzer to a package. + // It returns an error if the analyzer failed. + // + // On success, the Run function may return a result + // computed by the Analyzer; its type must match ResultType. + // The driver makes this result available as an input to + // another Analyzer that depends directly on this one (see + // Requires) when it analyzes the same package. + // + // To pass analysis results between packages (and thus + // potentially between address spaces), use Facts, which are + // serializable. + Run func(*Pass) (any, error) + + // RunDespiteErrors allows the driver to invoke + // the Run method of this analyzer even on a + // package that contains parse or type errors. + // The [Pass.TypeErrors] field may consequently be non-empty. + RunDespiteErrors bool + + // Requires is a set of analyzers that must run successfully + // before this one on a given package. This analyzer may inspect + // the outputs produced by each analyzer in Requires. + // The graph over analyzers implied by Requires edges must be acyclic. + // + // Requires establishes a "horizontal" dependency between + // analysis passes (different analyzers, same package). + Requires []*Analyzer + + // ResultType is the type of the optional result of the Run function. + ResultType reflect.Type + + // FactTypes indicates that this analyzer imports and exports + // Facts of the specified concrete types. + // An analyzer that uses facts may assume that its import + // dependencies have been similarly analyzed before it runs. + // Facts must be pointers. + // + // FactTypes establishes a "vertical" dependency between + // analysis passes (same analyzer, different packages). + FactTypes []Fact +} + +func (a *Analyzer) String() string { return a.Name } + +// A Pass provides information to the Run function that +// applies a specific analyzer to a single Go package. +// +// It forms the interface between the analysis logic and the driver +// program, and has both input and an output components. +// +// As in a compiler, one pass may depend on the result computed by another. +// +// The Run function should not call any of the Pass functions concurrently. +type Pass struct { + Analyzer *Analyzer // the identity of the current analyzer + + // syntax and type information + Fset *token.FileSet // file position information; Run may add new files + Files []*ast.File // the abstract syntax tree of each file + OtherFiles []string // names of non-Go files of this package + IgnoredFiles []string // names of ignored source files in this package + Pkg *types.Package // type information about the package + TypesInfo *types.Info // type information about the syntax trees + TypesSizes types.Sizes // function for computing sizes of types + TypeErrors []types.Error // type errors (only if Analyzer.RunDespiteErrors) + + Module *Module // the package's enclosing module (possibly nil in some drivers) + + // Report reports a Diagnostic, a finding about a specific location + // in the analyzed source code such as a potential mistake. + // It may be called by the Run function. + Report func(Diagnostic) + + // ResultOf provides the inputs to this analysis pass, which are + // the corresponding results of its prerequisite analyzers. + // The map keys are the elements of Analysis.Required, + // and the type of each corresponding value is the required + // analysis's ResultType. + ResultOf map[*Analyzer]any + + // ReadFile returns the contents of the named file. + // + // The only valid file names are the elements of OtherFiles + // and IgnoredFiles, and names returned by + // Fset.File(f.FileStart).Name() for each f in Files. + // + // Analyzers must use this function (if provided) instead of + // accessing the file system directly. This allows a driver to + // provide a virtualized file tree (including, for example, + // unsaved editor buffers) and to track dependencies precisely + // to avoid unnecessary recomputation. + ReadFile func(filename string) ([]byte, error) + + // -- facts -- + + // ImportObjectFact retrieves a fact associated with obj. + // Given a value ptr of type *T, where *T satisfies Fact, + // ImportObjectFact copies the value to *ptr. + // + // ImportObjectFact panics if called after the pass is complete. + // ImportObjectFact is not concurrency-safe. + ImportObjectFact func(obj types.Object, fact Fact) bool + + // ImportPackageFact retrieves a fact associated with package pkg, + // which must be this package or one of its dependencies. + // See comments for ImportObjectFact. + ImportPackageFact func(pkg *types.Package, fact Fact) bool + + // ExportObjectFact associates a fact of type *T with the obj, + // replacing any previous fact of that type. + // + // ExportObjectFact panics if it is called after the pass is + // complete, or if obj does not belong to the package being analyzed. + // ExportObjectFact is not concurrency-safe. + ExportObjectFact func(obj types.Object, fact Fact) + + // ExportPackageFact associates a fact with the current package. + // See comments for ExportObjectFact. + ExportPackageFact func(fact Fact) + + // AllPackageFacts returns a new slice containing all package + // facts of the analysis's FactTypes in unspecified order. + // See comments for AllObjectFacts. + AllPackageFacts func() []PackageFact + + // AllObjectFacts returns a new slice containing all object + // facts of the analysis's FactTypes in unspecified order. + // + // The result includes all facts exported by packages + // whose symbols are referenced by the current package + // (by qualified identifiers or field/method selections). + // And it includes all facts exported from the current + // package by the current analysis pass. + AllObjectFacts func() []ObjectFact + + /* Further fields may be added in future. */ +} + +// PackageFact is a package together with an associated fact. +type PackageFact struct { + Package *types.Package + Fact Fact +} + +// ObjectFact is an object together with an associated fact. +type ObjectFact struct { + Object types.Object + Fact Fact +} + +// Reportf is a helper function that reports a Diagnostic using the +// specified position and formatted error message. +func (pass *Pass) Reportf(pos token.Pos, format string, args ...any) { + msg := fmt.Sprintf(format, args...) + pass.Report(Diagnostic{Pos: pos, Message: msg}) +} + +// The Range interface provides a range. It's equivalent to and satisfied by +// ast.Node. +type Range interface { + Pos() token.Pos // position of first character belonging to the node + End() token.Pos // position of first character immediately after the node +} + +// ReportRangef is a helper function that reports a Diagnostic using the +// range provided. ast.Node values can be passed in as the range because +// they satisfy the Range interface. +func (pass *Pass) ReportRangef(rng Range, format string, args ...any) { + msg := fmt.Sprintf(format, args...) + pass.Report(Diagnostic{Pos: rng.Pos(), End: rng.End(), Message: msg}) +} + +func (pass *Pass) String() string { + return fmt.Sprintf("%s@%s", pass.Analyzer.Name, pass.Pkg.Path()) +} + +// A Fact is an intermediate fact produced during analysis. +// +// Each fact is associated with a named declaration (a types.Object) or +// with a package as a whole. A single object or package may have +// multiple associated facts, but only one of any particular fact type. +// +// A Fact represents a predicate such as "never returns", but does not +// represent the subject of the predicate such as "function F" or "package P". +// +// Facts may be produced in one analysis pass and consumed by another +// analysis pass even if these are in different address spaces. +// If package P imports Q, all facts about Q produced during +// analysis of that package will be available during later analysis of P. +// Facts are analogous to type export data in a build system: +// just as export data enables separate compilation of several passes, +// facts enable "separate analysis". +// +// Each pass (a, p) starts with the set of facts produced by the +// same analyzer a applied to the packages directly imported by p. +// The analysis may add facts to the set, and they may be exported in turn. +// An analysis's Run function may retrieve facts by calling +// Pass.Import{Object,Package}Fact and update them using +// Pass.Export{Object,Package}Fact. +// +// A fact is logically private to its Analysis. To pass values +// between different analyzers, use the results mechanism; +// see Analyzer.Requires, Analyzer.ResultType, and Pass.ResultOf. +// +// A Fact type must be a pointer. +// Facts are encoded and decoded using encoding/gob. +// A Fact may implement the GobEncoder/GobDecoder interfaces +// to customize its encoding. Fact encoding should not fail. +// +// A Fact should not be modified once exported. +type Fact interface { + AFact() // dummy method to avoid type errors +} + +// A Module describes the module to which a package belongs. +type Module struct { + Path string // module path + Version string // module version ("" if unknown, such as for workspace modules) + Replace *Module // replaced by this module + Time *time.Time // time version was created + Main bool // is this the main module? + Indirect bool // is this module only an indirect dependency of main module? + Dir string // directory holding files for this module, if any + GoMod string // path to go.mod file used when loading this module, if any + GoVersion string // go version used in module (e.g. "go1.22.0") + Error *ModuleError // error loading module +} + +// ModuleError holds errors loading a module. +type ModuleError struct { + Err string // the error itself +} diff --git a/vendor/golang.org/x/tools/go/analysis/diagnostic.go b/vendor/golang.org/x/tools/go/analysis/diagnostic.go new file mode 100644 index 0000000..527540c --- /dev/null +++ b/vendor/golang.org/x/tools/go/analysis/diagnostic.go @@ -0,0 +1,88 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package analysis + +import "go/token" + +// A Diagnostic is a message associated with a source location or range. +// +// An Analyzer may return a variety of diagnostics; the optional Category, +// which should be a constant, may be used to classify them. +// It is primarily intended to make it easy to look up documentation. +// +// All Pos values are interpreted relative to Pass.Fset. If End is +// provided, the diagnostic is specified to apply to the range between +// Pos and End. +type Diagnostic struct { + Pos token.Pos + End token.Pos // optional + Category string // optional + Message string + + // URL is the optional location of a web page that provides + // additional documentation for this diagnostic. + // + // If URL is empty but a Category is specified, then the + // Analysis driver should treat the URL as "#"+Category. + // + // The URL may be relative. If so, the base URL is that of the + // Analyzer that produced the diagnostic; + // see https://pkg.go.dev/net/url#URL.ResolveReference. + URL string + + // SuggestedFixes is an optional list of fixes to address the + // problem described by the diagnostic. Each one represents an + // alternative strategy, and should have a distinct and + // descriptive message; at most one may be applied. + // + // Fixes for different diagnostics should be treated as + // independent changes to the same baseline file state, + // analogous to a set of git commits all with the same parent. + // Combining fixes requires resolving any conflicts that + // arise, analogous to a git merge. + // Any conflicts that remain may be dealt with, depending on + // the tool, by discarding fixes, consulting the user, or + // aborting the operation. + SuggestedFixes []SuggestedFix + + // Related contains optional secondary positions and messages + // related to the primary diagnostic. + Related []RelatedInformation +} + +// RelatedInformation contains information related to a diagnostic. +// For example, a diagnostic that flags duplicated declarations of a +// variable may include one RelatedInformation per existing +// declaration. +type RelatedInformation struct { + Pos token.Pos + End token.Pos // optional + Message string +} + +// A SuggestedFix is a code change associated with a Diagnostic that a +// user can choose to apply to their code. Usually the SuggestedFix is +// meant to fix the issue flagged by the diagnostic. +// +// The TextEdits must not overlap, nor contain edits for other +// packages. Edits need not be totally ordered, but the order +// determines how insertions at the same point will be applied. +type SuggestedFix struct { + // A verb phrase describing the fix, to be shown to + // a user trying to decide whether to accept it. + // + // Example: "Remove the surplus argument" + Message string + TextEdits []TextEdit +} + +// A TextEdit represents the replacement of the code between Pos and End with the new text. +// Each TextEdit should apply to a single file. End should not be earlier in the file than Pos. +type TextEdit struct { + // For a pure insertion, End can either be set to Pos or token.NoPos. + Pos token.Pos + End token.Pos + NewText []byte +} diff --git a/vendor/golang.org/x/tools/go/analysis/doc.go b/vendor/golang.org/x/tools/go/analysis/doc.go new file mode 100644 index 0000000..2a0aa57 --- /dev/null +++ b/vendor/golang.org/x/tools/go/analysis/doc.go @@ -0,0 +1,317 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package analysis defines the interface between a modular static +analysis and an analysis driver program. + +# Background + +A static analysis is a function that inspects a package of Go code and +reports a set of diagnostics (typically mistakes in the code), and +perhaps produces other results as well, such as suggested refactorings +or other facts. An analysis that reports mistakes is informally called a +"checker". For example, the printf checker reports mistakes in +fmt.Printf format strings. + +A "modular" analysis is one that inspects one package at a time but can +save information from a lower-level package and use it when inspecting a +higher-level package, analogous to separate compilation in a toolchain. +The printf checker is modular: when it discovers that a function such as +log.Fatalf delegates to fmt.Printf, it records this fact, and checks +calls to that function too, including calls made from another package. + +By implementing a common interface, checkers from a variety of sources +can be easily selected, incorporated, and reused in a wide range of +driver programs including command-line tools (such as vet), text editors and +IDEs, build and test systems (such as go build, Bazel, or Buck), test +frameworks, code review tools, code-base indexers (such as SourceGraph), +documentation viewers (such as godoc), batch pipelines for large code +bases, and so on. + +# Analyzer + +The primary type in the API is [Analyzer]. An Analyzer statically +describes an analysis function: its name, documentation, flags, +relationship to other analyzers, and of course, its logic. + +To define an analysis, a user declares a (logically constant) variable +of type Analyzer. Here is a typical example from one of the analyzers in +the go/analysis/passes/ subdirectory: + + package unusedresult + + var Analyzer = &analysis.Analyzer{ + Name: "unusedresult", + Doc: "check for unused results of calls to some functions", + Run: run, + ... + } + + func run(pass *analysis.Pass) (interface{}, error) { + ... + } + +An analysis driver is a program such as vet that runs a set of +analyses and prints the diagnostics that they report. +The driver program must import the list of Analyzers it needs. +Typically each Analyzer resides in a separate package. +To add a new Analyzer to an existing driver, add another item to the list: + + import ( "unusedresult"; "nilness"; "printf" ) + + var analyses = []*analysis.Analyzer{ + unusedresult.Analyzer, + nilness.Analyzer, + printf.Analyzer, + } + +A driver may use the name, flags, and documentation to provide on-line +help that describes the analyses it performs. +The doc comment contains a brief one-line summary, +optionally followed by paragraphs of explanation. + +The [Analyzer] type has more fields besides those shown above: + + type Analyzer struct { + Name string + Doc string + Flags flag.FlagSet + Run func(*Pass) (interface{}, error) + RunDespiteErrors bool + ResultType reflect.Type + Requires []*Analyzer + FactTypes []Fact + } + +The Flags field declares a set of named (global) flag variables that +control analysis behavior. Unlike vet, analysis flags are not declared +directly in the command line FlagSet; it is up to the driver to set the +flag variables. A driver for a single analysis, a, might expose its flag +f directly on the command line as -f, whereas a driver for multiple +analyses might prefix the flag name by the analysis name (-a.f) to avoid +ambiguity. An IDE might expose the flags through a graphical interface, +and a batch pipeline might configure them from a config file. +See the "findcall" analyzer for an example of flags in action. + +The RunDespiteErrors flag indicates whether the analysis is equipped to +handle ill-typed code. If not, the driver will skip the analysis if +there were parse or type errors. +The optional ResultType field specifies the type of the result value +computed by this analysis and made available to other analyses. +The Requires field specifies a list of analyses upon which +this one depends and whose results it may access, and it constrains the +order in which a driver may run analyses. +The FactTypes field is discussed in the section on Modularity. +The analysis package provides a Validate function to perform basic +sanity checks on an Analyzer, such as that its Requires graph is +acyclic, its fact and result types are unique, and so on. + +Finally, the Run field contains a function to be called by the driver to +execute the analysis on a single package. The driver passes it an +instance of the Pass type. + +# Pass + +A [Pass] describes a single unit of work: the application of a particular +Analyzer to a particular package of Go code. +The Pass provides information to the Analyzer's Run function about the +package being analyzed, and provides operations to the Run function for +reporting diagnostics and other information back to the driver. + + type Pass struct { + Fset *token.FileSet + Files []*ast.File + OtherFiles []string + IgnoredFiles []string + Pkg *types.Package + TypesInfo *types.Info + ResultOf map[*Analyzer]interface{} + Report func(Diagnostic) + ... + } + +The Fset, Files, Pkg, and TypesInfo fields provide the syntax trees, +type information, and source positions for a single package of Go code. + +The OtherFiles field provides the names of non-Go +files such as assembly that are part of this package. +Similarly, the IgnoredFiles field provides the names of Go and non-Go +source files that are not part of this package with the current build +configuration but may be part of other build configurations. +The contents of these files may be read using Pass.ReadFile; +see the "asmdecl" or "buildtags" analyzers for examples of loading +non-Go files and reporting diagnostics against them. + +The ResultOf field provides the results computed by the analyzers +required by this one, as expressed in its Analyzer.Requires field. The +driver runs the required analyzers first and makes their results +available in this map. Each Analyzer must return a value of the type +described in its Analyzer.ResultType field. +For example, the "ctrlflow" analyzer returns a *ctrlflow.CFGs, which +provides a control-flow graph for each function in the package (see +golang.org/x/tools/go/cfg); the "inspect" analyzer returns a value that +enables other Analyzers to traverse the syntax trees of the package more +efficiently; and the "buildssa" analyzer constructs an SSA-form +intermediate representation. +Each of these Analyzers extends the capabilities of later Analyzers +without adding a dependency to the core API, so an analysis tool pays +only for the extensions it needs. + +The Report function emits a diagnostic, a message associated with a +source position. For most analyses, diagnostics are their primary +result. +For convenience, Pass provides a helper method, Reportf, to report a new +diagnostic by formatting a string. +Diagnostic is defined as: + + type Diagnostic struct { + Pos token.Pos + Category string // optional + Message string + } + +The optional Category field is a short identifier that classifies the +kind of message when an analysis produces several kinds of diagnostic. + +The [Diagnostic] struct does not have a field to indicate its severity +because opinions about the relative importance of Analyzers and their +diagnostics vary widely among users. The design of this framework does +not hold each Analyzer responsible for identifying the severity of its +diagnostics. Instead, we expect that drivers will allow the user to +customize the filtering and prioritization of diagnostics based on the +producing Analyzer and optional Category, according to the user's +preferences. + +Most Analyzers inspect typed Go syntax trees, but a few, such as asmdecl +and buildtag, inspect the raw text of Go source files or even non-Go +files such as assembly. To report a diagnostic against a line of a +raw text file, use the following sequence: + + content, err := pass.ReadFile(filename) + if err != nil { ... } + tf := fset.AddFile(filename, -1, len(content)) + tf.SetLinesForContent(content) + ... + pass.Reportf(tf.LineStart(line), "oops") + +# Modular analysis with Facts + +To improve efficiency and scalability, large programs are routinely +built using separate compilation: units of the program are compiled +separately, and recompiled only when one of their dependencies changes; +independent modules may be compiled in parallel. The same technique may +be applied to static analyses, for the same benefits. Such analyses are +described as "modular". + +A compiler’s type checker is an example of a modular static analysis. +Many other checkers we would like to apply to Go programs can be +understood as alternative or non-standard type systems. For example, +vet's printf checker infers whether a function has the "printf wrapper" +type, and it applies stricter checks to calls of such functions. In +addition, it records which functions are printf wrappers for use by +later analysis passes to identify other printf wrappers by induction. +A result such as “f is a printf wrapper” that is not interesting by +itself but serves as a stepping stone to an interesting result (such as +a diagnostic) is called a [Fact]. + +The analysis API allows an analysis to define new types of facts, to +associate facts of these types with objects (named entities) declared +within the current package, or with the package as a whole, and to query +for an existing fact of a given type associated with an object or +package. + +An Analyzer that uses facts must declare their types: + + var Analyzer = &analysis.Analyzer{ + Name: "printf", + FactTypes: []analysis.Fact{new(isWrapper)}, + ... + } + + type isWrapper struct{} // => *types.Func f “is a printf wrapper” + +The driver program ensures that facts for a pass’s dependencies are +generated before analyzing the package and is responsible for propagating +facts from one package to another, possibly across address spaces. +Consequently, Facts must be serializable. The API requires that drivers +use the gob encoding, an efficient, robust, self-describing binary +protocol. A fact type may implement the GobEncoder/GobDecoder interfaces +if the default encoding is unsuitable. Facts should be stateless. +Because serialized facts may appear within build outputs, the gob encoding +of a fact must be deterministic, to avoid spurious cache misses in +build systems that use content-addressable caches. +The driver makes a single call to the gob encoder for all facts +exported by a given analysis pass, so that the topology of +shared data structures referenced by multiple facts is preserved. + +The Pass type has functions to import and export facts, +associated either with an object or with a package: + + type Pass struct { + ... + ExportObjectFact func(types.Object, Fact) + ImportObjectFact func(types.Object, Fact) bool + + ExportPackageFact func(fact Fact) + ImportPackageFact func(*types.Package, Fact) bool + } + +An Analyzer may only export facts associated with the current package or +its objects, though it may import facts from any package or object that +is an import dependency of the current package. + +Conceptually, ExportObjectFact(obj, fact) inserts fact into a hidden map keyed by +the pair (obj, TypeOf(fact)), and the ImportObjectFact function +retrieves the entry from this map and copies its value into the variable +pointed to by fact. This scheme assumes that the concrete type of fact +is a pointer; this assumption is checked by the Validate function. +See the "printf" analyzer for an example of object facts in action. + +Some driver implementations (such as those based on Bazel and Blaze) do +not currently apply analyzers to packages of the standard library. +Therefore, for best results, analyzer authors should not rely on +analysis facts being available for standard packages. +For example, although the printf checker is capable of deducing during +analysis of the log package that log.Printf is a printf wrapper, +this fact is built in to the analyzer so that it correctly checks +calls to log.Printf even when run in a driver that does not apply +it to standard packages. We would like to remove this limitation in future. + +# Testing an Analyzer + +The analysistest subpackage provides utilities for testing an Analyzer. +In a few lines of code, it is possible to run an analyzer on a package +of testdata files and check that it reported all the expected +diagnostics and facts (and no more). Expectations are expressed using +"// want ..." comments in the input code. + +# Standalone commands + +Analyzers are provided in the form of packages that a driver program is +expected to import. The vet command imports a set of several analyzers, +but users may wish to define their own analysis commands that perform +additional checks. To simplify the task of creating an analysis command, +either for a single analyzer or for a whole suite, we provide the +singlechecker and multichecker subpackages. + +The singlechecker package provides the main function for a command that +runs one analyzer. By convention, each analyzer such as +go/analysis/passes/findcall should be accompanied by a singlechecker-based +command such as go/analysis/passes/findcall/cmd/findcall, defined in its +entirety as: + + package main + + import ( + "golang.org/x/tools/go/analysis/passes/findcall" + "golang.org/x/tools/go/analysis/singlechecker" + ) + + func main() { singlechecker.Main(findcall.Analyzer) } + +A tool that provides multiple analyzers can use multichecker in a +similar way, giving it the list of Analyzers. +*/ +package analysis diff --git a/vendor/golang.org/x/tools/go/analysis/passes/ctrlflow/ctrlflow.go b/vendor/golang.org/x/tools/go/analysis/passes/ctrlflow/ctrlflow.go new file mode 100644 index 0000000..4e6ea9d --- /dev/null +++ b/vendor/golang.org/x/tools/go/analysis/passes/ctrlflow/ctrlflow.go @@ -0,0 +1,278 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ctrlflow is an analysis that provides a syntactic +// control-flow graph (CFG) for the body of a function. +// It records whether a function cannot return. +// By itself, it does not report any diagnostics. +package ctrlflow + +import ( + "go/ast" + "go/types" + "log" + "reflect" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/ast/inspector" + "golang.org/x/tools/go/cfg" + "golang.org/x/tools/go/types/typeutil" + "golang.org/x/tools/internal/typesinternal" +) + +var Analyzer = &analysis.Analyzer{ + Name: "ctrlflow", + Doc: "build a control-flow graph", + URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/ctrlflow", + Run: run, + ResultType: reflect.TypeFor[*CFGs](), + FactTypes: []analysis.Fact{new(noReturn)}, + Requires: []*analysis.Analyzer{inspect.Analyzer}, +} + +// noReturn is a fact indicating that a function does not return. +type noReturn struct{} + +func (*noReturn) AFact() {} + +func (*noReturn) String() string { return "noReturn" } + +// A CFGs holds the control-flow graphs +// for all the functions of the current package. +type CFGs struct { + defs map[*ast.Ident]types.Object // from Pass.TypesInfo.Defs + funcDecls map[*types.Func]*declInfo + funcLits map[*ast.FuncLit]*litInfo + noReturn map[*types.Func]bool // functions lacking a reachable return statement + pass *analysis.Pass // transient; nil after construction +} + +// NoReturn reports whether the specified control-flow graph cannot return normally. +// +// It is defined for at least all function symbols that appear as the static callee of a +// CallExpr in the current package, even if the callee was imported from a dependency. +// +// The result may incorporate interprocedural information based on induction of +// the "no return" property over the static call graph within the package. +// For example, if f simply calls g and g always calls os.Exit, then both f and g may +// be deemed never to return. +func (c *CFGs) NoReturn(fn *types.Func) bool { + return c.noReturn[fn] +} + +// CFGs has two maps: funcDecls for named functions and funcLits for +// unnamed ones. Unlike funcLits, the funcDecls map is not keyed by its +// syntax node, *ast.FuncDecl, because callMayReturn needs to do a +// look-up by *types.Func, and you can get from an *ast.FuncDecl to a +// *types.Func but not the other way. + +type declInfo struct { + decl *ast.FuncDecl + cfg *cfg.CFG // iff decl.Body != nil + started bool // to break cycles +} + +type litInfo struct { + cfg *cfg.CFG + noReturn bool // (currently unused) +} + +// FuncDecl returns the control-flow graph for a named function. +// It returns nil if decl.Body==nil. +func (c *CFGs) FuncDecl(decl *ast.FuncDecl) *cfg.CFG { + if decl.Body == nil { + return nil + } + fn := c.defs[decl.Name].(*types.Func) + return c.funcDecls[fn].cfg +} + +// FuncLit returns the control-flow graph for a literal function. +func (c *CFGs) FuncLit(lit *ast.FuncLit) *cfg.CFG { + return c.funcLits[lit].cfg +} + +func run(pass *analysis.Pass) (any, error) { + inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + + // Because CFG construction consumes and produces noReturn + // facts, CFGs for exported FuncDecls must be built before 'run' + // returns; we cannot construct them lazily. + // (We could build CFGs for FuncLits lazily, + // but the benefit is marginal.) + + // Pass 1. Map types.Funcs to ast.FuncDecls in this package. + funcDecls := make(map[*types.Func]*declInfo) // functions and methods + funcLits := make(map[*ast.FuncLit]*litInfo) + + var decls []*types.Func // keys(funcDecls), in order + var lits []*ast.FuncLit // keys(funcLits), in order + + nodeFilter := []ast.Node{ + (*ast.FuncDecl)(nil), + (*ast.FuncLit)(nil), + } + inspect.Preorder(nodeFilter, func(n ast.Node) { + switch n := n.(type) { + case *ast.FuncDecl: + // Type information may be incomplete. + if fn, ok := pass.TypesInfo.Defs[n.Name].(*types.Func); ok { + funcDecls[fn] = &declInfo{decl: n} + decls = append(decls, fn) + } + case *ast.FuncLit: + funcLits[n] = new(litInfo) + lits = append(lits, n) + } + }) + + c := &CFGs{ + defs: pass.TypesInfo.Defs, + funcDecls: funcDecls, + funcLits: funcLits, + noReturn: make(map[*types.Func]bool), + pass: pass, + } + + // Pass 2. Build CFGs. + + // Build CFGs for named functions. + // Cycles in the static call graph are broken + // arbitrarily but deterministically. + // We create noReturn facts as discovered. + for _, fn := range decls { + c.buildDecl(fn, funcDecls[fn]) + } + + // Build CFGs for literal functions. + // These aren't relevant to facts (since they aren't named) + // but are required for the CFGs.FuncLit API. + for _, lit := range lits { + li := funcLits[lit] + if li.cfg == nil { + li.cfg = cfg.New(lit.Body, c.callMayReturn) + if li.cfg.NoReturn() { + li.noReturn = true + } + } + } + + // All CFGs are now built. + c.pass = nil + + return c, nil +} + +// di.cfg may be nil on return. +func (c *CFGs) buildDecl(fn *types.Func, di *declInfo) { + // buildDecl may call itself recursively for the same function, + // because cfg.New is passed the callMayReturn method, which + // builds the CFG of the callee, leading to recursion. + // The buildDecl call tree thus resembles the static call graph. + // We mark each node when we start working on it to break cycles. + + if di.started { + return // break cycle + } + di.started = true + + noreturn, known := knownIntrinsic(fn) + if !known { + if di.decl.Body != nil { + di.cfg = cfg.New(di.decl.Body, c.callMayReturn) + if di.cfg.NoReturn() { + noreturn = true + } + } + } + if noreturn { + c.pass.ExportObjectFact(fn, new(noReturn)) + c.noReturn[fn] = true + } + + // debugging + if false { + log.Printf("CFG for %s:\n%s (noreturn=%t)\n", fn, di.cfg.Format(c.pass.Fset), noreturn) + } +} + +// callMayReturn reports whether the called function may return. +// It is passed to the CFG builder. +func (c *CFGs) callMayReturn(call *ast.CallExpr) (r bool) { + if id, ok := call.Fun.(*ast.Ident); ok && c.pass.TypesInfo.Uses[id] == panicBuiltin { + return false // panic never returns + } + + // Is this a static call? Also includes static functions + // parameterized by a type. Such functions may or may not + // return depending on the parameter type, but in some + // cases the answer is definite. We let ctrlflow figure + // that out. + fn := typeutil.StaticCallee(c.pass.TypesInfo, call) + if fn == nil { + return true // callee not statically known; be conservative + } + + // Function or method declared in this package? + if di, ok := c.funcDecls[fn]; ok { + c.buildDecl(fn, di) + return !c.noReturn[fn] + } + + // Not declared in this package. + // Is there a fact from another package? + if c.pass.ImportObjectFact(fn, new(noReturn)) { + c.noReturn[fn] = true + return false + } + + return true +} + +var panicBuiltin = types.Universe.Lookup("panic").(*types.Builtin) + +// knownIntrinsic reports whether a function intrinsically never +// returns because it stops execution of the calling thread, or does +// in fact return, contrary to its apparent body, because it is +// handled specially by the compiler. +// +// It is the base case in the recursion. +func knownIntrinsic(fn *types.Func) (noreturn, known bool) { + // Add functions here as the need arises, but don't allocate memory. + + // Functions known intrinsically never to return. + if typesinternal.IsFunctionNamed(fn, "syscall", "Exit", "ExitProcess", "ExitThread") || + typesinternal.IsFunctionNamed(fn, "runtime", "Goexit", "fatalthrow", "fatalpanic", "exit") || + // Following staticcheck (see go/ir/exits.go) we include functions + // in several popular logging packages whose no-return status is + // beyond the analysis to infer. + // TODO(adonovan): make this list extensible. + typesinternal.IsMethodNamed(fn, "go.uber.org/zap", "Logger", "Fatal", "Panic") || + typesinternal.IsMethodNamed(fn, "go.uber.org/zap", "SugaredLogger", "Fatal", "Fatalw", "Fatalf", "Panic", "Panicw", "Panicf") || + typesinternal.IsMethodNamed(fn, "github.com/sirupsen/logrus", "Logger", "Exit", "Panic", "Panicf", "Panicln") || + typesinternal.IsMethodNamed(fn, "github.com/sirupsen/logrus", "Entry", "Panicf", "Panicln") || + typesinternal.IsFunctionNamed(fn, "k8s.io/klog", "Exit", "ExitDepth", "Exitf", "Exitln", "Fatal", "FatalDepth", "Fatalf", "Fatalln") || + typesinternal.IsFunctionNamed(fn, "k8s.io/klog/v2", "Exit", "ExitDepth", "Exitf", "Exitln", "Fatal", "FatalDepth", "Fatalf", "Fatalln") { + return true, true + } + + // Compiler intrinsics known to return, contrary to + // what analysis of the function body would conclude. + // + // Not all such intrinsics must be listed here: ctrlflow + // considers any function called for its value--such as + // crypto/internal/constanttime.bool2Uint8--to potentially + // return; only functions called as a statement, for effects, + // are no-return candidates. + // + // Unfortunately this does sometimes mean peering into internals. + // Where possible, use the nearest enclosing public API function. + if typesinternal.IsFunctionNamed(fn, "internal/abi", "EscapeNonString") || + typesinternal.IsFunctionNamed(fn, "hash/maphash", "Comparable") { + return false, true + } + + return // unknown +} diff --git a/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go b/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go new file mode 100644 index 0000000..aae5d25 --- /dev/null +++ b/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go @@ -0,0 +1,49 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package inspect defines an Analyzer that provides an AST inspector +// (golang.org/x/tools/go/ast/inspector.Inspector) for the syntax trees +// of a package. It is only a building block for other analyzers. +// +// Example of use in another analysis: +// +// import ( +// "golang.org/x/tools/go/analysis" +// "golang.org/x/tools/go/analysis/passes/inspect" +// "golang.org/x/tools/go/ast/inspector" +// ) +// +// var Analyzer = &analysis.Analyzer{ +// ... +// Requires: []*analysis.Analyzer{inspect.Analyzer}, +// } +// +// func run(pass *analysis.Pass) (interface{}, error) { +// inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) +// inspect.Preorder(nil, func(n ast.Node) { +// ... +// }) +// return nil, nil +// } +package inspect + +import ( + "reflect" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/ast/inspector" +) + +var Analyzer = &analysis.Analyzer{ + Name: "inspect", + Doc: "optimize AST traversal for later passes", + URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/inspect", + Run: run, + RunDespiteErrors: true, + ResultType: reflect.TypeFor[*inspector.Inspector](), +} + +func run(pass *analysis.Pass) (any, error) { + return inspector.New(pass.Files), nil +} diff --git a/vendor/golang.org/x/tools/go/analysis/validate.go b/vendor/golang.org/x/tools/go/analysis/validate.go new file mode 100644 index 0000000..1453939 --- /dev/null +++ b/vendor/golang.org/x/tools/go/analysis/validate.go @@ -0,0 +1,137 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package analysis + +import ( + "fmt" + "reflect" + "strings" + "unicode" +) + +// Validate reports an error if any of the analyzers are misconfigured. +// Checks include: +// that the name is a valid identifier; +// that the Doc is not empty; +// that the Run is non-nil; +// that the Requires graph is acyclic; +// that analyzer fact types are unique; +// that each fact type is a pointer. +// +// Analyzer names need not be unique, though this may be confusing. +func Validate(analyzers []*Analyzer) error { + // Map each fact type to its sole generating analyzer. + factTypes := make(map[reflect.Type]*Analyzer) + + // Traverse the Requires graph, depth first. + const ( + white = iota + grey + black + finished + ) + color := make(map[*Analyzer]uint8) + var visit func(a *Analyzer) error + visit = func(a *Analyzer) error { + if a == nil { + return fmt.Errorf("nil *Analyzer") + } + if color[a] == white { + color[a] = grey + + // names + if !validIdent(a.Name) { + return fmt.Errorf("invalid analyzer name %q", a) + } + + if a.Doc == "" { + return fmt.Errorf("analyzer %q is undocumented", a) + } + + if a.Run == nil { + return fmt.Errorf("analyzer %q has nil Run", a) + } + // fact types + for _, f := range a.FactTypes { + if f == nil { + return fmt.Errorf("analyzer %s has nil FactType", a) + } + t := reflect.TypeOf(f) + if prev := factTypes[t]; prev != nil { + return fmt.Errorf("fact type %s registered by two analyzers: %v, %v", + t, a, prev) + } + if t.Kind() != reflect.Pointer { + return fmt.Errorf("%s: fact type %s is not a pointer", a, t) + } + factTypes[t] = a + } + + // recursion + for _, req := range a.Requires { + if err := visit(req); err != nil { + return err + } + } + color[a] = black + } + + if color[a] == grey { + stack := []*Analyzer{a} + inCycle := map[string]bool{} + for len(stack) > 0 { + current := stack[len(stack)-1] + stack = stack[:len(stack)-1] + if color[current] == grey && !inCycle[current.Name] { + inCycle[current.Name] = true + stack = append(stack, current.Requires...) + } + } + return &CycleInRequiresGraphError{AnalyzerNames: inCycle} + } + + return nil + } + for _, a := range analyzers { + if err := visit(a); err != nil { + return err + } + } + + // Reject duplicates among analyzers. + // Precondition: color[a] == black. + // Postcondition: color[a] == finished. + for _, a := range analyzers { + if color[a] == finished { + return fmt.Errorf("duplicate analyzer: %s", a.Name) + } + color[a] = finished + } + + return nil +} + +func validIdent(name string) bool { + for i, r := range name { + if !(r == '_' || unicode.IsLetter(r) || i > 0 && unicode.IsDigit(r)) { + return false + } + } + return name != "" +} + +type CycleInRequiresGraphError struct { + AnalyzerNames map[string]bool +} + +func (e *CycleInRequiresGraphError) Error() string { + var b strings.Builder + b.WriteString("cycle detected involving the following analyzers:") + for n := range e.AnalyzerNames { + b.WriteByte(' ') + b.WriteString(n) + } + return b.String() +} diff --git a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go new file mode 100644 index 0000000..0fb4e7e --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go @@ -0,0 +1,663 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package astutil + +// This file defines utilities for working with source positions. + +import ( + "fmt" + "go/ast" + "go/token" + "sort" +) + +// PathEnclosingInterval returns the node that encloses the source +// interval [start, end), and all its ancestors up to the AST root. +// +// The definition of "enclosing" used by this function considers +// additional whitespace abutting a node to be enclosed by it. +// In this example: +// +// z := x + y // add them +// <-A-> +// <----B-----> +// +// the ast.BinaryExpr(+) node is considered to enclose interval B +// even though its [Pos()..End()) is actually only interval A. +// This behaviour makes user interfaces more tolerant of imperfect +// input. +// +// This function treats tokens as nodes, though they are not included +// in the result. e.g. PathEnclosingInterval("+") returns the +// enclosing ast.BinaryExpr("x + y"). +// +// If start==end, the 1-char interval following start is used instead. +// +// The 'exact' result is true if the interval contains only path[0] +// and perhaps some adjacent whitespace. It is false if the interval +// overlaps multiple children of path[0], or if it contains only +// interior whitespace of path[0]. +// In this example: +// +// z := x + y // add them +// <--C--> <---E--> +// ^ +// D +// +// intervals C, D and E are inexact. C is contained by the +// z-assignment statement, because it spans three of its children (:=, +// x, +). So too is the 1-char interval D, because it contains only +// interior whitespace of the assignment. E is considered interior +// whitespace of the BlockStmt containing the assignment. +// +// The resulting path is never empty; it always contains at least the +// 'root' *ast.File. Ideally PathEnclosingInterval would reject +// intervals that lie wholly or partially outside the range of the +// file, but unfortunately ast.File records only the token.Pos of +// the 'package' keyword, but not of the start of the file itself. +func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool) { + // fmt.Printf("EnclosingInterval %d %d\n", start, end) // debugging + + // Precondition: node.[Pos..End) and adjoining whitespace contain [start, end). + var visit func(node ast.Node) bool + visit = func(node ast.Node) bool { + path = append(path, node) + + nodePos := node.Pos() + nodeEnd := node.End() + + // fmt.Printf("visit(%T, %d, %d)\n", node, nodePos, nodeEnd) // debugging + + // Intersect [start, end) with interval of node. + if start < nodePos { + start = nodePos + } + if end > nodeEnd { + end = nodeEnd + } + + // Find sole child that contains [start, end). + children := childrenOf(node) + l := len(children) + for i, child := range children { + // [childPos, childEnd) is unaugmented interval of child. + childPos := child.Pos() + childEnd := child.End() + + // [augPos, augEnd) is whitespace-augmented interval of child. + augPos := childPos + augEnd := childEnd + if i > 0 { + augPos = children[i-1].End() // start of preceding whitespace + } + if i < l-1 { + nextChildPos := children[i+1].Pos() + // Does [start, end) lie between child and next child? + if start >= augEnd && end <= nextChildPos { + return false // inexact match + } + augEnd = nextChildPos // end of following whitespace + } + + // fmt.Printf("\tchild %d: [%d..%d)\tcontains interval [%d..%d)?\n", + // i, augPos, augEnd, start, end) // debugging + + // Does augmented child strictly contain [start, end)? + if augPos <= start && end <= augEnd { + if is[tokenNode](child) { + return true + } + + // childrenOf elides the FuncType node beneath FuncDecl. + // Add it back here for TypeParams, Params, Results, + // all FieldLists). But we don't add it back for the "func" token + // even though it is the tree at FuncDecl.Type.Func. + if decl, ok := node.(*ast.FuncDecl); ok { + if fields, ok := child.(*ast.FieldList); ok && fields != decl.Recv { + path = append(path, decl.Type) + } + } + + return visit(child) + } + + // Does [start, end) overlap multiple children? + // i.e. left-augmented child contains start + // but LR-augmented child does not contain end. + if start < childEnd && end > augEnd { + break + } + } + + // No single child contained [start, end), + // so node is the result. Is it exact? + + // (It's tempting to put this condition before the + // child loop, but it gives the wrong result in the + // case where a node (e.g. ExprStmt) and its sole + // child have equal intervals.) + if start == nodePos && end == nodeEnd { + return true // exact match + } + + return false // inexact: overlaps multiple children + } + + // Ensure [start,end) is nondecreasing. + if start > end { + start, end = end, start + } + + if start < root.End() && end > root.Pos() { + if start == end { + end = start + 1 // empty interval => interval of size 1 + } + exact = visit(root) + + // Reverse the path: + for i, l := 0, len(path); i < l/2; i++ { + path[i], path[l-1-i] = path[l-1-i], path[i] + } + } else { + // Selection lies within whitespace preceding the + // first (or following the last) declaration in the file. + // The result nonetheless always includes the ast.File. + path = append(path, root) + } + + return +} + +// tokenNode is a dummy implementation of ast.Node for a single token. +// They are used transiently by PathEnclosingInterval but never escape +// this package. +type tokenNode struct { + pos token.Pos + end token.Pos +} + +func (n tokenNode) Pos() token.Pos { + return n.pos +} + +func (n tokenNode) End() token.Pos { + return n.end +} + +func tok(pos token.Pos, len int) ast.Node { + return tokenNode{pos, pos + token.Pos(len)} +} + +// childrenOf returns the direct non-nil children of ast.Node n. +// It may include fake ast.Node implementations for bare tokens. +// it is not safe to call (e.g.) ast.Walk on such nodes. +func childrenOf(n ast.Node) []ast.Node { + var children []ast.Node + + // First add nodes for all true subtrees. + ast.Inspect(n, func(node ast.Node) bool { + if node == n { // push n + return true // recur + } + if node != nil { // push child + children = append(children, node) + } + return false // no recursion + }) + + // TODO(adonovan): be more careful about missing (!Pos.Valid) + // tokens in trees produced from invalid input. + + // Then add fake Nodes for bare tokens. + switch n := n.(type) { + case *ast.ArrayType: + children = append(children, + tok(n.Lbrack, len("[")), + tok(n.Elt.End(), len("]"))) + + case *ast.AssignStmt: + children = append(children, + tok(n.TokPos, len(n.Tok.String()))) + + case *ast.BasicLit: + children = append(children, + tok(n.ValuePos, len(n.Value))) + + case *ast.BinaryExpr: + children = append(children, tok(n.OpPos, len(n.Op.String()))) + + case *ast.BlockStmt: + if n.Lbrace.IsValid() { + children = append(children, tok(n.Lbrace, len("{"))) + } + if n.Rbrace.IsValid() { + children = append(children, tok(n.Rbrace, len("}"))) + } + + case *ast.BranchStmt: + children = append(children, + tok(n.TokPos, len(n.Tok.String()))) + + case *ast.CallExpr: + children = append(children, + tok(n.Lparen, len("(")), + tok(n.Rparen, len(")"))) + if n.Ellipsis != 0 { + children = append(children, tok(n.Ellipsis, len("..."))) + } + + case *ast.CaseClause: + if n.List == nil { + children = append(children, + tok(n.Case, len("default"))) + } else { + children = append(children, + tok(n.Case, len("case"))) + } + children = append(children, tok(n.Colon, len(":"))) + + case *ast.ChanType: + switch n.Dir { + case ast.RECV: + children = append(children, tok(n.Begin, len("<-chan"))) + case ast.SEND: + children = append(children, tok(n.Begin, len("chan<-"))) + case ast.RECV | ast.SEND: + children = append(children, tok(n.Begin, len("chan"))) + } + + case *ast.CommClause: + if n.Comm == nil { + children = append(children, + tok(n.Case, len("default"))) + } else { + children = append(children, + tok(n.Case, len("case"))) + } + children = append(children, tok(n.Colon, len(":"))) + + case *ast.Comment: + // nop + + case *ast.CommentGroup: + // nop + + case *ast.CompositeLit: + children = append(children, + tok(n.Lbrace, len("{")), + tok(n.Rbrace, len("{"))) + + case *ast.DeclStmt: + // nop + + case *ast.DeferStmt: + children = append(children, + tok(n.Defer, len("defer"))) + + case *ast.Ellipsis: + children = append(children, + tok(n.Ellipsis, len("..."))) + + case *ast.EmptyStmt: + // nop + + case *ast.ExprStmt: + // nop + + case *ast.Field: + // TODO(adonovan): Field.{Doc,Comment,Tag}? + + case *ast.FieldList: + if n.Opening.IsValid() { + children = append(children, tok(n.Opening, len("("))) + } + if n.Closing.IsValid() { + children = append(children, tok(n.Closing, len(")"))) + } + + case *ast.File: + // TODO test: Doc + children = append(children, + tok(n.Package, len("package"))) + + case *ast.ForStmt: + children = append(children, + tok(n.For, len("for"))) + + case *ast.FuncDecl: + // TODO(adonovan): FuncDecl.Comment? + + // Uniquely, FuncDecl breaks the invariant that + // preorder traversal yields tokens in lexical order: + // in fact, FuncDecl.Recv precedes FuncDecl.Type.Func. + // + // As a workaround, we inline the case for FuncType + // here and order things correctly. + // We also need to insert the elided FuncType just + // before the 'visit' recursion. + // + children = nil // discard ast.Walk(FuncDecl) info subtrees + children = append(children, tok(n.Type.Func, len("func"))) + if n.Recv != nil { + children = append(children, n.Recv) + } + children = append(children, n.Name) + if tparams := n.Type.TypeParams; tparams != nil { + children = append(children, tparams) + } + if n.Type.Params != nil { + children = append(children, n.Type.Params) + } + if n.Type.Results != nil { + children = append(children, n.Type.Results) + } + if n.Body != nil { + children = append(children, n.Body) + } + + case *ast.FuncLit: + // nop + + case *ast.FuncType: + if n.Func != 0 { + children = append(children, + tok(n.Func, len("func"))) + } + + case *ast.GenDecl: + children = append(children, + tok(n.TokPos, len(n.Tok.String()))) + if n.Lparen != 0 { + children = append(children, + tok(n.Lparen, len("(")), + tok(n.Rparen, len(")"))) + } + + case *ast.GoStmt: + children = append(children, + tok(n.Go, len("go"))) + + case *ast.Ident: + children = append(children, + tok(n.NamePos, len(n.Name))) + + case *ast.IfStmt: + children = append(children, + tok(n.If, len("if"))) + + case *ast.ImportSpec: + // TODO(adonovan): ImportSpec.{Doc,EndPos}? + + case *ast.IncDecStmt: + children = append(children, + tok(n.TokPos, len(n.Tok.String()))) + + case *ast.IndexExpr: + children = append(children, + tok(n.Lbrack, len("[")), + tok(n.Rbrack, len("]"))) + + case *ast.IndexListExpr: + children = append(children, + tok(n.Lbrack, len("[")), + tok(n.Rbrack, len("]"))) + + case *ast.InterfaceType: + children = append(children, + tok(n.Interface, len("interface"))) + + case *ast.KeyValueExpr: + children = append(children, + tok(n.Colon, len(":"))) + + case *ast.LabeledStmt: + children = append(children, + tok(n.Colon, len(":"))) + + case *ast.MapType: + children = append(children, + tok(n.Map, len("map"))) + + case *ast.ParenExpr: + children = append(children, + tok(n.Lparen, len("(")), + tok(n.Rparen, len(")"))) + + case *ast.RangeStmt: + children = append(children, + tok(n.For, len("for")), + tok(n.TokPos, len(n.Tok.String()))) + + case *ast.ReturnStmt: + children = append(children, + tok(n.Return, len("return"))) + + case *ast.SelectStmt: + children = append(children, + tok(n.Select, len("select"))) + + case *ast.SelectorExpr: + // nop + + case *ast.SendStmt: + children = append(children, + tok(n.Arrow, len("<-"))) + + case *ast.SliceExpr: + children = append(children, + tok(n.Lbrack, len("[")), + tok(n.Rbrack, len("]"))) + + case *ast.StarExpr: + children = append(children, tok(n.Star, len("*"))) + + case *ast.StructType: + children = append(children, tok(n.Struct, len("struct"))) + + case *ast.SwitchStmt: + children = append(children, tok(n.Switch, len("switch"))) + + case *ast.TypeAssertExpr: + children = append(children, + tok(n.Lparen-1, len(".")), + tok(n.Lparen, len("(")), + tok(n.Rparen, len(")"))) + + case *ast.TypeSpec: + // TODO(adonovan): TypeSpec.{Doc,Comment}? + + case *ast.TypeSwitchStmt: + children = append(children, tok(n.Switch, len("switch"))) + + case *ast.UnaryExpr: + children = append(children, tok(n.OpPos, len(n.Op.String()))) + + case *ast.ValueSpec: + // TODO(adonovan): ValueSpec.{Doc,Comment}? + + case *ast.BadDecl, *ast.BadExpr, *ast.BadStmt: + // nop + } + + // TODO(adonovan): opt: merge the logic of ast.Inspect() into + // the switch above so we can make interleaved callbacks for + // both Nodes and Tokens in the right order and avoid the need + // to sort. + sort.Sort(byPos(children)) + + return children +} + +type byPos []ast.Node + +func (sl byPos) Len() int { + return len(sl) +} +func (sl byPos) Less(i, j int) bool { + return sl[i].Pos() < sl[j].Pos() +} +func (sl byPos) Swap(i, j int) { + sl[i], sl[j] = sl[j], sl[i] +} + +// NodeDescription returns a description of the concrete type of n suitable +// for a user interface. +// +// TODO(adonovan): in some cases (e.g. Field, FieldList, Ident, +// StarExpr) we could be much more specific given the path to the AST +// root. Perhaps we should do that. +func NodeDescription(n ast.Node) string { + switch n := n.(type) { + case *ast.ArrayType: + return "array type" + case *ast.AssignStmt: + return "assignment" + case *ast.BadDecl: + return "bad declaration" + case *ast.BadExpr: + return "bad expression" + case *ast.BadStmt: + return "bad statement" + case *ast.BasicLit: + return "basic literal" + case *ast.BinaryExpr: + return fmt.Sprintf("binary %s operation", n.Op) + case *ast.BlockStmt: + return "block" + case *ast.BranchStmt: + switch n.Tok { + case token.BREAK: + return "break statement" + case token.CONTINUE: + return "continue statement" + case token.GOTO: + return "goto statement" + case token.FALLTHROUGH: + return "fall-through statement" + } + case *ast.CallExpr: + if len(n.Args) == 1 && !n.Ellipsis.IsValid() { + return "function call (or conversion)" + } + return "function call" + case *ast.CaseClause: + return "case clause" + case *ast.ChanType: + return "channel type" + case *ast.CommClause: + return "communication clause" + case *ast.Comment: + return "comment" + case *ast.CommentGroup: + return "comment group" + case *ast.CompositeLit: + return "composite literal" + case *ast.DeclStmt: + return NodeDescription(n.Decl) + " statement" + case *ast.DeferStmt: + return "defer statement" + case *ast.Ellipsis: + return "ellipsis" + case *ast.EmptyStmt: + return "empty statement" + case *ast.ExprStmt: + return "expression statement" + case *ast.Field: + // Can be any of these: + // struct {x, y int} -- struct field(s) + // struct {T} -- anon struct field + // interface {I} -- interface embedding + // interface {f()} -- interface method + // func (A) func(B) C -- receiver, param(s), result(s) + return "field/method/parameter" + case *ast.FieldList: + return "field/method/parameter list" + case *ast.File: + return "source file" + case *ast.ForStmt: + return "for loop" + case *ast.FuncDecl: + return "function declaration" + case *ast.FuncLit: + return "function literal" + case *ast.FuncType: + return "function type" + case *ast.GenDecl: + switch n.Tok { + case token.IMPORT: + return "import declaration" + case token.CONST: + return "constant declaration" + case token.TYPE: + return "type declaration" + case token.VAR: + return "variable declaration" + } + case *ast.GoStmt: + return "go statement" + case *ast.Ident: + return "identifier" + case *ast.IfStmt: + return "if statement" + case *ast.ImportSpec: + return "import specification" + case *ast.IncDecStmt: + if n.Tok == token.INC { + return "increment statement" + } + return "decrement statement" + case *ast.IndexExpr: + return "index expression" + case *ast.IndexListExpr: + return "index list expression" + case *ast.InterfaceType: + return "interface type" + case *ast.KeyValueExpr: + return "key/value association" + case *ast.LabeledStmt: + return "statement label" + case *ast.MapType: + return "map type" + case *ast.Package: + return "package" + case *ast.ParenExpr: + return "parenthesized " + NodeDescription(n.X) + case *ast.RangeStmt: + return "range loop" + case *ast.ReturnStmt: + return "return statement" + case *ast.SelectStmt: + return "select statement" + case *ast.SelectorExpr: + return "selector" + case *ast.SendStmt: + return "channel send" + case *ast.SliceExpr: + return "slice expression" + case *ast.StarExpr: + return "*-operation" // load/store expr or pointer type + case *ast.StructType: + return "struct type" + case *ast.SwitchStmt: + return "switch statement" + case *ast.TypeAssertExpr: + return "type assertion" + case *ast.TypeSpec: + return "type specification" + case *ast.TypeSwitchStmt: + return "type switch" + case *ast.UnaryExpr: + return fmt.Sprintf("unary %s operation", n.Op) + case *ast.ValueSpec: + return "value specification" + + } + panic(fmt.Sprintf("unexpected node type: %T", n)) +} + +func is[T any](x any) bool { + _, ok := x.(T) + return ok +} diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/vendor/golang.org/x/tools/go/ast/astutil/imports.go new file mode 100644 index 0000000..6121bdd --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/astutil/imports.go @@ -0,0 +1,481 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package astutil contains common utilities for working with the Go AST. +package astutil // import "golang.org/x/tools/go/ast/astutil" + +import ( + "fmt" + "go/ast" + "go/token" + "slices" + "strconv" + "strings" +) + +// AddImport adds the import path to the file f, if absent. +func AddImport(fset *token.FileSet, f *ast.File, path string) (added bool) { + return AddNamedImport(fset, f, "", path) +} + +// AddNamedImport adds the import with the given name and path to the file f, if absent. +// If name is not empty, it is used to rename the import. +// +// For example, calling +// +// AddNamedImport(fset, f, "pathpkg", "path") +// +// adds +// +// import pathpkg "path" +func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added bool) { + if imports(f, name, path) { + return false + } + + newImport := &ast.ImportSpec{ + Path: &ast.BasicLit{ + Kind: token.STRING, + Value: strconv.Quote(path), + }, + } + if name != "" { + newImport.Name = &ast.Ident{Name: name} + } + + // Find an import decl to add to. + // The goal is to find an existing import + // whose import path has the longest shared + // prefix with path. + var ( + bestMatch = -1 // length of longest shared prefix + lastImport = -1 // index in f.Decls of the file's final import decl + impDecl *ast.GenDecl // import decl containing the best match + impIndex = -1 // spec index in impDecl containing the best match + + isThirdPartyPath = isThirdParty(path) + ) + for i, decl := range f.Decls { + gen, ok := decl.(*ast.GenDecl) + if ok && gen.Tok == token.IMPORT { + lastImport = i + // Do not add to import "C", to avoid disrupting the + // association with its doc comment, breaking cgo. + if declImports(gen, "C") { + continue + } + + // Match an empty import decl if that's all that is available. + if len(gen.Specs) == 0 && bestMatch == -1 { + impDecl = gen + } + + // Compute longest shared prefix with imports in this group and find best + // matched import spec. + // 1. Always prefer import spec with longest shared prefix. + // 2. While match length is 0, + // - for stdlib package: prefer first import spec. + // - for third party package: prefer first third party import spec. + // We cannot use last import spec as best match for third party package + // because grouped imports are usually placed last by goimports -local + // flag. + // See issue #19190. + seenAnyThirdParty := false + for j, spec := range gen.Specs { + impspec := spec.(*ast.ImportSpec) + p := importPath(impspec) + n := matchLen(p, path) + if n > bestMatch || (bestMatch == 0 && !seenAnyThirdParty && isThirdPartyPath) { + bestMatch = n + impDecl = gen + impIndex = j + } + seenAnyThirdParty = seenAnyThirdParty || isThirdParty(p) + } + } + } + + // If no import decl found, add one after the last import. + if impDecl == nil { + impDecl = &ast.GenDecl{ + Tok: token.IMPORT, + } + if lastImport >= 0 { + impDecl.TokPos = f.Decls[lastImport].End() + } else { + // There are no existing imports. + // Our new import, preceded by a blank line, goes after the package declaration + // and after the comment, if any, that starts on the same line as the + // package declaration. + impDecl.TokPos = f.Package + + file := fset.File(f.Package) + pkgLine := file.Line(f.Package) + for _, c := range f.Comments { + if file.Line(c.Pos()) > pkgLine { + break + } + // +2 for a blank line + impDecl.TokPos = c.End() + 2 + } + } + f.Decls = append(f.Decls, nil) + copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:]) + f.Decls[lastImport+1] = impDecl + } + + // Insert new import at insertAt. + insertAt := 0 + if impIndex >= 0 { + // insert after the found import + insertAt = impIndex + 1 + } + impDecl.Specs = append(impDecl.Specs, nil) + copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:]) + impDecl.Specs[insertAt] = newImport + pos := impDecl.Pos() + if insertAt > 0 { + // If there is a comment after an existing import, preserve the comment + // position by adding the new import after the comment. + if spec, ok := impDecl.Specs[insertAt-1].(*ast.ImportSpec); ok && spec.Comment != nil { + pos = spec.Comment.End() + } else { + // Assign same position as the previous import, + // so that the sorter sees it as being in the same block. + pos = impDecl.Specs[insertAt-1].Pos() + } + } + if newImport.Name != nil { + newImport.Name.NamePos = pos + } + updateBasicLitPos(newImport.Path, pos) + newImport.EndPos = pos + + // Clean up parens. impDecl contains at least one spec. + if len(impDecl.Specs) == 1 { + // Remove unneeded parens. + impDecl.Lparen = token.NoPos + } else if !impDecl.Lparen.IsValid() { + // impDecl needs parens added. + impDecl.Lparen = impDecl.Specs[0].Pos() + } + + f.Imports = append(f.Imports, newImport) + + if len(f.Decls) <= 1 { + return true + } + + // Merge all the import declarations into the first one. + var first *ast.GenDecl + for i := 0; i < len(f.Decls); i++ { + decl := f.Decls[i] + gen, ok := decl.(*ast.GenDecl) + if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") { + continue + } + if first == nil { + first = gen + continue // Don't touch the first one. + } + // We now know there is more than one package in this import + // declaration. Ensure that it ends up parenthesized. + first.Lparen = first.Pos() + // Move the imports of the other import declaration to the first one. + for _, spec := range gen.Specs { + updateBasicLitPos(spec.(*ast.ImportSpec).Path, first.Pos()) + first.Specs = append(first.Specs, spec) + } + f.Decls = slices.Delete(f.Decls, i, i+1) + i-- + } + + return true +} + +func isThirdParty(importPath string) bool { + // Third party package import path usually contains "." (".com", ".org", ...) + // This logic is taken from golang.org/x/tools/imports package. + return strings.Contains(importPath, ".") +} + +// DeleteImport deletes the import path from the file f, if present. +// If there are duplicate import declarations, all matching ones are deleted. +func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) { + return DeleteNamedImport(fset, f, "", path) +} + +// DeleteNamedImport deletes the import with the given name and path from the file f, if present. +// If there are duplicate import declarations, all matching ones are deleted. +func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) { + var ( + delspecs = make(map[*ast.ImportSpec]bool) + delcomments = make(map[*ast.CommentGroup]bool) + ) + + // Find the import nodes that import path, if any. + for i := 0; i < len(f.Decls); i++ { + gen, ok := f.Decls[i].(*ast.GenDecl) + if !ok || gen.Tok != token.IMPORT { + continue + } + for j := 0; j < len(gen.Specs); j++ { + impspec := gen.Specs[j].(*ast.ImportSpec) + if importName(impspec) != name || importPath(impspec) != path { + continue + } + + // We found an import spec that imports path. + // Delete it. + delspecs[impspec] = true + deleted = true + gen.Specs = slices.Delete(gen.Specs, j, j+1) + + // If this was the last import spec in this decl, + // delete the decl, too. + if len(gen.Specs) == 0 { + f.Decls = slices.Delete(f.Decls, i, i+1) + i-- + break + } else if len(gen.Specs) == 1 { + if impspec.Doc != nil { + delcomments[impspec.Doc] = true + } + if impspec.Comment != nil { + delcomments[impspec.Comment] = true + } + for _, cg := range f.Comments { + // Found comment on the same line as the import spec. + if cg.End() < impspec.Pos() && fset.Position(cg.End()).Line == fset.Position(impspec.Pos()).Line { + delcomments[cg] = true + break + } + } + + spec := gen.Specs[0].(*ast.ImportSpec) + + // Move the documentation right after the import decl. + if spec.Doc != nil { + for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Doc.Pos()).Line { + fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line) + } + } + for _, cg := range f.Comments { + if cg.End() < spec.Pos() && fset.Position(cg.End()).Line == fset.Position(spec.Pos()).Line { + for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Pos()).Line { + fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line) + } + break + } + } + } + if j > 0 { + lastImpspec := gen.Specs[j-1].(*ast.ImportSpec) + lastLine := fset.PositionFor(lastImpspec.Path.ValuePos, false).Line + line := fset.PositionFor(impspec.Path.ValuePos, false).Line + + // We deleted an entry but now there may be + // a blank line-sized hole where the import was. + if line-lastLine > 1 || !gen.Rparen.IsValid() { + // There was a blank line immediately preceding the deleted import, + // so there's no need to close the hole. The right parenthesis is + // invalid after AddImport to an import statement without parenthesis. + // Do nothing. + } else if line != fset.File(gen.Rparen).LineCount() { + // There was no blank line. Close the hole. + fset.File(gen.Rparen).MergeLine(line) + } + } + j-- + } + } + + // Delete imports from f.Imports. + before := len(f.Imports) + f.Imports = slices.DeleteFunc(f.Imports, func(imp *ast.ImportSpec) bool { + _, ok := delspecs[imp] + return ok + }) + if len(f.Imports)+len(delspecs) != before { + // This can happen when the AST is invalid (i.e. imports differ between f.Decls and f.Imports). + panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs)) + } + + // Delete comments from f.Comments. + f.Comments = slices.DeleteFunc(f.Comments, func(cg *ast.CommentGroup) bool { + _, ok := delcomments[cg] + return ok + }) + + return +} + +// RewriteImport rewrites any import of path oldPath to path newPath. +func RewriteImport(fset *token.FileSet, f *ast.File, oldPath, newPath string) (rewrote bool) { + for _, imp := range f.Imports { + if importPath(imp) == oldPath { + rewrote = true + // record old End, because the default is to compute + // it using the length of imp.Path.Value. + imp.EndPos = imp.End() + imp.Path.Value = strconv.Quote(newPath) + } + } + return +} + +// UsesImport reports whether a given import is used. +// The provided File must have been parsed with syntactic object resolution +// (not using go/parser.SkipObjectResolution). +func UsesImport(f *ast.File, path string) (used bool) { + if f.Scope == nil { + panic("file f was not parsed with syntactic object resolution") + } + spec := importSpec(f, path) + if spec == nil { + return + } + + name := spec.Name.String() + switch name { + case "": + // If the package name is not explicitly specified, + // make an educated guess. This is not guaranteed to be correct. + lastSlash := strings.LastIndex(path, "/") + if lastSlash == -1 { + name = path + } else { + name = path[lastSlash+1:] + } + case "_", ".": + // Not sure if this import is used - err on the side of caution. + return true + } + + ast.Walk(visitFn(func(n ast.Node) { + sel, ok := n.(*ast.SelectorExpr) + if ok && isTopName(sel.X, name) { + used = true + } + }), f) + + return +} + +type visitFn func(node ast.Node) + +func (fn visitFn) Visit(node ast.Node) ast.Visitor { + fn(node) + return fn +} + +// imports reports whether f has an import with the specified name and path. +func imports(f *ast.File, name, path string) bool { + for _, s := range f.Imports { + if importName(s) == name && importPath(s) == path { + return true + } + } + return false +} + +// importSpec returns the import spec if f imports path, +// or nil otherwise. +func importSpec(f *ast.File, path string) *ast.ImportSpec { + for _, s := range f.Imports { + if importPath(s) == path { + return s + } + } + return nil +} + +// importName returns the name of s, +// or "" if the import is not named. +func importName(s *ast.ImportSpec) string { + if s.Name == nil { + return "" + } + return s.Name.Name +} + +// importPath returns the unquoted import path of s, +// or "" if the path is not properly quoted. +func importPath(s *ast.ImportSpec) string { + t, err := strconv.Unquote(s.Path.Value) + if err != nil { + return "" + } + return t +} + +// declImports reports whether gen contains an import of path. +func declImports(gen *ast.GenDecl, path string) bool { + if gen.Tok != token.IMPORT { + return false + } + for _, spec := range gen.Specs { + impspec := spec.(*ast.ImportSpec) + if importPath(impspec) == path { + return true + } + } + return false +} + +// matchLen returns the length of the longest path segment prefix shared by x and y. +func matchLen(x, y string) int { + n := 0 + for i := 0; i < len(x) && i < len(y) && x[i] == y[i]; i++ { + if x[i] == '/' { + n++ + } + } + return n +} + +// isTopName returns true if n is a top-level unresolved identifier with the given name. +func isTopName(n ast.Expr, name string) bool { + id, ok := n.(*ast.Ident) + return ok && id.Name == name && id.Obj == nil +} + +// Imports returns the file imports grouped by paragraph. +func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec { + var groups [][]*ast.ImportSpec + + for _, decl := range f.Decls { + genDecl, ok := decl.(*ast.GenDecl) + if !ok || genDecl.Tok != token.IMPORT { + break + } + + group := []*ast.ImportSpec{} + + var lastLine int + for _, spec := range genDecl.Specs { + importSpec := spec.(*ast.ImportSpec) + pos := importSpec.Path.ValuePos + line := fset.Position(pos).Line + if lastLine > 0 && pos > 0 && line-lastLine > 1 { + groups = append(groups, group) + group = []*ast.ImportSpec{} + } + group = append(group, importSpec) + lastLine = line + } + groups = append(groups, group) + } + + return groups +} + +// updateBasicLitPos updates lit.Pos, +// ensuring that lit.End is displaced by the same amount. +// (See https://go.dev/issue/76395.) +func updateBasicLitPos(lit *ast.BasicLit, pos token.Pos) { + len := lit.End() - lit.Pos() + lit.ValuePos = pos + lit.ValueEnd = pos + len +} diff --git a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go b/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go new file mode 100644 index 0000000..4ad0549 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go @@ -0,0 +1,490 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package astutil + +import ( + "fmt" + "go/ast" + "reflect" + "sort" +) + +// An ApplyFunc is invoked by Apply for each node n, even if n is nil, +// before and/or after the node's children, using a Cursor describing +// the current node and providing operations on it. +// +// The return value of ApplyFunc controls the syntax tree traversal. +// See Apply for details. +type ApplyFunc func(*Cursor) bool + +// Apply traverses a syntax tree recursively, starting with root, +// and calling pre and post for each node as described below. +// Apply returns the syntax tree, possibly modified. +// +// If pre is not nil, it is called for each node before the node's +// children are traversed (pre-order). If pre returns false, no +// children are traversed, and post is not called for that node. +// +// If post is not nil, and a prior call of pre didn't return false, +// post is called for each node after its children are traversed +// (post-order). If post returns false, traversal is terminated and +// Apply returns immediately. +// +// Only fields that refer to AST nodes are considered children; +// i.e., token.Pos, Scopes, Objects, and fields of basic types +// (strings, etc.) are ignored. +// +// Children are traversed in the order in which they appear in the +// respective node's struct definition. A package's files are +// traversed in the filenames' alphabetical order. +func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node) { + parent := &struct{ ast.Node }{root} + defer func() { + if r := recover(); r != nil && r != abort { + panic(r) + } + result = parent.Node + }() + a := &application{pre: pre, post: post} + a.apply(parent, "Node", nil, root) + return +} + +var abort = new(int) // singleton, to signal termination of Apply + +// A Cursor describes a node encountered during Apply. +// Information about the node and its parent is available +// from the Node, Parent, Name, and Index methods. +// +// If p is a variable of type and value of the current parent node +// c.Parent(), and f is the field identifier with name c.Name(), +// the following invariants hold: +// +// p.f == c.Node() if c.Index() < 0 +// p.f[c.Index()] == c.Node() if c.Index() >= 0 +// +// The methods Replace, Delete, InsertBefore, and InsertAfter +// can be used to change the AST without disrupting Apply. +// +// This type is not to be confused with [inspector.Cursor] from +// package [golang.org/x/tools/go/ast/inspector], which provides +// stateless navigation of immutable syntax trees. +type Cursor struct { + parent ast.Node + name string + iter *iterator // valid if non-nil + node ast.Node +} + +// Node returns the current Node. +func (c *Cursor) Node() ast.Node { return c.node } + +// Parent returns the parent of the current Node. +func (c *Cursor) Parent() ast.Node { return c.parent } + +// Name returns the name of the parent Node field that contains the current Node. +// If the parent is a *ast.Package and the current Node is a *ast.File, Name returns +// the filename for the current Node. +func (c *Cursor) Name() string { return c.name } + +// Index reports the index >= 0 of the current Node in the slice of Nodes that +// contains it, or a value < 0 if the current Node is not part of a slice. +// The index of the current node changes if InsertBefore is called while +// processing the current node. +func (c *Cursor) Index() int { + if c.iter != nil { + return c.iter.index + } + return -1 +} + +// field returns the current node's parent field value. +func (c *Cursor) field() reflect.Value { + return reflect.Indirect(reflect.ValueOf(c.parent)).FieldByName(c.name) +} + +// Replace replaces the current Node with n. +// The replacement node is not walked by Apply. +func (c *Cursor) Replace(n ast.Node) { + if _, ok := c.node.(*ast.File); ok { + file, ok := n.(*ast.File) + if !ok { + panic("attempt to replace *ast.File with non-*ast.File") + } + c.parent.(*ast.Package).Files[c.name] = file + return + } + + v := c.field() + if i := c.Index(); i >= 0 { + v = v.Index(i) + } + v.Set(reflect.ValueOf(n)) +} + +// Delete deletes the current Node from its containing slice. +// If the current Node is not part of a slice, Delete panics. +// As a special case, if the current node is a package file, +// Delete removes it from the package's Files map. +func (c *Cursor) Delete() { + if _, ok := c.node.(*ast.File); ok { + delete(c.parent.(*ast.Package).Files, c.name) + return + } + + i := c.Index() + if i < 0 { + panic("Delete node not contained in slice") + } + v := c.field() + l := v.Len() + reflect.Copy(v.Slice(i, l), v.Slice(i+1, l)) + v.Index(l - 1).Set(reflect.Zero(v.Type().Elem())) + v.SetLen(l - 1) + c.iter.step-- +} + +// InsertAfter inserts n after the current Node in its containing slice. +// If the current Node is not part of a slice, InsertAfter panics. +// Apply does not walk n. +func (c *Cursor) InsertAfter(n ast.Node) { + i := c.Index() + if i < 0 { + panic("InsertAfter node not contained in slice") + } + v := c.field() + v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem()))) + l := v.Len() + reflect.Copy(v.Slice(i+2, l), v.Slice(i+1, l)) + v.Index(i + 1).Set(reflect.ValueOf(n)) + c.iter.step++ +} + +// InsertBefore inserts n before the current Node in its containing slice. +// If the current Node is not part of a slice, InsertBefore panics. +// Apply will not walk n. +func (c *Cursor) InsertBefore(n ast.Node) { + i := c.Index() + if i < 0 { + panic("InsertBefore node not contained in slice") + } + v := c.field() + v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem()))) + l := v.Len() + reflect.Copy(v.Slice(i+1, l), v.Slice(i, l)) + v.Index(i).Set(reflect.ValueOf(n)) + c.iter.index++ +} + +// application carries all the shared data so we can pass it around cheaply. +type application struct { + pre, post ApplyFunc + cursor Cursor + iter iterator +} + +func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.Node) { + // convert typed nil into untyped nil + if v := reflect.ValueOf(n); v.Kind() == reflect.Pointer && v.IsNil() { + n = nil + } + + // avoid heap-allocating a new cursor for each apply call; reuse a.cursor instead + saved := a.cursor + a.cursor.parent = parent + a.cursor.name = name + a.cursor.iter = iter + a.cursor.node = n + + if a.pre != nil && !a.pre(&a.cursor) { + a.cursor = saved + return + } + + // walk children + // (the order of the cases matches the order of the corresponding node types in go/ast) + switch n := n.(type) { + case nil: + // nothing to do + + // Comments and fields + case *ast.Comment: + // nothing to do + + case *ast.CommentGroup: + if n != nil { + a.applyList(n, "List") + } + + case *ast.Field: + a.apply(n, "Doc", nil, n.Doc) + a.applyList(n, "Names") + a.apply(n, "Type", nil, n.Type) + a.apply(n, "Tag", nil, n.Tag) + a.apply(n, "Comment", nil, n.Comment) + + case *ast.FieldList: + a.applyList(n, "List") + + // Expressions + case *ast.BadExpr, *ast.Ident, *ast.BasicLit: + // nothing to do + + case *ast.Ellipsis: + a.apply(n, "Elt", nil, n.Elt) + + case *ast.FuncLit: + a.apply(n, "Type", nil, n.Type) + a.apply(n, "Body", nil, n.Body) + + case *ast.CompositeLit: + a.apply(n, "Type", nil, n.Type) + a.applyList(n, "Elts") + + case *ast.ParenExpr: + a.apply(n, "X", nil, n.X) + + case *ast.SelectorExpr: + a.apply(n, "X", nil, n.X) + a.apply(n, "Sel", nil, n.Sel) + + case *ast.IndexExpr: + a.apply(n, "X", nil, n.X) + a.apply(n, "Index", nil, n.Index) + + case *ast.IndexListExpr: + a.apply(n, "X", nil, n.X) + a.applyList(n, "Indices") + + case *ast.SliceExpr: + a.apply(n, "X", nil, n.X) + a.apply(n, "Low", nil, n.Low) + a.apply(n, "High", nil, n.High) + a.apply(n, "Max", nil, n.Max) + + case *ast.TypeAssertExpr: + a.apply(n, "X", nil, n.X) + a.apply(n, "Type", nil, n.Type) + + case *ast.CallExpr: + a.apply(n, "Fun", nil, n.Fun) + a.applyList(n, "Args") + + case *ast.StarExpr: + a.apply(n, "X", nil, n.X) + + case *ast.UnaryExpr: + a.apply(n, "X", nil, n.X) + + case *ast.BinaryExpr: + a.apply(n, "X", nil, n.X) + a.apply(n, "Y", nil, n.Y) + + case *ast.KeyValueExpr: + a.apply(n, "Key", nil, n.Key) + a.apply(n, "Value", nil, n.Value) + + // Types + case *ast.ArrayType: + a.apply(n, "Len", nil, n.Len) + a.apply(n, "Elt", nil, n.Elt) + + case *ast.StructType: + a.apply(n, "Fields", nil, n.Fields) + + case *ast.FuncType: + if tparams := n.TypeParams; tparams != nil { + a.apply(n, "TypeParams", nil, tparams) + } + a.apply(n, "Params", nil, n.Params) + a.apply(n, "Results", nil, n.Results) + + case *ast.InterfaceType: + a.apply(n, "Methods", nil, n.Methods) + + case *ast.MapType: + a.apply(n, "Key", nil, n.Key) + a.apply(n, "Value", nil, n.Value) + + case *ast.ChanType: + a.apply(n, "Value", nil, n.Value) + + // Statements + case *ast.BadStmt: + // nothing to do + + case *ast.DeclStmt: + a.apply(n, "Decl", nil, n.Decl) + + case *ast.EmptyStmt: + // nothing to do + + case *ast.LabeledStmt: + a.apply(n, "Label", nil, n.Label) + a.apply(n, "Stmt", nil, n.Stmt) + + case *ast.ExprStmt: + a.apply(n, "X", nil, n.X) + + case *ast.SendStmt: + a.apply(n, "Chan", nil, n.Chan) + a.apply(n, "Value", nil, n.Value) + + case *ast.IncDecStmt: + a.apply(n, "X", nil, n.X) + + case *ast.AssignStmt: + a.applyList(n, "Lhs") + a.applyList(n, "Rhs") + + case *ast.GoStmt: + a.apply(n, "Call", nil, n.Call) + + case *ast.DeferStmt: + a.apply(n, "Call", nil, n.Call) + + case *ast.ReturnStmt: + a.applyList(n, "Results") + + case *ast.BranchStmt: + a.apply(n, "Label", nil, n.Label) + + case *ast.BlockStmt: + a.applyList(n, "List") + + case *ast.IfStmt: + a.apply(n, "Init", nil, n.Init) + a.apply(n, "Cond", nil, n.Cond) + a.apply(n, "Body", nil, n.Body) + a.apply(n, "Else", nil, n.Else) + + case *ast.CaseClause: + a.applyList(n, "List") + a.applyList(n, "Body") + + case *ast.SwitchStmt: + a.apply(n, "Init", nil, n.Init) + a.apply(n, "Tag", nil, n.Tag) + a.apply(n, "Body", nil, n.Body) + + case *ast.TypeSwitchStmt: + a.apply(n, "Init", nil, n.Init) + a.apply(n, "Assign", nil, n.Assign) + a.apply(n, "Body", nil, n.Body) + + case *ast.CommClause: + a.apply(n, "Comm", nil, n.Comm) + a.applyList(n, "Body") + + case *ast.SelectStmt: + a.apply(n, "Body", nil, n.Body) + + case *ast.ForStmt: + a.apply(n, "Init", nil, n.Init) + a.apply(n, "Cond", nil, n.Cond) + a.apply(n, "Post", nil, n.Post) + a.apply(n, "Body", nil, n.Body) + + case *ast.RangeStmt: + a.apply(n, "Key", nil, n.Key) + a.apply(n, "Value", nil, n.Value) + a.apply(n, "X", nil, n.X) + a.apply(n, "Body", nil, n.Body) + + // Declarations + case *ast.ImportSpec: + a.apply(n, "Doc", nil, n.Doc) + a.apply(n, "Name", nil, n.Name) + a.apply(n, "Path", nil, n.Path) + a.apply(n, "Comment", nil, n.Comment) + + case *ast.ValueSpec: + a.apply(n, "Doc", nil, n.Doc) + a.applyList(n, "Names") + a.apply(n, "Type", nil, n.Type) + a.applyList(n, "Values") + a.apply(n, "Comment", nil, n.Comment) + + case *ast.TypeSpec: + a.apply(n, "Doc", nil, n.Doc) + a.apply(n, "Name", nil, n.Name) + if tparams := n.TypeParams; tparams != nil { + a.apply(n, "TypeParams", nil, tparams) + } + a.apply(n, "Type", nil, n.Type) + a.apply(n, "Comment", nil, n.Comment) + + case *ast.BadDecl: + // nothing to do + + case *ast.GenDecl: + a.apply(n, "Doc", nil, n.Doc) + a.applyList(n, "Specs") + + case *ast.FuncDecl: + a.apply(n, "Doc", nil, n.Doc) + a.apply(n, "Recv", nil, n.Recv) + a.apply(n, "Name", nil, n.Name) + a.apply(n, "Type", nil, n.Type) + a.apply(n, "Body", nil, n.Body) + + // Files and packages + case *ast.File: + a.apply(n, "Doc", nil, n.Doc) + a.apply(n, "Name", nil, n.Name) + a.applyList(n, "Decls") + // Don't walk n.Comments; they have either been walked already if + // they are Doc comments, or they can be easily walked explicitly. + + case *ast.Package: + // collect and sort names for reproducible behavior + var names []string + for name := range n.Files { + names = append(names, name) + } + sort.Strings(names) + for _, name := range names { + a.apply(n, name, nil, n.Files[name]) + } + + default: + panic(fmt.Sprintf("Apply: unexpected node type %T", n)) + } + + if a.post != nil && !a.post(&a.cursor) { + panic(abort) + } + + a.cursor = saved +} + +// An iterator controls iteration over a slice of nodes. +type iterator struct { + index, step int +} + +func (a *application) applyList(parent ast.Node, name string) { + // avoid heap-allocating a new iterator for each applyList call; reuse a.iter instead + saved := a.iter + a.iter.index = 0 + for { + // must reload parent.name each time, since cursor modifications might change it + v := reflect.Indirect(reflect.ValueOf(parent)).FieldByName(name) + if a.iter.index >= v.Len() { + break + } + + // element x may be nil in a bad AST - be cautious + var x ast.Node + if e := v.Index(a.iter.index); e.IsValid() { + x = e.Interface().(ast.Node) + } + + a.iter.step = 1 + a.apply(parent, name, &a.iter, x) + a.iter.index += a.iter.step + } + a.iter = saved +} diff --git a/vendor/golang.org/x/tools/go/ast/astutil/util.go b/vendor/golang.org/x/tools/go/ast/astutil/util.go new file mode 100644 index 0000000..c820b20 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/astutil/util.go @@ -0,0 +1,13 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package astutil + +import "go/ast" + +// Unparen returns e with any enclosing parentheses stripped. +// Deprecated: use [ast.Unparen]. +// +//go:fix inline +func Unparen(e ast.Expr) ast.Expr { return ast.Unparen(e) } diff --git a/vendor/golang.org/x/tools/go/ast/edge/edge.go b/vendor/golang.org/x/tools/go/ast/edge/edge.go new file mode 100644 index 0000000..8dc4dd1 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/edge/edge.go @@ -0,0 +1,299 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package edge defines identifiers for each field of an ast.Node +// struct type that refers to another Node. +package edge + +import ( + "fmt" + "go/ast" + "reflect" +) + +// A Kind describes a field of an [ast.Node] struct. +type Kind uint8 + +// String returns a description of the edge kind. +func (k Kind) String() string { + if k == Invalid { + return "" + } + info := fieldInfos[k] + return fmt.Sprintf("%v.%s", info.nodeType.Elem().Name(), info.name) +} + +// NodeType returns the pointer-to-struct type of the ast.Node implementation. +func (k Kind) NodeType() reflect.Type { return fieldInfos[k].nodeType } + +// FieldName returns the name of the field. +func (k Kind) FieldName() string { return fieldInfos[k].name } + +// FieldType returns the declared type of the field. +func (k Kind) FieldType() reflect.Type { return fieldInfos[k].fieldType } + +// Get returns the direct child of n identified by (k, idx). +// n's type must match k.NodeType(). +// idx must be a valid slice index, or -1 for a non-slice. +func (k Kind) Get(n ast.Node, idx int) ast.Node { + if k.NodeType() != reflect.TypeOf(n) { + panic(fmt.Sprintf("%v.Get(%T): invalid node type", k, n)) + } + v := reflect.ValueOf(n).Elem().Field(fieldInfos[k].index) + + if v.Kind() == reflect.Slice { + v = v.Index(idx) // asserts valid idx + } else if idx != -1 { + panic(fmt.Sprintf("%v, Get(%T, %d): cannot index non-slice", v, n, idx)) + } + + out, _ := v.Interface().(ast.Node) // may be nil + return out +} + +// Each [Kind] is named Type_Field, where Type is the +// [ast.Node] struct type and Field is the name of the field +const ( + Invalid Kind = iota // for nodes at the root of the traversal + + // As of Go1.26 these kinds are sorted alphabetically, but + // numbering must be stable, so any new addition of const should + // use a new value (be added at the end of the list). + + ArrayType_Elt + ArrayType_Len + AssignStmt_Lhs + AssignStmt_Rhs + BinaryExpr_X + BinaryExpr_Y + BlockStmt_List + BranchStmt_Label + CallExpr_Args + CallExpr_Fun + CaseClause_Body + CaseClause_List + ChanType_Value + CommClause_Body + CommClause_Comm + CommentGroup_List + CompositeLit_Elts + CompositeLit_Type + DeclStmt_Decl + DeferStmt_Call + Ellipsis_Elt + ExprStmt_X + FieldList_List + Field_Comment + Field_Doc + Field_Names + Field_Tag + Field_Type + File_Decls + File_Doc + File_Name + ForStmt_Body + ForStmt_Cond + ForStmt_Init + ForStmt_Post + FuncDecl_Body + FuncDecl_Doc + FuncDecl_Name + FuncDecl_Recv + FuncDecl_Type + FuncLit_Body + FuncLit_Type + FuncType_Params + FuncType_Results + FuncType_TypeParams + GenDecl_Doc + GenDecl_Specs + GoStmt_Call + IfStmt_Body + IfStmt_Cond + IfStmt_Else + IfStmt_Init + ImportSpec_Comment + ImportSpec_Doc + ImportSpec_Name + ImportSpec_Path + IncDecStmt_X + IndexExpr_Index + IndexExpr_X + IndexListExpr_Indices + IndexListExpr_X + InterfaceType_Methods + KeyValueExpr_Key + KeyValueExpr_Value + LabeledStmt_Label + LabeledStmt_Stmt + MapType_Key + MapType_Value + ParenExpr_X + RangeStmt_Body + RangeStmt_Key + RangeStmt_Value + RangeStmt_X + ReturnStmt_Results + SelectStmt_Body + SelectorExpr_Sel + SelectorExpr_X + SendStmt_Chan + SendStmt_Value + SliceExpr_High + SliceExpr_Low + SliceExpr_Max + SliceExpr_X + StarExpr_X + StructType_Fields + SwitchStmt_Body + SwitchStmt_Init + SwitchStmt_Tag + TypeAssertExpr_Type + TypeAssertExpr_X + TypeSpec_Comment + TypeSpec_Doc + TypeSpec_Name + TypeSpec_Type + TypeSpec_TypeParams + TypeSwitchStmt_Assign + TypeSwitchStmt_Body + TypeSwitchStmt_Init + UnaryExpr_X + ValueSpec_Comment + ValueSpec_Doc + ValueSpec_Names + ValueSpec_Type + ValueSpec_Values + + maxKind +) + +// Assert that the encoding fits in 7 bits, +// as the inspector relies on this. +// (We are currently at 104.) +var _ = [1 << 7]struct{}{}[maxKind] + +type fieldInfo struct { + nodeType reflect.Type // pointer-to-struct type of ast.Node implementation + name string + index int + fieldType reflect.Type +} + +func info[N ast.Node](fieldName string) fieldInfo { + nodePtrType := reflect.TypeFor[N]() + f, ok := nodePtrType.Elem().FieldByName(fieldName) + if !ok { + panic(fieldName) + } + return fieldInfo{nodePtrType, fieldName, f.Index[0], f.Type} +} + +var fieldInfos = [...]fieldInfo{ + Invalid: {}, + ArrayType_Elt: info[*ast.ArrayType]("Elt"), + ArrayType_Len: info[*ast.ArrayType]("Len"), + AssignStmt_Lhs: info[*ast.AssignStmt]("Lhs"), + AssignStmt_Rhs: info[*ast.AssignStmt]("Rhs"), + BinaryExpr_X: info[*ast.BinaryExpr]("X"), + BinaryExpr_Y: info[*ast.BinaryExpr]("Y"), + BlockStmt_List: info[*ast.BlockStmt]("List"), + BranchStmt_Label: info[*ast.BranchStmt]("Label"), + CallExpr_Args: info[*ast.CallExpr]("Args"), + CallExpr_Fun: info[*ast.CallExpr]("Fun"), + CaseClause_Body: info[*ast.CaseClause]("Body"), + CaseClause_List: info[*ast.CaseClause]("List"), + ChanType_Value: info[*ast.ChanType]("Value"), + CommClause_Body: info[*ast.CommClause]("Body"), + CommClause_Comm: info[*ast.CommClause]("Comm"), + CommentGroup_List: info[*ast.CommentGroup]("List"), + CompositeLit_Elts: info[*ast.CompositeLit]("Elts"), + CompositeLit_Type: info[*ast.CompositeLit]("Type"), + DeclStmt_Decl: info[*ast.DeclStmt]("Decl"), + DeferStmt_Call: info[*ast.DeferStmt]("Call"), + Ellipsis_Elt: info[*ast.Ellipsis]("Elt"), + ExprStmt_X: info[*ast.ExprStmt]("X"), + FieldList_List: info[*ast.FieldList]("List"), + Field_Comment: info[*ast.Field]("Comment"), + Field_Doc: info[*ast.Field]("Doc"), + Field_Names: info[*ast.Field]("Names"), + Field_Tag: info[*ast.Field]("Tag"), + Field_Type: info[*ast.Field]("Type"), + File_Decls: info[*ast.File]("Decls"), + File_Doc: info[*ast.File]("Doc"), + File_Name: info[*ast.File]("Name"), + ForStmt_Body: info[*ast.ForStmt]("Body"), + ForStmt_Cond: info[*ast.ForStmt]("Cond"), + ForStmt_Init: info[*ast.ForStmt]("Init"), + ForStmt_Post: info[*ast.ForStmt]("Post"), + FuncDecl_Body: info[*ast.FuncDecl]("Body"), + FuncDecl_Doc: info[*ast.FuncDecl]("Doc"), + FuncDecl_Name: info[*ast.FuncDecl]("Name"), + FuncDecl_Recv: info[*ast.FuncDecl]("Recv"), + FuncDecl_Type: info[*ast.FuncDecl]("Type"), + FuncLit_Body: info[*ast.FuncLit]("Body"), + FuncLit_Type: info[*ast.FuncLit]("Type"), + FuncType_Params: info[*ast.FuncType]("Params"), + FuncType_Results: info[*ast.FuncType]("Results"), + FuncType_TypeParams: info[*ast.FuncType]("TypeParams"), + GenDecl_Doc: info[*ast.GenDecl]("Doc"), + GenDecl_Specs: info[*ast.GenDecl]("Specs"), + GoStmt_Call: info[*ast.GoStmt]("Call"), + IfStmt_Body: info[*ast.IfStmt]("Body"), + IfStmt_Cond: info[*ast.IfStmt]("Cond"), + IfStmt_Else: info[*ast.IfStmt]("Else"), + IfStmt_Init: info[*ast.IfStmt]("Init"), + ImportSpec_Comment: info[*ast.ImportSpec]("Comment"), + ImportSpec_Doc: info[*ast.ImportSpec]("Doc"), + ImportSpec_Name: info[*ast.ImportSpec]("Name"), + ImportSpec_Path: info[*ast.ImportSpec]("Path"), + IncDecStmt_X: info[*ast.IncDecStmt]("X"), + IndexExpr_Index: info[*ast.IndexExpr]("Index"), + IndexExpr_X: info[*ast.IndexExpr]("X"), + IndexListExpr_Indices: info[*ast.IndexListExpr]("Indices"), + IndexListExpr_X: info[*ast.IndexListExpr]("X"), + InterfaceType_Methods: info[*ast.InterfaceType]("Methods"), + KeyValueExpr_Key: info[*ast.KeyValueExpr]("Key"), + KeyValueExpr_Value: info[*ast.KeyValueExpr]("Value"), + LabeledStmt_Label: info[*ast.LabeledStmt]("Label"), + LabeledStmt_Stmt: info[*ast.LabeledStmt]("Stmt"), + MapType_Key: info[*ast.MapType]("Key"), + MapType_Value: info[*ast.MapType]("Value"), + ParenExpr_X: info[*ast.ParenExpr]("X"), + RangeStmt_Body: info[*ast.RangeStmt]("Body"), + RangeStmt_Key: info[*ast.RangeStmt]("Key"), + RangeStmt_Value: info[*ast.RangeStmt]("Value"), + RangeStmt_X: info[*ast.RangeStmt]("X"), + ReturnStmt_Results: info[*ast.ReturnStmt]("Results"), + SelectStmt_Body: info[*ast.SelectStmt]("Body"), + SelectorExpr_Sel: info[*ast.SelectorExpr]("Sel"), + SelectorExpr_X: info[*ast.SelectorExpr]("X"), + SendStmt_Chan: info[*ast.SendStmt]("Chan"), + SendStmt_Value: info[*ast.SendStmt]("Value"), + SliceExpr_High: info[*ast.SliceExpr]("High"), + SliceExpr_Low: info[*ast.SliceExpr]("Low"), + SliceExpr_Max: info[*ast.SliceExpr]("Max"), + SliceExpr_X: info[*ast.SliceExpr]("X"), + StarExpr_X: info[*ast.StarExpr]("X"), + StructType_Fields: info[*ast.StructType]("Fields"), + SwitchStmt_Body: info[*ast.SwitchStmt]("Body"), + SwitchStmt_Init: info[*ast.SwitchStmt]("Init"), + SwitchStmt_Tag: info[*ast.SwitchStmt]("Tag"), + TypeAssertExpr_Type: info[*ast.TypeAssertExpr]("Type"), + TypeAssertExpr_X: info[*ast.TypeAssertExpr]("X"), + TypeSpec_Comment: info[*ast.TypeSpec]("Comment"), + TypeSpec_Doc: info[*ast.TypeSpec]("Doc"), + TypeSpec_Name: info[*ast.TypeSpec]("Name"), + TypeSpec_Type: info[*ast.TypeSpec]("Type"), + TypeSpec_TypeParams: info[*ast.TypeSpec]("TypeParams"), + TypeSwitchStmt_Assign: info[*ast.TypeSwitchStmt]("Assign"), + TypeSwitchStmt_Body: info[*ast.TypeSwitchStmt]("Body"), + TypeSwitchStmt_Init: info[*ast.TypeSwitchStmt]("Init"), + UnaryExpr_X: info[*ast.UnaryExpr]("X"), + ValueSpec_Comment: info[*ast.ValueSpec]("Comment"), + ValueSpec_Doc: info[*ast.ValueSpec]("Doc"), + ValueSpec_Names: info[*ast.ValueSpec]("Names"), + ValueSpec_Type: info[*ast.ValueSpec]("Type"), + ValueSpec_Values: info[*ast.ValueSpec]("Values"), +} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go new file mode 100644 index 0000000..1c48225 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go @@ -0,0 +1,592 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package inspector + +import ( + "fmt" + "go/ast" + "go/token" + "iter" + "reflect" + "strings" + + "golang.org/x/tools/go/ast/edge" +) + +// A Cursor represents an [ast.Node]. It is immutable. +// +// Two Cursors compare equal if they represent the same node. +// +// The zero value of Cursor is not valid. +// +// Call [Inspector.Root] to obtain a cursor for the virtual root node +// of the traversal. This is the sole valid cursor for which [Cursor.Node] +// returns nil. +// +// Use the following methods to navigate efficiently around the tree: +// - for ancestors, use [Cursor.Parent] and [Cursor.Enclosing]; +// - for children, use [Cursor.Child], [Cursor.Children], +// [Cursor.FirstChild], and [Cursor.LastChild]; +// - for siblings, use [Cursor.PrevSibling] and [Cursor.NextSibling]; +// - for descendants, use [Cursor.FindByPos], [Cursor.FindNode], +// [Cursor.Inspect], and [Cursor.Preorder]. +// +// Use the [Cursor.ChildAt] and [Cursor.ParentEdge] methods for +// information about the edges in a tree: which field (and slice +// element) of the parent node holds the child. +type Cursor struct { + in *Inspector + index int32 // index of push node; -1 for virtual root node +} + +// Root returns a valid cursor for the virtual root node, +// whose children are the files provided to [New]. +// +// Its [Cursor.Node] method return nil. +func (in *Inspector) Root() Cursor { + return Cursor{in, -1} +} + +// At returns the cursor at the specified index in the traversal, +// which must have been obtained from [Cursor.Index] on a Cursor +// belonging to the same Inspector (see [Cursor.Inspector]). +func (in *Inspector) At(index int32) Cursor { + if index < 0 { + panic("negative index") + } + if int(index) >= len(in.events) { + panic("index out of range for this inspector") + } + if in.events[index].index < index { + panic("invalid index") // (a push, not a pop) + } + return Cursor{in, index} +} + +// Valid reports whether the cursor is valid. +// The zero value of cursor is invalid. +// Unless otherwise documented, it is not safe to call +// any other method on an invalid cursor. +func (c Cursor) Valid() bool { + return c.in != nil +} + +// Inspector returns the cursor's Inspector. +// It returns nil if the Cursor is not valid. +func (c Cursor) Inspector() *Inspector { return c.in } + +// Index returns the index of this cursor position within the package. +// +// Clients should not assume anything about the numeric Index value +// except that it increases monotonically throughout the traversal. +// It is provided for use with [Inspector.At]. +// +// Index must not be called on the Root node. +func (c Cursor) Index() int32 { + if c.index < 0 { + panic("Index called on Root node") + } + return c.index +} + +// Node returns the node at the current cursor position, +// or nil for the cursor returned by [Inspector.Root]. +func (c Cursor) Node() ast.Node { + if c.index < 0 { + return nil + } + return c.in.events[c.index].node +} + +// String returns information about the cursor's node, if any. +func (c Cursor) String() string { + if !c.Valid() { + return "(invalid)" + } + if c.index < 0 { + return "(root)" + } + return reflect.TypeOf(c.Node()).String() +} + +// GoString returns a string describing the cursor's path from the +// root, if any. +func (c Cursor) GoString() string { + if !c.Valid() { + return "(invalid)" + } + if c.index < 0 { + return "(root)" + } + // e.g "File.Decls[1].(*ast.GenDecl).Specs[0].(*ast.TypeSpec)" + // + // In hindsight even the File node should have reported a + // virtual ParentEdge of (Root_Files, i) where i is the index + // among the files passed to NewInspector. Then the path would + // read "(root).Files[i]", etc; but we missed the boat. + var buf strings.Builder + buf.WriteString("File") + var visit func(Cursor) + visit = func(c Cursor) { + ek, idx := c.ParentEdge() + if ek == edge.Invalid { + return // File + } + visit(c.Parent()) + fmt.Fprintf(&buf, ".%s", ek.FieldName()) + if idx >= 0 { + fmt.Fprintf(&buf, "[%d]", idx) + } + ftype := ek.FieldType() + if idx >= 0 { + ftype = ftype.Elem() // []T -> T + } + if ftype.Kind() == reflect.Interface { + fmt.Fprintf(&buf, ".(%T)", c.Node()) + } + } + visit(c) + return buf.String() +} + +// indices return the [start, end) half-open interval of event indices. +func (c Cursor) indices() (int32, int32) { + if c.index < 0 { + return 0, int32(len(c.in.events)) // root: all events + } else { + return c.index, c.in.events[c.index].index + 1 // just one subtree + } +} + +// Preorder returns an iterator over the nodes of the subtree +// represented by c in depth-first order. Each node in the sequence is +// represented by a Cursor that allows access to the Node, but may +// also be used to start a new traversal, or to obtain the stack of +// nodes enclosing the cursor. +// +// The traversal sequence is determined by [ast.Inspect]. The types +// argument, if non-empty, enables type-based filtering of events. The +// function f if is called only for nodes whose type matches an +// element of the types slice. +// +// If you need control over descent into subtrees, +// or need both pre- and post-order notifications, use [Cursor.Inspect] +func (c Cursor) Preorder(types ...ast.Node) iter.Seq[Cursor] { + mask := maskOf(types) + + return func(yield func(Cursor) bool) { + events := c.in.events + + for i, limit := c.indices(); i < limit; { + ev := events[i] + if ev.index > i { // push? + if ev.typ&mask != 0 && !yield(Cursor{c.in, i}) { + break + } + pop := ev.index + if events[pop].typ&mask == 0 { + // Subtree does not contain types: skip. + i = pop + 1 + continue + } + } + i++ + } + } +} + +// Inspect visits the nodes of the subtree represented by c in +// depth-first order. It calls f(n) for each node n before it +// visits n's children. If f returns true, Inspect invokes f +// recursively for each of the non-nil children of the node. +// +// Each node is represented by a Cursor that allows access to the +// Node, but may also be used to start a new traversal, or to obtain +// the stack of nodes enclosing the cursor. +// +// The complete traversal sequence is determined by [ast.Inspect]. +// The types argument, if non-empty, enables type-based filtering of +// events. The function f if is called only for nodes whose type +// matches an element of the types slice. +func (c Cursor) Inspect(types []ast.Node, f func(c Cursor) (descend bool)) { + mask := maskOf(types) + events := c.in.events + for i, limit := c.indices(); i < limit; { + ev := events[i] + if ev.index > i { + // push + pop := ev.index + if ev.typ&mask != 0 && !f(Cursor{c.in, i}) || + events[pop].typ&mask == 0 { + // The user opted not to descend, or the + // subtree does not contain types: + // skip past the pop. + i = pop + 1 + continue + } + } + i++ + } +} + +// Enclosing returns an iterator over the nodes enclosing the current +// current node, starting with the Cursor itself. +// +// Enclosing must not be called on the Root node (whose [Cursor.Node] returns nil). +// +// The types argument, if non-empty, enables type-based filtering of +// events: the sequence includes only enclosing nodes whose type +// matches an element of the types slice. +func (c Cursor) Enclosing(types ...ast.Node) iter.Seq[Cursor] { + if c.index < 0 { + panic("Cursor.Enclosing called on Root node") + } + + mask := maskOf(types) + + return func(yield func(Cursor) bool) { + events := c.in.events + for i := c.index; i >= 0; i = events[i].parent { + if events[i].typ&mask != 0 && !yield(Cursor{c.in, i}) { + break + } + } + } +} + +// Parent returns the parent of the current node. +// +// Parent must not be called on the Root node (whose [Cursor.Node] returns nil). +func (c Cursor) Parent() Cursor { + if c.index < 0 { + panic("Cursor.Parent called on Root node") + } + + return Cursor{c.in, c.in.events[c.index].parent} +} + +// ParentEdge returns the identity of the field in the parent node +// that holds this cursor's node, and if it is a list, the index within it. +// +// For example, f(x, y) is a CallExpr whose three children are Idents. +// f has edge kind [edge.CallExpr_Fun] and index -1. +// x and y have kind [edge.CallExpr_Args] and indices 0 and 1, respectively. +// +// If called on a child of the Root node, it returns ([edge.Invalid], -1). +// +// ParentEdge must not be called on the Root node (whose [Cursor.Node] returns nil). +func (c Cursor) ParentEdge() (edge.Kind, int) { + if c.index < 0 { + panic("Cursor.ParentEdge called on Root node") + } + events := c.in.events + pop := events[c.index].index + return unpackEdgeKindAndIndex(events[pop].parent) +} + +// ParentEdgeKind returns the kind component of the result of [Cursor.ParentEdge]. +func (c Cursor) ParentEdgeKind() edge.Kind { + ek, _ := c.ParentEdge() + return ek +} + +// ParentEdgeIndex returns the index component of the result of [Cursor.ParentEdge]. +func (c Cursor) ParentEdgeIndex() int { + _, index := c.ParentEdge() + return index +} + +// ChildAt returns the cursor for the child of the +// current node identified by its edge and index. +// The index must be -1 if the edge.Kind is not a slice. +// The indicated child node must exist. +// +// ChildAt must not be called on the Root node (whose [Cursor.Node] returns nil). +// +// Invariant: c.Parent().ChildAt(c.ParentEdge()) == c. +func (c Cursor) ChildAt(k edge.Kind, idx int) Cursor { + target := packEdgeKindAndIndex(k, idx) + + // Unfortunately there's no shortcut to looping. + events := c.in.events + i := c.index + 1 + for { + pop := events[i].index + if pop < i { + break + } + if events[pop].parent == target { + return Cursor{c.in, i} + } + i = pop + 1 + } + panic(fmt.Sprintf("ChildAt(%v, %d): no such child of %v", k, idx, c)) +} + +// Child returns the cursor for n, which must be a direct child of c's Node. +// +// Child must not be called on the Root node (whose [Cursor.Node] returns nil). +func (c Cursor) Child(n ast.Node) Cursor { + if c.index < 0 { + panic("Cursor.Child called on Root node") + } + + if false { + // reference implementation + for child := range c.Children() { + if child.Node() == n { + return child + } + } + + } else { + // optimized implementation + events := c.in.events + for i := c.index + 1; events[i].index > i; i = events[i].index + 1 { + if events[i].node == n { + return Cursor{c.in, i} + } + } + } + panic(fmt.Sprintf("Child(%T): not a child of %v", n, c)) +} + +// NextSibling returns the cursor for the next sibling node in the same list +// (for example, of files, decls, specs, statements, fields, or expressions) as +// the current node. It returns (zero, false) if the node is the last node in +// the list, or is not part of a list. +// +// NextSibling must not be called on the Root node. +// +// See note at [Cursor.Children]. +func (c Cursor) NextSibling() (Cursor, bool) { + if c.index < 0 { + panic("Cursor.NextSibling called on Root node") + } + + events := c.in.events + i := events[c.index].index + 1 // after corresponding pop + if i < int32(len(events)) { + if events[i].index > i { // push? + return Cursor{c.in, i}, true + } + } + return Cursor{}, false +} + +// PrevSibling returns the cursor for the previous sibling node in the +// same list (for example, of files, decls, specs, statements, fields, +// or expressions) as the current node. It returns zero if the node is +// the first node in the list, or is not part of a list. +// +// It must not be called on the Root node. +// +// See note at [Cursor.Children]. +func (c Cursor) PrevSibling() (Cursor, bool) { + if c.index < 0 { + panic("Cursor.PrevSibling called on Root node") + } + + events := c.in.events + i := c.index - 1 + if i >= 0 { + if j := events[i].index; j < i { // pop? + return Cursor{c.in, j}, true + } + } + return Cursor{}, false +} + +// FirstChild returns the first direct child of the current node, +// or zero if it has no children. +func (c Cursor) FirstChild() (Cursor, bool) { + events := c.in.events + i := c.index + 1 // i=0 if c is root + if i < int32(len(events)) && events[i].index > i { // push? + return Cursor{c.in, i}, true + } + return Cursor{}, false +} + +// LastChild returns the last direct child of the current node, +// or zero if it has no children. +func (c Cursor) LastChild() (Cursor, bool) { + events := c.in.events + if c.index < 0 { // root? + if len(events) > 0 { + // return push of final event (a pop) + return Cursor{c.in, events[len(events)-1].index}, true + } + } else { + j := events[c.index].index - 1 // before corresponding pop + // Inv: j == c.index if c has no children + // or j is last child's pop. + if j > c.index { // c has children + return Cursor{c.in, events[j].index}, true + } + } + return Cursor{}, false +} + +// Children returns an iterator over the direct children of the +// current node, if any. +// +// When using Children, NextChild, and PrevChild, bear in mind that a +// Node's children may come from different fields, some of which may +// be lists of nodes without a distinguished intervening container +// such as [ast.BlockStmt]. +// +// For example, [ast.CaseClause] has a field List of expressions and a +// field Body of statements, so the children of a CaseClause are a mix +// of expressions and statements. Other nodes that have "uncontained" +// list fields include: +// +// - [ast.ValueSpec] (Names, Values) +// - [ast.CompositeLit] (Type, Elts) +// - [ast.IndexListExpr] (X, Indices) +// - [ast.CallExpr] (Fun, Args) +// - [ast.AssignStmt] (Lhs, Rhs) +// +// So, do not assume that the previous sibling of an ast.Stmt is also +// an ast.Stmt, or if it is, that they are executed sequentially, +// unless you have established that, say, its parent is a BlockStmt +// or its [Cursor.ParentEdge] is [edge.BlockStmt_List]. +// For example, given "for S1; ; S2 {}", the predecessor of S2 is S1, +// even though they are not executed in sequence. +func (c Cursor) Children() iter.Seq[Cursor] { + return func(yield func(Cursor) bool) { + c, ok := c.FirstChild() + for ok && yield(c) { + c, ok = c.NextSibling() + } + } +} + +// Contains reports whether c contains or is equal to c2. +// +// Both Cursors must belong to the same [Inspector]; +// neither may be its Root node. +func (c Cursor) Contains(c2 Cursor) bool { + if c.in != c2.in { + panic("different inspectors") + } + events := c.in.events + return c.index <= c2.index && events[c2.index].index <= events[c.index].index +} + +// FindNode returns the cursor for node n if it belongs to the subtree +// rooted at c. It returns zero if n is not found. +func (c Cursor) FindNode(n ast.Node) (Cursor, bool) { + + // FindNode is equivalent to this code, + // but more convenient and 15-20% faster: + if false { + for candidate := range c.Preorder(n) { + if candidate.Node() == n { + return candidate, true + } + } + return Cursor{}, false + } + + // TODO(adonovan): opt: should we assume Node.Pos is accurate + // and combine type-based filtering with position filtering + // like FindByPos? + + mask := maskOf([]ast.Node{n}) + events := c.in.events + + for i, limit := c.indices(); i < limit; i++ { + ev := events[i] + if ev.index > i { // push? + if ev.typ&mask != 0 && ev.node == n { + return Cursor{c.in, i}, true + } + pop := ev.index + if events[pop].typ&mask == 0 { + // Subtree does not contain type of n: skip. + i = pop + } + } + } + return Cursor{}, false +} + +// FindByPos returns the cursor for the innermost node n in the tree +// rooted at c such that n.Pos() <= start && end <= n.End(). +// (For an *ast.File, it uses the bounds n.FileStart-n.FileEnd.) +// +// An empty range (start == end) between two adjacent nodes is +// considered to belong to the first node. +// +// It returns zero if none is found. +// Precondition: start <= end. +// +// See also [astutil.PathEnclosingInterval], which +// tolerates adjoining whitespace. +func (c Cursor) FindByPos(start, end token.Pos) (Cursor, bool) { + if end < start { + panic("end < start") + } + events := c.in.events + + // This algorithm could be implemented using c.Inspect, + // but it is about 2.5x slower. + + // best is the push-index of the latest (=innermost) node containing range. + // (Beware: latest is not always innermost because FuncDecl.{Name,Type} overlap.) + best := int32(-1) + for i, limit := c.indices(); i < limit; i++ { + ev := events[i] + if ev.index > i { // push? + n := ev.node + var nodeEnd token.Pos + if file, ok := n.(*ast.File); ok { + nodeEnd = file.FileEnd + // Note: files may be out of Pos order. + if file.FileStart > start { + i = ev.index // disjoint, after; skip to next file + continue + } + } else { + // Edge case: FuncDecl.Name and .Type overlap: + // Don't update best from Name to FuncDecl.Type. + // + // The condition can be read as: + // - n is FuncType + // - n.parent is FuncDecl + // - best is strictly beneath the FuncDecl + if ev.typ == 1< ev.parent { + continue + } + + nodeEnd = n.End() + if n.Pos() > start { + break // disjoint, after; stop + } + } + + // Inv: node.{Pos,FileStart} <= start + if end <= nodeEnd { + // node fully contains target range + best = i + + // Don't search beyond end of the first match. + // This is important only for an empty range (start=end) + // between two adjoining nodes, which would otherwise + // match both nodes; we want to match only the first. + limit = ev.index + } else if nodeEnd < start { + i = ev.index // disjoint, before; skip forward + } + } + } + if best >= 0 { + return Cursor{c.in, best}, true + } + return Cursor{}, false +} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/inspector.go b/vendor/golang.org/x/tools/go/ast/inspector/inspector.go new file mode 100644 index 0000000..b414d17 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/inspector/inspector.go @@ -0,0 +1,311 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package inspector provides helper functions for traversal over the +// syntax trees of a package, including node filtering by type, and +// materialization of the traversal stack. +// +// During construction, the inspector does a complete traversal and +// builds a list of push/pop events and their node type. Subsequent +// method calls that request a traversal scan this list, rather than walk +// the AST, and perform type filtering using efficient bit sets. +// This representation is sometimes called a "balanced parenthesis tree." +// +// Experiments suggest the inspector's traversals are about 2.5x faster +// than [ast.Inspect], but it may take around 5 traversals for this +// benefit to amortize the inspector's construction cost. +// If efficiency is the primary concern, do not use Inspector for +// one-off traversals. +// +// The [Cursor] type provides a more flexible API for efficient +// navigation of syntax trees in all four "cardinal directions". For +// example, traversals may be nested, so you can find each node of +// type A and then search within it for nodes of type B. Or you can +// traverse from a node to its immediate neighbors: its parent, its +// previous and next sibling, or its first and last child. We +// recommend using methods of Cursor in preference to Inspector where +// possible. +package inspector + +// There are four orthogonal features in a traversal: +// 1 type filtering +// 2 pruning +// 3 postorder calls to f +// 4 stack +// Rather than offer all of them in the API, +// only a few combinations are exposed: +// - Preorder is the fastest and has fewest features, +// but is the most commonly needed traversal. +// - Nodes and WithStack both provide pruning and postorder calls, +// even though few clients need it, because supporting two versions +// is not justified. +// More combinations could be supported by expressing them as +// wrappers around a more generic traversal, but this was measured +// and found to degrade performance significantly (30%). + +import ( + "go/ast" + + "golang.org/x/tools/go/ast/edge" +) + +// An Inspector provides methods for inspecting +// (traversing) the syntax trees of a package. +type Inspector struct { + events []event +} + +func packEdgeKindAndIndex(ek edge.Kind, index int) int32 { + return int32(uint32(index+1)<<7 | uint32(ek)) +} + +// unpackEdgeKindAndIndex unpacks the edge kind and edge index (within +// an []ast.Node slice) from the parent field of a pop event. +func unpackEdgeKindAndIndex(x int32) (edge.Kind, int) { + // The "parent" field of a pop node holds the + // edge Kind in the lower 7 bits and the index+1 + // in the upper 25. + return edge.Kind(x & 0x7f), int(x>>7) - 1 +} + +// New returns an Inspector for the specified syntax trees. +func New(files []*ast.File) *Inspector { + return &Inspector{traverse(files)} +} + +// An event represents a push or a pop +// of an ast.Node during a traversal. +type event struct { + node ast.Node + typ uint64 // typeOf(node) on push event, or union of typ strictly between push and pop events on pop events + index int32 // index of corresponding push or pop event + parent int32 // index of parent's push node (push nodes only), or packed edge kind/index (pop nodes only) +} + +// TODO: Experiment with storing only the second word of event.node (unsafe.Pointer). +// Type can be recovered from the sole bit in typ. +// [Tried this, wasn't faster. --adonovan] + +// Preorder visits all the nodes of the files supplied to [New] in +// depth-first order. It calls f(n) for each node n before it visits +// n's children. +// +// The complete traversal sequence is determined by [ast.Inspect]. +// The types argument, if non-empty, enables type-based filtering of +// events. The function f is called only for nodes whose type +// matches an element of the types slice. +// +// The [Cursor.Preorder] method provides a richer alternative interface. +// Example: +// +// for c := range in.Root().Preorder(types) { ... } +func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) { + // Because it avoids postorder calls to f, and the pruning + // check, Preorder is almost twice as fast as Nodes. The two + // features seem to contribute similar slowdowns (~1.4x each). + + // This function is equivalent to the PreorderSeq call below, + // but to avoid the additional dynamic call (which adds 13-35% + // to the benchmarks), we expand it out. + // + // in.PreorderSeq(types...)(func(n ast.Node) bool { + // f(n) + // return true + // }) + + mask := maskOf(types) + for i := int32(0); i < int32(len(in.events)); { + ev := in.events[i] + if ev.index > i { + // push + if ev.typ&mask != 0 { + f(ev.node) + } + pop := ev.index + if in.events[pop].typ&mask == 0 { + // Subtrees do not contain types: skip them and pop. + i = pop + 1 + continue + } + } + i++ + } +} + +// Nodes visits the nodes of the files supplied to [New] in depth-first +// order. It calls f(n, true) for each node n before it visits n's +// children. If f returns true, Nodes invokes f recursively for each +// of the non-nil children of the node, followed by a call of +// f(n, false). +// +// The complete traversal sequence is determined by [ast.Inspect]. +// The types argument, if non-empty, enables type-based filtering of +// events. The function f if is called only for nodes whose type +// matches an element of the types slice. +// +// The [Cursor.Inspect] method provides a richer alternative interface. +// Example: +// +// in.Root().Inspect(types, func(c Cursor) bool { +// ... +// return true +// } +func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proceed bool)) { + mask := maskOf(types) + for i := int32(0); i < int32(len(in.events)); { + ev := in.events[i] + if ev.index > i { + // push + pop := ev.index + if ev.typ&mask != 0 { + if !f(ev.node, true) { + i = pop + 1 // jump to corresponding pop + 1 + continue + } + } + if in.events[pop].typ&mask == 0 { + // Subtrees do not contain types: skip them. + i = pop + continue + } + } else { + // pop + push := ev.index + if in.events[push].typ&mask != 0 { + f(ev.node, false) + } + } + i++ + } +} + +// WithStack visits nodes in a similar manner to Nodes, but it +// supplies each call to f an additional argument, the current +// traversal stack. The stack's first element is the outermost node, +// an *ast.File; its last is the innermost, n. +// +// The [Cursor.Inspect] method provides a richer alternative interface. +// Example: +// +// in.Root().Inspect(types, func(c Cursor) bool { +// stack := slices.Collect(c.Enclosing()) +// ... +// return true +// }) +func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (proceed bool)) { + mask := maskOf(types) + var stack []ast.Node + for i := int32(0); i < int32(len(in.events)); { + ev := in.events[i] + if ev.index > i { + // push + pop := ev.index + stack = append(stack, ev.node) + if ev.typ&mask != 0 { + if !f(ev.node, true, stack) { + i = pop + 1 + stack = stack[:len(stack)-1] + continue + } + } + if in.events[pop].typ&mask == 0 { + // Subtrees does not contain types: skip them. + i = pop + continue + } + } else { + // pop + push := ev.index + if in.events[push].typ&mask != 0 { + f(ev.node, false, stack) + } + stack = stack[:len(stack)-1] + } + i++ + } +} + +// traverse builds the table of events representing a traversal. +func traverse(files []*ast.File) []event { + // Preallocate approximate number of events + // based on source file extent of the declarations. + // (We use End-Pos not FileStart-FileEnd to neglect + // the effect of long doc comments.) + // This makes traverse faster by 4x (!). + var extent int + for _, f := range files { + extent += int(f.End() - f.Pos()) + } + // This estimate is based on the net/http package. + capacity := min(extent*33/100, 1e6) // impose some reasonable maximum (1M) + + v := &visitor{ + events: make([]event, 0, capacity), + stack: []item{{index: -1}}, // include an extra event so file nodes have a parent + } + for _, file := range files { + walk(v, edge.Invalid, -1, file) + } + return v.events +} + +type visitor struct { + events []event + stack []item +} + +type item struct { + index int32 // index of current node's push event + parentIndex int32 // index of parent node's push event + typAccum uint64 // accumulated type bits of current node's descendants + edgeKindAndIndex int32 // edge.Kind and index, bit packed +} + +func (v *visitor) push(ek edge.Kind, eindex int, node ast.Node) { + var ( + index = int32(len(v.events)) + parentIndex = v.stack[len(v.stack)-1].index + ) + v.events = append(v.events, event{ + node: node, + parent: parentIndex, + typ: typeOf(node), + index: 0, // (pop index is set later by visitor.pop) + }) + v.stack = append(v.stack, item{ + index: index, + parentIndex: parentIndex, + edgeKindAndIndex: packEdgeKindAndIndex(ek, eindex), + }) + + // 2B nodes ought to be enough for anyone! + if int32(len(v.events)) < 0 { + panic("event index exceeded int32") + } + + // 32M elements in an []ast.Node ought to be enough for anyone! + if ek2, eindex2 := unpackEdgeKindAndIndex(packEdgeKindAndIndex(ek, eindex)); ek2 != ek || eindex2 != eindex { + panic("Node slice index exceeded uint25") + } +} + +func (v *visitor) pop(node ast.Node) { + top := len(v.stack) - 1 + current := v.stack[top] + + push := &v.events[current.index] + parent := &v.stack[top-1] + + push.index = int32(len(v.events)) // make push event refer to pop + parent.typAccum |= current.typAccum | push.typ // accumulate type bits into parent + + v.stack = v.stack[:top] + + v.events = append(v.events, event{ + node: node, + typ: current.typAccum, + index: current.index, + parent: current.edgeKindAndIndex, // see [unpackEdgeKindAndIndex] + }) +} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/iter.go b/vendor/golang.org/x/tools/go/ast/inspector/iter.go new file mode 100644 index 0000000..b68c553 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/inspector/iter.go @@ -0,0 +1,113 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.23 + +package inspector + +import ( + "go/ast" + "iter" +) + +// PreorderSeq returns an iterator that visits all the +// nodes of the files supplied to [New] in depth-first order. +// It visits each node n before n's children. +// The complete traversal sequence is determined by ast.Inspect. +// +// The types argument, if non-empty, enables type-based filtering: +// only nodes whose type matches an element of the types slice are +// included in the sequence. +// +// Example: +// +// for call := range in.PreorderSeq((*ast.CallExpr)(nil)) { ... } +// +// The [All] function is more convenient if there is exactly one node type: +// +// for call := range All[*ast.CallExpr](in) { ... } +// +// See also the newer and more flexible [Cursor] API, which lets you +// start the traversal at an arbitrary node, and reports each matching +// node by its Cursor, enabling easier navigation. +// The above example would be written thus: +// +// for curCall := range in.Root().Preorder((*ast.CallExpr)(nil)) { +// call := curCall.Node().(*ast.CallExpr) +// ... +// } +func (in *Inspector) PreorderSeq(types ...ast.Node) iter.Seq[ast.Node] { + + // This implementation is identical to Preorder, + // except that it supports breaking out of the loop. + + return func(yield func(ast.Node) bool) { + mask := maskOf(types) + for i := int32(0); i < int32(len(in.events)); { + ev := in.events[i] + if ev.index > i { + // push + if ev.typ&mask != 0 { + if !yield(ev.node) { + break + } + } + pop := ev.index + if in.events[pop].typ&mask == 0 { + // Subtrees do not contain types: skip them and pop. + i = pop + 1 + continue + } + } + i++ + } + } +} + +// All[N] returns an iterator over all the nodes of type N. +// N must be a pointer-to-struct type that implements ast.Node. +// +// Example: +// +// for call := range All[*ast.CallExpr](in) { ... } +// +// See also the newer and more flexible [Cursor] API, which lets you +// start the traversal at an arbitrary node, and reports each matching +// node by its Cursor, enabling easier navigation. +// The above example would be written thus: +// +// for curCall := range in.Root().Preorder((*ast.CallExpr)(nil)) { +// call := curCall.Node().(*ast.CallExpr) +// ... +// } +func All[N interface { + *S + ast.Node +}, S any](in *Inspector) iter.Seq[N] { + + // To avoid additional dynamic call overheads, + // we duplicate rather than call the logic of PreorderSeq. + + mask := typeOf((N)(nil)) + return func(yield func(N) bool) { + for i := int32(0); i < int32(len(in.events)); { + ev := in.events[i] + if ev.index > i { + // push + if ev.typ&mask != 0 { + if !yield(ev.node.(N)) { + break + } + } + pop := ev.index + if in.events[pop].typ&mask == 0 { + // Subtrees do not contain types: skip them and pop. + i = pop + 1 + continue + } + } + i++ + } + } +} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/typeof.go b/vendor/golang.org/x/tools/go/ast/inspector/typeof.go new file mode 100644 index 0000000..9852331 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/inspector/typeof.go @@ -0,0 +1,227 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package inspector + +// This file defines func typeOf(ast.Node) uint64. +// +// The initial map-based implementation was too slow; +// see https://go-review.googlesource.com/c/tools/+/135655/1/go/ast/inspector/inspector.go#196 + +import ( + "go/ast" + "math" +) + +const ( + nArrayType = iota + nAssignStmt + nBadDecl + nBadExpr + nBadStmt + nBasicLit + nBinaryExpr + nBlockStmt + nBranchStmt + nCallExpr + nCaseClause + nChanType + nCommClause + nComment + nCommentGroup + nCompositeLit + nDeclStmt + nDeferStmt + nEllipsis + nEmptyStmt + nExprStmt + nField + nFieldList + nFile + nForStmt + nFuncDecl + nFuncLit + nFuncType + nGenDecl + nGoStmt + nIdent + nIfStmt + nImportSpec + nIncDecStmt + nIndexExpr + nIndexListExpr + nInterfaceType + nKeyValueExpr + nLabeledStmt + nMapType + nPackage + nParenExpr + nRangeStmt + nReturnStmt + nSelectStmt + nSelectorExpr + nSendStmt + nSliceExpr + nStarExpr + nStructType + nSwitchStmt + nTypeAssertExpr + nTypeSpec + nTypeSwitchStmt + nUnaryExpr + nValueSpec +) + +// typeOf returns a distinct single-bit value that represents the type of n. +// +// Various implementations were benchmarked with BenchmarkNewInspector: +// +// GOGC=off +// - type switch 4.9-5.5ms 2.1ms +// - binary search over a sorted list of types 5.5-5.9ms 2.5ms +// - linear scan, frequency-ordered list 5.9-6.1ms 2.7ms +// - linear scan, unordered list 6.4ms 2.7ms +// - hash table 6.5ms 3.1ms +// +// A perfect hash seemed like overkill. +// +// The compiler's switch statement is the clear winner +// as it produces a binary tree in code, +// with constant conditions and good branch prediction. +// (Sadly it is the most verbose in source code.) +// Binary search suffered from poor branch prediction. +func typeOf(n ast.Node) uint64 { + // Fast path: nearly half of all nodes are identifiers. + if _, ok := n.(*ast.Ident); ok { + return 1 << nIdent + } + + // These cases include all nodes encountered by ast.Inspect. + switch n.(type) { + case *ast.ArrayType: + return 1 << nArrayType + case *ast.AssignStmt: + return 1 << nAssignStmt + case *ast.BadDecl: + return 1 << nBadDecl + case *ast.BadExpr: + return 1 << nBadExpr + case *ast.BadStmt: + return 1 << nBadStmt + case *ast.BasicLit: + return 1 << nBasicLit + case *ast.BinaryExpr: + return 1 << nBinaryExpr + case *ast.BlockStmt: + return 1 << nBlockStmt + case *ast.BranchStmt: + return 1 << nBranchStmt + case *ast.CallExpr: + return 1 << nCallExpr + case *ast.CaseClause: + return 1 << nCaseClause + case *ast.ChanType: + return 1 << nChanType + case *ast.CommClause: + return 1 << nCommClause + case *ast.Comment: + return 1 << nComment + case *ast.CommentGroup: + return 1 << nCommentGroup + case *ast.CompositeLit: + return 1 << nCompositeLit + case *ast.DeclStmt: + return 1 << nDeclStmt + case *ast.DeferStmt: + return 1 << nDeferStmt + case *ast.Ellipsis: + return 1 << nEllipsis + case *ast.EmptyStmt: + return 1 << nEmptyStmt + case *ast.ExprStmt: + return 1 << nExprStmt + case *ast.Field: + return 1 << nField + case *ast.FieldList: + return 1 << nFieldList + case *ast.File: + return 1 << nFile + case *ast.ForStmt: + return 1 << nForStmt + case *ast.FuncDecl: + return 1 << nFuncDecl + case *ast.FuncLit: + return 1 << nFuncLit + case *ast.FuncType: + return 1 << nFuncType + case *ast.GenDecl: + return 1 << nGenDecl + case *ast.GoStmt: + return 1 << nGoStmt + case *ast.Ident: + return 1 << nIdent + case *ast.IfStmt: + return 1 << nIfStmt + case *ast.ImportSpec: + return 1 << nImportSpec + case *ast.IncDecStmt: + return 1 << nIncDecStmt + case *ast.IndexExpr: + return 1 << nIndexExpr + case *ast.IndexListExpr: + return 1 << nIndexListExpr + case *ast.InterfaceType: + return 1 << nInterfaceType + case *ast.KeyValueExpr: + return 1 << nKeyValueExpr + case *ast.LabeledStmt: + return 1 << nLabeledStmt + case *ast.MapType: + return 1 << nMapType + case *ast.Package: + return 1 << nPackage + case *ast.ParenExpr: + return 1 << nParenExpr + case *ast.RangeStmt: + return 1 << nRangeStmt + case *ast.ReturnStmt: + return 1 << nReturnStmt + case *ast.SelectStmt: + return 1 << nSelectStmt + case *ast.SelectorExpr: + return 1 << nSelectorExpr + case *ast.SendStmt: + return 1 << nSendStmt + case *ast.SliceExpr: + return 1 << nSliceExpr + case *ast.StarExpr: + return 1 << nStarExpr + case *ast.StructType: + return 1 << nStructType + case *ast.SwitchStmt: + return 1 << nSwitchStmt + case *ast.TypeAssertExpr: + return 1 << nTypeAssertExpr + case *ast.TypeSpec: + return 1 << nTypeSpec + case *ast.TypeSwitchStmt: + return 1 << nTypeSwitchStmt + case *ast.UnaryExpr: + return 1 << nUnaryExpr + case *ast.ValueSpec: + return 1 << nValueSpec + } + return 0 +} + +func maskOf(nodes []ast.Node) uint64 { + if len(nodes) == 0 { + return math.MaxUint64 // match all node types + } + var mask uint64 + for _, n := range nodes { + mask |= typeOf(n) + } + return mask +} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/walk.go b/vendor/golang.org/x/tools/go/ast/inspector/walk.go new file mode 100644 index 0000000..5f1c93c --- /dev/null +++ b/vendor/golang.org/x/tools/go/ast/inspector/walk.go @@ -0,0 +1,341 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package inspector + +// This file is a fork of ast.Inspect to reduce unnecessary dynamic +// calls and to gather edge information. +// +// Consistency with the original is ensured by TestInspectAllNodes. + +import ( + "fmt" + "go/ast" + + "golang.org/x/tools/go/ast/edge" +) + +func walkList[N ast.Node](v *visitor, ek edge.Kind, list []N) { + for i, node := range list { + walk(v, ek, i, node) + } +} + +func walk(v *visitor, ek edge.Kind, index int, node ast.Node) { + v.push(ek, index, node) + + // walk children + // (the order of the cases matches the order + // of the corresponding node types in ast.go) + switch n := node.(type) { + // Comments and fields + case *ast.Comment: + // nothing to do + + case *ast.CommentGroup: + walkList(v, edge.CommentGroup_List, n.List) + + case *ast.Field: + if n.Doc != nil { + walk(v, edge.Field_Doc, -1, n.Doc) + } + walkList(v, edge.Field_Names, n.Names) + if n.Type != nil { + walk(v, edge.Field_Type, -1, n.Type) + } + if n.Tag != nil { + walk(v, edge.Field_Tag, -1, n.Tag) + } + if n.Comment != nil { + walk(v, edge.Field_Comment, -1, n.Comment) + } + + case *ast.FieldList: + walkList(v, edge.FieldList_List, n.List) + + // Expressions + case *ast.BadExpr, *ast.Ident, *ast.BasicLit: + // nothing to do + + case *ast.Ellipsis: + if n.Elt != nil { + walk(v, edge.Ellipsis_Elt, -1, n.Elt) + } + + case *ast.FuncLit: + walk(v, edge.FuncLit_Type, -1, n.Type) + walk(v, edge.FuncLit_Body, -1, n.Body) + + case *ast.CompositeLit: + if n.Type != nil { + walk(v, edge.CompositeLit_Type, -1, n.Type) + } + walkList(v, edge.CompositeLit_Elts, n.Elts) + + case *ast.ParenExpr: + walk(v, edge.ParenExpr_X, -1, n.X) + + case *ast.SelectorExpr: + walk(v, edge.SelectorExpr_X, -1, n.X) + walk(v, edge.SelectorExpr_Sel, -1, n.Sel) + + case *ast.IndexExpr: + walk(v, edge.IndexExpr_X, -1, n.X) + walk(v, edge.IndexExpr_Index, -1, n.Index) + + case *ast.IndexListExpr: + walk(v, edge.IndexListExpr_X, -1, n.X) + walkList(v, edge.IndexListExpr_Indices, n.Indices) + + case *ast.SliceExpr: + walk(v, edge.SliceExpr_X, -1, n.X) + if n.Low != nil { + walk(v, edge.SliceExpr_Low, -1, n.Low) + } + if n.High != nil { + walk(v, edge.SliceExpr_High, -1, n.High) + } + if n.Max != nil { + walk(v, edge.SliceExpr_Max, -1, n.Max) + } + + case *ast.TypeAssertExpr: + walk(v, edge.TypeAssertExpr_X, -1, n.X) + if n.Type != nil { + walk(v, edge.TypeAssertExpr_Type, -1, n.Type) + } + + case *ast.CallExpr: + walk(v, edge.CallExpr_Fun, -1, n.Fun) + walkList(v, edge.CallExpr_Args, n.Args) + + case *ast.StarExpr: + walk(v, edge.StarExpr_X, -1, n.X) + + case *ast.UnaryExpr: + walk(v, edge.UnaryExpr_X, -1, n.X) + + case *ast.BinaryExpr: + walk(v, edge.BinaryExpr_X, -1, n.X) + walk(v, edge.BinaryExpr_Y, -1, n.Y) + + case *ast.KeyValueExpr: + walk(v, edge.KeyValueExpr_Key, -1, n.Key) + walk(v, edge.KeyValueExpr_Value, -1, n.Value) + + // Types + case *ast.ArrayType: + if n.Len != nil { + walk(v, edge.ArrayType_Len, -1, n.Len) + } + walk(v, edge.ArrayType_Elt, -1, n.Elt) + + case *ast.StructType: + walk(v, edge.StructType_Fields, -1, n.Fields) + + case *ast.FuncType: + if n.TypeParams != nil { + walk(v, edge.FuncType_TypeParams, -1, n.TypeParams) + } + if n.Params != nil { + walk(v, edge.FuncType_Params, -1, n.Params) + } + if n.Results != nil { + walk(v, edge.FuncType_Results, -1, n.Results) + } + + case *ast.InterfaceType: + walk(v, edge.InterfaceType_Methods, -1, n.Methods) + + case *ast.MapType: + walk(v, edge.MapType_Key, -1, n.Key) + walk(v, edge.MapType_Value, -1, n.Value) + + case *ast.ChanType: + walk(v, edge.ChanType_Value, -1, n.Value) + + // Statements + case *ast.BadStmt: + // nothing to do + + case *ast.DeclStmt: + walk(v, edge.DeclStmt_Decl, -1, n.Decl) + + case *ast.EmptyStmt: + // nothing to do + + case *ast.LabeledStmt: + walk(v, edge.LabeledStmt_Label, -1, n.Label) + walk(v, edge.LabeledStmt_Stmt, -1, n.Stmt) + + case *ast.ExprStmt: + walk(v, edge.ExprStmt_X, -1, n.X) + + case *ast.SendStmt: + walk(v, edge.SendStmt_Chan, -1, n.Chan) + walk(v, edge.SendStmt_Value, -1, n.Value) + + case *ast.IncDecStmt: + walk(v, edge.IncDecStmt_X, -1, n.X) + + case *ast.AssignStmt: + walkList(v, edge.AssignStmt_Lhs, n.Lhs) + walkList(v, edge.AssignStmt_Rhs, n.Rhs) + + case *ast.GoStmt: + walk(v, edge.GoStmt_Call, -1, n.Call) + + case *ast.DeferStmt: + walk(v, edge.DeferStmt_Call, -1, n.Call) + + case *ast.ReturnStmt: + walkList(v, edge.ReturnStmt_Results, n.Results) + + case *ast.BranchStmt: + if n.Label != nil { + walk(v, edge.BranchStmt_Label, -1, n.Label) + } + + case *ast.BlockStmt: + walkList(v, edge.BlockStmt_List, n.List) + + case *ast.IfStmt: + if n.Init != nil { + walk(v, edge.IfStmt_Init, -1, n.Init) + } + walk(v, edge.IfStmt_Cond, -1, n.Cond) + walk(v, edge.IfStmt_Body, -1, n.Body) + if n.Else != nil { + walk(v, edge.IfStmt_Else, -1, n.Else) + } + + case *ast.CaseClause: + walkList(v, edge.CaseClause_List, n.List) + walkList(v, edge.CaseClause_Body, n.Body) + + case *ast.SwitchStmt: + if n.Init != nil { + walk(v, edge.SwitchStmt_Init, -1, n.Init) + } + if n.Tag != nil { + walk(v, edge.SwitchStmt_Tag, -1, n.Tag) + } + walk(v, edge.SwitchStmt_Body, -1, n.Body) + + case *ast.TypeSwitchStmt: + if n.Init != nil { + walk(v, edge.TypeSwitchStmt_Init, -1, n.Init) + } + walk(v, edge.TypeSwitchStmt_Assign, -1, n.Assign) + walk(v, edge.TypeSwitchStmt_Body, -1, n.Body) + + case *ast.CommClause: + if n.Comm != nil { + walk(v, edge.CommClause_Comm, -1, n.Comm) + } + walkList(v, edge.CommClause_Body, n.Body) + + case *ast.SelectStmt: + walk(v, edge.SelectStmt_Body, -1, n.Body) + + case *ast.ForStmt: + if n.Init != nil { + walk(v, edge.ForStmt_Init, -1, n.Init) + } + if n.Cond != nil { + walk(v, edge.ForStmt_Cond, -1, n.Cond) + } + if n.Post != nil { + walk(v, edge.ForStmt_Post, -1, n.Post) + } + walk(v, edge.ForStmt_Body, -1, n.Body) + + case *ast.RangeStmt: + if n.Key != nil { + walk(v, edge.RangeStmt_Key, -1, n.Key) + } + if n.Value != nil { + walk(v, edge.RangeStmt_Value, -1, n.Value) + } + walk(v, edge.RangeStmt_X, -1, n.X) + walk(v, edge.RangeStmt_Body, -1, n.Body) + + // Declarations + case *ast.ImportSpec: + if n.Doc != nil { + walk(v, edge.ImportSpec_Doc, -1, n.Doc) + } + if n.Name != nil { + walk(v, edge.ImportSpec_Name, -1, n.Name) + } + walk(v, edge.ImportSpec_Path, -1, n.Path) + if n.Comment != nil { + walk(v, edge.ImportSpec_Comment, -1, n.Comment) + } + + case *ast.ValueSpec: + if n.Doc != nil { + walk(v, edge.ValueSpec_Doc, -1, n.Doc) + } + walkList(v, edge.ValueSpec_Names, n.Names) + if n.Type != nil { + walk(v, edge.ValueSpec_Type, -1, n.Type) + } + walkList(v, edge.ValueSpec_Values, n.Values) + if n.Comment != nil { + walk(v, edge.ValueSpec_Comment, -1, n.Comment) + } + + case *ast.TypeSpec: + if n.Doc != nil { + walk(v, edge.TypeSpec_Doc, -1, n.Doc) + } + walk(v, edge.TypeSpec_Name, -1, n.Name) + if n.TypeParams != nil { + walk(v, edge.TypeSpec_TypeParams, -1, n.TypeParams) + } + walk(v, edge.TypeSpec_Type, -1, n.Type) + if n.Comment != nil { + walk(v, edge.TypeSpec_Comment, -1, n.Comment) + } + + case *ast.BadDecl: + // nothing to do + + case *ast.GenDecl: + if n.Doc != nil { + walk(v, edge.GenDecl_Doc, -1, n.Doc) + } + walkList(v, edge.GenDecl_Specs, n.Specs) + + case *ast.FuncDecl: + if n.Doc != nil { + walk(v, edge.FuncDecl_Doc, -1, n.Doc) + } + if n.Recv != nil { + walk(v, edge.FuncDecl_Recv, -1, n.Recv) + } + walk(v, edge.FuncDecl_Name, -1, n.Name) + walk(v, edge.FuncDecl_Type, -1, n.Type) + if n.Body != nil { + walk(v, edge.FuncDecl_Body, -1, n.Body) + } + + case *ast.File: + if n.Doc != nil { + walk(v, edge.File_Doc, -1, n.Doc) + } + walk(v, edge.File_Name, -1, n.Name) + walkList(v, edge.File_Decls, n.Decls) + // don't walk n.Comments - they have been + // visited already through the individual + // nodes + + default: + // (includes *ast.Package) + panic(fmt.Sprintf("Walk: unexpected node type %T", n)) + } + + v.pop(node) +} diff --git a/vendor/golang.org/x/tools/go/buildutil/allpackages.go b/vendor/golang.org/x/tools/go/buildutil/allpackages.go new file mode 100644 index 0000000..1a77435 --- /dev/null +++ b/vendor/golang.org/x/tools/go/buildutil/allpackages.go @@ -0,0 +1,189 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package buildutil provides utilities related to the go/build +// package in the standard library. +// +// All I/O is done via the build.Context file system interface, which must +// be concurrency-safe. +package buildutil // import "golang.org/x/tools/go/buildutil" + +import ( + "go/build" + "os" + "path/filepath" + "sort" + "strings" + "sync" +) + +// AllPackages returns the package path of each Go package in any source +// directory of the specified build context (e.g. $GOROOT or an element +// of $GOPATH). Errors are ignored. The results are sorted. +// All package paths are canonical, and thus may contain "/vendor/". +// +// The result may include import paths for directories that contain no +// *.go files, such as "archive" (in $GOROOT/src). +// +// All I/O is done via the build.Context file system interface, +// which must be concurrency-safe. +func AllPackages(ctxt *build.Context) []string { + var list []string + ForEachPackage(ctxt, func(pkg string, _ error) { + list = append(list, pkg) + }) + sort.Strings(list) + return list +} + +// ForEachPackage calls the found function with the package path of +// each Go package it finds in any source directory of the specified +// build context (e.g. $GOROOT or an element of $GOPATH). +// All package paths are canonical, and thus may contain "/vendor/". +// +// If the package directory exists but could not be read, the second +// argument to the found function provides the error. +// +// All I/O is done via the build.Context file system interface, +// which must be concurrency-safe. +func ForEachPackage(ctxt *build.Context, found func(importPath string, err error)) { + ch := make(chan item) + + var wg sync.WaitGroup + for _, root := range ctxt.SrcDirs() { + wg.Go(func() { + allPackages(ctxt, root, ch) + }) + } + go func() { + wg.Wait() + close(ch) + }() + + // All calls to found occur in the caller's goroutine. + for i := range ch { + found(i.importPath, i.err) + } +} + +type item struct { + importPath string + err error // (optional) +} + +// We use a process-wide counting semaphore to limit +// the number of parallel calls to ReadDir. +var ioLimit = make(chan bool, 20) + +func allPackages(ctxt *build.Context, root string, ch chan<- item) { + root = filepath.Clean(root) + string(os.PathSeparator) + + var wg sync.WaitGroup + + var walkDir func(dir string) + walkDir = func(dir string) { + // Avoid .foo, _foo, and testdata directory trees. + base := filepath.Base(dir) + if base == "" || base[0] == '.' || base[0] == '_' || base == "testdata" { + return + } + + pkg := filepath.ToSlash(strings.TrimPrefix(dir, root)) + + // Prune search if we encounter any of these import paths. + switch pkg { + case "builtin": + return + } + + ioLimit <- true + files, err := ReadDir(ctxt, dir) + <-ioLimit + if pkg != "" || err != nil { + ch <- item{pkg, err} + } + for _, fi := range files { + if fi.IsDir() { + wg.Go(func() { + walkDir(filepath.Join(dir, fi.Name())) + }) + } + } + } + + walkDir(root) + wg.Wait() +} + +// ExpandPatterns returns the set of packages matched by patterns, +// which may have the following forms: +// +// golang.org/x/tools/cmd/guru # a single package +// golang.org/x/tools/... # all packages beneath dir +// ... # the entire workspace. +// +// Order is significant: a pattern preceded by '-' removes matching +// packages from the set. For example, these patterns match all encoding +// packages except encoding/xml: +// +// encoding/... -encoding/xml +// +// A trailing slash in a pattern is ignored. (Path components of Go +// package names are separated by slash, not the platform's path separator.) +func ExpandPatterns(ctxt *build.Context, patterns []string) map[string]bool { + // TODO(adonovan): support other features of 'go list': + // - "std"/"cmd"/"all" meta-packages + // - "..." not at the end of a pattern + // - relative patterns using "./" or "../" prefix + + pkgs := make(map[string]bool) + doPkg := func(pkg string, neg bool) { + if neg { + delete(pkgs, pkg) + } else { + pkgs[pkg] = true + } + } + + // Scan entire workspace if wildcards are present. + // TODO(adonovan): opt: scan only the necessary subtrees of the workspace. + var all []string + for _, arg := range patterns { + if strings.HasSuffix(arg, "...") { + all = AllPackages(ctxt) + break + } + } + + for _, arg := range patterns { + if arg == "" { + continue + } + + neg := arg[0] == '-' + if neg { + arg = arg[1:] + } + + if arg == "..." { + // ... matches all packages + for _, pkg := range all { + doPkg(pkg, neg) + } + } else if dir, ok := strings.CutSuffix(arg, "/..."); ok { + // dir/... matches all packages beneath dir + for _, pkg := range all { + if strings.HasPrefix(pkg, dir) && + (len(pkg) == len(dir) || pkg[len(dir)] == '/') { + doPkg(pkg, neg) + } + } + } else { + // single package + doPkg(strings.TrimSuffix(arg, "/"), neg) + } + } + + return pkgs +} diff --git a/vendor/golang.org/x/tools/go/buildutil/fakecontext.go b/vendor/golang.org/x/tools/go/buildutil/fakecontext.go new file mode 100644 index 0000000..1f75141 --- /dev/null +++ b/vendor/golang.org/x/tools/go/buildutil/fakecontext.go @@ -0,0 +1,111 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package buildutil + +import ( + "fmt" + "go/build" + "io" + "os" + "path" + "path/filepath" + "sort" + "strings" + "time" +) + +// FakeContext returns a build.Context for the fake file tree specified +// by pkgs, which maps package import paths to a mapping from file base +// names to contents. +// +// The fake Context has a GOROOT of "/go" and no GOPATH, and overrides +// the necessary file access methods to read from memory instead of the +// real file system. +// +// Unlike a real file tree, the fake one has only two levels---packages +// and files---so ReadDir("/go/src/") returns all packages under +// /go/src/ including, for instance, "math" and "math/big". +// ReadDir("/go/src/math/big") would return all the files in the +// "math/big" package. +func FakeContext(pkgs map[string]map[string]string) *build.Context { + clean := func(filename string) string { + f := path.Clean(filepath.ToSlash(filename)) + // Removing "/go/src" while respecting segment + // boundaries has this unfortunate corner case: + if f == "/go/src" { + return "" + } + return strings.TrimPrefix(f, "/go/src/") + } + + ctxt := build.Default // copy + ctxt.GOROOT = "/go" + ctxt.GOPATH = "" + ctxt.Compiler = "gc" + ctxt.IsDir = func(dir string) bool { + dir = clean(dir) + if dir == "" { + return true // needed by (*build.Context).SrcDirs + } + return pkgs[dir] != nil + } + ctxt.ReadDir = func(dir string) ([]os.FileInfo, error) { + dir = clean(dir) + var fis []os.FileInfo + if dir == "" { + // enumerate packages + for importPath := range pkgs { + fis = append(fis, fakeDirInfo(importPath)) + } + } else { + // enumerate files of package + for basename := range pkgs[dir] { + fis = append(fis, fakeFileInfo(basename)) + } + } + sort.Sort(byName(fis)) + return fis, nil + } + ctxt.OpenFile = func(filename string) (io.ReadCloser, error) { + filename = clean(filename) + dir, base := path.Split(filename) + content, ok := pkgs[path.Clean(dir)][base] + if !ok { + return nil, fmt.Errorf("file not found: %s", filename) + } + return io.NopCloser(strings.NewReader(content)), nil + } + ctxt.IsAbsPath = func(path string) bool { + path = filepath.ToSlash(path) + // Don't rely on the default (filepath.Path) since on + // Windows, it reports virtual paths as non-absolute. + return strings.HasPrefix(path, "/") + } + return &ctxt +} + +type byName []os.FileInfo + +func (s byName) Len() int { return len(s) } +func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() } + +type fakeFileInfo string + +func (fi fakeFileInfo) Name() string { return string(fi) } +func (fakeFileInfo) Sys() any { return nil } +func (fakeFileInfo) ModTime() time.Time { return time.Time{} } +func (fakeFileInfo) IsDir() bool { return false } +func (fakeFileInfo) Size() int64 { return 0 } +func (fakeFileInfo) Mode() os.FileMode { return 0644 } + +type fakeDirInfo string + +func (fd fakeDirInfo) Name() string { return string(fd) } +func (fakeDirInfo) Sys() any { return nil } +func (fakeDirInfo) ModTime() time.Time { return time.Time{} } +func (fakeDirInfo) IsDir() bool { return true } +func (fakeDirInfo) Size() int64 { return 0 } +func (fakeDirInfo) Mode() os.FileMode { return 0755 } diff --git a/vendor/golang.org/x/tools/go/buildutil/overlay.go b/vendor/golang.org/x/tools/go/buildutil/overlay.go new file mode 100644 index 0000000..7e37165 --- /dev/null +++ b/vendor/golang.org/x/tools/go/buildutil/overlay.go @@ -0,0 +1,101 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package buildutil + +import ( + "bufio" + "bytes" + "fmt" + "go/build" + "io" + "path/filepath" + "strconv" + "strings" +) + +// OverlayContext overlays a build.Context with additional files from +// a map. Files in the map take precedence over other files. +// +// In addition to plain string comparison, two file names are +// considered equal if their base names match and their directory +// components point at the same directory on the file system. That is, +// symbolic links are followed for directories, but not files. +// +// A common use case for OverlayContext is to allow editors to pass in +// a set of unsaved, modified files. +// +// Currently, only the Context.OpenFile function will respect the +// overlay. This may change in the future. +func OverlayContext(orig *build.Context, overlay map[string][]byte) *build.Context { + // TODO(dominikh): Implement IsDir, HasSubdir and ReadDir + + rc := func(data []byte) (io.ReadCloser, error) { + return io.NopCloser(bytes.NewBuffer(data)), nil + } + + copy := *orig // make a copy + ctxt := © + ctxt.OpenFile = func(path string) (io.ReadCloser, error) { + // Fast path: names match exactly. + if content, ok := overlay[path]; ok { + return rc(content) + } + + // Slow path: check for same file under a different + // alias, perhaps due to a symbolic link. + for filename, content := range overlay { + if sameFile(path, filename) { + return rc(content) + } + } + + return OpenFile(orig, path) + } + return ctxt +} + +// ParseOverlayArchive parses an archive containing Go files and their +// contents. The result is intended to be used with OverlayContext. +// +// # Archive format +// +// The archive consists of a series of files. Each file consists of a +// name, a decimal file size and the file contents, separated by +// newlines. No newline follows after the file contents. +func ParseOverlayArchive(archive io.Reader) (map[string][]byte, error) { + overlay := make(map[string][]byte) + r := bufio.NewReader(archive) + for { + // Read file name. + filename, err := r.ReadString('\n') + if err != nil { + if err == io.EOF { + break // OK + } + return nil, fmt.Errorf("reading archive file name: %v", err) + } + filename = filepath.Clean(strings.TrimSpace(filename)) + + // Read file size. + sz, err := r.ReadString('\n') + if err != nil { + return nil, fmt.Errorf("reading size of archive file %s: %v", filename, err) + } + sz = strings.TrimSpace(sz) + size, err := strconv.ParseUint(sz, 10, 32) + if err != nil { + return nil, fmt.Errorf("parsing size of archive file %s: %v", filename, err) + } + + // Read file content. + content := make([]byte, size) + if _, err := io.ReadFull(r, content); err != nil { + return nil, fmt.Errorf("reading archive file %s: %v", filename, err) + } + overlay[filename] = content + } + + return overlay, nil +} diff --git a/vendor/golang.org/x/tools/go/buildutil/tags.go b/vendor/golang.org/x/tools/go/buildutil/tags.go new file mode 100644 index 0000000..f66cd5d --- /dev/null +++ b/vendor/golang.org/x/tools/go/buildutil/tags.go @@ -0,0 +1,100 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package buildutil + +// This duplicated logic must be kept in sync with that from go build: +// $GOROOT/src/cmd/go/internal/work/build.go (tagsFlag.Set) +// $GOROOT/src/cmd/go/internal/base/flag.go (StringsFlag.Set) +// $GOROOT/src/cmd/internal/quoted/quoted.go (isSpaceByte, Split) + +import ( + "fmt" + "strings" +) + +const TagsFlagDoc = "a list of `build tags` to consider satisfied during the build. " + + "For more information about build tags, see the description of " + + "build constraints in the documentation for the go/build package" + +// TagsFlag is an implementation of the flag.Value and flag.Getter interfaces that parses +// a flag value the same as go build's -tags flag and populates a []string slice. +// +// See $GOROOT/src/go/build/doc.go for description of build tags. +// See $GOROOT/src/cmd/go/doc.go for description of 'go build -tags' flag. +// +// Example: +// +// flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc) +type TagsFlag []string + +func (v *TagsFlag) Set(s string) error { + // See $GOROOT/src/cmd/go/internal/work/build.go (tagsFlag.Set) + // For compatibility with Go 1.12 and earlier, allow "-tags='a b c'" or even just "-tags='a'". + if strings.Contains(s, " ") || strings.Contains(s, "'") { + var err error + *v, err = splitQuotedFields(s) + if *v == nil { + *v = []string{} + } + return err + } + + // Starting in Go 1.13, the -tags flag is a comma-separated list of build tags. + *v = []string{} + for s := range strings.SplitSeq(s, ",") { + if s != "" { + *v = append(*v, s) + } + } + return nil +} + +func (v *TagsFlag) Get() any { return *v } + +func splitQuotedFields(s string) ([]string, error) { + // See $GOROOT/src/cmd/internal/quoted/quoted.go (Split) + // This must remain in sync with that logic. + var f []string + for len(s) > 0 { + for len(s) > 0 && isSpaceByte(s[0]) { + s = s[1:] + } + if len(s) == 0 { + break + } + // Accepted quoted string. No unescaping inside. + if s[0] == '"' || s[0] == '\'' { + quote := s[0] + s = s[1:] + i := 0 + for i < len(s) && s[i] != quote { + i++ + } + if i >= len(s) { + return nil, fmt.Errorf("unterminated %c string", quote) + } + f = append(f, s[:i]) + s = s[i+1:] + continue + } + i := 0 + for i < len(s) && !isSpaceByte(s[i]) { + i++ + } + f = append(f, s[:i]) + s = s[i:] + } + return f, nil +} + +func (v *TagsFlag) String() string { + return "" +} + +func isSpaceByte(c byte) bool { + // See $GOROOT/src/cmd/internal/quoted/quoted.go (isSpaceByte, Split) + // This list must remain in sync with that. + return c == ' ' || c == '\t' || c == '\n' || c == '\r' +} diff --git a/vendor/golang.org/x/tools/go/buildutil/util.go b/vendor/golang.org/x/tools/go/buildutil/util.go new file mode 100644 index 0000000..bee6390 --- /dev/null +++ b/vendor/golang.org/x/tools/go/buildutil/util.go @@ -0,0 +1,209 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package buildutil + +import ( + "fmt" + "go/ast" + "go/build" + "go/parser" + "go/token" + "io" + "io/ioutil" + "os" + "path" + "path/filepath" + "strings" +) + +// ParseFile behaves like parser.ParseFile, +// but uses the build context's file system interface, if any. +// +// If file is not absolute (as defined by IsAbsPath), the (dir, file) +// components are joined using JoinPath; dir must be absolute. +// +// The displayPath function, if provided, is used to transform the +// filename that will be attached to the ASTs. +// +// TODO(adonovan): call this from go/loader.parseFiles when the tree thaws. +func ParseFile(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, file string, mode parser.Mode) (*ast.File, error) { + if !IsAbsPath(ctxt, file) { + file = JoinPath(ctxt, dir, file) + } + rd, err := OpenFile(ctxt, file) + if err != nil { + return nil, err + } + defer rd.Close() // ignore error + if displayPath != nil { + file = displayPath(file) + } + return parser.ParseFile(fset, file, rd, mode) +} + +// ContainingPackage returns the package containing filename. +// +// If filename is not absolute, it is interpreted relative to working directory dir. +// All I/O is via the build context's file system interface, if any. +// +// The '...Files []string' fields of the resulting build.Package are not +// populated (build.FindOnly mode). +func ContainingPackage(ctxt *build.Context, dir, filename string) (*build.Package, error) { + if !IsAbsPath(ctxt, filename) { + filename = JoinPath(ctxt, dir, filename) + } + + // We must not assume the file tree uses + // "/" always, + // `\` always, + // or os.PathSeparator (which varies by platform), + // but to make any progress, we are forced to assume that + // paths will not use `\` unless the PathSeparator + // is also `\`, thus we can rely on filepath.ToSlash for some sanity. + + dirSlash := path.Dir(filepath.ToSlash(filename)) + "/" + + // We assume that no source root (GOPATH[i] or GOROOT) contains any other. + for _, srcdir := range ctxt.SrcDirs() { + srcdirSlash := filepath.ToSlash(srcdir) + "/" + if importPath, ok := HasSubdir(ctxt, srcdirSlash, dirSlash); ok { + return ctxt.Import(importPath, dir, build.FindOnly) + } + } + + return nil, fmt.Errorf("can't find package containing %s", filename) +} + +// -- Effective methods of file system interface ------------------------- + +// (go/build.Context defines these as methods, but does not export them.) + +// HasSubdir calls ctxt.HasSubdir (if not nil) or else uses +// the local file system to answer the question. +func HasSubdir(ctxt *build.Context, root, dir string) (rel string, ok bool) { + if f := ctxt.HasSubdir; f != nil { + return f(root, dir) + } + + // Try using paths we received. + if rel, ok = hasSubdir(root, dir); ok { + return + } + + // Try expanding symlinks and comparing + // expanded against unexpanded and + // expanded against expanded. + rootSym, _ := filepath.EvalSymlinks(root) + dirSym, _ := filepath.EvalSymlinks(dir) + + if rel, ok = hasSubdir(rootSym, dir); ok { + return + } + if rel, ok = hasSubdir(root, dirSym); ok { + return + } + return hasSubdir(rootSym, dirSym) +} + +func hasSubdir(root, dir string) (rel string, ok bool) { + const sep = string(filepath.Separator) + root = filepath.Clean(root) + if !strings.HasSuffix(root, sep) { + root += sep + } + + dir = filepath.Clean(dir) + if !strings.HasPrefix(dir, root) { + return "", false + } + + return filepath.ToSlash(dir[len(root):]), true +} + +// FileExists returns true if the specified file exists, +// using the build context's file system interface. +func FileExists(ctxt *build.Context, path string) bool { + if ctxt.OpenFile != nil { + r, err := ctxt.OpenFile(path) + if err != nil { + return false + } + r.Close() // ignore error + return true + } + _, err := os.Stat(path) + return err == nil +} + +// OpenFile behaves like os.Open, +// but uses the build context's file system interface, if any. +func OpenFile(ctxt *build.Context, path string) (io.ReadCloser, error) { + if ctxt.OpenFile != nil { + return ctxt.OpenFile(path) + } + return os.Open(path) +} + +// IsAbsPath behaves like filepath.IsAbs, +// but uses the build context's file system interface, if any. +func IsAbsPath(ctxt *build.Context, path string) bool { + if ctxt.IsAbsPath != nil { + return ctxt.IsAbsPath(path) + } + return filepath.IsAbs(path) +} + +// JoinPath behaves like filepath.Join, +// but uses the build context's file system interface, if any. +func JoinPath(ctxt *build.Context, path ...string) string { + if ctxt.JoinPath != nil { + return ctxt.JoinPath(path...) + } + return filepath.Join(path...) +} + +// IsDir behaves like os.Stat plus IsDir, +// but uses the build context's file system interface, if any. +func IsDir(ctxt *build.Context, path string) bool { + if ctxt.IsDir != nil { + return ctxt.IsDir(path) + } + fi, err := os.Stat(path) + return err == nil && fi.IsDir() +} + +// ReadDir behaves like ioutil.ReadDir, +// but uses the build context's file system interface, if any. +func ReadDir(ctxt *build.Context, path string) ([]os.FileInfo, error) { + if ctxt.ReadDir != nil { + return ctxt.ReadDir(path) + } + return ioutil.ReadDir(path) +} + +// SplitPathList behaves like filepath.SplitList, +// but uses the build context's file system interface, if any. +func SplitPathList(ctxt *build.Context, s string) []string { + if ctxt.SplitPathList != nil { + return ctxt.SplitPathList(s) + } + return filepath.SplitList(s) +} + +// sameFile returns true if x and y have the same basename and denote +// the same file. +func sameFile(x, y string) bool { + if path.Clean(x) == path.Clean(y) { + return true + } + if filepath.Base(x) == filepath.Base(y) { // (optimisation) + if xi, err := os.Stat(x); err == nil { + if yi, err := os.Stat(y); err == nil { + return os.SameFile(xi, yi) + } + } + } + return false +} diff --git a/vendor/golang.org/x/tools/go/callgraph/callgraph.go b/vendor/golang.org/x/tools/go/callgraph/callgraph.go new file mode 100644 index 0000000..cfbe504 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/callgraph.go @@ -0,0 +1,124 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package callgraph defines the call graph and various algorithms +and utilities to operate on it. + +A call graph is a labelled directed graph whose nodes represent +functions and whose edge labels represent syntactic function call +sites. The presence of a labelled edge (caller, site, callee) +indicates that caller may call callee at the specified call site. + +A call graph is a multigraph: it may contain multiple edges (caller, +*, callee) connecting the same pair of nodes, so long as the edges +differ by label; this occurs when one function calls another function +from multiple call sites. Also, it may contain multiple edges +(caller, site, *) that differ only by callee; this indicates a +polymorphic call. + +A SOUND call graph is one that overapproximates the dynamic calling +behaviors of the program in all possible executions. One call graph +is more PRECISE than another if it is a smaller overapproximation of +the dynamic behavior. + +All call graphs have a synthetic root node which is responsible for +calling main() and init(). + +Calls to built-in functions (e.g. panic, println) are not represented +in the call graph; they are treated like built-in operators of the +language. +*/ +package callgraph // import "golang.org/x/tools/go/callgraph" + +// TODO(zpavlinovic): decide how callgraphs handle calls to and from generic function bodies. + +import ( + "fmt" + "go/token" + + "golang.org/x/tools/go/ssa" +) + +// A Graph represents a call graph. +// +// A graph may contain nodes that are not reachable from the root. +// If the call graph is sound, such nodes indicate unreachable +// functions. +type Graph struct { + Root *Node // the distinguished root node (Root.Func may be nil) + Nodes map[*ssa.Function]*Node // all nodes by function +} + +// New returns a new Graph with the specified (optional) root node. +func New(root *ssa.Function) *Graph { + g := &Graph{Nodes: make(map[*ssa.Function]*Node)} + g.Root = g.CreateNode(root) + return g +} + +// CreateNode returns the Node for fn, creating it if not present. +// The root node may have fn=nil. +func (g *Graph) CreateNode(fn *ssa.Function) *Node { + n, ok := g.Nodes[fn] + if !ok { + n = &Node{Func: fn, ID: len(g.Nodes)} + g.Nodes[fn] = n + } + return n +} + +// A Node represents a node in a call graph. +type Node struct { + Func *ssa.Function // the function this node represents + ID int // 0-based sequence number + In []*Edge // unordered set of incoming call edges (n.In[*].Callee == n) + Out []*Edge // unordered set of outgoing call edges (n.Out[*].Caller == n) +} + +func (n *Node) String() string { + return fmt.Sprintf("n%d:%s", n.ID, n.Func) +} + +// A Edge represents an edge in the call graph. +// +// Site is nil for edges originating in synthetic or intrinsic +// functions, e.g. reflect.Value.Call or the root of the call graph. +type Edge struct { + Caller *Node + Site ssa.CallInstruction + Callee *Node +} + +func (e Edge) String() string { + return fmt.Sprintf("%s --> %s", e.Caller, e.Callee) +} + +func (e Edge) Description() string { + var prefix string + switch e.Site.(type) { + case nil: + return "synthetic call" + case *ssa.Go: + prefix = "concurrent " + case *ssa.Defer: + prefix = "deferred " + } + return prefix + e.Site.Common().Description() +} + +func (e Edge) Pos() token.Pos { + if e.Site == nil { + return token.NoPos + } + return e.Site.Pos() +} + +// AddEdge adds the edge (caller, site, callee) to the call graph. +// Elimination of duplicate edges is the caller's responsibility. +func AddEdge(caller *Node, site ssa.CallInstruction, callee *Node) { + e := &Edge{caller, site, callee} + callee.In = append(callee.In, e) + caller.Out = append(caller.Out, e) +} diff --git a/vendor/golang.org/x/tools/go/callgraph/cha/cha.go b/vendor/golang.org/x/tools/go/callgraph/cha/cha.go new file mode 100644 index 0000000..67a0356 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/cha/cha.go @@ -0,0 +1,77 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package cha computes the call graph of a Go program using the Class +// Hierarchy Analysis (CHA) algorithm. +// +// CHA was first described in "Optimization of Object-Oriented Programs +// Using Static Class Hierarchy Analysis", Jeffrey Dean, David Grove, +// and Craig Chambers, ECOOP'95. +// +// CHA is related to RTA (see go/callgraph/rta); the difference is that +// CHA conservatively computes the entire "implements" relation between +// interfaces and concrete types ahead of time, whereas RTA uses dynamic +// programming to construct it on the fly as it encounters new functions +// reachable from main. CHA may thus include spurious call edges for +// types that haven't been instantiated yet, or types that are never +// instantiated. +// +// Since CHA conservatively assumes that all functions are address-taken +// and all concrete types are put into interfaces, it is sound to run on +// partial programs, such as libraries without a main or test function. +package cha // import "golang.org/x/tools/go/callgraph/cha" + +// TODO(zpavlinovic): update CHA for how it handles generic function bodies. + +import ( + "golang.org/x/tools/go/callgraph" + "golang.org/x/tools/go/callgraph/internal/chautil" + "golang.org/x/tools/go/ssa" + "golang.org/x/tools/go/ssa/ssautil" +) + +// CallGraph computes the call graph of the specified program using the +// Class Hierarchy Analysis algorithm. +func CallGraph(prog *ssa.Program) *callgraph.Graph { + cg := callgraph.New(nil) // TODO(adonovan) eliminate concept of rooted callgraph + + allFuncs := ssautil.AllFunctions(prog) + + calleesOf := lazyCallees(allFuncs) + + addEdge := func(fnode *callgraph.Node, site ssa.CallInstruction, g *ssa.Function) { + gnode := cg.CreateNode(g) + callgraph.AddEdge(fnode, site, gnode) + } + + addEdges := func(fnode *callgraph.Node, site ssa.CallInstruction, callees []*ssa.Function) { + // Because every call to a highly polymorphic and + // frequently used abstract method such as + // (io.Writer).Write is assumed to call every concrete + // Write method in the program, the call graph can + // contain a lot of duplication. + for _, g := range callees { + addEdge(fnode, site, g) + } + } + + for f := range allFuncs { + fnode := cg.CreateNode(f) + for _, b := range f.Blocks { + for _, instr := range b.Instrs { + if site, ok := instr.(ssa.CallInstruction); ok { + if g := site.Common().StaticCallee(); g != nil { + addEdge(fnode, site, g) + } else { + addEdges(fnode, site, calleesOf(site)) + } + } + } + } + } + + return cg +} + +var lazyCallees = chautil.LazyCallees diff --git a/vendor/golang.org/x/tools/go/callgraph/internal/chautil/lazy.go b/vendor/golang.org/x/tools/go/callgraph/internal/chautil/lazy.go new file mode 100644 index 0000000..430bfea --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/internal/chautil/lazy.go @@ -0,0 +1,96 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package chautil provides helper functions related to +// class hierarchy analysis (CHA) for use in x/tools. +package chautil + +import ( + "go/types" + + "golang.org/x/tools/go/ssa" + "golang.org/x/tools/go/types/typeutil" +) + +// LazyCallees returns a function that maps a call site (in a function in fns) +// to its callees within fns. The set of callees is computed using the CHA algorithm, +// i.e., on the entire implements relation between interfaces and concrete types +// in fns. Please see golang.org/x/tools/go/callgraph/cha for more information. +// +// The resulting function is not concurrency safe. +func LazyCallees(fns map[*ssa.Function]bool) func(site ssa.CallInstruction) []*ssa.Function { + // funcsBySig contains all functions, keyed by signature. It is + // the effective set of address-taken functions used to resolve + // a dynamic call of a particular signature. + var funcsBySig typeutil.Map // value is []*ssa.Function + + // methodsByID contains all methods, grouped by ID for efficient + // lookup. + // + // We must key by ID, not name, for correct resolution of interface + // calls to a type with two (unexported) methods spelled the same but + // from different packages. The fact that the concrete type implements + // the interface does not mean the call dispatches to both methods. + methodsByID := make(map[string][]*ssa.Function) + + // An imethod represents an interface method I.m. + // (There's no go/types object for it; + // a *types.Func may be shared by many interfaces due to interface embedding.) + type imethod struct { + I *types.Interface + id string + } + // methodsMemo records, for every abstract method call I.m on + // interface type I, the set of concrete methods C.m of all + // types C that satisfy interface I. + // + // Abstract methods may be shared by several interfaces, + // hence we must pass I explicitly, not guess from m. + // + // methodsMemo is just a cache, so it needn't be a typeutil.Map. + methodsMemo := make(map[imethod][]*ssa.Function) + lookupMethods := func(I *types.Interface, m *types.Func) []*ssa.Function { + id := m.Id() + methods, ok := methodsMemo[imethod{I, id}] + if !ok { + for _, f := range methodsByID[id] { + C := f.Signature.Recv().Type() // named or *named + if types.Implements(C, I) { + methods = append(methods, f) + } + } + methodsMemo[imethod{I, id}] = methods + } + return methods + } + + for f := range fns { + if f.Signature.Recv() == nil { + // Package initializers can never be address-taken. + if f.Name() == "init" && f.Synthetic == "package initializer" { + continue + } + funcs, _ := funcsBySig.At(f.Signature).([]*ssa.Function) + funcs = append(funcs, f) + funcsBySig.Set(f.Signature, funcs) + } else if obj := f.Object(); obj != nil { + id := obj.(*types.Func).Id() + methodsByID[id] = append(methodsByID[id], f) + } + } + + return func(site ssa.CallInstruction) []*ssa.Function { + call := site.Common() + if call.IsInvoke() { + tiface := call.Value.Type().Underlying().(*types.Interface) + return lookupMethods(tiface, call.Method) + } else if g := call.StaticCallee(); g != nil { + return []*ssa.Function{g} + } else if _, ok := call.Value.(*ssa.Builtin); !ok { + fns, _ := funcsBySig.At(call.Signature()).([]*ssa.Function) + return fns + } + return nil + } +} diff --git a/vendor/golang.org/x/tools/go/callgraph/rta/rta.go b/vendor/golang.org/x/tools/go/callgraph/rta/rta.go new file mode 100644 index 0000000..d85ded7 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/rta/rta.go @@ -0,0 +1,493 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This package provides Rapid Type Analysis (RTA) for Go, a fast +// algorithm for call graph construction and discovery of reachable code +// (and hence dead code) and runtime types. The algorithm was first +// described in: +// +// David F. Bacon and Peter F. Sweeney. 1996. +// Fast static analysis of C++ virtual function calls. (OOPSLA '96) +// http://doi.acm.org/10.1145/236337.236371 +// +// The algorithm uses dynamic programming to tabulate the cross-product +// of the set of known "address-taken" functions with the set of known +// dynamic calls of the same type. As each new address-taken function +// is discovered, call graph edges are added from each known callsite, +// and as each new call site is discovered, call graph edges are added +// from it to each known address-taken function. +// +// A similar approach is used for dynamic calls via interfaces: it +// tabulates the cross-product of the set of known "runtime types", +// i.e. types that may appear in an interface value, or may be derived from +// one via reflection, with the set of known "invoke"-mode dynamic +// calls. As each new runtime type is discovered, call edges are +// added from the known call sites, and as each new call site is +// discovered, call graph edges are added to each compatible +// method. +// +// In addition, we must consider as reachable all address-taken +// functions and all exported methods of any runtime type, since they +// may be called via reflection. +// +// Each time a newly added call edge causes a new function to become +// reachable, the code of that function is analyzed for more call sites, +// address-taken functions, and runtime types. The process continues +// until a fixed point is reached. +package rta // import "golang.org/x/tools/go/callgraph/rta" + +import ( + "fmt" + "go/types" + "hash/crc32" + + "golang.org/x/tools/go/callgraph" + "golang.org/x/tools/go/ssa" + "golang.org/x/tools/go/types/typeutil" + "golang.org/x/tools/internal/typesinternal" +) + +// A Result holds the results of Rapid Type Analysis, which includes the +// set of reachable functions/methods, runtime types, and the call graph. +type Result struct { + // CallGraph is the discovered callgraph. + // It does not include edges for calls made via reflection. + CallGraph *callgraph.Graph + + // Reachable contains the set of reachable functions and methods. + // This includes exported methods of runtime types, since + // they may be accessed via reflection. + // The value indicates whether the function is address-taken. + // + // (We wrap the bool in a struct to avoid inadvertent use of + // "if Reachable[f] {" to test for set membership.) + Reachable map[*ssa.Function]struct{ AddrTaken bool } + + // RuntimeTypes contains the set of types that are needed at + // runtime, for interfaces or reflection. + // + // The value indicates whether the type is inaccessible to reflection. + // Consider: + // type A struct{B} + // fmt.Println(new(A)) + // Types *A, A and B are accessible to reflection, but the unnamed + // type struct{B} is not. + // + // TODO(adonovan): populating this field is expensive yet it + // is never used in x/tools. Add a revised [Analyze] API that + // provides the option not to set it. + RuntimeTypes typeutil.Map +} + +// Working state of the RTA algorithm. +type rta struct { + result *Result + + prog *ssa.Program + + reflectValueCall *ssa.Function // (*reflect.Value).Call, iff part of prog + + worklist []*ssa.Function // list of functions to visit + + // addrTakenFuncsBySig contains all address-taken *Functions, grouped by signature. + // Keys are *types.Signature, values are map[*ssa.Function]bool sets. + addrTakenFuncsBySig typeutil.Map + + // dynCallSites contains all dynamic "call"-mode call sites, grouped by signature. + // Keys are *types.Signature, values are unordered []ssa.CallInstruction. + dynCallSites typeutil.Map + + // invokeSites contains all "invoke"-mode call sites, grouped by interface. + // Keys are *types.Interface (never *types.Named), + // Values are unordered []ssa.CallInstruction sets. + invokeSites typeutil.Map + + // The following two maps together define the subset of the + // m:n "implements" relation needed by the algorithm. + + // concreteTypes maps each concrete type to information about it. + // concreteList holds the same infos in insertion order, for + // iteration without walking the hash map. + // Keys are types.Type, values are *concreteTypeInfo. + // Only concrete types used as MakeInterface operands are included. + concreteTypes typeutil.Map + concreteList []*concreteTypeInfo + + // interfaceTypes maps each interface type to information about it. + // Keys are *types.Interface, values are *interfaceTypeInfo. + // Only interfaces used in "invoke"-mode CallInstructions are included. + interfaceTypes typeutil.Map + interfaceList []*interfaceTypeInfo +} + +type concreteTypeInfo struct { + C types.Type + fprint uint64 // fingerprint of method set + implements []*types.Interface // unordered set of implemented interfaces +} + +type interfaceTypeInfo struct { + I *types.Interface + fprint uint64 // fingerprint of method set + implementations []types.Type // unordered set of concrete implementations +} + +// addReachable marks a function as potentially callable at run-time, +// and ensures that it gets processed. +func (r *rta) addReachable(f *ssa.Function, addrTaken bool) { + reachable := r.result.Reachable + n := len(reachable) + v := reachable[f] + if addrTaken { + v.AddrTaken = true + } + reachable[f] = v + if len(reachable) > n { + // First time seeing f. Add it to the worklist. + r.worklist = append(r.worklist, f) + } +} + +// addEdge adds the specified call graph edge, and marks it reachable. +// addrTaken indicates whether to mark the callee as "address-taken". +// site is nil for calls made via reflection. +func (r *rta) addEdge(caller *ssa.Function, site ssa.CallInstruction, callee *ssa.Function, addrTaken bool) { + r.addReachable(callee, addrTaken) + + if g := r.result.CallGraph; g != nil { + if caller == nil { + panic(site) + } + from := g.CreateNode(caller) + to := g.CreateNode(callee) + callgraph.AddEdge(from, site, to) + } +} + +// ---------- addrTakenFuncs × dynCallSites ---------- + +// visitAddrTakenFunc is called each time we encounter an address-taken function f. +func (r *rta) visitAddrTakenFunc(f *ssa.Function) { + // Create two-level map (Signature -> Function -> bool). + S := f.Signature + funcs, _ := r.addrTakenFuncsBySig.At(S).(map[*ssa.Function]bool) + if funcs == nil { + funcs = make(map[*ssa.Function]bool) + r.addrTakenFuncsBySig.Set(S, funcs) + } + if !funcs[f] { + // First time seeing f. + funcs[f] = true + + // If we've seen any dyncalls of this type, mark it reachable, + // and add call graph edges. + sites, _ := r.dynCallSites.At(S).([]ssa.CallInstruction) + for _, site := range sites { + r.addEdge(site.Parent(), site, f, true) + } + + // If the program includes (*reflect.Value).Call, + // add a dynamic call edge from it to any address-taken + // function, regardless of signature. + // + // This isn't perfect. + // - The actual call comes from an internal function + // called reflect.call, but we can't rely on that here. + // - reflect.Value.CallSlice behaves similarly, + // but we don't bother to create callgraph edges from + // it as well as it wouldn't fundamentally change the + // reachability but it would add a bunch more edges. + // - We assume that if reflect.Value.Call is among + // the dependencies of the application, it is itself + // reachable. (It would be more accurate to defer + // all the addEdges below until r.V.Call itself + // becomes reachable.) + // - Fake call graph edges are added from r.V.Call to + // each address-taken function, but not to every + // method reachable through a materialized rtype, + // which is a little inconsistent. Still, the + // reachable set includes both kinds, which is what + // matters for e.g. deadcode detection.) + if r.reflectValueCall != nil { + var site ssa.CallInstruction = nil // can't find actual call site + r.addEdge(r.reflectValueCall, site, f, true) + } + } +} + +// visitDynCall is called each time we encounter a dynamic "call"-mode call. +func (r *rta) visitDynCall(site ssa.CallInstruction) { + S := site.Common().Signature() + + // Record the call site. + sites, _ := r.dynCallSites.At(S).([]ssa.CallInstruction) + r.dynCallSites.Set(S, append(sites, site)) + + // For each function of signature S that we know is address-taken, + // add an edge and mark it reachable. + funcs, _ := r.addrTakenFuncsBySig.At(S).(map[*ssa.Function]bool) + for g := range funcs { + r.addEdge(site.Parent(), site, g, true) + } +} + +// ---------- concrete types × invoke sites ---------- + +// addInvokeEdge is called for each new pair (site, C) in the matrix. +func (r *rta) addInvokeEdge(site ssa.CallInstruction, C types.Type) { + // Ascertain the concrete method of C to be called. + imethod := site.Common().Method + cmethod := r.prog.LookupMethod(C, imethod.Pkg(), imethod.Name()) + r.addEdge(site.Parent(), site, cmethod, true) +} + +// visitInvoke is called each time the algorithm encounters an "invoke"-mode call. +func (r *rta) visitInvoke(site ssa.CallInstruction) { + I := site.Common().Value.Type().Underlying().(*types.Interface) + + // Record the invoke site. + sites, _ := r.invokeSites.At(I).([]ssa.CallInstruction) + r.invokeSites.Set(I, append(sites, site)) + + // Add callgraph edge for each existing + // address-taken concrete type implementing I. + for _, C := range r.implementations(I) { + r.addInvokeEdge(site, C) + } +} + +// ---------- main algorithm ---------- + +// visitFunc processes function f. +func (r *rta) visitFunc(f *ssa.Function) { + var space [32]*ssa.Value // preallocate space for common case + + for _, b := range f.Blocks { + for _, instr := range b.Instrs { + rands := instr.Operands(space[:0]) + + switch instr := instr.(type) { + case ssa.CallInstruction: + call := instr.Common() + if call.IsInvoke() { + r.visitInvoke(instr) + } else if g := call.StaticCallee(); g != nil { + r.addEdge(f, instr, g, false) + } else if _, ok := call.Value.(*ssa.Builtin); !ok { + r.visitDynCall(instr) + } + + // Ignore the call-position operand when + // looking for address-taken Functions. + // Hack: assume this is rands[0]. + rands = rands[1:] + + case *ssa.MakeInterface: + // Converting a value of type T to an + // interface materializes its runtime + // type, allowing any of its exported + // methods to be called though reflection. + r.addRuntimeType(instr.X.Type()) + } + + // Process all address-taken functions. + for _, op := range rands { + if g, ok := (*op).(*ssa.Function); ok { + r.visitAddrTakenFunc(g) + } + } + } + } +} + +// Analyze performs Rapid Type Analysis, starting at the specified root +// functions. It returns nil if no roots were specified. +// +// The root functions must be one or more entrypoints (main and init +// functions) of a complete SSA program, with function bodies for all +// dependencies, constructed with the [ssa.InstantiateGenerics] mode +// flag. +// +// If buildCallGraph is true, Result.CallGraph will contain a call +// graph; otherwise, only the other fields (reachable functions) are +// populated. +func Analyze(roots []*ssa.Function, buildCallGraph bool) *Result { + if len(roots) == 0 { + return nil + } + + r := &rta{ + result: &Result{Reachable: make(map[*ssa.Function]struct{ AddrTaken bool })}, + prog: roots[0].Prog, + } + + if buildCallGraph { + // TODO(adonovan): change callgraph API to eliminate the + // notion of a distinguished root node. Some callgraphs + // have many roots, or none. + r.result.CallGraph = callgraph.New(roots[0]) + } + + // Grab ssa.Function for (*reflect.Value).Call, + // if "reflect" is among the dependencies. + if reflectPkg := r.prog.ImportedPackage("reflect"); reflectPkg != nil { + reflectValue := reflectPkg.Members["Value"].(*ssa.Type) + r.reflectValueCall = r.prog.LookupMethod(reflectValue.Object().Type(), reflectPkg.Pkg, "Call") + } + + hasher := typeutil.MakeHasher() + r.result.RuntimeTypes.SetHasher(hasher) + r.addrTakenFuncsBySig.SetHasher(hasher) + r.dynCallSites.SetHasher(hasher) + r.invokeSites.SetHasher(hasher) + r.concreteTypes.SetHasher(hasher) + r.interfaceTypes.SetHasher(hasher) + + for _, root := range roots { + r.addReachable(root, false) + } + + // Visit functions, processing their instructions, and adding + // new functions to the worklist, until a fixed point is + // reached. + var shadow []*ssa.Function // for efficiency, we double-buffer the worklist + for len(r.worklist) > 0 { + shadow, r.worklist = r.worklist, shadow[:0] + for _, f := range shadow { + r.visitFunc(f) + } + } + return r.result +} + +// interfaces(C) returns all currently known interfaces implemented by C. +func (r *rta) interfaces(C types.Type) []*types.Interface { + // Create an info for C the first time we see it. + var cinfo *concreteTypeInfo + if v := r.concreteTypes.At(C); v != nil { + cinfo = v.(*concreteTypeInfo) + } else { + cinfo = &concreteTypeInfo{ + C: C, + fprint: fingerprint(r.prog.MethodSets.MethodSet(C)), + } + r.concreteTypes.Set(C, cinfo) + r.concreteList = append(r.concreteList, cinfo) + + // Ascertain set of interfaces C implements + // and update the 'implements' relation. + for _, iinfo := range r.interfaceList { + if implements(cinfo, iinfo) { + iinfo.implementations = append(iinfo.implementations, C) + cinfo.implements = append(cinfo.implements, iinfo.I) + } + } + } + + return cinfo.implements +} + +// implementations(I) returns all currently known concrete types that implement I. +func (r *rta) implementations(I *types.Interface) []types.Type { + // Create an info for I the first time we see it. + var iinfo *interfaceTypeInfo + if v := r.interfaceTypes.At(I); v != nil { + iinfo = v.(*interfaceTypeInfo) + } else { + iinfo = &interfaceTypeInfo{ + I: I, + fprint: fingerprint(r.prog.MethodSets.MethodSet(I)), + } + r.interfaceTypes.Set(I, iinfo) + r.interfaceList = append(r.interfaceList, iinfo) + + // Ascertain set of concrete types that implement I + // and update the 'implements' relation. + for _, cinfo := range r.concreteList { + if implements(cinfo, iinfo) { + cinfo.implements = append(cinfo.implements, I) + iinfo.implementations = append(iinfo.implementations, cinfo.C) + } + } + } + return iinfo.implementations +} + +// addRuntimeType is called for each concrete type that can be the +// dynamic type of some interface or reflect.Value. +func (r *rta) addRuntimeType(T types.Type) { + methodSetOf := r.prog.MethodSets.MethodSet + typesinternal.ForEachElement(methodSetOf, T, func(T types.Type, access bool) bool { + if prevInaccess, ok := r.result.RuntimeTypes.At(T).(bool); ok { + if prevInaccess && access { + // A type previously marked inaccessible (ok && prevInaccess) + // is now found to be accessible (access): + // record that it is no longer inaccessible (false). + // (The inverted sense of the map is regrettable.) + r.result.RuntimeTypes.Set(T, false) + } + return true // seen; prune traversal + } + r.result.RuntimeTypes.Set(T, !access) // record inaccessibility + + if !types.IsInterface(T) { + // T is a new concrete type. + + // Exported methods are always potentially callable via reflection. + for sel := range methodSetOf(T).Methods() { + obj := sel.Obj() + if !obj.Exported() { + continue + } + if obj.Type().(*types.Signature).TypeParams() != nil { + // Skip generic methods: they have no single ssa.Function, + // so MethodValue returns nil, and reflection cannot call + // them without instantiating them first. + continue + } + r.addReachable(r.prog.MethodValue(sel), true) + } + + // Add callgraph edge for each existing dynamic + // "invoke"-mode call via that interface. + for _, I := range r.interfaces(T) { + sites, _ := r.invokeSites.At(I).([]ssa.CallInstruction) + for _, site := range sites { + r.addInvokeEdge(site, T) + } + } + } + + return false + }) +} + +// fingerprint returns a bitmask with one bit set per method id, +// enabling 'implements' to quickly reject most candidates. +func fingerprint(mset *types.MethodSet) uint64 { + var space [64]byte + var mask uint64 + for method := range mset.Methods() { + method := method.Obj() + sig := method.Type().(*types.Signature) + if sig.TypeParams() != nil { + continue // skip generic methods since interfaces don't have them + } + sum := crc32.ChecksumIEEE(fmt.Appendf(space[:], "%s/%d/%d", + method.Id(), + sig.Params().Len(), + sig.Results().Len())) + mask |= 1 << (sum % 64) + } + return mask +} + +// implements reports whether types.Implements(cinfo.C, iinfo.I), +// but more efficiently. +func implements(cinfo *concreteTypeInfo, iinfo *interfaceTypeInfo) (got bool) { + // The concrete type must have at least the methods + // (bits) of the interface type. Use a bitwise subset + // test to reject most candidates quickly. + return iinfo.fprint & ^cinfo.fprint == 0 && types.Implements(cinfo.C, iinfo.I) +} diff --git a/vendor/golang.org/x/tools/go/callgraph/util.go b/vendor/golang.org/x/tools/go/callgraph/util.go new file mode 100644 index 0000000..d8562a9 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/util.go @@ -0,0 +1,181 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package callgraph + +import "golang.org/x/tools/go/ssa" + +// This file provides various utilities over call graphs, such as +// visitation and path search. + +// CalleesOf returns a new set containing all direct callees of the +// caller node. +func CalleesOf(caller *Node) map[*Node]bool { + callees := make(map[*Node]bool) + for _, e := range caller.Out { + callees[e.Callee] = true + } + return callees +} + +// GraphVisitEdges visits all the edges in graph g in depth-first order. +// The edge function is called for each edge in postorder. If it +// returns non-nil, visitation stops and GraphVisitEdges returns that +// value. +func GraphVisitEdges(g *Graph, edge func(*Edge) error) error { + seen := make(map[*Node]bool) + var visit func(n *Node) error + visit = func(n *Node) error { + if !seen[n] { + seen[n] = true + for _, e := range n.Out { + if err := visit(e.Callee); err != nil { + return err + } + if err := edge(e); err != nil { + return err + } + } + } + return nil + } + for _, n := range g.Nodes { + if err := visit(n); err != nil { + return err + } + } + return nil +} + +// PathSearch finds an arbitrary path starting at node start and +// ending at some node for which isEnd() returns true. On success, +// PathSearch returns the path as an ordered list of edges; on +// failure, it returns nil. +func PathSearch(start *Node, isEnd func(*Node) bool) []*Edge { + stack := make([]*Edge, 0, 32) + seen := make(map[*Node]bool) + var search func(n *Node) []*Edge + search = func(n *Node) []*Edge { + if !seen[n] { + seen[n] = true + if isEnd(n) { + return stack + } + for _, e := range n.Out { + stack = append(stack, e) // push + if found := search(e.Callee); found != nil { + return found + } + stack = stack[:len(stack)-1] // pop + } + } + return nil + } + return search(start) +} + +// DeleteSyntheticNodes removes from call graph g all nodes for +// functions that do not correspond to source syntax. For historical +// reasons, nodes for g.Root and package initializers are always +// kept. +// +// As nodes are removed, edges are created to preserve the +// reachability relation of the remaining nodes. +func (g *Graph) DeleteSyntheticNodes() { + // Measurements on the standard library and go.tools show that + // resulting graph has ~15% fewer nodes and 4-8% fewer edges + // than the input. + // + // Inlining a wrapper of in-degree m, out-degree n adds m*n + // and removes m+n edges. Since most wrappers are monomorphic + // (n=1) this results in a slight reduction. Polymorphic + // wrappers (n>1), e.g. from embedding an interface value + // inside a struct to satisfy some interface, cause an + // increase in the graph, but they seem to be uncommon. + + // Hash all existing edges to avoid creating duplicates. + edges := make(map[Edge]bool) + for _, cgn := range g.Nodes { + for _, e := range cgn.Out { + edges[*e] = true + } + } + // Note: these cross-products can exceed 100 x 100. + for fn, cgn := range g.Nodes { + if cgn == g.Root || isInit(cgn.Func) || fn.Syntax() != nil { + continue // keep + } + for _, eIn := range cgn.In { + for _, eOut := range cgn.Out { + newEdge := Edge{eIn.Caller, eIn.Site, eOut.Callee} + if edges[newEdge] { + continue // don't add duplicate + } + AddEdge(eIn.Caller, eIn.Site, eOut.Callee) + edges[newEdge] = true + } + } + g.DeleteNode(cgn) + } +} + +func isInit(fn *ssa.Function) bool { + return fn.Pkg != nil && fn.Pkg.Func("init") == fn +} + +// DeleteNode removes node n and its edges from the graph g. +// (NB: not efficient for batch deletion.) +func (g *Graph) DeleteNode(n *Node) { + n.deleteIns() + n.deleteOuts() + delete(g.Nodes, n.Func) +} + +// deleteIns deletes all incoming edges to n. +func (n *Node) deleteIns() { + for _, e := range n.In { + removeOutEdge(e) + } + n.In = nil +} + +// deleteOuts deletes all outgoing edges from n. +func (n *Node) deleteOuts() { + for _, e := range n.Out { + removeInEdge(e) + } + n.Out = nil +} + +// removeOutEdge removes edge.Caller's outgoing edge 'edge'. +func removeOutEdge(edge *Edge) { + caller := edge.Caller + n := len(caller.Out) + for i, e := range caller.Out { + if e == edge { + // Replace it with the final element and shrink the slice. + caller.Out[i] = caller.Out[n-1] + caller.Out[n-1] = nil // aid GC + caller.Out = caller.Out[:n-1] + return + } + } + panic("edge not found: " + edge.String()) +} + +// removeInEdge removes edge.Callee's incoming edge 'edge'. +func removeInEdge(edge *Edge) { + caller := edge.Callee + n := len(caller.In) + for i, e := range caller.In { + if e == edge { + // Replace it with the final element and shrink the slice. + caller.In[i] = caller.In[n-1] + caller.In[n-1] = nil // aid GC + caller.In = caller.In[:n-1] + return + } + } + panic("edge not found: " + edge.String()) +} diff --git a/vendor/golang.org/x/tools/go/callgraph/vta/graph.go b/vendor/golang.org/x/tools/go/callgraph/vta/graph.go new file mode 100644 index 0000000..f66f4c7 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/vta/graph.go @@ -0,0 +1,861 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package vta + +import ( + "fmt" + "go/token" + "go/types" + "iter" + + "golang.org/x/tools/go/ssa" + "golang.org/x/tools/go/types/typeutil" + "golang.org/x/tools/internal/typeparams" +) + +// node interface for VTA nodes. +type node interface { + Type() types.Type + String() string +} + +// constant node for VTA. +type constant struct { + typ types.Type +} + +func (c constant) Type() types.Type { + return c.typ +} + +func (c constant) String() string { + return fmt.Sprintf("Constant(%v)", c.Type()) +} + +// pointer node for VTA. +type pointer struct { + typ *types.Pointer +} + +func (p pointer) Type() types.Type { + return p.typ +} + +func (p pointer) String() string { + return fmt.Sprintf("Pointer(%v)", p.Type()) +} + +// mapKey node for VTA, modeling reachable map key types. +type mapKey struct { + typ types.Type +} + +func (mk mapKey) Type() types.Type { + return mk.typ +} + +func (mk mapKey) String() string { + return fmt.Sprintf("MapKey(%v)", mk.Type()) +} + +// mapValue node for VTA, modeling reachable map value types. +type mapValue struct { + typ types.Type +} + +func (mv mapValue) Type() types.Type { + return mv.typ +} + +func (mv mapValue) String() string { + return fmt.Sprintf("MapValue(%v)", mv.Type()) +} + +// sliceElem node for VTA, modeling reachable slice and array element types. +type sliceElem struct { + typ types.Type +} + +func (s sliceElem) Type() types.Type { + return s.typ +} + +func (s sliceElem) String() string { + return fmt.Sprintf("Slice([]%v)", s.Type()) +} + +// channelElem node for VTA, modeling reachable channel element types. +type channelElem struct { + typ types.Type +} + +func (c channelElem) Type() types.Type { + return c.typ +} + +func (c channelElem) String() string { + return fmt.Sprintf("Channel(chan %v)", c.Type()) +} + +// field node for VTA. +type field struct { + StructType types.Type + index int // index of the field in the struct +} + +func (f field) Type() types.Type { + s := typeparams.CoreType(f.StructType).(*types.Struct) + return s.Field(f.index).Type() +} + +func (f field) String() string { + s := typeparams.CoreType(f.StructType).(*types.Struct) + return fmt.Sprintf("Field(%v:%s)", f.StructType, s.Field(f.index).Name()) +} + +// global node for VTA. +type global struct { + val *ssa.Global +} + +func (g global) Type() types.Type { + return g.val.Type() +} + +func (g global) String() string { + return fmt.Sprintf("Global(%s)", g.val.Name()) +} + +// local node for VTA modeling local variables +// and function/method parameters. +type local struct { + val ssa.Value +} + +func (l local) Type() types.Type { + return l.val.Type() +} + +func (l local) String() string { + return fmt.Sprintf("Local(%s)", l.val.Name()) +} + +// indexedLocal node for VTA node. Models indexed locals +// related to the ssa extract instructions. +type indexedLocal struct { + val ssa.Value + index int + typ types.Type +} + +func (i indexedLocal) Type() types.Type { + return i.typ +} + +func (i indexedLocal) String() string { + return fmt.Sprintf("Local(%s[%d])", i.val.Name(), i.index) +} + +// function node for VTA. +type function struct { + f *ssa.Function +} + +func (f function) Type() types.Type { + return f.f.Type() +} + +func (f function) String() string { + return fmt.Sprintf("Function(%s)", f.f.Name()) +} + +// resultVar represents the result +// variable of a function, whether +// named or not. +type resultVar struct { + f *ssa.Function + index int // valid index into result var tuple +} + +func (o resultVar) Type() types.Type { + return o.f.Signature.Results().At(o.index).Type() +} + +func (o resultVar) String() string { + v := o.f.Signature.Results().At(o.index) + if n := v.Name(); n != "" { + return fmt.Sprintf("Return(%s[%s])", o.f.Name(), n) + } + return fmt.Sprintf("Return(%s[%d])", o.f.Name(), o.index) +} + +// nestedPtrInterface node represents all references and dereferences +// of locals and globals that have a nested pointer to interface type. +// We merge such constructs into a single node for simplicity and without +// much precision sacrifice as such variables are rare in practice. Both +// a and b would be represented as the same PtrInterface(I) node in: +// +// type I interface +// var a ***I +// var b **I +type nestedPtrInterface struct { + typ types.Type +} + +func (l nestedPtrInterface) Type() types.Type { + return l.typ +} + +func (l nestedPtrInterface) String() string { + return fmt.Sprintf("PtrInterface(%v)", l.typ) +} + +// nestedPtrFunction node represents all references and dereferences of locals +// and globals that have a nested pointer to function type. We merge such +// constructs into a single node for simplicity and without much precision +// sacrifice as such variables are rare in practice. Both a and b would be +// represented as the same PtrFunction(func()) node in: +// +// var a *func() +// var b **func() +type nestedPtrFunction struct { + typ types.Type +} + +func (p nestedPtrFunction) Type() types.Type { + return p.typ +} + +func (p nestedPtrFunction) String() string { + return fmt.Sprintf("PtrFunction(%v)", p.typ) +} + +// panicArg models types of all arguments passed to panic. +type panicArg struct{} + +func (p panicArg) Type() types.Type { + return nil +} + +func (p panicArg) String() string { + return "Panic" +} + +// recoverReturn models types of all return values of recover(). +type recoverReturn struct{} + +func (r recoverReturn) Type() types.Type { + return nil +} + +func (r recoverReturn) String() string { + return "Recover" +} + +type empty = struct{} + +// idx is an index representing a unique node in a vtaGraph. +type idx int + +// vtaGraph remembers for each VTA node the set of its successors. +// Tailored for VTA, hence does not support singleton (sub)graphs. +type vtaGraph struct { + m []map[idx]empty // m[i] has the successors for the node with index i. + idx map[node]idx // idx[n] is the index for the node n. + node []node // node[i] is the node with index i. +} + +func (g *vtaGraph) numNodes() int { + return len(g.idx) +} + +func (g *vtaGraph) successors(x idx) iter.Seq[idx] { + return func(yield func(y idx) bool) { + for y := range g.m[x] { + if !yield(y) { + return + } + } + } +} + +// addEdge adds an edge x->y to the graph. +func (g *vtaGraph) addEdge(x, y node) { + if g.idx == nil { + g.idx = make(map[node]idx) + } + lookup := func(n node) idx { + i, ok := g.idx[n] + if !ok { + i = idx(len(g.idx)) + g.m = append(g.m, nil) + g.idx[n] = i + g.node = append(g.node, n) + } + return i + } + a := lookup(x) + b := lookup(y) + succs := g.m[a] + if succs == nil { + succs = make(map[idx]empty) + g.m[a] = succs + } + succs[b] = empty{} +} + +// typePropGraph builds a VTA graph for a set of `funcs` and initial +// `callgraph` needed to establish interprocedural edges. Returns the +// graph and a map for unique type representatives. +func typePropGraph(funcs map[*ssa.Function]bool, callees calleesFunc) (*vtaGraph, *typeutil.Map) { + b := builder{callees: callees} + b.visit(funcs) + b.callees = nil // ensure callees is not pinned by pointers to other fields of b. + return &b.graph, &b.canon +} + +// Data structure responsible for linearly traversing the +// code and building a VTA graph. +type builder struct { + graph vtaGraph + callees calleesFunc // initial call graph for creating flows at unresolved call sites. + + // Specialized type map for canonicalization of types.Type. + // Semantically equivalent types can have different implementations, + // i.e., they are different pointer values. The map allows us to + // have one unique representative. The keys are fixed and from the + // client perspective they are types. The values in our case are + // types too, in particular type representatives. Each value is a + // pointer so this map is not expected to take much memory. + canon typeutil.Map +} + +func (b *builder) visit(funcs map[*ssa.Function]bool) { + // Add the fixed edge Panic -> Recover + b.graph.addEdge(panicArg{}, recoverReturn{}) + + for f, in := range funcs { + if in { + b.fun(f) + } + } +} + +func (b *builder) fun(f *ssa.Function) { + for _, bl := range f.Blocks { + for _, instr := range bl.Instrs { + b.instr(instr) + } + } +} + +func (b *builder) instr(instr ssa.Instruction) { + switch i := instr.(type) { + case *ssa.Store: + b.addInFlowAliasEdges(b.nodeFromVal(i.Addr), b.nodeFromVal(i.Val)) + case *ssa.MakeInterface: + b.addInFlowEdge(b.nodeFromVal(i.X), b.nodeFromVal(i)) + case *ssa.MakeClosure: + b.closure(i) + case *ssa.UnOp: + b.unop(i) + case *ssa.Phi: + b.phi(i) + case *ssa.ChangeInterface: + // Although in change interface a := A(b) command a and b are + // the same object, the only interesting flow happens when A + // is an interface. We create flow b -> a, but omit a -> b. + // The latter flow is not needed: if a gets assigned concrete + // type later on, that cannot be propagated back to b as b + // is a separate variable. The a -> b flow can happen when + // A is a pointer to interface, but then the command is of + // type ChangeType, handled below. + b.addInFlowEdge(b.nodeFromVal(i.X), b.nodeFromVal(i)) + case *ssa.ChangeType: + // change type command a := A(b) results in a and b being the + // same value. For concrete type A, there is no interesting flow. + // + // When A is an interface, most interface casts are handled + // by the ChangeInterface instruction. The relevant case here is + // when converting a pointer to an interface type. This can happen + // when the underlying interfaces have the same method set. + // + // type I interface{ foo() } + // type J interface{ foo() } + // var b *I + // a := (*J)(b) + // + // When this happens we add flows between a <--> b. + b.addInFlowAliasEdges(b.nodeFromVal(i), b.nodeFromVal(i.X)) + case *ssa.TypeAssert: + b.tassert(i) + case *ssa.Extract: + b.extract(i) + case *ssa.Field: + b.field(i) + case *ssa.FieldAddr: + b.fieldAddr(i) + case *ssa.Send: + b.send(i) + case *ssa.Select: + b.selekt(i) + case *ssa.Index: + b.index(i) + case *ssa.IndexAddr: + b.indexAddr(i) + case *ssa.Lookup: + b.lookup(i) + case *ssa.MapUpdate: + b.mapUpdate(i) + case *ssa.Next: + b.next(i) + case ssa.CallInstruction: + b.call(i) + case *ssa.Panic: + b.panic(i) + case *ssa.Return: + b.rtrn(i) + case *ssa.MakeChan, *ssa.MakeMap, *ssa.MakeSlice, *ssa.BinOp, + *ssa.Alloc, *ssa.DebugRef, *ssa.Convert, *ssa.Jump, *ssa.If, + *ssa.Slice, *ssa.SliceToArrayPointer, *ssa.Range, *ssa.RunDefers: + // No interesting flow here. + // Notes on individual instructions: + // SliceToArrayPointer: t1 = slice to array pointer *[4]T <- []T (t0) + // No interesting flow as sliceArrayElem(t1) == sliceArrayElem(t0). + return + case *ssa.MultiConvert: + b.multiconvert(i) + default: + panic(fmt.Sprintf("unsupported instruction %v\n", instr)) + } +} + +func (b *builder) unop(u *ssa.UnOp) { + switch u.Op { + case token.MUL: + // Multiplication operator * is used here as a dereference operator. + b.addInFlowAliasEdges(b.nodeFromVal(u), b.nodeFromVal(u.X)) + case token.ARROW: + t := typeparams.CoreType(u.X.Type()).(*types.Chan).Elem() + b.addInFlowAliasEdges(b.nodeFromVal(u), channelElem{typ: t}) + default: + // There is no interesting type flow otherwise. + } +} + +func (b *builder) phi(p *ssa.Phi) { + for _, edge := range p.Edges { + b.addInFlowAliasEdges(b.nodeFromVal(p), b.nodeFromVal(edge)) + } +} + +func (b *builder) tassert(a *ssa.TypeAssert) { + if !a.CommaOk { + b.addInFlowEdge(b.nodeFromVal(a.X), b.nodeFromVal(a)) + return + } + // The case where a is register so there + // is a flow from a.X to a[0]. Here, a[0] is represented as an + // indexedLocal: an entry into local tuple register a at index 0. + tup := a.Type().(*types.Tuple) + t := tup.At(0).Type() + + local := indexedLocal{val: a, typ: t, index: 0} + b.addInFlowEdge(b.nodeFromVal(a.X), local) +} + +// extract instruction t1 := t2[i] generates flows between t2[i] +// and t1 where the source is indexed local representing a value +// from tuple register t2 at index i and the target is t1. +func (b *builder) extract(e *ssa.Extract) { + tup := e.Tuple.Type().(*types.Tuple) + t := tup.At(e.Index).Type() + + local := indexedLocal{val: e.Tuple, typ: t, index: e.Index} + b.addInFlowAliasEdges(b.nodeFromVal(e), local) +} + +func (b *builder) field(f *ssa.Field) { + fnode := field{StructType: f.X.Type(), index: f.Field} + b.addInFlowEdge(fnode, b.nodeFromVal(f)) +} + +func (b *builder) fieldAddr(f *ssa.FieldAddr) { + t := typeparams.CoreType(f.X.Type()).(*types.Pointer).Elem() + + // Since we are getting pointer to a field, make a bidirectional edge. + fnode := field{StructType: t, index: f.Field} + b.addInFlowEdge(fnode, b.nodeFromVal(f)) + b.addInFlowEdge(b.nodeFromVal(f), fnode) +} + +func (b *builder) send(s *ssa.Send) { + t := typeparams.CoreType(s.Chan.Type()).(*types.Chan).Elem() + b.addInFlowAliasEdges(channelElem{typ: t}, b.nodeFromVal(s.X)) +} + +// selekt generates flows for select statement +// +// a = select blocking/nonblocking [c_1 <- t_1, c_2 <- t_2, ..., <- o_1, <- o_2, ...] +// +// between receiving channel registers c_i and corresponding input register t_i. Further, +// flows are generated between o_i and a[2 + i]. Note that a is a tuple register of type +// where the type of r_i is the element type of channel o_i. +func (b *builder) selekt(s *ssa.Select) { + recvIndex := 0 + for _, state := range s.States { + t := typeparams.CoreType(state.Chan.Type()).(*types.Chan).Elem() + + if state.Dir == types.SendOnly { + b.addInFlowAliasEdges(channelElem{typ: t}, b.nodeFromVal(state.Send)) + } else { + // state.Dir == RecvOnly by definition of select instructions. + tupEntry := indexedLocal{val: s, typ: t, index: 2 + recvIndex} + b.addInFlowAliasEdges(tupEntry, channelElem{typ: t}) + recvIndex++ + } + } +} + +// index instruction a := b[c] on slices creates flows between a and +// SliceElem(t) flow where t is an interface type of c. Arrays and +// slice elements are both modeled as SliceElem. +func (b *builder) index(i *ssa.Index) { + et := sliceArrayElem(i.X.Type()) + b.addInFlowAliasEdges(b.nodeFromVal(i), sliceElem{typ: et}) +} + +// indexAddr instruction a := &b[c] fetches address of a index +// into the field so we create bidirectional flow a <-> SliceElem(t) +// where t is an interface type of c. Arrays and slice elements are +// both modeled as SliceElem. +func (b *builder) indexAddr(i *ssa.IndexAddr) { + et := sliceArrayElem(i.X.Type()) + b.addInFlowEdge(sliceElem{typ: et}, b.nodeFromVal(i)) + b.addInFlowEdge(b.nodeFromVal(i), sliceElem{typ: et}) +} + +// lookup handles map query commands a := m[b] where m is of type +// map[...]V and V is an interface. It creates flows between `a` +// and MapValue(V). +func (b *builder) lookup(l *ssa.Lookup) { + t, ok := l.X.Type().Underlying().(*types.Map) + if !ok { + // No interesting flows for string lookups. + return + } + + if !l.CommaOk { + b.addInFlowAliasEdges(b.nodeFromVal(l), mapValue{typ: t.Elem()}) + } else { + i := indexedLocal{val: l, typ: t.Elem(), index: 0} + b.addInFlowAliasEdges(i, mapValue{typ: t.Elem()}) + } +} + +// mapUpdate handles map update commands m[b] = a where m is of type +// map[K]V and K and V are interfaces. It creates flows between `a` +// and MapValue(V) as well as between MapKey(K) and `b`. +func (b *builder) mapUpdate(u *ssa.MapUpdate) { + t, ok := u.Map.Type().Underlying().(*types.Map) + if !ok { + // No interesting flows for string updates. + return + } + + b.addInFlowAliasEdges(mapKey{typ: t.Key()}, b.nodeFromVal(u.Key)) + b.addInFlowAliasEdges(mapValue{typ: t.Elem()}, b.nodeFromVal(u.Value)) +} + +// next instruction := next r, where r +// is a range over map or string generates flow between +// key and MapKey as well value and MapValue nodes. +func (b *builder) next(n *ssa.Next) { + if n.IsString { + return + } + tup := n.Type().(*types.Tuple) + kt := tup.At(1).Type() + vt := tup.At(2).Type() + + b.addInFlowAliasEdges(indexedLocal{val: n, typ: kt, index: 1}, mapKey{typ: kt}) + b.addInFlowAliasEdges(indexedLocal{val: n, typ: vt, index: 2}, mapValue{typ: vt}) +} + +// addInFlowAliasEdges adds an edge r -> l to b.graph if l is a node that can +// have an inflow, i.e., a node that represents an interface or an unresolved +// function value. Similarly for the edge l -> r with an additional condition +// of that l and r can potentially alias. +func (b *builder) addInFlowAliasEdges(l, r node) { + b.addInFlowEdge(r, l) + + if canAlias(l, r) { + b.addInFlowEdge(l, r) + } +} + +func (b *builder) closure(c *ssa.MakeClosure) { + f := c.Fn.(*ssa.Function) + b.addInFlowEdge(function{f: f}, b.nodeFromVal(c)) + + for i, fv := range f.FreeVars { + b.addInFlowAliasEdges(b.nodeFromVal(fv), b.nodeFromVal(c.Bindings[i])) + } +} + +// panic creates a flow from arguments to panic instructions to return +// registers of all recover statements in the program. Introduces a +// global panic node Panic and +// 1. for every panic statement p: add p -> Panic +// 2. for every recover statement r: add Panic -> r (handled in call) +// +// TODO(zpavlinovic): improve precision by explicitly modeling how panic +// values flow from callees to callers and into deferred recover instructions. +func (b *builder) panic(p *ssa.Panic) { + // Panics often have, for instance, strings as arguments which do + // not create interesting flows. + if !canHaveMethods(p.X.Type()) { + return + } + + b.addInFlowEdge(b.nodeFromVal(p.X), panicArg{}) +} + +// call adds flows between arguments/parameters and return values/registers +// for both static and dynamic calls, as well as go and defer calls. +func (b *builder) call(c ssa.CallInstruction) { + // When c is r := recover() call register instruction, we add Recover -> r. + if bf, ok := c.Common().Value.(*ssa.Builtin); ok && bf.Name() == "recover" { + if v, ok := c.(ssa.Value); ok { + b.addInFlowEdge(recoverReturn{}, b.nodeFromVal(v)) + } + return + } + + for f := range siteCallees(c, b.callees) { + addArgumentFlows(b, c, f) + + site, ok := c.(ssa.Value) + if !ok { + continue // go or defer + } + + results := f.Signature.Results() + if results.Len() == 1 { + // When there is only one return value, the destination register does not + // have a tuple type. + b.addInFlowEdge(resultVar{f: f, index: 0}, b.nodeFromVal(site)) + } else { + tup := site.Type().(*types.Tuple) + for i := 0; i < results.Len(); i++ { + local := indexedLocal{val: site, typ: tup.At(i).Type(), index: i} + b.addInFlowEdge(resultVar{f: f, index: i}, local) + } + } + } +} + +func addArgumentFlows(b *builder, c ssa.CallInstruction, f *ssa.Function) { + // When f has no parameters (including receiver), there is no type + // flow here. Also, f's body and parameters might be missing, such + // as when vta is used within the golang.org/x/tools/go/analysis + // framework (see github.com/golang/go/issues/50670). + if len(f.Params) == 0 { + return + } + cc := c.Common() + if cc.Method != nil { + // In principle we don't add interprocedural flows for receiver + // objects. At a call site, the receiver object is interface + // while the callee object is concrete. The flow from interface + // to concrete type in general does not make sense. The exception + // is when the concrete type is a named function type (see #57756). + // + // The flow other way around would bake in information from the + // initial call graph. + if isFunction(f.Params[0].Type()) { + b.addInFlowEdge(b.nodeFromVal(cc.Value), b.nodeFromVal(f.Params[0])) + } + } + + offset := 0 + if cc.Method != nil { + offset = 1 + } + for i, v := range cc.Args { + // Parameters of f might not be available, as in the case + // when vta is used within the golang.org/x/tools/go/analysis + // framework (see github.com/golang/go/issues/50670). + // + // TODO: investigate other cases of missing body and parameters + if len(f.Params) <= i+offset { + return + } + b.addInFlowAliasEdges(b.nodeFromVal(f.Params[i+offset]), b.nodeFromVal(v)) + } +} + +// rtrn creates flow edges from the operands of the return +// statement to the result variables of the enclosing function. +func (b *builder) rtrn(r *ssa.Return) { + for i, rs := range r.Results { + b.addInFlowEdge(b.nodeFromVal(rs), resultVar{f: r.Parent(), index: i}) + } +} + +func (b *builder) multiconvert(c *ssa.MultiConvert) { + // TODO(zpavlinovic): decide what to do on MultiConvert long term. + // TODO(zpavlinovic): add unit tests. + typeSetOf := func(typ types.Type) []*types.Term { + // This is a adaptation of x/exp/typeparams.NormalTerms which x/tools cannot depend on. + var terms []*types.Term + var err error + switch typ := types.Unalias(typ).(type) { + case *types.TypeParam: + terms, err = typeparams.StructuralTerms(typ) + case *types.Union: + terms, err = typeparams.UnionTermSet(typ) + case *types.Interface: + terms, err = typeparams.InterfaceTermSet(typ) + default: + // Common case. + // Specializing the len=1 case to avoid a slice + // had no measurable space/time benefit. + terms = []*types.Term{types.NewTerm(false, typ)} + } + + if err != nil { + return nil + } + return terms + } + // isValuePreserving returns true if a conversion from ut_src to + // ut_dst is value-preserving, i.e. just a change of type. + // Precondition: neither argument is a named or alias type. + isValuePreserving := func(ut_src, ut_dst types.Type) bool { + // Identical underlying types? + if types.IdenticalIgnoreTags(ut_dst, ut_src) { + return true + } + + switch ut_dst.(type) { + case *types.Chan: + // Conversion between channel types? + _, ok := ut_src.(*types.Chan) + return ok + + case *types.Pointer: + // Conversion between pointers with identical base types? + _, ok := ut_src.(*types.Pointer) + return ok + } + return false + } + dst_terms := typeSetOf(c.Type()) + src_terms := typeSetOf(c.X.Type()) + for _, s := range src_terms { + us := s.Type().Underlying() + for _, d := range dst_terms { + ud := d.Type().Underlying() + if isValuePreserving(us, ud) { + // This is equivalent to a ChangeType. + b.addInFlowAliasEdges(b.nodeFromVal(c), b.nodeFromVal(c.X)) + return + } + // This is equivalent to either: SliceToArrayPointer,, + // SliceToArrayPointer+Deref, Size 0 Array constant, or a Convert. + } + } +} + +// addInFlowEdge adds s -> d to g if d is node that can have an inflow, i.e., a node +// that represents an interface or an unresolved function value. Otherwise, there +// is no interesting type flow so the edge is omitted. +func (b *builder) addInFlowEdge(s, d node) { + if hasInFlow(d) { + b.graph.addEdge(b.representative(s), b.representative(d)) + } +} + +// Creates const, pointer, global, func, and local nodes based on register instructions. +func (b *builder) nodeFromVal(val ssa.Value) node { + if p, ok := types.Unalias(val.Type()).(*types.Pointer); ok && !types.IsInterface(p.Elem()) && !isFunction(p.Elem()) { + // Nested pointer to interfaces are modeled as a special + // nestedPtrInterface node. + if i := interfaceUnderPtr(p.Elem()); i != nil { + return nestedPtrInterface{typ: i} + } + // The same goes for nested function types. + if f := functionUnderPtr(p.Elem()); f != nil { + return nestedPtrFunction{typ: f} + } + return pointer{typ: p} + } + + switch v := val.(type) { + case *ssa.Const: + return constant{typ: val.Type()} + case *ssa.Global: + return global{val: v} + case *ssa.Function: + return function{f: v} + case *ssa.Parameter, *ssa.FreeVar, ssa.Instruction: + // ssa.Param, ssa.FreeVar, and a specific set of "register" instructions, + // satisfying the ssa.Value interface, can serve as local variables. + return local{val: v} + default: + panic(fmt.Errorf("unsupported value %v in node creation", val)) + } +} + +// representative returns a unique representative for node `n`. Since +// semantically equivalent types can have different implementations, +// this method guarantees the same implementation is always used. +func (b *builder) representative(n node) node { + if n.Type() == nil { + // panicArg and recoverReturn do not have + // types and are unique by definition. + return n + } + t := canonicalize(n.Type(), &b.canon) + + switch i := n.(type) { + case constant: + return constant{typ: t} + case pointer: + return pointer{typ: t.(*types.Pointer)} + case sliceElem: + return sliceElem{typ: t} + case mapKey: + return mapKey{typ: t} + case mapValue: + return mapValue{typ: t} + case channelElem: + return channelElem{typ: t} + case nestedPtrInterface: + return nestedPtrInterface{typ: t} + case nestedPtrFunction: + return nestedPtrFunction{typ: t} + case field: + return field{StructType: canonicalize(i.StructType, &b.canon), index: i.index} + case indexedLocal: + return indexedLocal{typ: t, val: i.val, index: i.index} + case local, global, panicArg, recoverReturn, function, resultVar: + return n + default: + panic(fmt.Errorf("canonicalizing unrecognized node %v", n)) + } +} + +// canonicalize returns a type representative of `t` unique subject +// to type map `canon`. +func canonicalize(t types.Type, canon *typeutil.Map) types.Type { + rep := canon.At(t) + if rep != nil { + return rep.(types.Type) + } + canon.Set(t, t) + return t +} diff --git a/vendor/golang.org/x/tools/go/callgraph/vta/initial.go b/vendor/golang.org/x/tools/go/callgraph/vta/initial.go new file mode 100644 index 0000000..4dddc4e --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/vta/initial.go @@ -0,0 +1,37 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package vta + +import ( + "golang.org/x/tools/go/callgraph" + "golang.org/x/tools/go/callgraph/internal/chautil" + "golang.org/x/tools/go/ssa" +) + +// calleesFunc abstracts call graph in one direction, +// from call sites to callees. +type calleesFunc func(ssa.CallInstruction) []*ssa.Function + +// makeCalleesFunc returns an initial call graph for vta as a +// calleesFunc. If c is not nil, returns callees as given by c. +// Otherwise, it returns chautil.LazyCallees over fs. +func makeCalleesFunc(fs map[*ssa.Function]bool, c *callgraph.Graph) calleesFunc { + if c == nil { + return chautil.LazyCallees(fs) + } + return func(call ssa.CallInstruction) []*ssa.Function { + node := c.Nodes[call.Parent()] + if node == nil { + return nil + } + var cs []*ssa.Function + for _, edge := range node.Out { + if edge.Site == call { + cs = append(cs, edge.Callee.Func) + } + } + return cs + } +} diff --git a/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/bits.go b/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/bits.go new file mode 100644 index 0000000..c3aa159 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/bits.go @@ -0,0 +1,127 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package trie + +import ( + "math/bits" +) + +// This file contains bit twiddling functions for Patricia tries. +// Consult this paper for details. +// C. Okasaki and A. Gill, “Fast mergeable integer maps,” in ACM SIGPLAN +// Workshop on ML, September 1998, pp. 77–86. + +// key is a key in a Map. +type key uint64 + +// bitpos is the position of a bit. A position is represented by having a 1 +// bit in that position. +// Examples: +// - 0b0010 is the position of the `1` bit in 2. +// It is the 3rd most specific bit position in big endian encoding +// (0b0 and 0b1 are more specific). +// - 0b0100 is the position of the bit that 1 and 5 disagree on. +// - 0b0 is a special value indicating that all bit agree. +type bitpos uint64 + +// prefixes represent a set of keys that all agree with the +// prefix up to a bitpos m. +// +// The value for a prefix is determined by the mask(k, m) function. +// (See mask for details on the values.) +// A `p` prefix for position `m` matches a key `k` iff mask(k, m) == p. +// A prefix always mask(p, m) == p. +// +// A key is its own prefix for the bit position 64, +// e.g. seeing a `prefix(key)` is not a problem. +// +// Prefixes should never be turned into keys. +type prefix uint64 + +// branchingBit returns the position of the first bit in `x` and `y` +// that are not equal. +func branchingBit(x, y prefix) bitpos { + p := x ^ y + if p == 0 { + return 0 + } + return bitpos(1) << uint(bits.Len64(uint64(p))-1) // uint conversion needed for go1.12 +} + +// zeroBit returns true if k has a 0 bit at position `b`. +func zeroBit(k prefix, b bitpos) bool { + return (uint64(k) & uint64(b)) == 0 +} + +// matchPrefix returns true if a prefix k matches a prefix p up to position `b`. +func matchPrefix(k prefix, p prefix, b bitpos) bool { + return mask(k, b) == p +} + +// mask returns a prefix of `k` with all bits after and including `b` zeroed out. +// +// In big endian encoding, this value is the [64-(m-1)] most significant bits of k +// followed by a `0` bit at bitpos m, followed m-1 `1` bits. +// Examples: +// +// prefix(0b1011) for a bitpos 0b0100 represents the keys: +// 0b1000, 0b1001, 0b1010, 0b1011, 0b1100, 0b1101, 0b1110, 0b1111 +// +// This mask function has the property that if matchPrefix(k, p, b), then +// k <= p if and only if zeroBit(k, m). This induces binary search tree tries. +// See Okasaki & Gill for more details about this choice of mask function. +// +// mask is idempotent for a given `b`, i.e. mask(mask(p, b), b) == mask(p,b). +func mask(k prefix, b bitpos) prefix { + return prefix((uint64(k) | (uint64(b) - 1)) & (^uint64(b))) +} + +// ord returns true if m comes before n in the bit ordering. +func ord(m, n bitpos) bool { + return m > n // big endian encoding +} + +// prefixesOverlap returns true if there is some key a prefix `p` for bitpos `m` +// can hold that can also be held by a prefix `q` for some bitpos `n`. +// +// This is equivalent to: +// +// m ==n && p == q, +// higher(m, n) && matchPrefix(q, p, m), or +// higher(n, m) && matchPrefix(p, q, n) +func prefixesOverlap(p prefix, m bitpos, q prefix, n bitpos) bool { + fbb := n + if ord(m, n) { + fbb = m + } + return mask(p, fbb) == mask(q, fbb) + // Lemma: + // mask(p, fbb) == mask(q, fbb) + // iff + // m > n && matchPrefix(q, p, m) or (note: big endian encoding) + // m < n && matchPrefix(p, q, n) or (note: big endian encoding) + // m ==n && p == q + // Quick-n-dirty proof: + // p == mask(p0, m) for some p0 by precondition. + // q == mask(q0, n) for some q0 by precondition. + // So mask(p, m) == p and mask(q, n) == q as mask(*, n') is idempotent. + // + // [=> proof] + // Suppose mask(p, fbb) == mask(q, fbb). + // if m ==n, p == mask(p, m) == mask(p, fbb) == mask(q, fbb) == mask(q, n) == q + // if m > n, fbb = firstBranchBit(m, n) = m (big endian). + // p == mask(p, m) == mask(p, fbb) == mask(q, fbb) == mask(q, m) + // so mask(q, m) == p or matchPrefix(q, p, m) + // if m < n, is symmetric to the above. + // + // [<= proof] + // case m ==n && p == q. Then mask(p, fbb) == mask(q, fbb) + // + // case m > n && matchPrefix(q, p, m). + // fbb == firstBranchBit(m, n) == m (by m>n). + // mask(q, fbb) == mask(q, m) == p == mask(p, m) == mask(p, fbb) + // + // case m < n && matchPrefix(p, q, n) is symmetric. +} diff --git a/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/builder.go b/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/builder.go new file mode 100644 index 0000000..adef128 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/builder.go @@ -0,0 +1,516 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package trie + +// Collision functions combine a left and right hand side (lhs and rhs) values +// the two values are associated with the same key and produces the value that +// will be stored for the key. +// +// Collision functions must be idempotent: +// +// collision(x, x) == x for all x. +// +// Collisions functions may be applied whenever a value is inserted +// or two maps are merged, or intersected. +type Collision func(lhs any, rhs any) any + +// TakeLhs always returns the left value in a collision. +func TakeLhs(lhs, rhs any) any { return lhs } + +// TakeRhs always returns the right hand side in a collision. +func TakeRhs(lhs, rhs any) any { return rhs } + +// Builder creates new Map. Each Builder has a unique Scope. +// +// IMPORTANT: Nodes are hash-consed internally to reduce memory consumption. To +// support hash-consing Builders keep an internal Map of all of the Maps that they +// have created. To GC any of the Maps created by the Builder, all references to +// the Builder must be dropped. This includes MutMaps. +type Builder struct { + scope Scope + + // hash-consing maps for each node type. + empty *empty + leaves map[leaf]*leaf + branches map[branch]*branch + // It may be possible to support more types of patricia tries + // (e.g. non-hash-consed) by making Builder an interface and abstracting + // the mkLeaf and mkBranch functions. +} + +// NewBuilder creates a new Builder with a unique Scope. +func NewBuilder() *Builder { + s := newScope() + return &Builder{ + scope: s, + empty: &empty{s}, + leaves: make(map[leaf]*leaf), + branches: make(map[branch]*branch), + } +} + +func (b *Builder) Scope() Scope { return b.scope } + +// Rescope changes the builder's scope to a new unique Scope. +// +// Any Maps created using the previous scope need to be Cloned +// before any operation. +// +// This makes the old internals of the Builder eligible to be GC'ed. +func (b *Builder) Rescope() { + s := newScope() + b.scope = s + b.empty = &empty{s} + b.leaves = make(map[leaf]*leaf) + b.branches = make(map[branch]*branch) +} + +// Empty is the empty map. +func (b *Builder) Empty() Map { return Map{b.Scope(), b.empty} } + +// InsertWith inserts a new association from k to v into the Map m to create a new map +// in the current scope and handle collisions using the collision function c. +// +// This is roughly corresponds to updating a map[uint64]interface{} by: +// +// if _, ok := m[k]; ok { m[k] = c(m[k], v} else { m[k] = v} +// +// An insertion or update happened whenever Insert(m, ...) != m . +func (b *Builder) InsertWith(c Collision, m Map, k uint64, v any) Map { + m = b.Clone(m) + return Map{b.Scope(), b.insert(c, m.n, b.mkLeaf(key(k), v), false)} +} + +// Inserts a new association from key to value into the Map m to create +// a new map in the current scope. +// +// If there was a previous value mapped by key, keep the previously mapped value. +// This is roughly corresponds to updating a map[uint64]interface{} by: +// +// if _, ok := m[k]; ok { m[k] = val } +// +// This is equivalent to b.Merge(m, b.Create({k: v})). +func (b *Builder) Insert(m Map, k uint64, v any) Map { + return b.InsertWith(TakeLhs, m, k, v) +} + +// Updates a (key, value) in the map. This is roughly corresponds to +// updating a map[uint64]interface{} by: +// +// m[key] = val +func (b *Builder) Update(m Map, key uint64, val any) Map { + return b.InsertWith(TakeRhs, m, key, val) +} + +// Merge two maps lhs and rhs to create a new map in the current scope. +// +// Whenever there is a key in both maps (a collision), the resulting value mapped by +// the key will be `c(lhs[key], rhs[key])`. +func (b *Builder) MergeWith(c Collision, lhs, rhs Map) Map { + lhs, rhs = b.Clone(lhs), b.Clone(rhs) + return Map{b.Scope(), b.merge(c, lhs.n, rhs.n)} +} + +// Merge two maps lhs and rhs to create a new map in the current scope. +// +// Whenever there is a key in both maps (a collision), the resulting value mapped by +// the key will be the value in lhs `b.Collision(lhs[key], rhs[key])`. +func (b *Builder) Merge(lhs, rhs Map) Map { + return b.MergeWith(TakeLhs, lhs, rhs) +} + +// Clone returns a Map that contains the same (key, value) elements +// within b.Scope(), i.e. return m if m.Scope() == b.Scope() or return +// a deep copy of m within b.Scope() otherwise. +func (b *Builder) Clone(m Map) Map { + if m.Scope() == b.Scope() { + return m + } else if m.n == nil { + return Map{b.Scope(), b.empty} + } + return Map{b.Scope(), b.clone(m.n)} +} +func (b *Builder) clone(n node) node { + switch n := n.(type) { + case *empty: + return b.empty + case *leaf: + return b.mkLeaf(n.k, n.v) + case *branch: + return b.mkBranch(n.prefix, n.branching, b.clone(n.left), b.clone(n.right)) + default: + panic("unreachable") + } +} + +// Remove a key from a Map m and return the resulting Map. +func (b *Builder) Remove(m Map, k uint64) Map { + m = b.Clone(m) + return Map{b.Scope(), b.remove(m.n, key(k))} +} + +// Intersect Maps lhs and rhs and returns a map with all of the keys in +// both lhs and rhs and the value comes from lhs, i.e. +// +// {(k, lhs[k]) | k in lhs, k in rhs}. +func (b *Builder) Intersect(lhs, rhs Map) Map { + return b.IntersectWith(TakeLhs, lhs, rhs) +} + +// IntersectWith take lhs and rhs and returns the intersection +// with the value coming from the collision function, i.e. +// +// {(k, c(lhs[k], rhs[k]) ) | k in lhs, k in rhs}. +// +// The elements of the resulting map are always { } +// for each key k that a key in both lhs and rhs. +func (b *Builder) IntersectWith(c Collision, lhs, rhs Map) Map { + l, r := b.Clone(lhs), b.Clone(rhs) + return Map{b.Scope(), b.intersect(c, l.n, r.n)} +} + +// MutMap is a convenient wrapper for a Map and a *Builder that will be used to create +// new Maps from it. +type MutMap struct { + B *Builder + M Map +} + +// MutEmpty is an empty MutMap for a builder. +func (b *Builder) MutEmpty() MutMap { + return MutMap{b, b.Empty()} +} + +// Insert an element into the map using the collision function for the builder. +// Returns true if the element was inserted. +func (mm *MutMap) Insert(k uint64, v any) bool { + old := mm.M + mm.M = mm.B.Insert(old, k, v) + return old != mm.M +} + +// Updates an element in the map. Returns true if the map was updated. +func (mm *MutMap) Update(k uint64, v any) bool { + old := mm.M + mm.M = mm.B.Update(old, k, v) + return old != mm.M +} + +// Removes a key from the map. Returns true if the element was removed. +func (mm *MutMap) Remove(k uint64) bool { + old := mm.M + mm.M = mm.B.Remove(old, k) + return old != mm.M +} + +// Merge another map into the current one using the collision function +// for the builder. Returns true if the map changed. +func (mm *MutMap) Merge(other Map) bool { + old := mm.M + mm.M = mm.B.Merge(old, other) + return old != mm.M +} + +// Intersect another map into the current one using the collision function +// for the builder. Returns true if the map changed. +func (mm *MutMap) Intersect(other Map) bool { + old := mm.M + mm.M = mm.B.Intersect(old, other) + return old != mm.M +} + +func (b *Builder) Create(m map[uint64]any) Map { + var leaves []*leaf + for k, v := range m { + leaves = append(leaves, b.mkLeaf(key(k), v)) + } + return Map{b.Scope(), b.create(leaves)} +} + +// Merge another map into the current one using the collision function +// for the builder. Returns true if the map changed. +func (mm *MutMap) MergeWith(c Collision, other Map) bool { + old := mm.M + mm.M = mm.B.MergeWith(c, old, other) + return old != mm.M +} + +// creates a map for a collection of leaf nodes. +func (b *Builder) create(leaves []*leaf) node { + n := len(leaves) + if n == 0 { + return b.empty + } else if n == 1 { + return leaves[0] + } + // Note: we can do a more sophisticated algorithm by: + // - sorting the leaves ahead of time, + // - taking the prefix and branching bit of the min and max key, + // - binary searching for the branching bit, + // - splitting exactly where the branch will be, and + // - making the branch node for this prefix + branching bit. + // Skipping until this is a performance bottleneck. + + m := n / 2 // (n >= 2) ==> 1 <= m < n + l, r := leaves[:m], leaves[m:] + return b.merge(nil, b.create(l), b.create(r)) +} + +// mkLeaf returns the hash-consed representative of (k, v) in the current scope. +func (b *Builder) mkLeaf(k key, v any) *leaf { + rep, ok := b.leaves[leaf{k, v}] + if !ok { + rep = &leaf{k, v} // heap-allocated copy + b.leaves[leaf{k, v}] = rep + } + return rep +} + +// mkBranch returns the hash-consed representative of the tuple +// +// (prefix, branch, left, right) +// +// in the current scope. +func (b *Builder) mkBranch(p prefix, bp bitpos, left node, right node) *branch { + br := branch{ + sz: left.size() + right.size(), + prefix: p, + branching: bp, + left: left, + right: right, + } + rep, ok := b.branches[br] + if !ok { + rep = new(branch) // heap-allocated copy + *rep = br + b.branches[br] = rep + } + return rep +} + +// join two maps with prefixes p0 and p1 that are *known* to disagree. +func (b *Builder) join(p0 prefix, t0 node, p1 prefix, t1 node) *branch { + m := branchingBit(p0, p1) + var left, right node + if zeroBit(p0, m) { + left, right = t0, t1 + } else { + left, right = t1, t0 + } + prefix := mask(p0, m) + return b.mkBranch(prefix, m, left, right) +} + +// collide two leaves with the same key to create a leaf +// with the collided value. +func (b *Builder) collide(c Collision, left, right *leaf) *leaf { + if left == right { + return left // c is idempotent: c(x, x) == x + } + val := left.v // keep the left value by default if c is nil + if c != nil { + val = c(left.v, right.v) + } + switch val { + case left.v: + return left + case right.v: + return right + default: + return b.mkLeaf(left.k, val) + } +} + +// inserts a leaf l into a map m and returns the resulting map. +// When lhs is true, l is the left hand side in a collision. +// Both l and m are in the current scope. +func (b *Builder) insert(c Collision, m node, l *leaf, lhs bool) node { + switch m := m.(type) { + case *empty: + return l + case *leaf: + if m.k == l.k { + left, right := l, m + if !lhs { + left, right = right, left + } + return b.collide(c, left, right) + } + return b.join(prefix(l.k), l, prefix(m.k), m) + case *branch: + // fallthrough + } + // m is a branch + br := m.(*branch) + if !matchPrefix(prefix(l.k), br.prefix, br.branching) { + return b.join(prefix(l.k), l, br.prefix, br) + } + var left, right node + if zeroBit(prefix(l.k), br.branching) { + left, right = b.insert(c, br.left, l, lhs), br.right + } else { + left, right = br.left, b.insert(c, br.right, l, lhs) + } + if left == br.left && right == br.right { + return m + } + return b.mkBranch(br.prefix, br.branching, left, right) +} + +// merge two maps in the current scope. +func (b *Builder) merge(c Collision, lhs, rhs node) node { + if lhs == rhs { + return lhs + } + switch lhs := lhs.(type) { + case *empty: + return rhs + case *leaf: + return b.insert(c, rhs, lhs, true) + case *branch: + switch rhs := rhs.(type) { + case *empty: + return lhs + case *leaf: + return b.insert(c, lhs, rhs, false) + case *branch: + // fallthrough + } + } + + // Last remaining case is branch merging. + // For brevity, we adopt the Okasaki and Gill naming conventions + // for branching and prefixes. + s, t := lhs.(*branch), rhs.(*branch) + p, m := s.prefix, s.branching + q, n := t.prefix, t.branching + + if m == n && p == q { // prefixes are identical. + left, right := b.merge(c, s.left, t.left), b.merge(c, s.right, t.right) + return b.mkBranch(p, m, left, right) + } + if !prefixesOverlap(p, m, q, n) { + return b.join(p, s, q, t) // prefixes are disjoint. + } + // prefixesOverlap(p, m, q, n) && !(m ==n && p == q) + // By prefixesOverlap(...), either: + // higher(m, n) && matchPrefix(q, p, m), or + // higher(n, m) && matchPrefix(p, q, n) + // So either s or t may can be merged with one branch or the other. + switch { + case ord(m, n) && zeroBit(q, m): + return b.mkBranch(p, m, b.merge(c, s.left, t), s.right) + case ord(m, n) && !zeroBit(q, m): + return b.mkBranch(p, m, s.left, b.merge(c, s.right, t)) + case ord(n, m) && zeroBit(p, n): + return b.mkBranch(q, n, b.merge(c, s, t.left), t.right) + default: + return b.mkBranch(q, n, t.left, b.merge(c, s, t.right)) + } +} + +func (b *Builder) remove(m node, k key) node { + switch m := m.(type) { + case *empty: + return m + case *leaf: + if m.k == k { + return b.empty + } + return m + case *branch: + // fallthrough + } + br := m.(*branch) + kp := prefix(k) + if !matchPrefix(kp, br.prefix, br.branching) { + // The prefix does not match. kp is not in br. + return br + } + // the prefix matches. try to remove from the left or right branch. + left, right := br.left, br.right + if zeroBit(kp, br.branching) { + left = b.remove(left, k) // k may be in the left branch. + } else { + right = b.remove(right, k) // k may be in the right branch. + } + if left == br.left && right == br.right { + return br // no update + } else if _, ok := left.(*empty); ok { + return right // left updated and is empty. + } else if _, ok := right.(*empty); ok { + return left // right updated and is empty. + } + // Either left or right updated. Both left and right are not empty. + // The left and right branches still share the same prefix and disagree + // on the same branching bit. It is safe to directly create the branch. + return b.mkBranch(br.prefix, br.branching, left, right) +} + +func (b *Builder) intersect(c Collision, l, r node) node { + if l == r { + return l + } + switch l := l.(type) { + case *empty: + return b.empty + case *leaf: + if rleaf := r.find(l.k); rleaf != nil { + return b.collide(c, l, rleaf) + } + return b.empty + case *branch: + switch r := r.(type) { + case *empty: + return b.empty + case *leaf: + if lleaf := l.find(r.k); lleaf != nil { + return b.collide(c, lleaf, r) + } + return b.empty + case *branch: + // fallthrough + } + } + // Last remaining case is branch intersection. + s, t := l.(*branch), r.(*branch) + p, m := s.prefix, s.branching + q, n := t.prefix, t.branching + + if m == n && p == q { + // prefixes are identical. + left, right := b.intersect(c, s.left, t.left), b.intersect(c, s.right, t.right) + if _, ok := left.(*empty); ok { + return right + } else if _, ok := right.(*empty); ok { + return left + } + // The left and right branches are both non-empty. + // They still share the same prefix and disagree on the same branching bit. + // It is safe to directly create the branch. + return b.mkBranch(p, m, left, right) + } + + if !prefixesOverlap(p, m, q, n) { + return b.empty // The prefixes share no keys. + } + // prefixesOverlap(p, m, q, n) && !(m ==n && p == q) + // By prefixesOverlap(...), either: + // ord(m, n) && matchPrefix(q, p, m), or + // ord(n, m) && matchPrefix(p, q, n) + // So either s or t may be a strict subtree of the other. + var lhs, rhs node + switch { + case ord(m, n) && zeroBit(q, m): + lhs, rhs = s.left, t + case ord(m, n) && !zeroBit(q, m): + lhs, rhs = s.right, t + case ord(n, m) && zeroBit(p, n): + lhs, rhs = s, t.left + default: + lhs, rhs = s, t.right + } + return b.intersect(c, lhs, rhs) +} diff --git a/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/scope.go b/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/scope.go new file mode 100644 index 0000000..1f43742 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/scope.go @@ -0,0 +1,28 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package trie + +import ( + "strconv" + "sync/atomic" +) + +// Scope represents a distinct collection of maps. +// Maps with the same Scope can be equal. Maps in different scopes are distinct. +// Each Builder creates maps within a unique Scope. +type Scope struct { + id int32 +} + +var nextScopeId atomic.Int32 + +func newScope() Scope { + id := nextScopeId.Add(1) + return Scope{id: id} +} + +func (s Scope) String() string { + return strconv.Itoa(int(s.id)) +} diff --git a/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/trie.go b/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/trie.go new file mode 100644 index 0000000..a848019 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/trie.go @@ -0,0 +1,229 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// trie implements persistent Patricia trie maps. +// +// Each Map is effectively a map from uint64 to interface{}. Patricia tries are +// a form of radix tree that are particularly appropriate when many maps will be +// created, merged together and large amounts of sharing are expected (e.g. +// environment abstract domains in program analysis). +// +// This implementation closely follows the paper: +// +// C. Okasaki and A. Gill, “Fast mergeable integer maps,” in ACM SIGPLAN +// Workshop on ML, September 1998, pp. 77–86. +// +// Each Map is immutable and can be read from concurrently. The map does not +// guarantee that the value pointed to by the interface{} value is not updated +// concurrently. +// +// These Maps are optimized for situations where there will be many maps created at +// with a high degree of sharing and combining of maps together. If you do not expect, +// significant amount of sharing, the builtin map[T]U is much better choice! +// +// Each Map is created by a Builder. Each Builder has a unique Scope and each node is +// created within this scope. Maps x and y are == if they contains the same +// (key,value) mappings and have equal scopes. +// +// Internally these are big endian Patricia trie nodes, and the keys are sorted. +package trie + +import ( + "fmt" + "strings" +) + +// Map is effectively a finite mapping from uint64 keys to interface{} values. +// Maps are immutable and can be read from concurrently. +// +// Notes on concurrency: +// - A Map value itself is an interface and assignments to a Map value can race. +// - Map does not guarantee that the value pointed to by the interface{} value +// is not updated concurrently. +type Map struct { + s Scope + n node +} + +func (m Map) Scope() Scope { + return m.s +} +func (m Map) Size() int { + if m.n == nil { + return 0 + } + return m.n.size() +} +func (m Map) Lookup(k uint64) (any, bool) { + if m.n != nil { + if leaf := m.n.find(key(k)); leaf != nil { + return leaf.v, true + } + } + return nil, false +} + +// Converts the map into a {: [, ...]} string. This uses the default +// %s string conversion for . +func (m Map) String() string { + var kvs []string + m.Range(func(u uint64, i any) bool { + kvs = append(kvs, fmt.Sprintf("%d: %s", u, i)) + return true + }) + return fmt.Sprintf("{%s}", strings.Join(kvs, ", ")) +} + +// Range over the leaf (key, value) pairs in the map in order and +// applies cb(key, value) to each. Stops early if cb returns false. +// Returns true if all elements were visited without stopping early. +func (m Map) Range(cb func(uint64, any) bool) bool { + if m.n != nil { + return m.n.visit(cb) + } + return true +} + +// DeepEqual returns true if m and other contain the same (k, v) mappings +// [regardless of Scope]. +// +// Equivalently m.DeepEqual(other) <=> reflect.DeepEqual(Elems(m), Elems(other)) +func (m Map) DeepEqual(other Map) bool { + if m.Scope() == other.Scope() { + return m.n == other.n + } + if (m.n == nil) || (other.n == nil) { + return m.Size() == 0 && other.Size() == 0 + } + return m.n.deepEqual(other.n) +} + +// Elems are the (k,v) elements in the Map as a map[uint64]interface{} +func Elems(m Map) map[uint64]any { + dest := make(map[uint64]any, m.Size()) + m.Range(func(k uint64, v any) bool { + dest[k] = v + return true + }) + return dest +} + +// node is an internal node within a trie map. +// A node is either empty, a leaf or a branch. +type node interface { + size() int + + // visit the leaves (key, value) pairs in the map in order and + // applies cb(key, value) to each. Stops early if cb returns false. + // Returns true if all elements were visited without stopping early. + visit(cb func(uint64, any) bool) bool + + // Two nodes contain the same elements regardless of scope. + deepEqual(node) bool + + // find the leaf for the given key value or nil if it is not present. + find(k key) *leaf + + // implementations must implement this. + nodeImpl() +} + +// empty represents the empty map within a scope. +// +// The current builder ensure +type empty struct { + s Scope +} + +// leaf represents a single pair. +type leaf struct { + k key + v any +} + +// branch represents a tree node within the Patricia trie. +// +// All keys within the branch match a `prefix` of the key +// up to a `branching` bit, and the left and right nodes +// contain keys that disagree on the bit at the `branching` bit. +type branch struct { + sz int // size. cached for O(1) lookup + prefix prefix // == mask(p0, branching) for some p0 + branching bitpos + + // Invariants: + // - neither is nil. + // - neither is *empty. + // - all keys in left are <= p. + // - all keys in right are > p. + left, right node +} + +// all of these types are Maps. +var _ node = &empty{} +var _ node = &leaf{} +var _ node = &branch{} + +func (*empty) nodeImpl() {} +func (*leaf) nodeImpl() {} +func (*branch) nodeImpl() {} + +func (*empty) find(k key) *leaf { return nil } +func (l *leaf) find(k key) *leaf { + if k == l.k { + return l + } + return nil +} +func (br *branch) find(k key) *leaf { + kp := prefix(k) + if !matchPrefix(kp, br.prefix, br.branching) { + return nil + } + if zeroBit(kp, br.branching) { + return br.left.find(k) + } + return br.right.find(k) +} + +func (*empty) size() int { return 0 } +func (*leaf) size() int { return 1 } +func (br *branch) size() int { return br.sz } + +func (*empty) deepEqual(m node) bool { + _, ok := m.(*empty) + return ok +} +func (l *leaf) deepEqual(m node) bool { + if m, ok := m.(*leaf); ok { + return m == l || (l.k == m.k && l.v == m.v) + } + return false +} + +func (br *branch) deepEqual(m node) bool { + if m, ok := m.(*branch); ok { + if br == m { + return true + } + return br.sz == m.sz && br.branching == m.branching && br.prefix == m.prefix && + br.left.deepEqual(m.left) && br.right.deepEqual(m.right) + } + // if m is not a branch, m contains 0 or 1 elem. + // br contains at least 2 keys that disagree on a prefix. + return false +} + +func (*empty) visit(cb func(uint64, any) bool) bool { + return true +} +func (l *leaf) visit(cb func(uint64, any) bool) bool { + return cb(uint64(l.k), l.v) +} +func (br *branch) visit(cb func(uint64, any) bool) bool { + if !br.left.visit(cb) { + return false + } + return br.right.visit(cb) +} diff --git a/vendor/golang.org/x/tools/go/callgraph/vta/propagation.go b/vendor/golang.org/x/tools/go/callgraph/vta/propagation.go new file mode 100644 index 0000000..33ec246 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/vta/propagation.go @@ -0,0 +1,201 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package vta + +import ( + "go/types" + "iter" + "slices" + + "golang.org/x/tools/go/callgraph/vta/internal/trie" + "golang.org/x/tools/go/ssa" + + "golang.org/x/tools/go/types/typeutil" +) + +// scc computes strongly connected components (SCCs) of `g` using the +// classical Tarjan's algorithm for SCCs. The result is two slices: +// - sccs: the SCCs, each represented as a slice of node indices +// - idxToSccID: the inverse map, from node index to SCC number. +// +// The SCCs are sorted in reverse topological order: for SCCs +// with ids X and Y s.t. X < Y, Y comes before X in the topological order. +func scc(g *vtaGraph) (sccs [][]idx, idxToSccID []int) { + // standard data structures used by Tarjan's algorithm. + type state struct { + pre int // preorder of the node (0 if unvisited) + lowLink int + onStack bool + } + states := make([]state, g.numNodes()) + var stack []idx + + idxToSccID = make([]int, g.numNodes()) + nextPre := 0 + + var doSCC func(idx) + doSCC = func(n idx) { + nextPre++ + ns := &states[n] + *ns = state{pre: nextPre, lowLink: nextPre, onStack: true} + stack = append(stack, n) + + for s := range g.successors(n) { + if ss := &states[s]; ss.pre == 0 { + // Analyze successor s that has not been visited yet. + doSCC(s) + ns.lowLink = min(ns.lowLink, ss.lowLink) + } else if ss.onStack { + // The successor is on the stack, meaning it has to be + // in the current SCC. + ns.lowLink = min(ns.lowLink, ss.pre) + } + } + + // if n is a root node, pop the stack and generate a new SCC. + if ns.lowLink == ns.pre { + sccStart := slicesLastIndex(stack, n) + scc := slices.Clone(stack[sccStart:]) + stack = stack[:sccStart] + sccID := len(sccs) + sccs = append(sccs, scc) + for _, w := range scc { + states[w].onStack = false + idxToSccID[w] = sccID + } + } + } + + for n, nn := 0, g.numNodes(); n < nn; n++ { + if states[n].pre == 0 { + doSCC(idx(n)) + } + } + + return sccs, idxToSccID +} + +// slicesLastIndex returns the index of the last occurrence of v in s, or -1 if v is +// not present in s. +// +// slicesLastIndex iterates backwards through the elements of s, stopping when the == +// operator determines an element is equal to v. +func slicesLastIndex[S ~[]E, E comparable](s S, v E) int { + // TODO: move to / dedup with slices.LastIndex + for i := len(s) - 1; i >= 0; i-- { + if s[i] == v { + return i + } + } + return -1 +} + +// propType represents type information being propagated +// over the vta graph. f != nil only for function nodes +// and nodes reachable from function nodes. There, we also +// remember the actual *ssa.Function in order to more +// precisely model higher-order flow. +type propType struct { + typ types.Type + f *ssa.Function +} + +// propTypeMap is an auxiliary structure that serves +// the role of a map from nodes to a set of propTypes. +type propTypeMap map[node]*trie.MutMap + +// propTypes returns an iterator for the propTypes associated with +// node `n` in map `ptm`. +func (ptm propTypeMap) propTypes(n node) iter.Seq[propType] { + return func(yield func(propType) bool) { + if types := ptm[n]; types != nil { + types.M.Range(func(_ uint64, elem any) bool { + return yield(elem.(propType)) + }) + } + } +} + +// propagate reduces the `graph` based on its SCCs and +// then propagates type information through the reduced +// graph. The result is a map from nodes to a set of types +// and functions, stemming from higher-order data flow, +// reaching the node. `canon` is used for type uniqueness. +func propagate(graph *vtaGraph, canon *typeutil.Map) propTypeMap { + sccs, idxToSccID := scc(graph) + + // propTypeIds are used to create unique ids for + // propType, to be used for trie-based type sets. + propTypeIds := make(map[propType]uint64) + // Id creation is based on == equality, which works + // as types are canonicalized (see getPropType). + propTypeId := func(p propType) uint64 { + if id, ok := propTypeIds[p]; ok { + return id + } + id := uint64(len(propTypeIds)) + propTypeIds[p] = id + return id + } + builder := trie.NewBuilder() + // Initialize sccToTypes to avoid repeated check + // for initialization later. + sccToTypes := make([]*trie.MutMap, len(sccs)) + for sccID, scc := range sccs { + typeSet := builder.MutEmpty() + for _, idx := range scc { + if n := graph.node[idx]; hasInitialTypes(n) { + // add the propType for idx to typeSet. + pt := getPropType(n, canon) + typeSet.Update(propTypeId(pt), pt) + } + } + sccToTypes[sccID] = &typeSet + } + + for i, scc := range slices.Backward(sccs) { + nextSccs := make(map[int]empty) + for _, n := range scc { + for succ := range graph.successors(n) { + nextSccs[idxToSccID[succ]] = empty{} + } + } + // Propagate types to all successor SCCs. + for nextScc := range nextSccs { + sccToTypes[nextScc].Merge(sccToTypes[i].M) + } + } + nodeToTypes := make(propTypeMap, graph.numNodes()) + for sccID, scc := range sccs { + types := sccToTypes[sccID] + for _, idx := range scc { + nodeToTypes[graph.node[idx]] = types + } + } + return nodeToTypes +} + +// hasInitialTypes check if a node can have initial types. +// Returns true iff `n` is not a panic, recover, nestedPtr* +// node, nor a node whose type is an interface. +func hasInitialTypes(n node) bool { + switch n.(type) { + case panicArg, recoverReturn, nestedPtrFunction, nestedPtrInterface: + return false + default: + return !types.IsInterface(n.Type()) + } +} + +// getPropType creates a propType for `node` based on its type. +// propType.typ is always node.Type(). If node is function, then +// propType.val is the underlying function; nil otherwise. +func getPropType(node node, canon *typeutil.Map) propType { + t := canonicalize(node.Type(), canon) + if fn, ok := node.(function); ok { + return propType{f: fn.f, typ: t} + } + return propType{f: nil, typ: t} +} diff --git a/vendor/golang.org/x/tools/go/callgraph/vta/utils.go b/vendor/golang.org/x/tools/go/callgraph/vta/utils.go new file mode 100644 index 0000000..3a708f2 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/vta/utils.go @@ -0,0 +1,188 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package vta + +import ( + "go/types" + "iter" + + "golang.org/x/tools/go/ssa" + "golang.org/x/tools/internal/typeparams" +) + +func canAlias(n1, n2 node) bool { + return isReferenceNode(n1) && isReferenceNode(n2) +} + +func isReferenceNode(n node) bool { + if _, ok := n.(nestedPtrInterface); ok { + return true + } + if _, ok := n.(nestedPtrFunction); ok { + return true + } + + if _, ok := types.Unalias(n.Type()).(*types.Pointer); ok { + return true + } + + return false +} + +// hasInFlow checks if a concrete type can flow to node `n`. +// Returns yes iff the type of `n` satisfies one the following: +// 1. is an interface +// 2. is a (nested) pointer to interface (needed for, say, +// slice elements of nested pointers to interface type) +// 3. is a function type (needed for higher-order type flow) +// 4. is a (nested) pointer to function (needed for, say, +// slice elements of nested pointers to function type) +// 5. is a global Recover or Panic node +func hasInFlow(n node) bool { + if _, ok := n.(panicArg); ok { + return true + } + if _, ok := n.(recoverReturn); ok { + return true + } + + t := n.Type() + + if i := interfaceUnderPtr(t); i != nil { + return true + } + if f := functionUnderPtr(t); f != nil { + return true + } + + return types.IsInterface(t) || isFunction(t) +} + +func isFunction(t types.Type) bool { + _, ok := t.Underlying().(*types.Signature) + return ok +} + +// interfaceUnderPtr checks if type `t` is a potentially nested +// pointer to interface and if yes, returns the interface type. +// Otherwise, returns nil. +func interfaceUnderPtr(t types.Type) types.Type { + seen := make(map[types.Type]bool) + var visit func(types.Type) types.Type + visit = func(t types.Type) types.Type { + if seen[t] { + return nil + } + seen[t] = true + + p, ok := t.Underlying().(*types.Pointer) + if !ok { + return nil + } + + if types.IsInterface(p.Elem()) { + return p.Elem() + } + + return visit(p.Elem()) + } + return visit(t) +} + +// functionUnderPtr checks if type `t` is a potentially nested +// pointer to function type and if yes, returns the function type. +// Otherwise, returns nil. +func functionUnderPtr(t types.Type) types.Type { + seen := make(map[types.Type]bool) + var visit func(types.Type) types.Type + visit = func(t types.Type) types.Type { + if seen[t] { + return nil + } + seen[t] = true + + p, ok := t.Underlying().(*types.Pointer) + if !ok { + return nil + } + + if isFunction(p.Elem()) { + return p.Elem() + } + + return visit(p.Elem()) + } + return visit(t) +} + +// sliceArrayElem returns the element type of type `t` that is +// expected to be a (pointer to) array, slice or string, consistent with +// the ssa.Index and ssa.IndexAddr instructions. Panics otherwise. +func sliceArrayElem(t types.Type) types.Type { + switch u := t.Underlying().(type) { + case *types.Pointer: + switch e := u.Elem().Underlying().(type) { + case *types.Array: + return e.Elem() + case *types.Interface: + return sliceArrayElem(e) // e is a type param with matching element types. + default: + panic(t) + } + case *types.Array: + return u.Elem() + case *types.Slice: + return u.Elem() + case *types.Basic: + return types.Typ[types.Byte] + case *types.Interface: // type param. + terms, err := typeparams.InterfaceTermSet(u) + if err != nil || len(terms) == 0 { + panic(t) + } + return sliceArrayElem(terms[0].Type()) // Element types must match. + default: + panic(t) + } +} + +// siteCallees returns an iterator for the callees for call site `c`. +func siteCallees(c ssa.CallInstruction, callees calleesFunc) iter.Seq[*ssa.Function] { + return func(yield func(*ssa.Function) bool) { + for _, callee := range callees(c) { + if !yield(callee) { + return + } + } + } +} + +func canHaveMethods(t types.Type) bool { + t = types.Unalias(t) + if _, ok := t.(*types.Named); ok { + return true + } + + u := t.Underlying() + switch u.(type) { + case *types.Interface, *types.Signature, *types.Struct: + return true + default: + return false + } +} + +// calls returns the set of call instructions in `f`. +func calls(f *ssa.Function) []ssa.CallInstruction { + var calls []ssa.CallInstruction + for _, bl := range f.Blocks { + for _, instr := range bl.Instrs { + if c, ok := instr.(ssa.CallInstruction); ok { + calls = append(calls, c) + } + } + } + return calls +} diff --git a/vendor/golang.org/x/tools/go/callgraph/vta/vta.go b/vendor/golang.org/x/tools/go/callgraph/vta/vta.go new file mode 100644 index 0000000..26b33f0 --- /dev/null +++ b/vendor/golang.org/x/tools/go/callgraph/vta/vta.go @@ -0,0 +1,193 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package vta computes the call graph of a Go program using the Variable +// Type Analysis (VTA) algorithm originally described in "Practical Virtual +// Method Call Resolution for Java," Vijay Sundaresan, Laurie Hendren, +// Chrislain Razafimahefa, Raja Vallée-Rai, Patrick Lam, Etienne Gagnon, and +// Charles Godin. +// +// Note: this package is in experimental phase and its interface is +// subject to change. +// TODO(zpavlinovic): reiterate on documentation. +// +// The VTA algorithm overapproximates the set of types (and function literals) +// a variable can take during runtime by building a global type propagation +// graph and propagating types (and function literals) through the graph. +// +// A type propagation is a directed, labeled graph. A node can represent +// one of the following: +// - A field of a struct type. +// - A local (SSA) variable of a method/function. +// - All pointers to a non-interface type. +// - The return value of a method. +// - All elements in an array. +// - All elements in a slice. +// - All elements in a map. +// - All elements in a channel. +// - A global variable. +// +// In addition, the implementation used in this package introduces +// a few Go specific kinds of nodes: +// - (De)references of nested pointers to interfaces are modeled +// as a unique nestedPtrInterface node in the type propagation graph. +// - Each function literal is represented as a function node whose +// internal value is the (SSA) representation of the function. This +// is done to precisely infer flow of higher-order functions. +// +// Edges in the graph represent flow of types (and function literals) through +// the program. That is, the model 1) typing constraints that are induced by +// assignment statements or function and method calls and 2) higher-order flow +// of functions in the program. +// +// The labeling function maps each node to a set of types and functions that +// can intuitively reach the program construct the node represents. Initially, +// every node is assigned a type corresponding to the program construct it +// represents. Function nodes are also assigned the function they represent. +// The labeling function then propagates types and function through the graph. +// +// The result of VTA is a type propagation graph in which each node is labeled +// with a conservative overapproximation of the set of types (and functions) +// it may have. This information is then used to construct the call graph. +// For each unresolved call site, vta uses the set of types and functions +// reaching the node representing the call site to create a set of callees. +package vta + +// TODO(zpavlinovic): update VTA for how it handles generic function bodies and instantiation wrappers. + +import ( + "go/types" + + "golang.org/x/tools/go/callgraph" + "golang.org/x/tools/go/ssa" +) + +// CallGraph uses the VTA algorithm to compute call graph for all functions +// f:true in funcs. VTA refines the results of initial call graph and uses it +// to establish interprocedural type flow. If initial is nil, VTA uses a more +// efficient approach to construct a CHA call graph. +// +// The resulting graph does not have a root node. +// +// CallGraph does not make any assumptions on initial types global variables +// and function/method inputs can have. CallGraph is then sound, modulo use of +// reflection and unsafe, if the initial call graph is sound. +// +// The supplied SSA functions must have been constructed with the +// [ssa.InstantiateGenerics] mode flag. +func CallGraph(funcs map[*ssa.Function]bool, initial *callgraph.Graph) *callgraph.Graph { + callees := makeCalleesFunc(funcs, initial) + vtaG, canon := typePropGraph(funcs, callees) + types := propagate(vtaG, canon) + + c := &constructor{types: types, callees: callees, cache: make(methodCache)} + return c.construct(funcs) +} + +// constructor type linearly traverses the input program +// and constructs a callgraph based on the results of the +// VTA type propagation phase. +type constructor struct { + types propTypeMap + cache methodCache + callees calleesFunc +} + +func (c *constructor) construct(funcs map[*ssa.Function]bool) *callgraph.Graph { + cg := &callgraph.Graph{Nodes: make(map[*ssa.Function]*callgraph.Node)} + for f, in := range funcs { + if in { + c.constrct(cg, f) + } + } + return cg +} + +func (c *constructor) constrct(g *callgraph.Graph, f *ssa.Function) { + caller := g.CreateNode(f) + for _, call := range calls(f) { + for _, c := range c.resolves(call) { + callgraph.AddEdge(caller, call, g.CreateNode(c)) + } + } +} + +// resolves computes the set of functions to which VTA resolves `c`. The resolved +// functions are intersected with functions to which `c.initial` resolves `c`. +func (c *constructor) resolves(call ssa.CallInstruction) []*ssa.Function { + cc := call.Common() + if cc.StaticCallee() != nil { + return []*ssa.Function{cc.StaticCallee()} + } + + // Skip builtins as they are not *ssa.Function. + if _, ok := cc.Value.(*ssa.Builtin); ok { + return nil + } + + // Cover the case of dynamic higher-order and interface calls. + var res []*ssa.Function + resolved := resolve(call, c.types, c.cache) + for f := range siteCallees(call, c.callees) { + if _, ok := resolved[f]; ok { + res = append(res, f) + } + } + return res +} + +// resolve returns a set of functions `c` resolves to based on the +// type propagation results in `types`. +func resolve(c ssa.CallInstruction, types propTypeMap, cache methodCache) map[*ssa.Function]empty { + fns := make(map[*ssa.Function]empty) + n := local{val: c.Common().Value} + for p := range types.propTypes(n) { + for _, f := range propFunc(p, c, cache) { + fns[f] = empty{} + } + } + return fns +} + +// propFunc returns the functions modeled with the propagation type `p` +// assigned to call site `c`. If no such function exists, nil is returned. +func propFunc(p propType, c ssa.CallInstruction, cache methodCache) []*ssa.Function { + if p.f != nil { + return []*ssa.Function{p.f} + } + + if c.Common().Method == nil { + return nil + } + + return cache.methods(p.typ, c.Common().Method.Name(), c.Parent().Prog) +} + +// methodCache serves as a type -> method name -> methods +// cache when computing methods of a type using the +// ssa.Program.MethodSets and ssa.Program.MethodValue +// APIs. The cache is used to speed up querying of +// methods of a type as the mentioned APIs are expensive. +type methodCache map[types.Type]map[string][]*ssa.Function + +// methods returns methods of a type `t` named `name`. First consults +// `mc` and otherwise queries `prog` for the method. If no such method +// exists, nil is returned. +func (mc methodCache) methods(t types.Type, name string, prog *ssa.Program) []*ssa.Function { + if ms, ok := mc[t]; ok { + return ms[name] + } + + ms := make(map[string][]*ssa.Function) + mset := prog.MethodSets.MethodSet(t) + for i, n := 0, mset.Len(); i < n; i++ { + // f can be nil when t is an interface or some + // other type without any runtime methods. + if f := prog.MethodValue(mset.At(i)); f != nil { + ms[f.Name()] = append(ms[f.Name()], f) + } + } + mc[t] = ms + return ms[name] +} diff --git a/vendor/golang.org/x/tools/go/cfg/builder.go b/vendor/golang.org/x/tools/go/cfg/builder.go new file mode 100644 index 0000000..f16cd42 --- /dev/null +++ b/vendor/golang.org/x/tools/go/cfg/builder.go @@ -0,0 +1,519 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cfg + +// This file implements the CFG construction pass. + +import ( + "fmt" + "go/ast" + "go/token" +) + +type builder struct { + blocks []*Block + mayReturn func(*ast.CallExpr) bool + current *Block + lblocks map[string]*lblock // labeled blocks + targets *targets // linked stack of branch targets +} + +func (b *builder) stmt(_s ast.Stmt) { + // The label of the current statement. If non-nil, its _goto + // target is always set; its _break and _continue are set only + // within the body of switch/typeswitch/select/for/range. + // It is effectively an additional default-nil parameter of stmt(). + var label *lblock +start: + switch s := _s.(type) { + case *ast.BadStmt, + *ast.SendStmt, + *ast.IncDecStmt, + *ast.GoStmt, + *ast.EmptyStmt, + *ast.AssignStmt: + // No effect on control flow. + b.add(s) + + case *ast.DeferStmt: + b.add(s) + // Assume conservatively that this behaves like: + // defer func() { recover() } + // so any subsequent panic may act like a return. + b.current.returns = true + + case *ast.ExprStmt: + b.add(s) + if call, ok := s.X.(*ast.CallExpr); ok && !b.mayReturn(call) { + // Calls to panic, os.Exit, etc, never return. + b.current = b.newBlock(KindUnreachable, s) + } + + case *ast.DeclStmt: + // Treat each var ValueSpec as a separate statement. + d := s.Decl.(*ast.GenDecl) + if d.Tok == token.VAR { + for _, spec := range d.Specs { + if spec, ok := spec.(*ast.ValueSpec); ok { + b.add(spec) + } + } + } + + case *ast.LabeledStmt: + label = b.labeledBlock(s.Label, s) + b.jump(label._goto) + b.current = label._goto + _s = s.Stmt + goto start // effectively: tailcall stmt(g, s.Stmt, label) + + case *ast.ReturnStmt: + b.current.returns = true + b.add(s) + b.current = b.newBlock(KindUnreachable, s) + + case *ast.BranchStmt: + b.branchStmt(s) + + case *ast.BlockStmt: + b.stmtList(s.List) + + case *ast.IfStmt: + if s.Init != nil { + b.stmt(s.Init) + } + then := b.newBlock(KindIfThen, s) + done := b.newBlock(KindIfDone, s) + _else := done + if s.Else != nil { + _else = b.newBlock(KindIfElse, s) + } + b.add(s.Cond) + b.ifelse(then, _else) + b.current = then + b.stmt(s.Body) + b.jump(done) + + if s.Else != nil { + b.current = _else + b.stmt(s.Else) + b.jump(done) + } + + b.current = done + + case *ast.SwitchStmt: + b.switchStmt(s, label) + + case *ast.TypeSwitchStmt: + b.typeSwitchStmt(s, label) + + case *ast.SelectStmt: + b.selectStmt(s, label) + + case *ast.ForStmt: + b.forStmt(s, label) + + case *ast.RangeStmt: + b.rangeStmt(s, label) + + default: + panic(fmt.Sprintf("unexpected statement kind: %T", s)) + } +} + +func (b *builder) stmtList(list []ast.Stmt) { + for _, s := range list { + b.stmt(s) + } +} + +func (b *builder) branchStmt(s *ast.BranchStmt) { + var block *Block + switch s.Tok { + case token.BREAK: + if s.Label != nil { + if lb := b.labeledBlock(s.Label, nil); lb != nil { + block = lb._break + } + } else { + for t := b.targets; t != nil && block == nil; t = t.tail { + block = t._break + } + } + + case token.CONTINUE: + if s.Label != nil { + if lb := b.labeledBlock(s.Label, nil); lb != nil { + block = lb._continue + } + } else { + for t := b.targets; t != nil && block == nil; t = t.tail { + block = t._continue + } + } + + case token.FALLTHROUGH: + for t := b.targets; t != nil && block == nil; t = t.tail { + block = t._fallthrough + } + + case token.GOTO: + if s.Label != nil { + block = b.labeledBlock(s.Label, nil)._goto + } + } + if block == nil { // ill-typed (e.g. undefined label) + block = b.newBlock(KindUnreachable, s) + } + b.jump(block) + b.current = b.newBlock(KindUnreachable, s) +} + +func (b *builder) switchStmt(s *ast.SwitchStmt, label *lblock) { + if s.Init != nil { + b.stmt(s.Init) + } + if s.Tag != nil { + b.add(s.Tag) + } + done := b.newBlock(KindSwitchDone, s) + if label != nil { + label._break = done + } + // We pull the default case (if present) down to the end. + // But each fallthrough label must point to the next + // body block in source order, so we preallocate a + // body block (fallthru) for the next case. + // Unfortunately this makes for a confusing block order. + var defaultBody *[]ast.Stmt + var defaultFallthrough *Block + var fallthru, defaultBlock *Block + ncases := len(s.Body.List) + for i, clause := range s.Body.List { + body := fallthru + if body == nil { + body = b.newBlock(KindSwitchCaseBody, clause) // first case only + } + + // Preallocate body block for the next case. + fallthru = done + if i+1 < ncases { + fallthru = b.newBlock(KindSwitchCaseBody, s.Body.List[i+1]) + } + + cc := clause.(*ast.CaseClause) + if cc.List == nil { + // Default case. + defaultBody = &cc.Body + defaultFallthrough = fallthru + defaultBlock = body + continue + } + + var nextCond *Block + for _, cond := range cc.List { + nextCond = b.newBlock(KindSwitchNextCase, cc) + b.add(cond) // one half of the tag==cond condition + b.ifelse(body, nextCond) + b.current = nextCond + } + b.current = body + b.targets = &targets{ + tail: b.targets, + _break: done, + _fallthrough: fallthru, + } + b.stmtList(cc.Body) + b.targets = b.targets.tail + b.jump(done) + b.current = nextCond + } + if defaultBlock != nil { + b.jump(defaultBlock) + b.current = defaultBlock + b.targets = &targets{ + tail: b.targets, + _break: done, + _fallthrough: defaultFallthrough, + } + b.stmtList(*defaultBody) + b.targets = b.targets.tail + } + b.jump(done) + b.current = done +} + +func (b *builder) typeSwitchStmt(s *ast.TypeSwitchStmt, label *lblock) { + if s.Init != nil { + b.stmt(s.Init) + } + if s.Assign != nil { + b.add(s.Assign) + } + + done := b.newBlock(KindSwitchDone, s) + if label != nil { + label._break = done + } + var default_ *ast.CaseClause + for _, clause := range s.Body.List { + cc := clause.(*ast.CaseClause) + if cc.List == nil { + default_ = cc + continue + } + body := b.newBlock(KindSwitchCaseBody, cc) + var next *Block + for _, casetype := range cc.List { + next = b.newBlock(KindSwitchNextCase, cc) + // casetype is a type, so don't call b.add(casetype). + // This block logically contains a type assertion, + // x.(casetype), but it's unclear how to represent x. + _ = casetype + b.ifelse(body, next) + b.current = next + } + b.current = body + b.typeCaseBody(cc, done) + b.current = next + } + if default_ != nil { + b.typeCaseBody(default_, done) + } else { + b.jump(done) + } + b.current = done +} + +func (b *builder) typeCaseBody(cc *ast.CaseClause, done *Block) { + b.targets = &targets{ + tail: b.targets, + _break: done, + } + b.stmtList(cc.Body) + b.targets = b.targets.tail + b.jump(done) +} + +func (b *builder) selectStmt(s *ast.SelectStmt, label *lblock) { + // First evaluate channel expressions. + // TODO(adonovan): fix: evaluate only channel exprs here. + for _, clause := range s.Body.List { + if comm := clause.(*ast.CommClause).Comm; comm != nil { + b.stmt(comm) + } + } + + done := b.newBlock(KindSelectDone, s) + if label != nil { + label._break = done + } + + var defaultBody *[]ast.Stmt + for _, cc := range s.Body.List { + clause := cc.(*ast.CommClause) + if clause.Comm == nil { + defaultBody = &clause.Body + continue + } + body := b.newBlock(KindSelectCaseBody, clause) + next := b.newBlock(KindSelectAfterCase, clause) + b.ifelse(body, next) + b.current = body + b.targets = &targets{ + tail: b.targets, + _break: done, + } + switch comm := clause.Comm.(type) { + case *ast.ExprStmt: // <-ch + // nop + case *ast.AssignStmt: // x := <-states[state].Chan + b.add(comm.Lhs[0]) + } + b.stmtList(clause.Body) + b.targets = b.targets.tail + b.jump(done) + b.current = next + } + if defaultBody != nil { + b.targets = &targets{ + tail: b.targets, + _break: done, + } + b.stmtList(*defaultBody) + b.targets = b.targets.tail + b.jump(done) + } + b.current = done +} + +func (b *builder) forStmt(s *ast.ForStmt, label *lblock) { + // ...init... + // jump loop + // loop: + // if cond goto body else done + // body: + // ...body... + // jump post + // post: (target of continue) + // ...post... + // jump loop + // done: (target of break) + if s.Init != nil { + b.stmt(s.Init) + } + body := b.newBlock(KindForBody, s) + done := b.newBlock(KindForDone, s) // target of 'break' + loop := body // target of back-edge + if s.Cond != nil { + loop = b.newBlock(KindForLoop, s) + } + cont := loop // target of 'continue' + if s.Post != nil { + cont = b.newBlock(KindForPost, s) + } + if label != nil { + label._break = done + label._continue = cont + } + b.jump(loop) + b.current = loop + if loop != body { + b.add(s.Cond) + b.ifelse(body, done) + b.current = body + } + b.targets = &targets{ + tail: b.targets, + _break: done, + _continue: cont, + } + b.stmt(s.Body) + b.targets = b.targets.tail + b.jump(cont) + + if s.Post != nil { + b.current = cont + b.stmt(s.Post) + b.jump(loop) // back-edge + } + b.current = done +} + +func (b *builder) rangeStmt(s *ast.RangeStmt, label *lblock) { + b.add(s.X) + + if s.Key != nil { + b.add(s.Key) + } + if s.Value != nil { + b.add(s.Value) + } + + // ... + // loop: (target of continue) + // if ... goto body else done + // body: + // ... + // jump loop + // done: (target of break) + + loop := b.newBlock(KindRangeLoop, s) + b.jump(loop) + b.current = loop + + body := b.newBlock(KindRangeBody, s) + done := b.newBlock(KindRangeDone, s) + b.ifelse(body, done) + b.current = body + + if label != nil { + label._break = done + label._continue = loop + } + b.targets = &targets{ + tail: b.targets, + _break: done, + _continue: loop, + } + b.stmt(s.Body) + b.targets = b.targets.tail + b.jump(loop) // back-edge + b.current = done +} + +// -------- helpers -------- + +// Destinations associated with unlabeled for/switch/select stmts. +// We push/pop one of these as we enter/leave each construct and for +// each BranchStmt we scan for the innermost target of the right type. +type targets struct { + tail *targets // rest of stack + _break *Block + _continue *Block + _fallthrough *Block +} + +// Destinations associated with a labeled block. +// We populate these as labels are encountered in forward gotos or +// labeled statements. +type lblock struct { + _goto *Block + _break *Block + _continue *Block +} + +// labeledBlock returns the branch target associated with the +// specified label, creating it if needed. +func (b *builder) labeledBlock(label *ast.Ident, stmt *ast.LabeledStmt) *lblock { + lb := b.lblocks[label.Name] + if lb == nil { + lb = &lblock{_goto: b.newBlock(KindLabel, nil)} + if b.lblocks == nil { + b.lblocks = make(map[string]*lblock) + } + b.lblocks[label.Name] = lb + } + // Fill in the label later (in case of forward goto). + // Stmt may be set already if labels are duplicated (ill-typed). + if stmt != nil && lb._goto.Stmt == nil { + lb._goto.Stmt = stmt + } + return lb +} + +// newBlock appends a new unconnected basic block to b.cfg's block +// slice and returns it. +// It does not automatically become the current block. +// comment is an optional string for more readable debugging output. +func (b *builder) newBlock(kind BlockKind, stmt ast.Stmt) *Block { + block := &Block{ + Index: int32(len(b.blocks)), + Kind: kind, + Stmt: stmt, + } + block.Succs = block.succs2[:0] + b.blocks = append(b.blocks, block) + return block +} + +func (b *builder) add(n ast.Node) { + b.current.Nodes = append(b.current.Nodes, n) +} + +// jump adds an edge from the current block to the target block, +// and sets b.current to nil. +func (b *builder) jump(target *Block) { + b.current.Succs = append(b.current.Succs, target) + b.current = nil +} + +// ifelse emits edges from the current block to the t and f blocks, +// and sets b.current to nil. +func (b *builder) ifelse(t, f *Block) { + b.current.Succs = append(b.current.Succs, t, f) + b.current = nil +} diff --git a/vendor/golang.org/x/tools/go/cfg/cfg.go b/vendor/golang.org/x/tools/go/cfg/cfg.go new file mode 100644 index 0000000..f69912c --- /dev/null +++ b/vendor/golang.org/x/tools/go/cfg/cfg.go @@ -0,0 +1,273 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package cfg constructs a simple control-flow graph (CFG) of the +// statements and expressions within a single function. +// +// Use cfg.New to construct the CFG for a function body. +// +// The blocks of the CFG contain all the function's non-control +// statements. The CFG does not contain control statements such as If, +// Switch, Select, and Branch, but does contain their subexpressions; +// also, each block records the control statement (Block.Stmt) that +// gave rise to it and its relationship (Block.Kind) to that statement. +// +// For example, this source code: +// +// if x := f(); x != nil { +// T() +// } else { +// F() +// } +// +// produces this CFG: +// +// 1: x := f() Body +// x != nil +// succs: 2, 3 +// 2: T() IfThen +// succs: 4 +// 3: F() IfElse +// succs: 4 +// 4: IfDone +// +// The CFG does contain Return statements; even implicit returns are +// materialized (at the position of the function's closing brace). +// +// The CFG does not record conditions associated with conditional branch +// edges, nor the short-circuit semantics of the && and || operators, +// nor abnormal control flow caused by panic. If you need this +// information, use golang.org/x/tools/go/ssa instead. +package cfg + +import ( + "bytes" + "fmt" + "go/ast" + "go/format" + "go/token" +) + +// A CFG represents the control-flow graph of a single function. +// +// The entry point is Blocks[0]; there may be multiple return blocks. +type CFG struct { + Blocks []*Block // block[0] is entry; order otherwise undefined + noreturn bool // function body lacks a reachable return statement +} + +// NoReturn reports whether the function has no reachable return. +func (cfg *CFG) NoReturn() bool { return cfg.noreturn } + +// A Block represents a basic block: a list of statements and +// expressions that are always evaluated sequentially. +// +// A block may have 0-2 successors: zero for a return block or a block +// that calls a function such as panic that never returns; one for a +// normal (jump) block; and two for a conditional (if) block. +// +// In a conditional block, the last entry in Nodes is the condition and always +// an [ast.Expr], Succs[0] is the successor if the condition is true, and +// Succs[1] is the successor if the condition is false. +type Block struct { + Nodes []ast.Node // statements, expressions, and ValueSpecs + Succs []*Block // successor nodes in the graph + Index int32 // index within CFG.Blocks + Live bool // block is reachable from entry + returns bool // block contains return or defer (which may recover and return) + Kind BlockKind // block kind + Stmt ast.Stmt // statement that gave rise to this block (see BlockKind for details) + + succs2 [2]*Block // underlying array for Succs +} + +// A BlockKind identifies the purpose of a block. +// It also determines the possible types of its Stmt field. +type BlockKind uint8 + +const ( + KindInvalid BlockKind = iota // Stmt=nil + + KindUnreachable // unreachable block after {Branch,Return}Stmt / no-return call ExprStmt + KindBody // function body BlockStmt + KindForBody // body of ForStmt + KindForDone // block after ForStmt + KindForLoop // head of ForStmt + KindForPost // post condition of ForStmt + KindIfDone // block after IfStmt + KindIfElse // else block of IfStmt + KindIfThen // then block of IfStmt + KindLabel // labeled block of BranchStmt (Stmt may be nil for dangling label) + KindRangeBody // body of RangeStmt + KindRangeDone // block after RangeStmt + KindRangeLoop // head of RangeStmt + KindSelectCaseBody // body of SelectStmt + KindSelectDone // block after SelectStmt + KindSelectAfterCase // block after a CommClause + KindSwitchCaseBody // body of CaseClause + KindSwitchDone // block after {Type.}SwitchStmt + KindSwitchNextCase // secondary expression of a multi-expression CaseClause +) + +func (kind BlockKind) String() string { + return [...]string{ + KindInvalid: "Invalid", + KindUnreachable: "Unreachable", + KindBody: "Body", + KindForBody: "ForBody", + KindForDone: "ForDone", + KindForLoop: "ForLoop", + KindForPost: "ForPost", + KindIfDone: "IfDone", + KindIfElse: "IfElse", + KindIfThen: "IfThen", + KindLabel: "Label", + KindRangeBody: "RangeBody", + KindRangeDone: "RangeDone", + KindRangeLoop: "RangeLoop", + KindSelectCaseBody: "SelectCaseBody", + KindSelectDone: "SelectDone", + KindSelectAfterCase: "SelectAfterCase", + KindSwitchCaseBody: "SwitchCaseBody", + KindSwitchDone: "SwitchDone", + KindSwitchNextCase: "SwitchNextCase", + }[kind] +} + +// New returns a new control-flow graph for the specified function body, +// which must be non-nil. +// +// The CFG builder calls mayReturn to determine whether a given function +// call may return. For example, calls to panic, os.Exit, and log.Fatal +// do not return, so the builder can remove infeasible graph edges +// following such calls. The builder calls mayReturn only for a +// CallExpr beneath an ExprStmt. +func New(body *ast.BlockStmt, mayReturn func(*ast.CallExpr) bool) *CFG { + b := builder{ + mayReturn: mayReturn, + } + b.current = b.newBlock(KindBody, body) + b.stmt(body) + + // Compute liveness (reachability from entry point), + // breadth-first, marking Block.Live flags. + q := make([]*Block, 0, len(b.blocks)) + q = append(q, b.blocks[0]) // entry point + for len(q) > 0 { + b := q[len(q)-1] + q = q[:len(q)-1] + + if !b.Live { + b.Live = true + q = append(q, b.Succs...) + } + } + + // Does control fall off the end of the function's body? + // Make implicit return explicit. + if b.current != nil && b.current.Live { + b.current.returns = true + b.add(&ast.ReturnStmt{ + Return: body.End() - 1, + }) + } + + // Is any return (or defer+recover) block reachable? + noreturn := true + for _, bl := range b.blocks { + if bl.Live && bl.returns { + noreturn = false + break + } + } + + return &CFG{Blocks: b.blocks, noreturn: noreturn} +} + +func (b *Block) String() string { + return fmt.Sprintf("block %d (%s)", b.Index, b.comment(nil)) +} + +func (b *Block) comment(fset *token.FileSet) string { + s := b.Kind.String() + if fset != nil && b.Stmt != nil { + s = fmt.Sprintf("%s@L%d", s, fset.Position(b.Stmt.Pos()).Line) + } + return s +} + +// Return returns the return statement at the end of this block if present, nil +// otherwise. +// +// When control falls off the end of the function, the ReturnStmt is synthetic +// and its [ast.Node.End] position may be beyond the end of the file. +// +// A function that contains no return statement (explicit or implied) +// may yet return normally, and may even return a nonzero value. For example: +// +// func() (res any) { +// defer func() { res = recover() }() +// panic(123) +// } +func (b *Block) Return() (ret *ast.ReturnStmt) { + if len(b.Nodes) > 0 { + ret, _ = b.Nodes[len(b.Nodes)-1].(*ast.ReturnStmt) + } + return +} + +// Format formats the control-flow graph for ease of debugging. +func (g *CFG) Format(fset *token.FileSet) string { + var buf bytes.Buffer + for _, b := range g.Blocks { + fmt.Fprintf(&buf, ".%d: # %s\n", b.Index, b.comment(fset)) + for _, n := range b.Nodes { + fmt.Fprintf(&buf, "\t%s\n", formatNode(fset, n)) + } + if len(b.Succs) > 0 { + fmt.Fprintf(&buf, "\tsuccs:") + for _, succ := range b.Succs { + fmt.Fprintf(&buf, " %d", succ.Index) + } + buf.WriteByte('\n') + } + buf.WriteByte('\n') + } + return buf.String() +} + +// Dot returns the control-flow graph in the [Dot graph description language]. +// Use a command such as 'dot -Tsvg' to render it in a form viewable in a browser. +// This method is provided as a debugging aid; the details of the +// output are unspecified and may change. +// +// [Dot graph description language]: ​​https://en.wikipedia.org/wiki/DOT_(graph_description_language) +func (g *CFG) Dot(fset *token.FileSet) string { + var buf bytes.Buffer + buf.WriteString("digraph CFG {\n") + buf.WriteString(" node [shape=box];\n") + for _, b := range g.Blocks { + // node label + var text bytes.Buffer + text.WriteString(b.comment(fset)) + for _, n := range b.Nodes { + fmt.Fprintf(&text, "\n%s", formatNode(fset, n)) + } + + // node and edges + fmt.Fprintf(&buf, " n%d [label=%q];\n", b.Index, &text) + for _, succ := range b.Succs { + fmt.Fprintf(&buf, " n%d -> n%d;\n", b.Index, succ.Index) + } + } + buf.WriteString("}\n") + return buf.String() +} + +func formatNode(fset *token.FileSet, n ast.Node) string { + var buf bytes.Buffer + format.Node(&buf, fset, n) + // Indent secondary lines by a tab. + return string(bytes.Replace(buf.Bytes(), []byte("\n"), []byte("\n\t"), -1)) +} diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go new file mode 100644 index 0000000..ea918e7 --- /dev/null +++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go @@ -0,0 +1,213 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package gcexportdata provides functions for writing and reading +// export data, a serialized representation of a [types.Package]. +// It describes the API of a Go package, including the names, +// kinds, types, and locations of all exported declarations. +// +// Files may be written and read using the [Write] and [Read] +// functions. +// Alternatively, files may be produced by the "go list -export" command. +// This command runs the type checker on each specified Go package and +// writes export data for each package into a file named by the Export +// field of go list's -json output. +// The [Read] function may then be used to read those files. +// +// The export data format evolves with each Go release. As a matter of +// policy, [Read] supports reading files produced by only the last two +// Go releases plus tip; see https://go.dev/issue/68898. +// +// The name of this package reflects its origins at a time when +// cmd/compile was named gc, and [Read] parsed export data +// from .a archives produced by the Go compiler. +// However, starting with go1.28, the format of the files +// produced by "go list -export" will diverge from the format +// used by the standard Go compiler. +// Consequently, this package will eventually stop being +// capable of reading those files. +// In the meantime, when using [Read] on a .a file written by the +// compiler, be aware that export data is not at the start of the file. +// Before calling Read, one must use [NewReader] to locate the export +// data section of the file. +// For more information on the compiler's export data, see the +// "Export" section in the GOROOT/src/cmd/compile/README file. +// +// # Deprecations +// +// The [NewImporter], [Find], and [NewReader] functions are deprecated +// and should not be used in new code. +// The [WriteBundle] and [ReadBundle] functions are obsolete experiments +// and are no longer supported (https://go.dev/issue/69573). +package gcexportdata + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "go/token" + "go/types" + "io" + "os/exec" + + "golang.org/x/tools/internal/gcimporter" +) + +// Find returns the name of an object (.o) or archive (.a) file +// containing type information for the specified import path, +// using the go command. +// If no file was found, an empty filename is returned. +// +// A relative srcDir is interpreted relative to the current working directory. +// +// Find also returns the package's resolved (canonical) import path, +// reflecting the effects of srcDir and vendoring on importPath. +// +// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, +// which is more efficient. +func Find(importPath, srcDir string) (filename, path string) { + cmd := exec.Command("go", "list", "-json", "-export", "--", importPath) + cmd.Dir = srcDir + out, err := cmd.Output() + if err != nil { + return "", "" + } + var data struct { + ImportPath string + Export string + } + json.Unmarshal(out, &data) + return data.Export, data.ImportPath +} + +// NewReader returns a reader for export data read from r. Export data +// may be read from: +// +// - The export data section of an object (.o) or archive file (.a). +// In this case, the new reader may provide additional trailing data +// beyond the end of the export data. +// - The output of the cmd/export tool (e.g. via "go list -export"). +// In this case, the new reader contains no trailing data. +// +// Deprecated: This package will stop supporting the reading of export +// data from compiler-produced archive files in Go 1.29. To read +// cmd/export files, use [Read] directly instead. +func NewReader(r io.Reader) (io.Reader, error) { + buf := bufio.NewReader(r) + peek, err := buf.Peek(1) + if err != nil { + return nil, err + } + if peek[0] == 'i' { + // We were given an output of cmd/export. The entire file is + // export data. + return buf, nil + } + + size, err := gcimporter.FindExportData(buf) + if err != nil { + return nil, err + } + + // We were given an archive and found the __.PKGDEF in it. + // This tells us the size of the export data, and we don't + // need to return the entire file. + return &io.LimitedReader{ + R: buf, + N: size, + }, nil +} + +// readAll works the same way as io.ReadAll, but avoids allocations and copies +// by preallocating a byte slice of the necessary size if the size is known up +// front. This is always possible when the input is an archive. In that case, +// NewReader will return the known size using an io.LimitedReader. +func readAll(r io.Reader) ([]byte, error) { + if lr, ok := r.(*io.LimitedReader); ok { + data := make([]byte, lr.N) + _, err := io.ReadFull(lr, data) + return data, err + } + return io.ReadAll(r) +} + +// Read reads export data from in, decodes it, and returns type +// information for the package. +// +// Read is capable of reading export data produced by [Write] at the +// same source code version, or by the last two Go releases (plus tip) +// of the standard Go compiler. Reading files from older compilers may +// produce an error. +// +// The package path (effectively its linker symbol prefix) is +// specified by path, since unlike the package name, this information +// may not be recorded in the export data. +// +// File position information is added to fset. +// +// Read may inspect and add to the imports map to ensure that references +// within the export data to other packages are consistent. The caller +// must ensure that imports[path] does not exist, or exists but is +// incomplete (see types.Package.Complete), and Read inserts the +// resulting package into this map entry. +// +// On return, the state of the reader is undefined. +func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) { + data, err := readAll(in) + if err != nil { + return nil, fmt.Errorf("reading export data for %q: %v", path, err) + } + + if bytes.HasPrefix(data, []byte("!")) { + 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) + } + + // The indexed export format starts with an 'i'; the older + // binary export format starts with a 'c', 'd', or 'v' + // (from "version"). Select appropriate importer. + if len(data) > 0 { + switch data[0] { + case 'v', 'c', 'd': + // binary, produced by cmd/compile till go1.10 + return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0]) + + case 'i': + // indexed, produced by cmd/compile till go1.19, + // and also by [Write]. Starting with go1.28, + // go list -export runs cmd/export, which emits this format. + return gcimporter.IImportData(fset, imports, data[1:], path) + + case 'u': + // unified, produced by cmd/compile since go1.20. + // Produced by go list -export from go1.20 to go1.27. + _, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path) + return pkg, err + + default: + l := min(len(data), 10) + return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), path) + } + } + return nil, fmt.Errorf("empty export data for %s", path) +} + +// Write writes encoded type information for the specified package to out. +// The FileSet provides file position information for named objects. +func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error { + if _, err := io.WriteString(out, "i"); err != nil { + return err + } + return gcimporter.IExportData(out, fset, pkg) +} + +// Deprecated: ReadBundle is an unsupported obsolete experimental API. It returns an error. +func ReadBundle(in io.Reader, fset *token.FileSet, imports map[string]*types.Package) ([]*types.Package, error) { + return nil, fmt.Errorf("ReadBundle is an unsupported obsolete experimental API") +} + +// Deprecated: WriteBundle is an unsupported obsolete experimental API. It returns an error. +func WriteBundle(io.Writer, *token.FileSet, []*types.Package) error { + return fmt.Errorf("WriteBundle is an unsupported obsolete experimental API") +} diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go new file mode 100644 index 0000000..37a7247 --- /dev/null +++ b/vendor/golang.org/x/tools/go/gcexportdata/importer.go @@ -0,0 +1,75 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gcexportdata + +import ( + "fmt" + "go/token" + "go/types" + "os" +) + +// NewImporter returns a new instance of the types.Importer interface +// that reads type information from export data files written by gc. +// The Importer also satisfies types.ImporterFrom. +// +// Export data files are located using "go build" workspace conventions +// and the build.Default context. +// +// Use this importer instead of go/importer.For("gc", ...) to avoid the +// version-skew problems described in the documentation of this package, +// or to control the FileSet or access the imports map populated during +// package loading. +// +// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, +// which is more efficient. +func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { + return importer{fset, imports} +} + +type importer struct { + fset *token.FileSet + imports map[string]*types.Package +} + +func (imp importer) Import(importPath string) (*types.Package, error) { + return imp.ImportFrom(importPath, "", 0) +} + +func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) { + filename, path := Find(importPath, srcDir) + if filename == "" { + if importPath == "unsafe" { + // Even for unsafe, call Find first in case + // the package was vendored. + return types.Unsafe, nil + } + return nil, fmt.Errorf("can't find import: %s", importPath) + } + + if pkg, ok := imp.imports[path]; ok && pkg.Complete() { + return pkg, nil // cache hit + } + + // open file + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer func() { + f.Close() + if err != nil { + // add file name to error + err = fmt.Errorf("reading export data: %s: %v", filename, err) + } + }() + + r, err := NewReader(f) + if err != nil { + return nil, err + } + + return Read(r, imp.fset, imp.imports, path) +} diff --git a/vendor/golang.org/x/tools/go/internal/cgo/cgo.go b/vendor/golang.org/x/tools/go/internal/cgo/cgo.go new file mode 100644 index 0000000..735efeb --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/cgo/cgo.go @@ -0,0 +1,219 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package cgo handles cgo preprocessing of files containing `import "C"`. +// +// DESIGN +// +// The approach taken is to run the cgo processor on the package's +// CgoFiles and parse the output, faking the filenames of the +// resulting ASTs so that the synthetic file containing the C types is +// called "C" (e.g. "~/go/src/net/C") and the preprocessed files +// have their original names (e.g. "~/go/src/net/cgo_unix.go"), +// not the names of the actual temporary files. +// +// The advantage of this approach is its fidelity to 'go build'. The +// downside is that the token.Position.Offset for each AST node is +// incorrect, being an offset within the temporary file. Line numbers +// should still be correct because of the //line comments. +// +// The logic of this file is mostly plundered from the 'go build' +// tool, which also invokes the cgo preprocessor. +// +// +// REJECTED ALTERNATIVE +// +// An alternative approach that we explored is to extend go/types' +// Importer mechanism to provide the identity of the importing package +// so that each time `import "C"` appears it resolves to a different +// synthetic package containing just the objects needed in that case. +// The loader would invoke cgo but parse only the cgo_types.go file +// defining the package-level objects, discarding the other files +// resulting from preprocessing. +// +// The benefit of this approach would have been that source-level +// syntax information would correspond exactly to the original cgo +// file, with no preprocessing involved, making source tools like +// godoc, guru, and eg happy. However, the approach was rejected +// due to the additional complexity it would impose on go/types. (It +// made for a beautiful demo, though.) +// +// cgo files, despite their *.go extension, are not legal Go source +// files per the specification since they may refer to unexported +// members of package "C" such as C.int. Also, a function such as +// C.getpwent has in effect two types, one matching its C type and one +// which additionally returns (errno C.int). The cgo preprocessor +// uses name mangling to distinguish these two functions in the +// processed code, but go/types would need to duplicate this logic in +// its handling of function calls, analogous to the treatment of map +// lookups in which y=m[k] and y,ok=m[k] are both legal. + +package cgo + +import ( + "fmt" + "go/ast" + "go/build" + "go/parser" + "go/token" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "strings" +) + +// ProcessFiles invokes the cgo preprocessor on bp.CgoFiles, parses +// the output and returns the resulting ASTs. +func ProcessFiles(bp *build.Package, fset *token.FileSet, DisplayPath func(path string) string, mode parser.Mode) ([]*ast.File, error) { + tmpdir, err := os.MkdirTemp("", strings.Replace(bp.ImportPath, "/", "_", -1)+"_C") + if err != nil { + return nil, err + } + defer os.RemoveAll(tmpdir) + + pkgdir := bp.Dir + if DisplayPath != nil { + pkgdir = DisplayPath(pkgdir) + } + + cgoFiles, cgoDisplayFiles, err := Run(bp, pkgdir, tmpdir, false) + if err != nil { + return nil, err + } + var files []*ast.File + for i := range cgoFiles { + rd, err := os.Open(cgoFiles[i]) + if err != nil { + return nil, err + } + display := filepath.Join(bp.Dir, cgoDisplayFiles[i]) + f, err := parser.ParseFile(fset, display, rd, mode) + rd.Close() + if err != nil { + return nil, err + } + files = append(files, f) + } + return files, nil +} + +var cgoRe = regexp.MustCompile(`[/\\:]`) + +// Run invokes the cgo preprocessor on bp.CgoFiles and returns two +// lists of files: the resulting processed files (in temporary +// directory tmpdir) and the corresponding names of the unprocessed files. +// +// Run is adapted from (*builder).cgo in +// $GOROOT/src/cmd/go/build.go, but these features are unsupported: +// Objective C, CGOPKGPATH, CGO_FLAGS. +// +// If useabs is set to true, absolute paths of the bp.CgoFiles will be passed in +// to the cgo preprocessor. This in turn will set the // line comments +// referring to those files to use absolute paths. This is needed for +// go/packages using the legacy go list support so it is able to find +// the original files. +func Run(bp *build.Package, pkgdir, tmpdir string, useabs bool) (files, displayFiles []string, err error) { + cgoCPPFLAGS, _, _, _ := cflags(bp, true) + _, cgoexeCFLAGS, _, _ := cflags(bp, false) + + if len(bp.CgoPkgConfig) > 0 { + pcCFLAGS, err := pkgConfigFlags(bp) + if err != nil { + return nil, nil, err + } + cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...) + } + + // Allows including _cgo_export.h from .[ch] files in the package. + cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", tmpdir) + + // _cgo_gotypes.go (displayed "C") contains the type definitions. + files = append(files, filepath.Join(tmpdir, "_cgo_gotypes.go")) + displayFiles = append(displayFiles, "C") + for _, fn := range bp.CgoFiles { + // "foo.cgo1.go" (displayed "foo.go") is the processed Go source. + f := cgoRe.ReplaceAllString(fn[:len(fn)-len("go")], "_") + files = append(files, filepath.Join(tmpdir, f+"cgo1.go")) + displayFiles = append(displayFiles, fn) + } + + var cgoflags []string + if bp.Goroot && bp.ImportPath == "runtime/cgo" { + cgoflags = append(cgoflags, "-import_runtime_cgo=false") + } + if bp.Goroot && bp.ImportPath == "runtime/race" || bp.ImportPath == "runtime/cgo" { + cgoflags = append(cgoflags, "-import_syscall=false") + } + + var cgoFiles []string = bp.CgoFiles + if useabs { + cgoFiles = make([]string, len(bp.CgoFiles)) + for i := range cgoFiles { + cgoFiles[i] = filepath.Join(pkgdir, bp.CgoFiles[i]) + } + } + + args := stringList( + "go", "tool", "cgo", "-objdir", tmpdir, cgoflags, "--", + cgoCPPFLAGS, cgoexeCFLAGS, cgoFiles, + ) + if false { + log.Printf("Running cgo for package %q: %s (dir=%s)", bp.ImportPath, args, pkgdir) + } + cmd := exec.Command(args[0], args[1:]...) + cmd.Dir = pkgdir + cmd.Env = append(os.Environ(), "PWD="+pkgdir) + cmd.Stdout = os.Stderr + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return nil, nil, fmt.Errorf("cgo failed: %s: %s", args, err) + } + + return files, displayFiles, nil +} + +// -- unmodified from 'go build' --------------------------------------- + +// Return the flags to use when invoking the C or C++ compilers, or cgo. +func cflags(p *build.Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) { + var defaults string + if def { + defaults = "-g -O2" + } + + cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS) + cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS) + cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS) + ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS) + return +} + +// envList returns the value of the given environment variable broken +// into fields, using the default value when the variable is empty. +func envList(key, def string) []string { + v := os.Getenv(key) + if v == "" { + v = def + } + return strings.Fields(v) +} + +// stringList's arguments should be a sequence of string or []string values. +// stringList flattens them into a single []string. +func stringList(args ...any) []string { + var x []string + for _, arg := range args { + switch arg := arg.(type) { + case []string: + x = append(x, arg...) + case string: + x = append(x, arg) + default: + panic("stringList: invalid argument") + } + } + return x +} diff --git a/vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go b/vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go new file mode 100644 index 0000000..2455be5 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go @@ -0,0 +1,42 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgo + +import ( + "errors" + "fmt" + "go/build" + "os/exec" + "strings" +) + +// pkgConfig runs pkg-config with the specified arguments and returns the flags it prints. +func pkgConfig(mode string, pkgs []string) (flags []string, err error) { + cmd := exec.Command("pkg-config", append([]string{mode}, pkgs...)...) + out, err := cmd.Output() + if err != nil { + s := fmt.Sprintf("%s failed: %v", strings.Join(cmd.Args, " "), err) + if len(out) > 0 { + s = fmt.Sprintf("%s: %s", s, out) + } + if err, ok := err.(*exec.ExitError); ok && len(err.Stderr) > 0 { + s = fmt.Sprintf("%s\nstderr:\n%s", s, err.Stderr) + } + return nil, errors.New(s) + } + if len(out) > 0 { + flags = strings.Fields(string(out)) + } + return +} + +// pkgConfigFlags calls pkg-config if needed and returns the cflags +// needed to build the package. +func pkgConfigFlags(p *build.Package) (cflags []string, err error) { + if len(p.CgoPkgConfig) == 0 { + return nil, nil + } + return pkgConfig("--cflags", p.CgoPkgConfig) +} diff --git a/vendor/golang.org/x/tools/go/loader/doc.go b/vendor/golang.org/x/tools/go/loader/doc.go new file mode 100644 index 0000000..769a1fc --- /dev/null +++ b/vendor/golang.org/x/tools/go/loader/doc.go @@ -0,0 +1,202 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package loader loads a complete Go program from source code, parsing +// and type-checking the initial packages plus their transitive closure +// of dependencies. The ASTs and the derived facts are retained for +// later use. +// +// Deprecated: This is an older API and does not have support +// for modules. Use golang.org/x/tools/go/packages instead. +// +// The package defines two primary types: Config, which specifies a +// set of initial packages to load and various other options; and +// Program, which is the result of successfully loading the packages +// specified by a configuration. +// +// The configuration can be set directly, but *Config provides various +// convenience methods to simplify the common cases, each of which can +// be called any number of times. Finally, these are followed by a +// call to Load() to actually load and type-check the program. +// +// var conf loader.Config +// +// // Use the command-line arguments to specify +// // a set of initial packages to load from source. +// // See FromArgsUsage for help. +// rest, err := conf.FromArgs(os.Args[1:], wantTests) +// +// // Parse the specified files and create an ad hoc package with path "foo". +// // All files must have the same 'package' declaration. +// conf.CreateFromFilenames("foo", "foo.go", "bar.go") +// +// // Create an ad hoc package with path "foo" from +// // the specified already-parsed files. +// // All ASTs must have the same 'package' declaration. +// conf.CreateFromFiles("foo", parsedFiles) +// +// // Add "runtime" to the set of packages to be loaded. +// conf.Import("runtime") +// +// // Adds "fmt" and "fmt_test" to the set of packages +// // to be loaded. "fmt" will include *_test.go files. +// conf.ImportWithTests("fmt") +// +// // Finally, load all the packages specified by the configuration. +// prog, err := conf.Load() +// +// See examples_test.go for examples of API usage. +// +// # CONCEPTS AND TERMINOLOGY +// +// The WORKSPACE is the set of packages accessible to the loader. The +// workspace is defined by Config.Build, a *build.Context. The +// default context treats subdirectories of $GOROOT and $GOPATH as +// packages, but this behavior may be overridden. +// +// An AD HOC package is one specified as a set of source files on the +// command line. In the simplest case, it may consist of a single file +// such as $GOROOT/src/net/http/triv.go. +// +// EXTERNAL TEST packages are those comprised of a set of *_test.go +// files all with the same 'package foo_test' declaration, all in the +// same directory. (go/build.Package calls these files XTestFiles.) +// +// An IMPORTABLE package is one that can be referred to by some import +// spec. Every importable package is uniquely identified by its +// PACKAGE PATH or just PATH, a string such as "fmt", "encoding/json", +// or "cmd/vendor/golang.org/x/arch/x86/x86asm". A package path +// typically denotes a subdirectory of the workspace. +// +// An import declaration uses an IMPORT PATH to refer to a package. +// Most import declarations use the package path as the import path. +// +// Due to VENDORING (https://golang.org/s/go15vendor), the +// interpretation of an import path may depend on the directory in which +// it appears. To resolve an import path to a package path, go/build +// must search the enclosing directories for a subdirectory named +// "vendor". +// +// ad hoc packages and external test packages are NON-IMPORTABLE. The +// path of an ad hoc package is inferred from the package +// declarations of its files and is therefore not a unique package key. +// For example, Config.CreatePkgs may specify two initial ad hoc +// packages, both with path "main". +// +// An AUGMENTED package is an importable package P plus all the +// *_test.go files with same 'package foo' declaration as P. +// (go/build.Package calls these files TestFiles.) +// +// The INITIAL packages are those specified in the configuration. A +// DEPENDENCY is a package loaded to satisfy an import in an initial +// package or another dependency. +package loader + +// IMPLEMENTATION NOTES +// +// 'go test', in-package test files, and import cycles +// --------------------------------------------------- +// +// An external test package may depend upon members of the augmented +// package that are not in the unaugmented package, such as functions +// that expose internals. (See bufio/export_test.go for an example.) +// So, the loader must ensure that for each external test package +// it loads, it also augments the corresponding non-test package. +// +// The import graph over n unaugmented packages must be acyclic; the +// import graph over n-1 unaugmented packages plus one augmented +// package must also be acyclic. ('go test' relies on this.) But the +// import graph over n augmented packages may contain cycles. +// +// First, all the (unaugmented) non-test packages and their +// dependencies are imported in the usual way; the loader reports an +// error if it detects an import cycle. +// +// Then, each package P for which testing is desired is augmented by +// the list P' of its in-package test files, by calling +// (*types.Checker).Files. This arrangement ensures that P' may +// reference definitions within P, but P may not reference definitions +// within P'. Furthermore, P' may import any other package, including +// ones that depend upon P, without an import cycle error. +// +// Consider two packages A and B, both of which have lists of +// in-package test files we'll call A' and B', and which have the +// following import graph edges: +// B imports A +// B' imports A +// A' imports B +// This last edge would be expected to create an error were it not +// for the special type-checking discipline above. +// Cycles of size greater than two are possible. For example: +// compress/bzip2/bzip2_test.go (package bzip2) imports "io/ioutil" +// io/ioutil/tempfile_test.go (package ioutil) imports "regexp" +// regexp/exec_test.go (package regexp) imports "compress/bzip2" +// +// +// Concurrency +// ----------- +// +// Let us define the import dependency graph as follows. Each node is a +// list of files passed to (Checker).Files at once. Many of these lists +// are the production code of an importable Go package, so those nodes +// are labelled by the package's path. The remaining nodes are +// ad hoc packages and lists of in-package *_test.go files that augment +// an importable package; those nodes have no label. +// +// The edges of the graph represent import statements appearing within a +// file. An edge connects a node (a list of files) to the node it +// imports, which is importable and thus always labelled. +// +// Loading is controlled by this dependency graph. +// +// To reduce I/O latency, we start loading a package's dependencies +// asynchronously as soon as we've parsed its files and enumerated its +// imports (scanImports). This performs a preorder traversal of the +// import dependency graph. +// +// To exploit hardware parallelism, we type-check unrelated packages in +// parallel, where "unrelated" means not ordered by the partial order of +// the import dependency graph. +// +// We use a concurrency-safe non-blocking cache (importer.imported) to +// record the results of type-checking, whether success or failure. An +// entry is created in this cache by startLoad the first time the +// package is imported. The first goroutine to request an entry becomes +// responsible for completing the task and broadcasting completion to +// subsequent requesters, which block until then. +// +// Type checking occurs in (parallel) postorder: we cannot type-check a +// set of files until we have loaded and type-checked all of their +// immediate dependencies (and thus all of their transitive +// dependencies). If the input were guaranteed free of import cycles, +// this would be trivial: we could simply wait for completion of the +// dependencies and then invoke the typechecker. +// +// But as we saw in the 'go test' section above, some cycles in the +// import graph over packages are actually legal, so long as the +// cycle-forming edge originates in the in-package test files that +// augment the package. This explains why the nodes of the import +// dependency graph are not packages, but lists of files: the unlabelled +// nodes avoid the cycles. Consider packages A and B where B imports A +// and A's in-package tests AT import B. The naively constructed import +// graph over packages would contain a cycle (A+AT) --> B --> (A+AT) but +// the graph over lists of files is AT --> B --> A, where AT is an +// unlabelled node. +// +// Awaiting completion of the dependencies in a cyclic graph would +// deadlock, so we must materialize the import dependency graph (as +// importer.graph) and check whether each import edge forms a cycle. If +// x imports y, and the graph already contains a path from y to x, then +// there is an import cycle, in which case the processing of x must not +// wait for the completion of processing of y. +// +// When the type-checker makes a callback (doImport) to the loader for a +// given import edge, there are two possible cases. In the normal case, +// the dependency has already been completely type-checked; doImport +// does a cache lookup and returns it. In the cyclic case, the entry in +// the cache is still necessarily incomplete, indicating a cycle. We +// perform the cycle check again to obtain the error message, and return +// the error. +// +// The result of using concurrency is about a 2.5x speedup for stdlib_test. diff --git a/vendor/golang.org/x/tools/go/loader/loader.go b/vendor/golang.org/x/tools/go/loader/loader.go new file mode 100644 index 0000000..3c9d4fe --- /dev/null +++ b/vendor/golang.org/x/tools/go/loader/loader.go @@ -0,0 +1,1061 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package loader + +// See doc.go for package documentation and implementation notes. + +import ( + "errors" + "fmt" + "go/ast" + "go/build" + "go/parser" + "go/token" + "go/types" + "os" + "path/filepath" + "sort" + "strings" + "sync" + "time" + + "golang.org/x/tools/go/ast/astutil" + "golang.org/x/tools/go/internal/cgo" +) + +var ignoreVendor build.ImportMode + +const trace = false // show timing info for type-checking + +// Config specifies the configuration for loading a whole program from +// Go source code. +// The zero value for Config is a ready-to-use default configuration. +type Config struct { + // Fset is the file set for the parser to use when loading the + // program. If nil, it may be lazily initialized by any + // method of Config. + Fset *token.FileSet + + // ParserMode specifies the mode to be used by the parser when + // loading source packages. + ParserMode parser.Mode + + // TypeChecker contains options relating to the type checker. + // + // The supplied IgnoreFuncBodies is not used; the effective + // value comes from the TypeCheckFuncBodies func below. + // The supplied Import function is not used either. + TypeChecker types.Config + + // TypeCheckFuncBodies is a predicate over package paths. + // A package for which the predicate is false will + // have its package-level declarations type checked, but not + // its function bodies; this can be used to quickly load + // dependencies from source. If nil, all func bodies are type + // checked. + TypeCheckFuncBodies func(path string) bool + + // If Build is non-nil, it is used to locate source packages. + // Otherwise &build.Default is used. + // + // By default, cgo is invoked to preprocess Go files that + // import the fake package "C". This behaviour can be + // disabled by setting CGO_ENABLED=0 in the environment prior + // to startup, or by setting Build.CgoEnabled=false. + Build *build.Context + + // The current directory, used for resolving relative package + // references such as "./go/loader". If empty, os.Getwd will be + // used instead. + Cwd string + + // If DisplayPath is non-nil, it is used to transform each + // file name obtained from Build.Import(). This can be used + // to prevent a virtualized build.Config's file names from + // leaking into the user interface. + DisplayPath func(path string) string + + // If AllowErrors is true, Load will return a Program even + // if some of the its packages contained I/O, parser or type + // errors; such errors are accessible via PackageInfo.Errors. If + // false, Load will fail if any package had an error. + AllowErrors bool + + // CreatePkgs specifies a list of non-importable initial + // packages to create. The resulting packages will appear in + // the corresponding elements of the Program.Created slice. + CreatePkgs []PkgSpec + + // ImportPkgs specifies a set of initial packages to load. + // The map keys are package paths. + // + // The map value indicates whether to load tests. If true, Load + // will add and type-check two lists of files to the package: + // non-test files followed by in-package *_test.go files. In + // addition, it will append the external test package (if any) + // to Program.Created. + ImportPkgs map[string]bool + + // FindPackage is called during Load to create the build.Package + // for a given import path from a given directory. + // If FindPackage is nil, (*build.Context).Import is used. + // A client may use this hook to adapt to a proprietary build + // system that does not follow the "go build" layout + // conventions, for example. + // + // It must be safe to call concurrently from multiple goroutines. + FindPackage func(ctxt *build.Context, importPath, fromDir string, mode build.ImportMode) (*build.Package, error) + + // AfterTypeCheck is called immediately after a list of files + // has been type-checked and appended to info.Files. + // + // This optional hook function is the earliest opportunity for + // the client to observe the output of the type checker, + // which may be useful to reduce analysis latency when loading + // a large program. + // + // The function is permitted to modify info.Info, for instance + // to clear data structures that are no longer needed, which can + // dramatically reduce peak memory consumption. + // + // The function may be called twice for the same PackageInfo: + // once for the files of the package and again for the + // in-package test files. + // + // It must be safe to call concurrently from multiple goroutines. + AfterTypeCheck func(info *PackageInfo, files []*ast.File) +} + +// A PkgSpec specifies a non-importable package to be created by Load. +// Files are processed first, but typically only one of Files and +// Filenames is provided. The path needn't be globally unique. +// +// For vendoring purposes, the package's directory is the one that +// contains the first file. +type PkgSpec struct { + Path string // package path ("" => use package declaration) + Files []*ast.File // ASTs of already-parsed files + Filenames []string // names of files to be parsed +} + +// A Program is a Go program loaded from source as specified by a Config. +type Program struct { + Fset *token.FileSet // the file set for this program + + // Created[i] contains the initial package whose ASTs or + // filenames were supplied by Config.CreatePkgs[i], followed by + // the external test package, if any, of each package in + // Config.ImportPkgs ordered by ImportPath. + // + // NOTE: these files must not import "C". Cgo preprocessing is + // only performed on imported packages, not ad hoc packages. + // + // TODO(adonovan): we need to copy and adapt the logic of + // goFilesPackage (from $GOROOT/src/cmd/go/build.go) and make + // Config.Import and Config.Create methods return the same kind + // of entity, essentially a build.Package. + // Perhaps we can even reuse that type directly. + Created []*PackageInfo + + // Imported contains the initially imported packages, + // as specified by Config.ImportPkgs. + Imported map[string]*PackageInfo + + // AllPackages contains the PackageInfo of every package + // encountered by Load: all initial packages and all + // dependencies, including incomplete ones. + AllPackages map[*types.Package]*PackageInfo + + // importMap is the canonical mapping of package paths to + // packages. It contains all Imported initial packages, but not + // Created ones, and all imported dependencies. + importMap map[string]*types.Package +} + +// PackageInfo holds the ASTs and facts derived by the type-checker +// for a single package. +// +// Not mutated once exposed via the API. +type PackageInfo struct { + Pkg *types.Package + Importable bool // true if 'import "Pkg.Path()"' would resolve to this + TransitivelyErrorFree bool // true if Pkg and all its dependencies are free of errors + Files []*ast.File // syntax trees for the package's files + Errors []error // non-nil if the package had errors + types.Info // type-checker deductions. + dir string // package directory + + checker *types.Checker // transient type-checker state + errorFunc func(error) +} + +func (info *PackageInfo) String() string { return info.Pkg.Path() } + +func (info *PackageInfo) appendError(err error) { + if info.errorFunc != nil { + info.errorFunc(err) + } else { + fmt.Fprintln(os.Stderr, err) + } + info.Errors = append(info.Errors, err) +} + +func (conf *Config) fset() *token.FileSet { + if conf.Fset == nil { + conf.Fset = token.NewFileSet() + } + return conf.Fset +} + +// ParseFile is a convenience function (intended for testing) that invokes +// the parser using the Config's FileSet, which is initialized if nil. +// +// src specifies the parser input as a string, []byte, or io.Reader, and +// filename is its apparent name. If src is nil, the contents of +// filename are read from the file system. +func (conf *Config) ParseFile(filename string, src any) (*ast.File, error) { + // TODO(adonovan): use conf.build() etc like parseFiles does. + return parser.ParseFile(conf.fset(), filename, src, conf.ParserMode) +} + +// FromArgsUsage is a partial usage message that applications calling +// FromArgs may wish to include in their -help output. +const FromArgsUsage = ` + is a list of arguments denoting a set of initial packages. +It may take one of two forms: + +1. A list of *.go source files. + + All of the specified files are loaded, parsed and type-checked + as a single package. All the files must belong to the same directory. + +2. A list of import paths, each denoting a package. + + The package's directory is found relative to the $GOROOT and + $GOPATH using similar logic to 'go build', and the *.go files in + that directory are loaded, parsed and type-checked as a single + package. + + In addition, all *_test.go files in the directory are then loaded + and parsed. Those files whose package declaration equals that of + the non-*_test.go files are included in the primary package. Test + files whose package declaration ends with "_test" are type-checked + as another package, the 'external' test package, so that a single + import path may denote two packages. (Whether this behaviour is + enabled is tool-specific, and may depend on additional flags.) + +A '--' argument terminates the list of packages. +` + +// FromArgs interprets args as a set of initial packages to load from +// source and updates the configuration. It returns the list of +// unconsumed arguments. +// +// It is intended for use in command-line interfaces that require a +// set of initial packages to be specified; see FromArgsUsage message +// for details. +// +// Only superficial errors are reported at this stage; errors dependent +// on I/O are detected during Load. +func (conf *Config) FromArgs(args []string, xtest bool) ([]string, error) { + var rest []string + for i, arg := range args { + if arg == "--" { + rest = args[i+1:] + args = args[:i] + break // consume "--" and return the remaining args + } + } + + if len(args) > 0 && strings.HasSuffix(args[0], ".go") { + // Assume args is a list of a *.go files + // denoting a single ad hoc package. + for _, arg := range args { + if !strings.HasSuffix(arg, ".go") { + return nil, fmt.Errorf("named files must be .go files: %s", arg) + } + } + conf.CreateFromFilenames("", args...) + } else { + // Assume args are directories each denoting a + // package and (perhaps) an external test, iff xtest. + for _, arg := range args { + if xtest { + conf.ImportWithTests(arg) + } else { + conf.Import(arg) + } + } + } + + return rest, nil +} + +// CreateFromFilenames is a convenience function that adds +// a conf.CreatePkgs entry to create a package of the specified *.go +// files. +func (conf *Config) CreateFromFilenames(path string, filenames ...string) { + conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Filenames: filenames}) +} + +// CreateFromFiles is a convenience function that adds a conf.CreatePkgs +// entry to create package of the specified path and parsed files. +func (conf *Config) CreateFromFiles(path string, files ...*ast.File) { + conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Files: files}) +} + +// ImportWithTests is a convenience function that adds path to +// ImportPkgs, the set of initial source packages located relative to +// $GOPATH. The package will be augmented by any *_test.go files in +// its directory that contain a "package x" (not "package x_test") +// declaration. +// +// In addition, if any *_test.go files contain a "package x_test" +// declaration, an additional package comprising just those files will +// be added to CreatePkgs. +func (conf *Config) ImportWithTests(path string) { conf.addImport(path, true) } + +// Import is a convenience function that adds path to ImportPkgs, the +// set of initial packages that will be imported from source. +func (conf *Config) Import(path string) { conf.addImport(path, false) } + +func (conf *Config) addImport(path string, tests bool) { + if path == "C" { + return // ignore; not a real package + } + if conf.ImportPkgs == nil { + conf.ImportPkgs = make(map[string]bool) + } + conf.ImportPkgs[path] = conf.ImportPkgs[path] || tests +} + +// PathEnclosingInterval returns the PackageInfo and ast.Node that +// contain source interval [start, end), and all the node's ancestors +// up to the AST root. It searches all ast.Files of all packages in prog. +// exact is defined as for astutil.PathEnclosingInterval. +// +// The zero value is returned if not found. +func (prog *Program) PathEnclosingInterval(start, end token.Pos) (pkg *PackageInfo, path []ast.Node, exact bool) { + for _, info := range prog.AllPackages { + for _, f := range info.Files { + if !tokenFileContainsPos(prog.Fset.File(f.FileStart), start) { + continue + } + if path, exact := astutil.PathEnclosingInterval(f, start, end); path != nil { + return info, path, exact + } + } + } + return nil, nil, false +} + +// InitialPackages returns a new slice containing the set of initial +// packages (Created + Imported) in unspecified order. +func (prog *Program) InitialPackages() []*PackageInfo { + infos := make([]*PackageInfo, 0, len(prog.Created)+len(prog.Imported)) + infos = append(infos, prog.Created...) + for _, info := range prog.Imported { + infos = append(infos, info) + } + return infos +} + +// Package returns the ASTs and results of type checking for the +// specified package. +func (prog *Program) Package(path string) *PackageInfo { + if info, ok := prog.AllPackages[prog.importMap[path]]; ok { + return info + } + for _, info := range prog.Created { + if path == info.Pkg.Path() { + return info + } + } + return nil +} + +// ---------- Implementation ---------- + +// importer holds the working state of the algorithm. +type importer struct { + conf *Config // the client configuration + start time.Time // for logging + + progMu sync.Mutex // guards prog + prog *Program // the resulting program + + // findpkg is a memoization of FindPackage. + findpkgMu sync.Mutex // guards findpkg + findpkg map[findpkgKey]*findpkgValue + + importedMu sync.Mutex // guards imported + imported map[string]*importInfo // all imported packages (incl. failures) by import path + + // import dependency graph: graph[x][y] => x imports y + // + // Since non-importable packages cannot be cyclic, we ignore + // their imports, thus we only need the subgraph over importable + // packages. Nodes are identified by their import paths. + graphMu sync.Mutex + graph map[string]map[string]bool +} + +type findpkgKey struct { + importPath string + fromDir string + mode build.ImportMode +} + +type findpkgValue struct { + ready chan struct{} // closed to broadcast readiness + bp *build.Package + err error +} + +// importInfo tracks the success or failure of a single import. +// +// Upon completion, exactly one of info and err is non-nil: +// info on successful creation of a package, err otherwise. +// A successful package may still contain type errors. +type importInfo struct { + path string // import path + info *PackageInfo // results of typechecking (including errors) + complete chan struct{} // closed to broadcast that info is set. +} + +// awaitCompletion blocks until ii is complete, +// i.e. the info field is safe to inspect. +func (ii *importInfo) awaitCompletion() { + <-ii.complete // wait for close +} + +// Complete marks ii as complete. +// Its info and err fields will not be subsequently updated. +func (ii *importInfo) Complete(info *PackageInfo) { + if info == nil { + panic("info == nil") + } + ii.info = info + close(ii.complete) +} + +type importError struct { + path string // import path + err error // reason for failure to create a package +} + +// Load creates the initial packages specified by conf.{Create,Import}Pkgs, +// loading their dependencies packages as needed. +// +// On success, Load returns a Program containing a PackageInfo for +// each package. On failure, it returns an error. +// +// If AllowErrors is true, Load will return a Program even if some +// packages contained I/O, parser or type errors, or if dependencies +// were missing. (Such errors are accessible via PackageInfo.Errors. If +// false, Load will fail if any package had an error. +// +// It is an error if no packages were loaded. +func (conf *Config) Load() (*Program, error) { + // Create a simple default error handler for parse/type errors. + if conf.TypeChecker.Error == nil { + conf.TypeChecker.Error = func(e error) { fmt.Fprintln(os.Stderr, e) } + } + + // Set default working directory for relative package references. + if conf.Cwd == "" { + var err error + conf.Cwd, err = os.Getwd() + if err != nil { + return nil, err + } + } + + // Install default FindPackage hook using go/build logic. + if conf.FindPackage == nil { + conf.FindPackage = (*build.Context).Import + } + + prog := &Program{ + Fset: conf.fset(), + Imported: make(map[string]*PackageInfo), + importMap: make(map[string]*types.Package), + AllPackages: make(map[*types.Package]*PackageInfo), + } + + imp := importer{ + conf: conf, + prog: prog, + findpkg: make(map[findpkgKey]*findpkgValue), + imported: make(map[string]*importInfo), + start: time.Now(), + graph: make(map[string]map[string]bool), + } + + // -- loading proper (concurrent phase) -------------------------------- + + var errpkgs []string // packages that contained errors + + // Load the initially imported packages and their dependencies, + // in parallel. + // No vendor check on packages imported from the command line. + infos, importErrors := imp.importAll("", conf.Cwd, conf.ImportPkgs, ignoreVendor) + for _, ie := range importErrors { + conf.TypeChecker.Error(ie.err) // failed to create package + errpkgs = append(errpkgs, ie.path) + } + for _, info := range infos { + prog.Imported[info.Pkg.Path()] = info + } + + // Augment the designated initial packages by their tests. + // Dependencies are loaded in parallel. + var xtestPkgs []*build.Package + for importPath, augment := range conf.ImportPkgs { + if !augment { + continue + } + + // No vendor check on packages imported from command line. + bp, err := imp.findPackage(importPath, conf.Cwd, ignoreVendor) + if err != nil { + // Package not found, or can't even parse package declaration. + // Already reported by previous loop; ignore it. + continue + } + + // Needs external test package? + if len(bp.XTestGoFiles) > 0 { + xtestPkgs = append(xtestPkgs, bp) + } + + // Consult the cache using the canonical package path. + path := bp.ImportPath + imp.importedMu.Lock() // (unnecessary, we're sequential here) + ii, ok := imp.imported[path] + // Paranoid checks added due to issue #11012. + if !ok { + // Unreachable. + // The previous loop called importAll and thus + // startLoad for each path in ImportPkgs, which + // populates imp.imported[path] with a non-zero value. + panic(fmt.Sprintf("imported[%q] not found", path)) + } + if ii == nil { + // Unreachable. + // The ii values in this loop are the same as in + // the previous loop, which enforced the invariant + // that at least one of ii.err and ii.info is non-nil. + panic(fmt.Sprintf("imported[%q] == nil", path)) + } + if ii.info == nil { + // Unreachable. + // awaitCompletion has the postcondition + // ii.info != nil. + panic(fmt.Sprintf("imported[%q].info = nil", path)) + } + info := ii.info + imp.importedMu.Unlock() + + // Parse the in-package test files. + files, errs := imp.conf.parsePackageFiles(bp, 't') + for _, err := range errs { + info.appendError(err) + } + + // The test files augmenting package P cannot be imported, + // but may import packages that import P, + // so we must disable the cycle check. + imp.addFiles(info, files, false) + } + + createPkg := func(path, dir string, files []*ast.File, errs []error) { + info := imp.newPackageInfo(path, dir) + for _, err := range errs { + info.appendError(err) + } + + // Ad hoc packages are non-importable, + // so no cycle check is needed. + // addFiles loads dependencies in parallel. + imp.addFiles(info, files, false) + prog.Created = append(prog.Created, info) + } + + // Create packages specified by conf.CreatePkgs. + for _, cp := range conf.CreatePkgs { + files, errs := parseFiles(conf.fset(), conf.build(), nil, conf.Cwd, cp.Filenames, conf.ParserMode) + files = append(files, cp.Files...) + + path := cp.Path + if path == "" { + if len(files) > 0 { + path = files[0].Name.Name + } else { + path = "(unnamed)" + } + } + + dir := conf.Cwd + if len(files) > 0 && files[0].Pos().IsValid() { + dir = filepath.Dir(conf.fset().File(files[0].Pos()).Name()) + } + createPkg(path, dir, files, errs) + } + + // Create external test packages. + sort.Sort(byImportPath(xtestPkgs)) + for _, bp := range xtestPkgs { + files, errs := imp.conf.parsePackageFiles(bp, 'x') + createPkg(bp.ImportPath+"_test", bp.Dir, files, errs) + } + + // -- finishing up (sequential) ---------------------------------------- + + if len(prog.Imported)+len(prog.Created) == 0 { + return nil, errors.New("no initial packages were loaded") + } + + // Create infos for indirectly imported packages. + // e.g. incomplete packages without syntax, loaded from export data. + for _, obj := range prog.importMap { + info := prog.AllPackages[obj] + if info == nil { + prog.AllPackages[obj] = &PackageInfo{Pkg: obj, Importable: true} + } else { + // finished + info.checker = nil + info.errorFunc = nil + } + } + + if !conf.AllowErrors { + // Report errors in indirectly imported packages. + for _, info := range prog.AllPackages { + if len(info.Errors) > 0 { + errpkgs = append(errpkgs, info.Pkg.Path()) + } + } + if errpkgs != nil { + var more string + if len(errpkgs) > 3 { + more = fmt.Sprintf(" and %d more", len(errpkgs)-3) + errpkgs = errpkgs[:3] + } + return nil, fmt.Errorf("couldn't load packages due to errors: %s%s", + strings.Join(errpkgs, ", "), more) + } + } + + markErrorFreePackages(prog.AllPackages) + + return prog, nil +} + +type byImportPath []*build.Package + +func (b byImportPath) Len() int { return len(b) } +func (b byImportPath) Less(i, j int) bool { return b[i].ImportPath < b[j].ImportPath } +func (b byImportPath) Swap(i, j int) { b[i], b[j] = b[j], b[i] } + +// markErrorFreePackages sets the TransitivelyErrorFree flag on all +// applicable packages. +func markErrorFreePackages(allPackages map[*types.Package]*PackageInfo) { + // Build the transpose of the import graph. + importedBy := make(map[*types.Package]map[*types.Package]bool) + for P := range allPackages { + for _, Q := range P.Imports() { + clients, ok := importedBy[Q] + if !ok { + clients = make(map[*types.Package]bool) + importedBy[Q] = clients + } + clients[P] = true + } + } + + // Find all packages reachable from some error package. + reachable := make(map[*types.Package]bool) + var visit func(*types.Package) + visit = func(p *types.Package) { + if !reachable[p] { + reachable[p] = true + for q := range importedBy[p] { + visit(q) + } + } + } + for _, info := range allPackages { + if len(info.Errors) > 0 { + visit(info.Pkg) + } + } + + // Mark the others as "transitively error-free". + for _, info := range allPackages { + if !reachable[info.Pkg] { + info.TransitivelyErrorFree = true + } + } +} + +// build returns the effective build context. +func (conf *Config) build() *build.Context { + if conf.Build != nil { + return conf.Build + } + return &build.Default +} + +// parsePackageFiles enumerates the files belonging to package path, +// then loads, parses and returns them, plus a list of I/O or parse +// errors that were encountered. +// +// 'which' indicates which files to include: +// +// 'g': include non-test *.go source files (GoFiles + processed CgoFiles) +// 't': include in-package *_test.go source files (TestGoFiles) +// 'x': include external *_test.go source files. (XTestGoFiles) +func (conf *Config) parsePackageFiles(bp *build.Package, which rune) ([]*ast.File, []error) { + if bp.ImportPath == "unsafe" { + return nil, nil + } + var filenames []string + switch which { + case 'g': + filenames = bp.GoFiles + case 't': + filenames = bp.TestGoFiles + case 'x': + filenames = bp.XTestGoFiles + default: + panic(which) + } + + files, errs := parseFiles(conf.fset(), conf.build(), conf.DisplayPath, bp.Dir, filenames, conf.ParserMode) + + // Preprocess CgoFiles and parse the outputs (sequentially). + if which == 'g' && bp.CgoFiles != nil { + ioLimit <- true + cgofiles, err := cgo.ProcessFiles(bp, conf.fset(), conf.DisplayPath, conf.ParserMode) + <-ioLimit + if err != nil { + errs = append(errs, err) + } else { + files = append(files, cgofiles...) + } + } + + return files, errs +} + +// doImport imports the package denoted by path. +// It implements the types.Importer signature. +// +// It returns an error if a package could not be created +// (e.g. go/build or parse error), but type errors are reported via +// the types.Config.Error callback (the first of which is also saved +// in the package's PackageInfo). +// +// Idempotent. +func (imp *importer) doImport(from *PackageInfo, to string) (*types.Package, error) { + if to == "C" { + // This should be unreachable, but ad hoc packages are + // not currently subject to cgo preprocessing. + // See https://golang.org/issue/11627. + return nil, fmt.Errorf(`the loader doesn't cgo-process ad hoc packages like %q; see Go issue 11627`, + from.Pkg.Path()) + } + + bp, err := imp.findPackage(to, from.dir, 0) + if err != nil { + return nil, err + } + + // The standard unsafe package is handled specially, + // and has no PackageInfo. + if bp.ImportPath == "unsafe" { + return types.Unsafe, nil + } + + // Look for the package in the cache using its canonical path. + path := bp.ImportPath + imp.importedMu.Lock() + ii := imp.imported[path] + imp.importedMu.Unlock() + if ii == nil { + panic("internal error: unexpected import: " + path) + } + if ii.info != nil { + return ii.info.Pkg, nil + } + + // Import of incomplete package: this indicates a cycle. + fromPath := from.Pkg.Path() + if cycle := imp.findPath(path, fromPath); cycle != nil { + // Normalize cycle: start from alphabetically largest node. + pos, start := -1, "" + for i, s := range cycle { + if pos < 0 || s > start { + pos, start = i, s + } + } + cycle = append(cycle, cycle[:pos]...)[pos:] // rotate cycle to start from largest + cycle = append(cycle, cycle[0]) // add start node to end to show cycliness + return nil, fmt.Errorf("import cycle: %s", strings.Join(cycle, " -> ")) + } + + panic("internal error: import of incomplete (yet acyclic) package: " + fromPath) +} + +// findPackage locates the package denoted by the importPath in the +// specified directory. +func (imp *importer) findPackage(importPath, fromDir string, mode build.ImportMode) (*build.Package, error) { + // We use a non-blocking duplicate-suppressing cache (gopl.io §9.7) + // to avoid holding the lock around FindPackage. + key := findpkgKey{importPath, fromDir, mode} + imp.findpkgMu.Lock() + v, ok := imp.findpkg[key] + if ok { + // cache hit + imp.findpkgMu.Unlock() + + <-v.ready // wait for entry to become ready + } else { + // Cache miss: this goroutine becomes responsible for + // populating the map entry and broadcasting its readiness. + v = &findpkgValue{ready: make(chan struct{})} + imp.findpkg[key] = v + imp.findpkgMu.Unlock() + + ioLimit <- true + v.bp, v.err = imp.conf.FindPackage(imp.conf.build(), importPath, fromDir, mode) + <-ioLimit + + if _, ok := v.err.(*build.NoGoError); ok { + v.err = nil // empty directory is not an error + } + + close(v.ready) // broadcast ready condition + } + return v.bp, v.err +} + +// importAll loads, parses, and type-checks the specified packages in +// parallel and returns their completed importInfos in unspecified order. +// +// fromPath is the package path of the importing package, if it is +// importable, "" otherwise. It is used for cycle detection. +// +// fromDir is the directory containing the import declaration that +// caused these imports. +func (imp *importer) importAll(fromPath, fromDir string, imports map[string]bool, mode build.ImportMode) (infos []*PackageInfo, errors []importError) { + if fromPath != "" { + // We're loading a set of imports. + // + // We must record graph edges from the importing package + // to its dependencies, and check for cycles. + imp.graphMu.Lock() + deps, ok := imp.graph[fromPath] + if !ok { + deps = make(map[string]bool) + imp.graph[fromPath] = deps + } + for importPath := range imports { + deps[importPath] = true + } + imp.graphMu.Unlock() + } + + var pending []*importInfo + for importPath := range imports { + if fromPath != "" { + if cycle := imp.findPath(importPath, fromPath); cycle != nil { + // Cycle-forming import: we must not check it + // since it would deadlock. + if trace { + fmt.Fprintf(os.Stderr, "import cycle: %q\n", cycle) + } + continue + } + } + bp, err := imp.findPackage(importPath, fromDir, mode) + if err != nil { + errors = append(errors, importError{ + path: importPath, + err: err, + }) + continue + } + pending = append(pending, imp.startLoad(bp)) + } + + for _, ii := range pending { + ii.awaitCompletion() + infos = append(infos, ii.info) + } + + return infos, errors +} + +// findPath returns an arbitrary path from 'from' to 'to' in the import +// graph, or nil if there was none. +func (imp *importer) findPath(from, to string) []string { + imp.graphMu.Lock() + defer imp.graphMu.Unlock() + + seen := make(map[string]bool) + var search func(stack []string, importPath string) []string + search = func(stack []string, importPath string) []string { + if !seen[importPath] { + seen[importPath] = true + stack = append(stack, importPath) + if importPath == to { + return stack + } + for x := range imp.graph[importPath] { + if p := search(stack, x); p != nil { + return p + } + } + } + return nil + } + return search(make([]string, 0, 20), from) +} + +// startLoad initiates the loading, parsing and type-checking of the +// specified package and its dependencies, if it has not already begun. +// +// It returns an importInfo, not necessarily in a completed state. The +// caller must call awaitCompletion() before accessing its info field. +// +// startLoad is concurrency-safe and idempotent. +func (imp *importer) startLoad(bp *build.Package) *importInfo { + path := bp.ImportPath + imp.importedMu.Lock() + ii, ok := imp.imported[path] + if !ok { + ii = &importInfo{path: path, complete: make(chan struct{})} + imp.imported[path] = ii + go func() { + info := imp.load(bp) + ii.Complete(info) + }() + } + imp.importedMu.Unlock() + + return ii +} + +// load implements package loading by parsing Go source files +// located by go/build. +func (imp *importer) load(bp *build.Package) *PackageInfo { + info := imp.newPackageInfo(bp.ImportPath, bp.Dir) + info.Importable = true + files, errs := imp.conf.parsePackageFiles(bp, 'g') + for _, err := range errs { + info.appendError(err) + } + + imp.addFiles(info, files, true) + + imp.progMu.Lock() + imp.prog.importMap[bp.ImportPath] = info.Pkg + imp.progMu.Unlock() + + return info +} + +// addFiles adds and type-checks the specified files to info, loading +// their dependencies if needed. The order of files determines the +// package initialization order. It may be called multiple times on the +// same package. Errors are appended to the info.Errors field. +// +// cycleCheck determines whether the imports within files create +// dependency edges that should be checked for potential cycles. +func (imp *importer) addFiles(info *PackageInfo, files []*ast.File, cycleCheck bool) { + // Ensure the dependencies are loaded, in parallel. + var fromPath string + if cycleCheck { + fromPath = info.Pkg.Path() + } + // TODO(adonovan): opt: make the caller do scanImports. + // Callers with a build.Package can skip it. + imp.importAll(fromPath, info.dir, scanImports(files), 0) + + if trace { + fmt.Fprintf(os.Stderr, "%s: start %q (%d)\n", + time.Since(imp.start), info.Pkg.Path(), len(files)) + } + + // Don't call checker.Files on Unsafe, even with zero files, + // because it would mutate the package, which is a global. + if info.Pkg == types.Unsafe { + if len(files) > 0 { + panic(`"unsafe" package contains unexpected files`) + } + } else { + // Ignore the returned (first) error since we + // already collect them all in the PackageInfo. + info.checker.Files(files) + info.Files = append(info.Files, files...) + } + + if imp.conf.AfterTypeCheck != nil { + imp.conf.AfterTypeCheck(info, files) + } + + if trace { + fmt.Fprintf(os.Stderr, "%s: stop %q\n", + time.Since(imp.start), info.Pkg.Path()) + } +} + +func (imp *importer) newPackageInfo(path, dir string) *PackageInfo { + var pkg *types.Package + if path == "unsafe" { + pkg = types.Unsafe + } else { + pkg = types.NewPackage(path, "") + } + info := &PackageInfo{ + Pkg: pkg, + Info: types.Info{ + Types: make(map[ast.Expr]types.TypeAndValue), + Defs: make(map[*ast.Ident]types.Object), + Uses: make(map[*ast.Ident]types.Object), + Implicits: make(map[ast.Node]types.Object), + Instances: make(map[*ast.Ident]types.Instance), + Scopes: make(map[ast.Node]*types.Scope), + Selections: make(map[*ast.SelectorExpr]*types.Selection), + FileVersions: make(map[*ast.File]string), + }, + errorFunc: imp.conf.TypeChecker.Error, + dir: dir, + } + + // Copy the types.Config so we can vary it across PackageInfos. + tc := imp.conf.TypeChecker + tc.IgnoreFuncBodies = false + if f := imp.conf.TypeCheckFuncBodies; f != nil { + tc.IgnoreFuncBodies = !f(path) + } + tc.Importer = closure{imp, info} + tc.Error = info.appendError // appendError wraps the user's Error function + + info.checker = types.NewChecker(&tc, imp.conf.fset(), pkg, &info.Info) + imp.progMu.Lock() + imp.prog.AllPackages[pkg] = info + imp.progMu.Unlock() + return info +} + +type closure struct { + imp *importer + info *PackageInfo +} + +func (c closure) Import(to string) (*types.Package, error) { return c.imp.doImport(c.info, to) } diff --git a/vendor/golang.org/x/tools/go/loader/util.go b/vendor/golang.org/x/tools/go/loader/util.go new file mode 100644 index 0000000..3a80aca --- /dev/null +++ b/vendor/golang.org/x/tools/go/loader/util.go @@ -0,0 +1,123 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package loader + +import ( + "go/ast" + "go/build" + "go/parser" + "go/token" + "io" + "os" + "strconv" + "sync" + + "golang.org/x/tools/go/buildutil" +) + +// We use a counting semaphore to limit +// the number of parallel I/O calls per process. +var ioLimit = make(chan bool, 10) + +// parseFiles parses the Go source files within directory dir and +// returns the ASTs of the ones that could be at least partially parsed, +// along with a list of I/O and parse errors encountered. +// +// I/O is done via ctxt, which may specify a virtual file system. +// displayPath is used to transform the filenames attached to the ASTs. +func parseFiles(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, files []string, mode parser.Mode) ([]*ast.File, []error) { + if displayPath == nil { + displayPath = func(path string) string { return path } + } + var wg sync.WaitGroup + n := len(files) + parsed := make([]*ast.File, n) + errors := make([]error, n) + for i, file := range files { + if !buildutil.IsAbsPath(ctxt, file) { + file = buildutil.JoinPath(ctxt, dir, file) + } + wg.Add(1) + go func(i int, file string) { + ioLimit <- true // wait + defer func() { + wg.Done() + <-ioLimit // signal + }() + var rd io.ReadCloser + var err error + if ctxt.OpenFile != nil { + rd, err = ctxt.OpenFile(file) + } else { + rd, err = os.Open(file) + } + if err != nil { + errors[i] = err // open failed + return + } + + // ParseFile may return both an AST and an error. + parsed[i], errors[i] = parser.ParseFile(fset, displayPath(file), rd, mode) + rd.Close() + }(i, file) + } + wg.Wait() + + // Eliminate nils, preserving order. + var o int + for _, f := range parsed { + if f != nil { + parsed[o] = f + o++ + } + } + parsed = parsed[:o] + + o = 0 + for _, err := range errors { + if err != nil { + errors[o] = err + o++ + } + } + errors = errors[:o] + + return parsed, errors +} + +// scanImports returns the set of all import paths from all +// import specs in the specified files. +func scanImports(files []*ast.File) map[string]bool { + imports := make(map[string]bool) + for _, f := range files { + for _, decl := range f.Decls { + if decl, ok := decl.(*ast.GenDecl); ok && decl.Tok == token.IMPORT { + for _, spec := range decl.Specs { + spec := spec.(*ast.ImportSpec) + + // NB: do not assume the program is well-formed! + path, err := strconv.Unquote(spec.Path.Value) + if err != nil { + continue // quietly ignore the error + } + if path == "C" { + continue // skip pseudopackage + } + imports[path] = true + } + } + } + } + return imports +} + +// ---------- Internal helpers ---------- + +// TODO(adonovan): make this a method: func (*token.File) Contains(token.Pos) +func tokenFileContainsPos(f *token.File, pos token.Pos) bool { + p := int(pos) + base := f.Base() + return base <= p && p < base+f.Size() +} diff --git a/vendor/golang.org/x/tools/go/packages/doc.go b/vendor/golang.org/x/tools/go/packages/doc.go new file mode 100644 index 0000000..366aab6 --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/doc.go @@ -0,0 +1,253 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package packages loads Go packages for inspection and analysis. + +The [Load] function takes as input a list of patterns and returns a +list of [Package] values describing individual packages matched by those +patterns. +A [Config] specifies configuration options, the most important of which is +the [LoadMode], which controls the amount of detail in the loaded packages. + +Load passes most patterns directly to the underlying build tool. +The default build tool is the go command. +Its supported patterns are described at +https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns. +Other build systems may be supported by providing a "driver"; +see [The driver protocol]. + +All patterns with the prefix "query=", where query is a +non-empty string of letters from [a-z], are reserved and may be +interpreted as query operators. + +Two query operators are currently supported: "file" and "pattern". + +The query "file=path/to/file.go" matches the package or packages enclosing +the Go source file path/to/file.go. For example "file=~/go/src/fmt/print.go" +might return the packages "fmt" and "fmt [fmt.test]". + +The query "pattern=string" causes "string" to be passed directly to +the underlying build tool. In most cases this is unnecessary, +but an application can use Load("pattern=" + x) as an escaping mechanism +to ensure that x is not interpreted as a query operator if it contains '='. + +All other query operators are reserved for future use and currently +cause Load to report an error. + +The Package struct provides basic information about the package, including + + - ID, a unique identifier for the package in the returned set; + - GoFiles, the names of the package's Go source files; + - Imports, a map from source import strings to the Packages they name; + - Types, the type information for the package's exported symbols; + - Syntax, the parsed syntax trees for the package's source code; and + - TypesInfo, the result of a complete type-check of the package syntax trees. + +(See the documentation for type Package for the complete list of fields +and more detailed descriptions.) + +For example, + + Load(nil, "bytes", "unicode...") + +returns four Package structs describing the standard library packages +bytes, unicode, unicode/utf16, and unicode/utf8. Note that one pattern +can match multiple packages and that a package might be matched by +multiple patterns: in general it is not possible to determine which +packages correspond to which patterns. + +Note that the list returned by Load contains only the packages matched +by the patterns. Their dependencies can be found by walking the import +graph using the Imports fields. + +The Load function can be configured by passing a pointer to a Config as +the first argument. A nil Config is equivalent to the zero Config, which +causes Load to run in [LoadFiles] mode, collecting minimal information. +See the documentation for type Config for details. + +As noted earlier, the Config.Mode controls the amount of detail +reported about the loaded packages. See the documentation for type LoadMode +for details. + +Most tools should pass their command-line arguments (after any flags) +uninterpreted to Load, so that it can interpret them +according to the conventions of the underlying build system. + +See the Example function for typical usage. +See also [golang.org/x/tools/go/packages/internal/linecount] +for an example application. + +# The driver protocol + +Load may be used to load Go packages even in Go projects that use +alternative build systems, by installing an appropriate "driver" +program for the build system and specifying its location in the +GOPACKAGESDRIVER environment variable. +For example, +https://github.com/bazelbuild/rules_go/wiki/Editor-and-tool-integration +explains how to use the driver for Bazel. + +The driver program is responsible for interpreting patterns in its +preferred notation and reporting information about the packages that +those patterns identify. Drivers must also support the special "file=" +and "pattern=" patterns described above. + +The patterns are provided as positional command-line arguments. A +JSON-encoded [DriverRequest] message providing additional information +is written to the driver's standard input. The driver must write a +JSON-encoded [DriverResponse] message to its standard output. (This +message differs from the JSON schema produced by 'go list'.) + +The value of the PWD environment variable seen by the driver process +is the preferred name of its working directory. (The working directory +may have other aliases due to symbolic links; see the comment on the +Dir field of [exec.Cmd] for related information.) +When the driver process emits in its response the name of a file +that is a descendant of this directory, it must use an absolute path +that has the value of PWD as a prefix, to ensure that the returned +filenames satisfy the original query. +*/ +package packages // import "golang.org/x/tools/go/packages" + +/* + +Motivation and design considerations + +The new package's design solves problems addressed by two existing +packages: go/build, which locates and describes packages, and +golang.org/x/tools/go/loader, which loads, parses and type-checks them. +The go/build.Package structure encodes too much of the 'go build' way +of organizing projects, leaving us in need of a data type that describes a +package of Go source code independent of the underlying build system. +We wanted something that works equally well with go build and vgo, and +also other build systems such as Bazel and Blaze, making it possible to +construct analysis tools that work in all these environments. +Tools such as errcheck and staticcheck were essentially unavailable to +the Go community at Google, and some of Google's internal tools for Go +are unavailable externally. +This new package provides a uniform way to obtain package metadata by +querying each of these build systems, optionally supporting their +preferred command-line notations for packages, so that tools integrate +neatly with users' build environments. The Metadata query function +executes an external query tool appropriate to the current workspace. + +Loading packages always returns the complete import graph "all the way down", +even if all you want is information about a single package, because the query +mechanisms of all the build systems we currently support ({go,vgo} list, and +blaze/bazel aspect-based query) cannot provide detailed information +about one package without visiting all its dependencies too, so there is +no additional asymptotic cost to providing transitive information. +(This property might not be true of a hypothetical 5th build system.) + +In calls to TypeCheck, all initial packages, and any package that +transitively depends on one of them, must be loaded from source. +Consider A->B->C->D->E: if A,C are initial, A,B,C must be loaded from +source; D may be loaded from export data, and E may not be loaded at all +(though it's possible that D's export data mentions it, so a +types.Package may be created for it and exposed.) + +The old loader had a feature to suppress type-checking of function +bodies on a per-package basis, primarily intended to reduce the work of +obtaining type information for imported packages. Now that imports are +satisfied by export data, the optimization no longer seems necessary. + +Despite some early attempts, the old loader did not exploit export data, +instead always using the equivalent of WholeProgram mode. This was due +to the complexity of mixing source and export data packages (now +resolved by the upward traversal mentioned above), and because export data +files were nearly always missing or stale. Now that 'go build' supports +caching, all the underlying build systems can guarantee to produce +export data in a reasonable (amortized) time. + +Test "main" packages synthesized by the build system are now reported as +first-class packages, avoiding the need for clients (such as go/ssa) to +reinvent this generation logic. + +One way in which go/packages is simpler than the old loader is in its +treatment of in-package tests. In-package tests are packages that +consist of all the files of the library under test, plus the test files. +The old loader constructed in-package tests by a two-phase process of +mutation called "augmentation": first it would construct and type check +all the ordinary library packages and type-check the packages that +depend on them; then it would add more (test) files to the package and +type-check again. This two-phase approach had four major problems: +1) in processing the tests, the loader modified the library package, + leaving no way for a client application to see both the test + package and the library package; one would mutate into the other. +2) because test files can declare additional methods on types defined in + the library portion of the package, the dispatch of method calls in + the library portion was affected by the presence of the test files. + This should have been a clue that the packages were logically + different. +3) this model of "augmentation" assumed at most one in-package test + per library package, which is true of projects using 'go build', + but not other build systems. +4) because of the two-phase nature of test processing, all packages that + import the library package had to be processed before augmentation, + forcing a "one-shot" API and preventing the client from calling Load + in several times in sequence as is now possible in WholeProgram mode. + (TypeCheck mode has a similar one-shot restriction for a different reason.) + +Early drafts of this package supported "multi-shot" operation. +Although it allowed clients to make a sequence of calls (or concurrent +calls) to Load, building up the graph of Packages incrementally, +it was of marginal value: it complicated the API +(since it allowed some options to vary across calls but not others), +it complicated the implementation, +it cannot be made to work in Types mode, as explained above, +and it was less efficient than making one combined call (when this is possible). +Among the clients we have inspected, none made multiple calls to load +but could not be easily and satisfactorily modified to make only a single call. +However, applications changes may be required. +For example, the ssadump command loads the user-specified packages +and in addition the runtime package. It is tempting to simply append +"runtime" to the user-provided list, but that does not work if the user +specified an ad-hoc package such as [a.go b.go]. +Instead, ssadump no longer requests the runtime package, +but seeks it among the dependencies of the user-specified packages, +and emits an error if it is not found. + +Questions & Tasks + +- Add GOARCH/GOOS? + They are not portable concepts, but could be made portable. + Our goal has been to allow users to express themselves using the conventions + of the underlying build system: if the build system honors GOARCH + during a build and during a metadata query, then so should + applications built atop that query mechanism. + Conversely, if the target architecture of the build is determined by + command-line flags, the application can pass the relevant + flags through to the build system using a command such as: + myapp -query_flag="--cpu=amd64" -query_flag="--os=darwin" + However, this approach is low-level, unwieldy, and non-portable. + GOOS and GOARCH seem important enough to warrant a dedicated option. + +- How should we handle partial failures such as a mixture of good and + malformed patterns, existing and non-existent packages, successful and + failed builds, import failures, import cycles, and so on, in a call to + Load? + +- Support bazel, blaze, and go1.10 list, not just go1.11 list. + +- Handle (and test) various partial success cases, e.g. + a mixture of good packages and: + invalid patterns + nonexistent packages + empty packages + packages with malformed package or import declarations + unreadable files + import cycles + other parse errors + type errors + Make sure we record errors at the correct place in the graph. + +- Missing packages among initial arguments are not reported. + Return bogus packages for them, like golist does. + +- "undeclared name" errors (for example) are reported out of source file + order. I suspect this is due to the breadth-first resolution now used + by go/types. Is that a bug? Discuss with gri. + +*/ diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go new file mode 100644 index 0000000..f37bc65 --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/external.go @@ -0,0 +1,153 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package packages + +// This file defines the protocol that enables an external "driver" +// tool to supply package metadata in place of 'go list'. + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "os/exec" + "slices" + "strings" +) + +// DriverRequest defines the schema of a request for package metadata +// from an external driver program. The JSON-encoded DriverRequest +// message is provided to the driver program's standard input. The +// query patterns are provided as command-line arguments. +// +// See the package documentation for an overview. +type DriverRequest struct { + Mode LoadMode `json:"mode"` + + // Env specifies the environment the underlying build system should be run in. + Env []string `json:"env"` + + // BuildFlags are flags that should be passed to the underlying build system. + BuildFlags []string `json:"build_flags"` + + // Tests specifies whether the patterns should also return test packages. + Tests bool `json:"tests"` + + // Overlay maps file paths (relative to the driver's working directory) + // to the contents of overlay files (see Config.Overlay). + Overlay map[string][]byte `json:"overlay"` +} + +// DriverResponse defines the schema of a response from an external +// driver program, providing the results of a query for package +// metadata. The driver program must write a JSON-encoded +// DriverResponse message to its standard output. +// +// See the package documentation for an overview. +type DriverResponse struct { + // NotHandled is returned if the request can't be handled by the current + // driver. If an external driver returns a response with NotHandled, the + // rest of the DriverResponse is ignored, and go/packages will fallback + // to the next driver. If go/packages is extended in the future to support + // lists of multiple drivers, go/packages will fall back to the next driver. + NotHandled bool + + // Compiler and Arch are the arguments pass of types.SizesFor + // to get a types.Sizes to use when type checking. + Compiler string + Arch string + + // Roots is the set of package IDs that make up the root packages. + // We have to encode this separately because when we encode a single package + // we cannot know if it is one of the roots as that requires knowledge of the + // graph it is part of. + Roots []string `json:",omitempty"` + + // Packages is the full set of packages in the graph. + // The packages are not connected into a graph. + // The Imports if populated will be stubs that only have their ID set. + // Imports will be connected and then type and syntax information added in a + // later pass (see refine). + Packages []*Package + + // GoVersion is the minor version number used by the driver + // (e.g. the go command on the PATH) when selecting .go files. + // Zero means unknown. + GoVersion int +} + +// driver is the type for functions that query the build system for the +// packages named by the patterns. +type driver func(cfg *Config, patterns []string) (*DriverResponse, error) + +// findExternalDriver returns the file path of a tool that supplies +// the build system package structure, or "" if not found. +// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its +// value, otherwise it searches for a binary named gopackagesdriver on the PATH. +func findExternalDriver(cfg *Config) driver { + const toolPrefix = "GOPACKAGESDRIVER=" + tool := "" + for _, env := range cfg.Env { + if val, ok := strings.CutPrefix(env, toolPrefix); ok { + tool = val + } + } + if tool != "" && tool == "off" { + return nil + } + if tool == "" { + var err error + tool, err = exec.LookPath("gopackagesdriver") + if err != nil { + return nil + } + } + return func(cfg *Config, patterns []string) (*DriverResponse, error) { + req, err := json.Marshal(DriverRequest{ + Mode: cfg.Mode, + Env: cfg.Env, + BuildFlags: cfg.BuildFlags, + Tests: cfg.Tests, + Overlay: cfg.Overlay, + }) + if err != nil { + return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) + } + + buf := new(bytes.Buffer) + stderr := new(bytes.Buffer) + cmd := exec.CommandContext(cfg.Context, tool, patterns...) + cmd.Dir = cfg.Dir + // The cwd gets resolved to the real path. On Darwin, where + // /tmp is a symlink, this breaks anything that expects the + // working directory to keep the original path, including the + // go command when dealing with modules. + // + // os.Getwd stdlib has a special feature where if the + // cwd and the PWD are the same node then it trusts + // the PWD, so by setting it in the env for the child + // process we fix up all the paths returned by the go + // command. + // + // (See similar trick in Invocation.run in ../../internal/gocommand/invoke.go) + cmd.Env = append(slices.Clip(cfg.Env), "PWD="+cfg.Dir) + cmd.Stdin = bytes.NewReader(req) + cmd.Stdout = buf + cmd.Stderr = stderr + + if err := cmd.Run(); err != nil { + return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) + } + if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" { + fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr) + } + + var response DriverResponse + if err := json.Unmarshal(buf.Bytes(), &response); err != nil { + return nil, err + } + return &response, nil + } +} diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go new file mode 100644 index 0000000..8f66c35 --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/golist.go @@ -0,0 +1,1140 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package packages + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log" + "os" + "os/exec" + "path" + "path/filepath" + "reflect" + "sort" + "strconv" + "strings" + "sync" + "unicode" + + "golang.org/x/tools/internal/gocommand" + "golang.org/x/tools/internal/packagesinternal" +) + +// debug controls verbose logging. +var debug, _ = strconv.ParseBool(os.Getenv("GOPACKAGESDEBUG")) + +// A goTooOldError reports that the go command +// found by exec.LookPath is too old to use the new go list behavior. +type goTooOldError struct { + error +} + +// responseDeduper wraps a DriverResponse, deduplicating its contents. +type responseDeduper struct { + seenRoots map[string]bool + seenPackages map[string]*Package + dr *DriverResponse +} + +func newDeduper() *responseDeduper { + return &responseDeduper{ + dr: &DriverResponse{}, + seenRoots: map[string]bool{}, + seenPackages: map[string]*Package{}, + } +} + +// addAll fills in r with a DriverResponse. +func (r *responseDeduper) addAll(dr *DriverResponse) { + for _, pkg := range dr.Packages { + r.addPackage(pkg) + } + for _, root := range dr.Roots { + r.addRoot(root) + } + r.dr.GoVersion = dr.GoVersion +} + +func (r *responseDeduper) addPackage(p *Package) { + if prev := r.seenPackages[p.ID]; prev != nil { + // Package already seen in a previous response. Merge the file lists, + // removing duplicates. This can happen when the same package appears + // in multiple driver responses that are being merged together. + prev.GoFiles = appendUniqueStrings(prev.GoFiles, p.GoFiles) + prev.CompiledGoFiles = appendUniqueStrings(prev.CompiledGoFiles, p.CompiledGoFiles) + prev.OtherFiles = appendUniqueStrings(prev.OtherFiles, p.OtherFiles) + prev.IgnoredFiles = appendUniqueStrings(prev.IgnoredFiles, p.IgnoredFiles) + prev.EmbedFiles = appendUniqueStrings(prev.EmbedFiles, p.EmbedFiles) + prev.EmbedPatterns = appendUniqueStrings(prev.EmbedPatterns, p.EmbedPatterns) + return + } + r.seenPackages[p.ID] = p + r.dr.Packages = append(r.dr.Packages, p) +} + +// appendUniqueStrings appends elements from src to dst, skipping duplicates. +func appendUniqueStrings(dst, src []string) []string { + if len(src) == 0 { + return dst + } + + seen := make(map[string]bool, len(dst)) + for _, s := range dst { + seen[s] = true + } + + for _, s := range src { + if !seen[s] { + dst = append(dst, s) + } + } + + return dst +} + +func (r *responseDeduper) addRoot(id string) { + if r.seenRoots[id] { + return + } + r.seenRoots[id] = true + r.dr.Roots = append(r.dr.Roots, id) +} + +type golistState struct { + cfg *Config + ctx context.Context + + runner *gocommand.Runner + + // overlay is the JSON file that encodes the Config.Overlay + // mapping, used by 'go list -overlay=...'. + overlay string + + envOnce sync.Once + goEnvError error + goEnv map[string]string + + rootsOnce sync.Once + rootDirsError error + rootDirs map[string]string + + goVersionOnce sync.Once + goVersionError error + goVersion int // The X in Go 1.X. + + // vendorDirs caches the (non)existence of vendor directories. + vendorDirs map[string]bool +} + +// getEnv returns Go environment variables. Only specific variables are +// populated -- computing all of them is slow. +func (state *golistState) getEnv() (map[string]string, error) { + state.envOnce.Do(func() { + var b *bytes.Buffer + b, state.goEnvError = state.invokeGo("env", "-json", "GOMOD", "GOPATH") + if state.goEnvError != nil { + return + } + + state.goEnv = make(map[string]string) + decoder := json.NewDecoder(b) + if state.goEnvError = decoder.Decode(&state.goEnv); state.goEnvError != nil { + return + } + }) + return state.goEnv, state.goEnvError +} + +// mustGetEnv is a convenience function that can be used if getEnv has already succeeded. +func (state *golistState) mustGetEnv() map[string]string { + env, err := state.getEnv() + if err != nil { + panic(fmt.Sprintf("mustGetEnv: %v", err)) + } + return env +} + +// goListDriver uses the go list command to interpret the patterns and produce +// the build system package structure. +// See driver for more details. +// +// overlay is the JSON file that encodes the cfg.Overlay +// mapping, used by 'go list -overlay=...' +func goListDriver(cfg *Config, runner *gocommand.Runner, overlay string, patterns []string) (_ *DriverResponse, err error) { + // Make sure that any asynchronous go commands are killed when we return. + parentCtx := cfg.Context + if parentCtx == nil { + parentCtx = context.Background() + } + ctx, cancel := context.WithCancel(parentCtx) + defer cancel() + + response := newDeduper() + + state := &golistState{ + cfg: cfg, + ctx: ctx, + vendorDirs: map[string]bool{}, + overlay: overlay, + runner: runner, + } + + // Fill in response.Sizes asynchronously if necessary. + if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 { + errCh := make(chan error) + go func() { + compiler, arch, err := getSizesForArgs(ctx, state.cfgInvocation(), runner) + response.dr.Compiler = compiler + response.dr.Arch = arch + errCh <- err + }() + defer func() { + if sizesErr := <-errCh; sizesErr != nil { + err = sizesErr + } + }() + } + + // Determine files requested in contains patterns + var containFiles []string + restPatterns := make([]string, 0, len(patterns)) + // Extract file= and other [querytype]= patterns. Report an error if querytype + // doesn't exist. +extractQueries: + for _, pattern := range patterns { + query, value, ok := strings.Cut(pattern, "=") + if !ok { + restPatterns = append(restPatterns, pattern) + } else { + switch query { + case "file": + containFiles = append(containFiles, value) + case "pattern": + restPatterns = append(restPatterns, value) + case "": // not a reserved query + restPatterns = append(restPatterns, pattern) + default: + for _, rune := range query { + if rune < 'a' || rune > 'z' { // not a reserved query + restPatterns = append(restPatterns, pattern) + continue extractQueries + } + } + // Reject all other patterns containing "=" + return nil, fmt.Errorf("invalid query type %q in query pattern %q", query, pattern) + } + } + } + + // See if we have any patterns to pass through to go list. Zero initial + // patterns also requires a go list call, since it's the equivalent of + // ".". + if len(restPatterns) > 0 || len(patterns) == 0 { + dr, err := state.createDriverResponse(restPatterns...) + if err != nil { + return nil, err + } + response.addAll(dr) + } + + if len(containFiles) != 0 { + if err := state.runContainsQueries(response, containFiles); err != nil { + return nil, err + } + } + + // (We may yet return an error due to defer.) + return response.dr, nil +} + +// abs returns an absolute representation of path, based on cfg.Dir. +func (cfg *Config) abs(path string) (string, error) { + if filepath.IsAbs(path) { + return path, nil + } + // In case cfg.Dir is relative, pass it to filepath.Abs. + return filepath.Abs(filepath.Join(cfg.Dir, path)) +} + +func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error { + for _, query := range queries { + // TODO(matloob): Do only one query per directory. + fdir := filepath.Dir(query) + // Pass absolute path of directory to go list so that it knows to treat it as a directory, + // not a package path. + pattern, err := state.cfg.abs(fdir) + if err != nil { + return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err) + } + dirResponse, err := state.createDriverResponse(pattern) + + // If there was an error loading the package, or no packages are returned, + // or the package is returned with errors, try to load the file as an + // ad-hoc package. + // Usually the error will appear in a returned package, but may not if we're + // in module mode and the ad-hoc is located outside a module. + if err != nil || len(dirResponse.Packages) == 0 || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && + len(dirResponse.Packages[0].Errors) == 1 { + var queryErr error + if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil { + return err // return the original error + } + } + isRoot := make(map[string]bool, len(dirResponse.Roots)) + for _, root := range dirResponse.Roots { + isRoot[root] = true + } + for _, pkg := range dirResponse.Packages { + // Add any new packages to the main set + // We don't bother to filter packages that will be dropped by the changes of roots, + // that will happen anyway during graph construction outside this function. + // Over-reporting packages is not a problem. + response.addPackage(pkg) + // if the package was not a root one, it cannot have the file + if !isRoot[pkg.ID] { + continue + } + for _, pkgFile := range pkg.GoFiles { + if filepath.Base(query) == filepath.Base(pkgFile) { + response.addRoot(pkg.ID) + break + } + } + } + } + return nil +} + +// adhocPackage attempts to load or construct an ad-hoc package for a given +// query, if the original call to the driver produced inadequate results. +func (state *golistState) adhocPackage(pattern, query string) (*DriverResponse, error) { + response, err := state.createDriverResponse(query) + if err != nil { + return nil, err + } + // Only .go files can form ad-hoc packages (command-line-arguments); + // non-Go files cannot be compiled as Go packages (golang.org/issue/54815). + if filepath.Ext(query) != ".go" { + return response, nil + } + + switch len(response.Packages) { + case 0: + // If we get nothing back from `go list`, + // try to make this file into its own ad-hoc package. + // TODO(rstambler): Should this check against the original response? + response.Packages = append(response.Packages, &Package{ + ID: "command-line-arguments", + PkgPath: query, + GoFiles: []string{query}, + CompiledGoFiles: []string{query}, + Imports: make(map[string]*Package), + }) + response.Roots = append(response.Roots, "command-line-arguments") + + case 1: + // Handle special cases. + // golang/go#33482: If this is a file= query for ad-hoc packages where + // the file only exists on an overlay, and exists outside of a module, + // add the file to the package and remove the errors. + pkg := response.Packages[0] + if pkg.ID == "command-line-arguments" || + filepath.ToSlash(pkg.PkgPath) == filepath.ToSlash(query) { + if len(pkg.GoFiles) == 0 { + filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath + // TODO(matloob): check if the file is outside of a root dir? + for path := range state.cfg.Overlay { + if path == filename { + pkg.Errors = nil + pkg.GoFiles = []string{path} + pkg.CompiledGoFiles = []string{path} + } + } + } + } + } + return response, nil +} + +// Fields must match go list; +// see $GOROOT/src/cmd/go/internal/load/pkg.go. +type jsonPackage struct { + ImportPath string + Dir string + Name string + Target string + Export string + GoFiles []string + CompiledGoFiles []string + IgnoredGoFiles []string + IgnoredOtherFiles []string + EmbedPatterns []string + EmbedFiles []string + CFiles []string + CgoFiles []string + CXXFiles []string + MFiles []string + HFiles []string + FFiles []string + SFiles []string + SwigFiles []string + SwigCXXFiles []string + SysoFiles []string + Imports []string + ImportMap map[string]string + Deps []string + Module *Module + TestGoFiles []string + TestImports []string + XTestGoFiles []string + XTestImports []string + ForTest string // q in a "p [q.test]" package, else "" + DepOnly bool + + Error *packagesinternal.PackageError + DepsErrors []*packagesinternal.PackageError +} + +func otherFiles(p *jsonPackage) [][]string { + return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles} +} + +// createDriverResponse uses the "go list" command to expand the pattern +// words and return a response for the specified packages. +func (state *golistState) createDriverResponse(words ...string) (*DriverResponse, error) { + // go list uses the following identifiers in ImportPath and Imports: + // + // "p" -- importable package or main (command) + // "q.test" -- q's test executable + // "p [q.test]" -- variant of p as built for q's test executable + // "q_test [q.test]" -- q's external test package + // + // The packages p that are built differently for a test q.test + // are q itself, plus any helpers used by the external test q_test, + // typically including "testing" and all its dependencies. + + // Run "go list" for complete + // information on the specified packages. + goVersion, err := state.getGoVersion() + if err != nil { + return nil, err + } + buf, err := state.invokeGo("list", golistargs(state.cfg, words, goVersion)...) + if err != nil { + return nil, err + } + + seen := make(map[string]*jsonPackage) + pkgs := make(map[string]*Package) + additionalErrors := make(map[string][]Error) + // Decode the JSON and convert it to Package form. + response := &DriverResponse{ + GoVersion: goVersion, + } + for dec := json.NewDecoder(buf); dec.More(); { + p := new(jsonPackage) + if err := dec.Decode(p); err != nil { + return nil, fmt.Errorf("JSON decoding failed: %v", err) + } + + if p.ImportPath == "" { + // The documentation for go list says that “[e]rroneous packages will have + // a non-empty ImportPath”. If for some reason it comes back empty, we + // prefer to error out rather than silently discarding data or handing + // back a package without any way to refer to it. + if p.Error != nil { + return nil, Error{ + Pos: p.Error.Pos, + Msg: p.Error.Err, + } + } + return nil, fmt.Errorf("package missing import path: %+v", p) + } + + // Work around https://golang.org/issue/33157: + // go list -e, when given an absolute path, will find the package contained at + // that directory. But when no package exists there, it will return a fake package + // with an error and the ImportPath set to the absolute path provided to go list. + // Try to convert that absolute path to what its package path would be if it's + // contained in a known module or GOPATH entry. This will allow the package to be + // properly "reclaimed" when overlays are processed. + if filepath.IsAbs(p.ImportPath) && p.Error != nil { + pkgPath, ok, err := state.getPkgPath(p.ImportPath) + if err != nil { + return nil, err + } + if ok { + p.ImportPath = pkgPath + } + } + + if old, found := seen[p.ImportPath]; found { + // If one version of the package has an error, and the other doesn't, assume + // that this is a case where go list is reporting a fake dependency variant + // of the imported package: When a package tries to invalidly import another + // package, go list emits a variant of the imported package (with the same + // import path, but with an error on it, and the package will have a + // DepError set on it). An example of when this can happen is for imports of + // main packages: main packages can not be imported, but they may be + // separately matched and listed by another pattern. + // See golang.org/issue/36188 for more details. + + // The plan is that eventually, hopefully in Go 1.15, the error will be + // reported on the importing package rather than the duplicate "fake" + // version of the imported package. Once all supported versions of Go + // have the new behavior this logic can be deleted. + // TODO(matloob): delete the workaround logic once all supported versions of + // Go return the errors on the proper package. + + // There should be exactly one version of a package that doesn't have an + // error. + if old.Error == nil && p.Error == nil { + if !reflect.DeepEqual(p, old) { + return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath) + } + continue + } + + // Determine if this package's error needs to be bubbled up. + // This is a hack, and we expect for go list to eventually set the error + // on the package. + if old.Error != nil { + var errkind string + if strings.Contains(old.Error.Err, "not an importable package") { + errkind = "not an importable package" + } else if strings.Contains(old.Error.Err, "use of internal package") && strings.Contains(old.Error.Err, "not allowed") { + errkind = "use of internal package not allowed" + } + if errkind != "" { + if len(old.Error.ImportStack) < 1 { + return nil, fmt.Errorf(`internal error: go list gave a %q error with empty import stack`, errkind) + } + importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1] + if importingPkg == old.ImportPath { + // Using an older version of Go which put this package itself on top of import + // stack, instead of the importer. Look for importer in second from top + // position. + if len(old.Error.ImportStack) < 2 { + return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`, errkind) + } + importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2] + } + additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{ + Pos: old.Error.Pos, + Msg: old.Error.Err, + Kind: ListError, + }) + } + } + + // Make sure that if there's a version of the package without an error, + // that's the one reported to the user. + if old.Error == nil { + continue + } + + // This package will replace the old one at the end of the loop. + } + seen[p.ImportPath] = p + + pkg := &Package{ + Name: p.Name, + ID: p.ImportPath, + Dir: p.Dir, + Target: p.Target, + GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles), + CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles), + OtherFiles: absJoin(p.Dir, otherFiles(p)...), + EmbedFiles: absJoin(p.Dir, p.EmbedFiles), + EmbedPatterns: absJoin(p.Dir, p.EmbedPatterns), + IgnoredFiles: absJoin(p.Dir, p.IgnoredGoFiles, p.IgnoredOtherFiles), + ForTest: p.ForTest, + depsErrors: p.DepsErrors, + Module: p.Module, + } + + if (state.cfg.Mode&typecheckCgo) != 0 && len(p.CgoFiles) != 0 { + if len(p.CompiledGoFiles) > len(p.GoFiles) { + // We need the cgo definitions, which are in the first + // CompiledGoFile after the non-cgo ones. This is a hack but there + // isn't currently a better way to find it. We also need the pure + // Go files and unprocessed cgo files, all of which are already + // in pkg.GoFiles. + cgoTypes := p.CompiledGoFiles[len(p.GoFiles)] + pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...) + } else { + // golang/go#38990: go list silently fails to do cgo processing + pkg.CompiledGoFiles = nil + + var msg strings.Builder + fmt.Fprintf(&msg, "go list failed to return CompiledGoFiles for %q.\n", p.Name) + + for _, err := range p.DepsErrors { + msg.WriteString(strings.TrimSpace(err.Err)) + msg.WriteByte('\n') + } + + msg.WriteString("This may indicate failure to perform cgo processing; try building at the command line. See https://golang.org/issue/38990.") + pkg.Errors = append(pkg.Errors, Error{ + Msg: msg.String(), + Kind: ListError, + }) + } + } + + // Work around https://golang.org/issue/28749: + // cmd/go puts assembly, C, and C++ files in CompiledGoFiles. + // Remove files from CompiledGoFiles that are non-go files + // (or are not files that look like they are from the cache). + if len(pkg.CompiledGoFiles) > 0 { + out := pkg.CompiledGoFiles[:0] + for _, f := range pkg.CompiledGoFiles { + if ext := filepath.Ext(f); ext != ".go" && ext != "" { // ext == "" means the file is from the cache, so probably cgo-processed file + continue + } + out = append(out, f) + } + pkg.CompiledGoFiles = out + } + + // Extract the PkgPath from the package's ID. + if i := strings.IndexByte(pkg.ID, ' '); i >= 0 { + pkg.PkgPath = pkg.ID[:i] + } else { + pkg.PkgPath = pkg.ID + } + + if pkg.PkgPath == "unsafe" { + pkg.CompiledGoFiles = nil // ignore fake unsafe.go file (#59929) + } else if len(pkg.CompiledGoFiles) == 0 { + // Work around for pre-go.1.11 versions of go list. + // TODO(matloob): they should be handled by the fallback. + // Can we delete this? + pkg.CompiledGoFiles = pkg.GoFiles + } + + // Assume go list emits only absolute paths for Dir. + if p.Dir != "" && !filepath.IsAbs(p.Dir) { + log.Fatalf("internal error: go list returned non-absolute Package.Dir: %s", p.Dir) + } + + if p.Export != "" && !filepath.IsAbs(p.Export) { + pkg.ExportFile = filepath.Join(p.Dir, p.Export) + } else { + pkg.ExportFile = p.Export + } + + // imports + // + // Imports contains the IDs of all imported packages. + // ImportsMap records (path, ID) only where they differ. + ids := make(map[string]bool) + for _, id := range p.Imports { + ids[id] = true + } + pkg.Imports = make(map[string]*Package) + for path, id := range p.ImportMap { + pkg.Imports[path] = &Package{ID: id} // non-identity import + delete(ids, id) + } + for id := range ids { + if id == "C" { + continue + } + + pkg.Imports[id] = &Package{ID: id} // identity import + } + if !p.DepOnly { + response.Roots = append(response.Roots, pkg.ID) + } + + // Temporary work-around for golang/go#39986. Parse filenames out of + // error messages. This happens if there are unrecoverable syntax + // errors in the source, so we can't match on a specific error message. + // + // TODO(rfindley): remove this heuristic, in favor of considering + // InvalidGoFiles from the list driver. + if err := p.Error; err != nil && state.shouldAddFilenameFromError(p) { + addFilenameFromPos := func(pos string) bool { + split := strings.Split(pos, ":") + if len(split) < 1 { + return false + } + filename := strings.TrimSpace(split[0]) + if filename == "" { + return false + } + if !filepath.IsAbs(filename) { + filename = filepath.Join(state.cfg.Dir, filename) + } + info, _ := os.Stat(filename) + if info == nil { + return false + } + pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename) + pkg.GoFiles = append(pkg.GoFiles, filename) + return true + } + found := addFilenameFromPos(err.Pos) + // In some cases, go list only reports the error position in the + // error text, not the error position. One such case is when the + // file's package name is a keyword (see golang.org/issue/39763). + if !found { + addFilenameFromPos(err.Err) + } + } + + if p.Error != nil { + msg := strings.TrimSpace(p.Error.Err) // Trim to work around golang.org/issue/32363. + // Address golang.org/issue/35964 and golang.org/issue/38826 by appending import stack to error message. + // Address golang/go#38826 by removing " (test)" + if (msg == "import cycle not allowed" || msg == "import cycle not allowed in test") && len(p.Error.ImportStack) != 0 { + stack := make([]string, len(p.Error.ImportStack)) + for i, s := range p.Error.ImportStack { + stack[i] = strings.TrimSuffix(s, " (test)") + } + msg += fmt.Sprintf(": import stack: %v", stack) + } + pkg.Errors = append(pkg.Errors, Error{ + Pos: p.Error.Pos, + Msg: msg, + Kind: ListError, + }) + } + + pkgs[pkg.ID] = pkg + } + + for id, errs := range additionalErrors { + if p, ok := pkgs[id]; ok { + p.Errors = append(p.Errors, errs...) + } + } + for _, pkg := range pkgs { + response.Packages = append(response.Packages, pkg) + } + sort.Slice(response.Packages, func(i, j int) bool { return response.Packages[i].ID < response.Packages[j].ID }) + + return response, nil +} + +func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool { + if len(p.GoFiles) > 0 || len(p.CompiledGoFiles) > 0 { + return false + } + + goV, err := state.getGoVersion() + if err != nil { + return false + } + + // On Go 1.14 and earlier, only add filenames from errors if the import stack is empty. + // The import stack behaves differently for these versions than newer Go versions. + if goV < 15 { + return len(p.Error.ImportStack) == 0 + } + + // On Go 1.15 and later, only parse filenames out of error if there's no import stack, + // or the current package is at the top of the import stack. This is not guaranteed + // to work perfectly, but should avoid some cases where files in errors don't belong to this + // package. + return len(p.Error.ImportStack) == 0 || p.Error.ImportStack[len(p.Error.ImportStack)-1] == p.ImportPath +} + +// getGoVersion returns the effective minor version of the go command. +func (state *golistState) getGoVersion() (int, error) { + state.goVersionOnce.Do(func() { + state.goVersion, state.goVersionError = gocommand.GoVersion(state.ctx, state.cfgInvocation(), state.runner) + }) + return state.goVersion, state.goVersionError +} + +// getPkgPath finds the package path of a directory if it's relative to a root +// directory. +func (state *golistState) getPkgPath(dir string) (string, bool, error) { + if !filepath.IsAbs(dir) { + panic("non-absolute dir passed to getPkgPath") + } + roots, err := state.determineRootDirs() + if err != nil { + return "", false, err + } + + // A directory can be contained in multiple roots, for example when a + // replaced module is nested inside the main module. Choose the most + // specific root, breaking ties lexically for deterministic behavior. + var bestRoot, bestPath, bestRel string + for rdir, rpath := range roots { + // TODO(matloob): This doesn't properly handle symlinks. + r, err := filepath.Rel(rdir, dir) + if err != nil || !filepath.IsLocal(r) { + continue + } + if bestRoot == "" || len(rdir) > len(bestRoot) || len(rdir) == len(bestRoot) && rdir < bestRoot { + bestRoot, bestPath, bestRel = rdir, rpath, r + } + } + if bestRoot == "" { + return "", false, nil + } + if bestPath != "" { + return path.Join(bestPath, filepath.ToSlash(bestRel)), true, nil + } + return filepath.ToSlash(bestRel), true, nil +} + +// absJoin absolutizes and flattens the lists of files. +func absJoin(dir string, fileses ...[]string) (res []string) { + for _, files := range fileses { + for _, file := range files { + if !filepath.IsAbs(file) { + file = filepath.Join(dir, file) + } + res = append(res, file) + } + } + return res +} + +func jsonFlag(cfg *Config, goVersion int) string { + if goVersion < 19 { + return "-json" + } + var fields []string + added := make(map[string]bool) + addFields := func(fs ...string) { + for _, f := range fs { + if !added[f] { + added[f] = true + fields = append(fields, f) + } + } + } + addFields("Name", "ImportPath", "Error") // These fields are always needed + if cfg.Mode&NeedFiles != 0 || cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 { + addFields("Dir", "GoFiles", "IgnoredGoFiles", "IgnoredOtherFiles", "CFiles", + "CgoFiles", "CXXFiles", "MFiles", "HFiles", "FFiles", "SFiles", + "SwigFiles", "SwigCXXFiles", "SysoFiles") + if cfg.Tests { + addFields("TestGoFiles", "XTestGoFiles") + } + } + if cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 { + // CompiledGoFiles seems to be required for the test case TestCgoNoSyntax, + // even when -compiled isn't passed in. + // TODO(#52435): Should we make the test ask for -compiled, or automatically + // request CompiledGoFiles in certain circumstances? + addFields("Dir", "CompiledGoFiles") + } + if cfg.Mode&NeedCompiledGoFiles != 0 { + addFields("Dir", "CompiledGoFiles", "Export") + } + if cfg.Mode&NeedImports != 0 { + // When imports are requested, DepOnly is used to distinguish between packages + // explicitly requested and transitive imports of those packages. + addFields("DepOnly", "Imports", "ImportMap") + if cfg.Tests { + addFields("TestImports", "XTestImports") + } + } + if cfg.Mode&NeedDeps != 0 { + addFields("DepOnly") + } + if usesExportData(cfg) { + // Request Dir in the unlikely case Export is not absolute. + addFields("Dir", "Export") + } + if cfg.Mode&NeedForTest != 0 { + addFields("ForTest") + } + if cfg.Mode&needInternalDepsErrors != 0 { + addFields("DepsErrors") + } + if cfg.Mode&NeedModule != 0 { + addFields("Module") + } + if cfg.Mode&NeedEmbedFiles != 0 { + addFields("EmbedFiles") + } + if cfg.Mode&NeedEmbedPatterns != 0 { + addFields("EmbedPatterns") + } + if cfg.Mode&NeedTarget != 0 { + addFields("Target") + } + return "-json=" + strings.Join(fields, ",") +} + +func golistargs(cfg *Config, words []string, goVersion int) []string { + const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo + fullargs := []string{ + "-e", jsonFlag(cfg, goVersion), + fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0), + fmt.Sprintf("-test=%t", cfg.Tests), + fmt.Sprintf("-export=%t", usesExportData(cfg)), + fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0), + // go list doesn't let you pass -test and -find together, + // probably because you'd just get the TestMain. + fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0 && !usesExportData(cfg)), + // VCS information is not needed when not printing Stale or StaleReason fields + "-buildvcs=false", + } + + // golang/go#60456: with go1.21 and later, go list serves pgo variants, which + // can be costly to compute and may result in redundant processing for the + // caller. Disable these variants. If someone wants to add e.g. a NeedPGO + // mode flag, that should be a separate proposal. + if goVersion >= 21 { + fullargs = append(fullargs, "-pgo=off") + } + + fullargs = append(fullargs, cfg.BuildFlags...) + fullargs = append(fullargs, "--") + fullargs = append(fullargs, words...) + return fullargs +} + +// cfgInvocation returns an Invocation that reflects cfg's settings. +func (state *golistState) cfgInvocation() gocommand.Invocation { + cfg := state.cfg + return gocommand.Invocation{ + BuildFlags: cfg.BuildFlags, + CleanEnv: cfg.Env != nil, + Env: cfg.Env, + Logf: cfg.Logf, + WorkingDir: cfg.Dir, + Overlay: state.overlay, + } +} + +// invokeGo returns the stdout of a go command invocation. +func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) { + cfg := state.cfg + + inv := state.cfgInvocation() + inv.Verb = verb + inv.Args = args + + stdout, stderr, friendlyErr, err := state.runner.RunRaw(cfg.Context, inv) + if err != nil { + // Check for 'go' executable not being found. + if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound { + return nil, fmt.Errorf("'go list' driver requires 'go', but %s", exec.ErrNotFound) + } + + exitErr, ok := err.(*exec.ExitError) + if !ok { + // Catastrophic error: + // - context cancellation + return nil, fmt.Errorf("couldn't run 'go': %w", err) + } + + // Old go version? + if strings.Contains(stderr.String(), "flag provided but not defined") { + return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)} + } + + // Related to #24854 + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "unexpected directory layout") { + return nil, friendlyErr + } + + // Return an error if 'go list' failed due to missing tools in + // $GOROOT/pkg/tool/$GOOS_$GOARCH (#69606). + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), `go: no such tool`) { + return nil, friendlyErr + } + + // Is there an error running the C compiler in cgo? This will be reported in the "Error" field + // and should be suppressed by go list -e. + // + // This condition is not perfect yet because the error message can include other error messages than runtime/cgo. + isPkgPathRune := func(r rune) bool { + // From https://golang.org/ref/spec#Import_declarations: + // Implementation restriction: A compiler may restrict ImportPaths to non-empty strings + // using only characters belonging to Unicode's L, M, N, P, and S general categories + // (the Graphic characters without spaces) and may also exclude the + // characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character U+FFFD. + return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) && + !strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r) + } + // golang/go#36770: Handle case where cmd/go prints module download messages before the error. + msg := stderr.String() + for strings.HasPrefix(msg, "go: downloading") { + msg = msg[strings.IndexRune(msg, '\n')+1:] + } + if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") { + msg := msg[len("# "):] + if strings.HasPrefix(strings.TrimLeftFunc(msg, isPkgPathRune), "\n") { + return stdout, nil + } + // Treat pkg-config errors as a special case (golang.org/issue/36770). + if strings.HasPrefix(msg, "pkg-config") { + return stdout, nil + } + } + + // This error only appears in stderr. See golang.org/cl/166398 for a fix in go list to show + // the error in the Err section of stdout in case -e option is provided. + // This fix is provided for backwards compatibility. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") { + output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Similar to the previous error, but currently lacks a fix in Go. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must all be in one directory") { + output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Backwards compatibility for Go 1.11 because 1.12 and 1.13 put the directory in the ImportPath. + // If the package doesn't exist, put the absolute path of the directory into the error message, + // as Go 1.13 list does. + const noSuchDirectory = "no such directory" + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), noSuchDirectory) { + errstr := stderr.String() + abspath := strings.TrimSpace(errstr[strings.Index(errstr, noSuchDirectory)+len(noSuchDirectory):]) + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + abspath, strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Workaround for #29280 and #31344: go list -e has incorrect behavior when an ad-hoc package doesn't exist. + // Note that the error message we look for in this case is different that the one looked for above. + // "no such file or directory" is emitted on Unix, + if len(stderr.String()) > 0 && (strings.Contains(stderr.String(), "no such file or directory") || // Unix + strings.Contains(stderr.String(), "The system cannot find the file specified") || // Windows ERROR_FILE_NOT_FOUND + strings.Contains(stderr.String(), "The system cannot find the path specified")) { // Windows ERROR_PATH_NOT_FOUND + output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Workaround for #34273. go list -e with GO111MODULE=on has incorrect behavior when listing a + // directory outside any module. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside available modules") { + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + // TODO(matloob): command-line-arguments isn't correct here. + "command-line-arguments", strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Another variation of the previous error + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside module root") { + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + // TODO(matloob): command-line-arguments isn't correct here. + "command-line-arguments", strings.Trim(stderr.String(), "\n")) + return bytes.NewBufferString(output), nil + } + + // Workaround for an instance of golang.org/issue/26755: go list -e will return a non-zero exit + // status if there's a dependency on a package that doesn't exist. But it should return + // a zero exit status and set an error on that package. + if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") { + // Don't clobber stdout if `go list` actually returned something. + if len(stdout.String()) > 0 { + return stdout, nil + } + // try to extract package name from string + stderrStr := stderr.String() + var importPath string + colon := strings.Index(stderrStr, ":") + if colon > 0 && strings.HasPrefix(stderrStr, "go build ") { + importPath = stderrStr[len("go build "):colon] + } + output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, + importPath, strings.Trim(stderrStr, "\n")) + return bytes.NewBufferString(output), nil + } + + // Export mode entails a build. + // If that build fails, errors appear on stderr + // (despite the -e flag) and the Export field is blank. + // Do not fail in that case. + // The same is true if an ad-hoc package given to go list doesn't exist. + // TODO(matloob): Remove these once we can depend on go list to exit with a zero status with -e even when + // packages don't exist or a build fails. + if !usesExportData(cfg) && !containsGoFile(args) { + return nil, friendlyErr + } + } + return stdout, nil +} + +func containsGoFile(s []string) bool { + for _, f := range s { + if strings.HasSuffix(f, ".go") { + return true + } + } + return false +} + +func cmdDebugStr(cmd *exec.Cmd) string { + env := make(map[string]string) + for _, kv := range cmd.Env { + split := strings.SplitN(kv, "=", 2) + k, v := split[0], split[1] + env[k] = v + } + + var args []string + for _, arg := range cmd.Args { + quoted := strconv.Quote(arg) + if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { + args = append(args, quoted) + } else { + args = append(args, arg) + } + } + return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) +} + +// getSizesForArgs queries 'go list' for the appropriate +// Compiler and GOARCH arguments to pass to [types.SizesFor]. +func getSizesForArgs(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) { + inv.Verb = "list" + inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"} + stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv) + var goarch, compiler string + if rawErr != nil { + rawErrMsg := rawErr.Error() + if strings.Contains(rawErrMsg, "cannot find main module") || + strings.Contains(rawErrMsg, "go.mod file not found") { + // User's running outside of a module. + // All bets are off. Get GOARCH and guess compiler is gc. + // TODO(matloob): Is this a problem in practice? + inv.Verb = "env" + inv.Args = []string{"GOARCH"} + envout, enverr := gocmdRunner.Run(ctx, inv) + if enverr != nil { + return "", "", enverr + } + goarch = strings.TrimSpace(envout.String()) + compiler = "gc" + } else if friendlyErr != nil { + return "", "", friendlyErr + } else { + // This should be unreachable, but be defensive + // in case RunRaw's error results are inconsistent. + return "", "", rawErr + } + } else { + fields := strings.Fields(stdout.String()) + if len(fields) < 2 { + return "", "", fmt.Errorf("could not parse GOARCH and Go compiler in format \" \":\nstdout: <<%s>>\nstderr: <<%s>>", + stdout.String(), stderr.String()) + } + goarch = fields[0] + compiler = fields[1] + } + return compiler, goarch, nil +} diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go new file mode 100644 index 0000000..8bd0f7f --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/golist_overlay.go @@ -0,0 +1,78 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package packages + +import ( + "encoding/json" + "path/filepath" + + "golang.org/x/tools/internal/gocommand" +) + +// determineRootDirs returns a mapping from absolute directories that could +// contain code to their corresponding import path prefixes. +func (state *golistState) determineRootDirs() (map[string]string, error) { + env, err := state.getEnv() + if err != nil { + return nil, err + } + if env["GOMOD"] != "" { + state.rootsOnce.Do(func() { + state.rootDirs, state.rootDirsError = state.determineRootDirsModules() + }) + } else { + state.rootsOnce.Do(func() { + state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH() + }) + } + return state.rootDirs, state.rootDirsError +} + +func (state *golistState) determineRootDirsModules() (map[string]string, error) { + // List all of the modules. Main modules and replaced modules need to be + // treated as roots. + // Editing files in the module cache isn't a great idea, so we don't + // plan to ever support that. + out, err := state.invokeGo("list", "-m", "-json", "all") + if err != nil { + // 'go list all' will fail if we're outside of a module and + // GO111MODULE=on. Try falling back without 'all'. + var innerErr error + out, innerErr = state.invokeGo("list", "-m", "-json") + if innerErr != nil { + return nil, err + } + } + roots := map[string]string{} + for dec := json.NewDecoder(out); dec.More(); { + mod := new(gocommand.ModuleJSON) + if err := dec.Decode(mod); err != nil { + return nil, err + } + if mod.Dir != "" && mod.Path != "" { + // This is a valid module; add it to the map. + absDir, err := state.cfg.abs(mod.Dir) + if err != nil { + return nil, err + } + if mod.Main || mod.Replace != nil && mod.Replace.Path != "" { + roots[absDir] = mod.Path + } + } + } + return roots, nil +} + +func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) { + m := map[string]string{} + for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) { + absDir, err := filepath.Abs(dir) + if err != nil { + return nil, err + } + m[filepath.Join(absDir, "src")] = "" + } + return m, nil +} diff --git a/vendor/golang.org/x/tools/go/packages/loadmode_string.go b/vendor/golang.org/x/tools/go/packages/loadmode_string.go new file mode 100644 index 0000000..69eec9f --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/loadmode_string.go @@ -0,0 +1,56 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package packages + +import ( + "fmt" + "strings" +) + +var modes = [...]struct { + mode LoadMode + name string +}{ + {NeedName, "NeedName"}, + {NeedFiles, "NeedFiles"}, + {NeedCompiledGoFiles, "NeedCompiledGoFiles"}, + {NeedImports, "NeedImports"}, + {NeedDeps, "NeedDeps"}, + {NeedExportFile, "NeedExportFile"}, + {NeedTypes, "NeedTypes"}, + {NeedSyntax, "NeedSyntax"}, + {NeedTypesInfo, "NeedTypesInfo"}, + {NeedTypesSizes, "NeedTypesSizes"}, + {NeedForTest, "NeedForTest"}, + {NeedModule, "NeedModule"}, + {NeedEmbedFiles, "NeedEmbedFiles"}, + {NeedEmbedPatterns, "NeedEmbedPatterns"}, + {NeedTarget, "NeedTarget"}, +} + +func (mode LoadMode) String() string { + if mode == 0 { + return "LoadMode(0)" + } + var out []string + // named bits + for _, item := range modes { + if (mode & item.mode) != 0 { + mode ^= item.mode + out = append(out, item.name) + } + } + // unnamed residue + if mode != 0 { + if out == nil { + return fmt.Sprintf("LoadMode(%#x)", int(mode)) + } + out = append(out, fmt.Sprintf("%#x", int(mode))) + } + if len(out) == 1 { + return out[0] + } + return "(" + strings.Join(out, "|") + ")" +} diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go new file mode 100644 index 0000000..5dadc1b --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/packages.go @@ -0,0 +1,1605 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package packages + +// See doc.go for package documentation and implementation notes. + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "go/ast" + "go/parser" + "go/scanner" + "go/token" + "go/types" + "log" + "os" + "path/filepath" + "runtime" + "strings" + "sync" + "sync/atomic" + "time" + + "golang.org/x/sync/errgroup" + + "golang.org/x/tools/go/gcexportdata" + "golang.org/x/tools/internal/gocommand" + "golang.org/x/tools/internal/packagesinternal" + "golang.org/x/tools/internal/typesinternal" +) + +// A LoadMode controls the amount of detail to return when loading. +// The bits below can be combined to specify which fields should be +// filled in the result packages. +// +// The zero value is a special case, equivalent to combining +// the NeedName, NeedFiles, and NeedCompiledGoFiles bits. +// +// ID and Errors (if present) will always be filled. +// [Load] may return more information than requested. +// +// The Mode flag is a union of several bits named NeedName, +// NeedFiles, and so on, each of which determines whether +// a given field of Package (Name, Files, etc) should be +// populated. +// +// For convenience, we provide named constants for the most +// common combinations of Need flags: +// +// [LoadFiles] lists of files in each package +// [LoadImports] ... plus imports +// [LoadTypes] ... plus type information +// [LoadSyntax] ... plus type-annotated syntax +// [LoadAllSyntax] ... for all dependencies +// +// Unfortunately there are a number of open bugs related to +// interactions among the LoadMode bits: +// - https://go.dev/issue/56633 +// - https://go.dev/issue/56677 +// - https://go.dev/issue/58726 +// - https://go.dev/issue/63517 +type LoadMode int + +const ( + // NeedName adds Name and PkgPath. + NeedName LoadMode = 1 << iota + + // NeedFiles adds Dir, GoFiles, OtherFiles, and IgnoredFiles + NeedFiles + + // NeedCompiledGoFiles adds CompiledGoFiles. + NeedCompiledGoFiles + + // NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain + // "placeholder" Packages with only the ID set. + NeedImports + + // NeedDeps adds the fields requested by the LoadMode in the packages in Imports. + NeedDeps + + // NeedExportFile adds ExportFile. + NeedExportFile + + // NeedTypes adds Types, Fset, and IllTyped. + NeedTypes + + // NeedSyntax adds Syntax and Fset. + NeedSyntax + + // NeedTypesInfo adds TypesInfo and Fset. + NeedTypesInfo + + // NeedTypesSizes adds TypesSizes. + NeedTypesSizes + + // needInternalDepsErrors adds the internal deps errors field for use by gopls. + needInternalDepsErrors + + // NeedForTest adds ForTest. + // + // Tests must also be set on the context for this field to be populated. + NeedForTest + + // typecheckCgo enables full support for type checking cgo. Requires Go 1.15+. + // Modifies CompiledGoFiles and Types, and has no effect on its own. + typecheckCgo + + // NeedModule adds Module. + NeedModule + + // NeedEmbedFiles adds EmbedFiles. + NeedEmbedFiles + + // NeedEmbedPatterns adds EmbedPatterns. + NeedEmbedPatterns + + // NeedTarget adds Target. + NeedTarget + + // Be sure to update loadmode_string.go when adding new items! +) + +const ( + // LoadFiles loads the name and file names for the initial packages. + LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles + + // LoadImports loads the name, file names, and import mapping for the initial packages. + LoadImports = LoadFiles | NeedImports + + // LoadTypes loads exported type information for the initial packages. + LoadTypes = LoadImports | NeedTypes | NeedTypesSizes + + // LoadSyntax loads typed syntax for the initial packages. + LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo + + // LoadAllSyntax loads typed syntax for the initial packages and all dependencies. + LoadAllSyntax = LoadSyntax | NeedDeps + + // Deprecated: NeedExportsFile is a historical misspelling of NeedExportFile. + // + //go:fix inline + NeedExportsFile = NeedExportFile +) + +// A Config specifies details about how packages should be loaded. +// The zero value is a valid configuration. +// +// Calls to [Load] do not modify this struct. +type Config struct { + // Mode controls the level of information returned for each package. + Mode LoadMode + + // Context specifies the context for the load operation. + // Cancelling the context may cause [Load] to abort and + // return an error. + Context context.Context + + // Logf is the logger for the config. + // If the user provides a logger, debug logging is enabled. + // If the GOPACKAGESDEBUG environment variable is set to true, + // but the logger is nil, default to log.Printf. + Logf func(format string, args ...any) + + // Dir is the directory in which to run the build system's query tool + // that provides information about the packages. + // If Dir is empty, the tool is run in the current directory. + Dir string + + // Env is the environment to use when invoking the build system's query tool. + // If Env is nil, the current environment is used. + // As in os/exec's Cmd, only the last value in the slice for + // each environment key is used. To specify the setting of only + // a few variables, append to the current environment, as in: + // + // opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386") + // + Env []string + + // BuildFlags is a list of command-line flags to be passed through to + // the build system's query tool. + BuildFlags []string + + // Fset provides source position information for syntax trees and types. + // If Fset is nil, Load will use a new fileset, but preserve Fset's value. + Fset *token.FileSet + + // ParseFile is called to read and parse each file + // when preparing a package's type-checked syntax tree. + // It must be safe to call ParseFile simultaneously from multiple goroutines. + // If ParseFile is nil, the loader will uses parser.ParseFile. + // + // ParseFile should parse the source from src and use filename only for + // recording position information. + // + // An application may supply a custom implementation of ParseFile + // to change the effective file contents or the behavior of the parser, + // or to modify the syntax tree. For example, selectively eliminating + // unwanted function bodies can significantly accelerate type checking. + ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) + + // If Tests is set, the loader includes not just the packages + // matching a particular pattern but also any related test packages, + // including test-only variants of the package and the test executable. + // + // For example, when using the go command, loading "fmt" with Tests=true + // returns four packages, with IDs "fmt" (the standard package), + // "fmt [fmt.test]" (the package as compiled for the test), + // "fmt_test" (the test functions from source files in package fmt_test), + // and "fmt.test" (the test binary). + // + // In build systems with explicit names for tests, + // setting Tests may have no effect. + Tests bool + + // Overlay is a mapping from absolute file paths to file contents. + // + // For each map entry, [Load] uses the alternative file + // contents provided by the overlay mapping instead of reading + // from the file system. This mechanism can be used to enable + // editor-integrated tools to correctly analyze the contents + // of modified but unsaved buffers, for example. + // + // The overlay mapping is passed to the build system's driver + // (see "The driver protocol") so that it too can report + // consistent package metadata about unsaved files. However, + // drivers may vary in their level of support for overlays. + Overlay map[string][]byte +} + +// Load loads and returns the Go packages named by the given patterns. +// +// The cfg parameter specifies loading options; nil behaves the same as an empty [Config]. +// +// The [Config.Mode] field is a set of bits that determine what kinds +// of information should be computed and returned. Modes that require +// more information tend to be slower. See [LoadMode] for details +// and important caveats. Its zero value is equivalent to +// [NeedName] | [NeedFiles] | [NeedCompiledGoFiles]. +// +// Each call to Load returns a new set of [Package] instances. +// The Packages and their Imports form a directed acyclic graph. +// +// If the [NeedTypes] mode flag was set, each call to Load uses a new +// [types.Importer], so [types.Object] and [types.Type] values from +// different calls to Load must not be mixed as they will have +// inconsistent notions of type identity. +// +// If any of the patterns was invalid as defined by the +// underlying build system, Load returns an error. +// It may return an empty list of packages without an error, +// for instance for an empty expansion of a valid wildcard. +// Errors associated with a particular package are recorded in the +// corresponding Package's Errors list, and do not cause Load to +// return an error. Clients may need to handle such errors before +// proceeding with further analysis. The [PrintErrors] function is +// provided for convenient display of all errors. +func Load(cfg *Config, patterns ...string) ([]*Package, error) { + ld := newLoader(cfg) + response, external, err := defaultDriver(&ld.Config, patterns...) + if err != nil { + return nil, err + } + + ld.sizes = types.SizesFor(response.Compiler, response.Arch) + if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 { + // Type size information is needed but unavailable. + if external { + // An external driver may fail to populate the Compiler/GOARCH fields, + // especially since they are relatively new (see #63700). + // Provide a sensible fallback in this case. + ld.sizes = types.SizesFor("gc", runtime.GOARCH) + if ld.sizes == nil { // gccgo-only arch + ld.sizes = types.SizesFor("gc", "amd64") + } + } else { + // Go list should never fail to deliver accurate size information. + // Reject the whole Load since the error is the same for every package. + return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q", + response.Compiler, response.Arch) + } + } + + ld.externalDriver = external + + return ld.refine(response) +} + +// defaultDriver is a driver that implements go/packages' fallback behavior. +// It will try to request to an external driver, if one exists. If there's +// no external driver, or the driver returns a response with NotHandled set, +// defaultDriver will fall back to the go list driver. +// The boolean result indicates that an external driver handled the request. +func defaultDriver(cfg *Config, patterns ...string) (*DriverResponse, bool, error) { + const ( + // windowsArgMax specifies the maximum command line length for + // the Windows' CreateProcess function. + windowsArgMax = 32767 + // maxEnvSize is a very rough estimation of the maximum environment + // size of a user. + maxEnvSize = 16384 + // safeArgMax specifies the maximum safe command line length to use + // by the underlying driver excl. the environment. We choose the Windows' + // ARG_MAX as the starting point because it's one of the lowest ARG_MAX + // constants out of the different supported platforms, + // e.g., https://www.in-ulm.de/~mascheck/various/argmax/#results. + safeArgMax = windowsArgMax - maxEnvSize + ) + chunks, err := splitIntoChunks(patterns, safeArgMax) + if err != nil { + return nil, false, err + } + + if driver := findExternalDriver(cfg); driver != nil { + response, err := callDriverOnChunks(driver, cfg, chunks) + if err != nil { + return nil, false, err + } else if !response.NotHandled { + return response, true, nil + } + // not handled: fall through + } + + // go list fallback + + // Write overlays once, as there are many calls + // to 'go list' (one per chunk plus others too). + overlayFile, cleanupOverlay, err := gocommand.WriteOverlays(cfg.Overlay) + if err != nil { + return nil, false, err + } + defer cleanupOverlay() + + var runner gocommand.Runner // (shared across many 'go list' calls) + driver := func(cfg *Config, patterns []string) (*DriverResponse, error) { + return goListDriver(cfg, &runner, overlayFile, patterns) + } + response, err := callDriverOnChunks(driver, cfg, chunks) + if err != nil { + return nil, false, err + } + return response, false, err +} + +// splitIntoChunks chunks the slice so that the total number of characters +// in a chunk is no longer than argMax. +func splitIntoChunks(patterns []string, argMax int) ([][]string, error) { + if argMax <= 0 { + return nil, errors.New("failed to split patterns into chunks, negative safe argMax value") + } + var chunks [][]string + charsInChunk := 0 + nextChunkStart := 0 + for i, v := range patterns { + vChars := len(v) + if vChars > argMax { + // a single pattern is longer than the maximum safe ARG_MAX, hardly should happen + return nil, errors.New("failed to split patterns into chunks, a pattern is too long") + } + charsInChunk += vChars + 1 // +1 is for a whitespace between patterns that has to be counted too + if charsInChunk > argMax { + chunks = append(chunks, patterns[nextChunkStart:i]) + nextChunkStart = i + charsInChunk = vChars + } + } + // add the last chunk + if nextChunkStart < len(patterns) { + chunks = append(chunks, patterns[nextChunkStart:]) + } + return chunks, nil +} + +func callDriverOnChunks(driver driver, cfg *Config, chunks [][]string) (*DriverResponse, error) { + if len(chunks) == 0 { + return driver(cfg, nil) + } + responses := make([]*DriverResponse, len(chunks)) + errNotHandled := errors.New("driver returned NotHandled") + var g errgroup.Group + for i, chunk := range chunks { + g.Go(func() (err error) { + responses[i], err = driver(cfg, chunk) + if responses[i] != nil && responses[i].NotHandled { + err = errNotHandled + } + return err + }) + } + if err := g.Wait(); err != nil { + if errors.Is(err, errNotHandled) { + return &DriverResponse{NotHandled: true}, nil + } + return nil, err + } + return mergeResponses(responses...), nil +} + +func mergeResponses(responses ...*DriverResponse) *DriverResponse { + if len(responses) == 0 { + return nil + } + // No dedup needed + if len(responses) == 1 { + return responses[0] + } + response := newDeduper() + response.dr.NotHandled = false + response.dr.Compiler = responses[0].Compiler + response.dr.Arch = responses[0].Arch + response.dr.GoVersion = responses[0].GoVersion + for _, v := range responses { + response.addAll(v) + } + return response.dr +} + +// A Package describes a loaded Go package. +// +// It also defines part of the JSON schema of [DriverResponse]. +// See the package documentation for an overview. +type Package struct { + // ID is a unique identifier for a package, + // in a syntax provided by the underlying build system. + // + // Because the syntax varies based on the build system, + // clients should treat IDs as opaque and not attempt to + // interpret them. + ID string + + // Name is the package name as it appears in the package source code. + Name string + + // PkgPath is the package path as used by the go/types package. + PkgPath string + + // Dir is the directory associated with the package, if it exists. + // + // For packages listed by the go command, this is the directory containing + // the package files. + Dir string + + // Errors contains any errors encountered querying the metadata + // of the package, or while parsing or type-checking its files. + Errors []Error + + // TypeErrors contains the subset of errors produced during type checking. + TypeErrors []types.Error + + // GoFiles lists the absolute file paths of the package's Go source files. + // It may include files that should not be compiled, for example because + // they contain non-matching build tags, are documentary pseudo-files such as + // unsafe/unsafe.go or builtin/builtin.go, or are subject to cgo preprocessing. + GoFiles []string + + // CompiledGoFiles lists the absolute file paths of the package's source + // files that are suitable for type checking. + // This may differ from GoFiles if files are processed before compilation. + CompiledGoFiles []string + + // OtherFiles lists the absolute file paths of the package's non-Go source files, + // including assembly, C, C++, Fortran, Objective-C, SWIG, and so on. + OtherFiles []string + + // EmbedFiles lists the absolute file paths of the package's files + // embedded with go:embed. + EmbedFiles []string + + // EmbedPatterns lists the absolute file patterns of the package's + // files embedded with go:embed. + EmbedPatterns []string + + // IgnoredFiles lists source files that are not part of the package + // using the current build configuration but that might be part of + // the package using other build configurations. + IgnoredFiles []string + + // ExportFile is the absolute path to a file containing type + // information for the package as provided by the build system. + ExportFile string + + // Target is the absolute install path of the .a file, for libraries, + // and of the executable file, for binaries. + Target string + + // Imports maps import paths appearing in the package's Go source files + // to corresponding loaded Packages. + Imports map[string]*Package + + // Module is the module information for the package if it exists. + // + // Note: it may be missing for std and cmd; see Go issue #65816. + Module *Module + + // -- The following fields are not part of the driver JSON schema. -- + + // Types provides type information for the package. + // The NeedTypes LoadMode bit sets this field for packages matching the + // patterns; type information for dependencies may be missing or incomplete, + // unless NeedDeps and NeedImports are also set. + // + // Each call to [Load] returns a consistent set of type + // symbols, as defined by the comment at [types.Identical]. + // Avoid mixing type information from two or more calls to [Load]. + Types *types.Package `json:"-"` + + // Fset provides position information for Types, TypesInfo, and Syntax. + // It is set only when Types is set. + Fset *token.FileSet `json:"-"` + + // IllTyped indicates whether the package or any dependency contains errors. + // It is set only when Types is set. + IllTyped bool `json:"-"` + + // Syntax is the package's syntax trees, for the files listed in CompiledGoFiles. + // + // The NeedSyntax LoadMode bit populates this field for packages matching the patterns. + // If NeedDeps and NeedImports are also set, this field will also be populated + // for dependencies. + // + // Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are + // removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles. + Syntax []*ast.File `json:"-"` + + // TypesInfo provides type information about the package's syntax trees. + // It is set only when Syntax is set. + TypesInfo *types.Info `json:"-"` + + // TypesSizes provides the effective size function for types in TypesInfo. + TypesSizes types.Sizes `json:"-"` + + // -- internal -- + + // ForTest is the package under test, if any. + ForTest string + + // depsErrors is the DepsErrors field from the go list response, if any. + depsErrors []*packagesinternal.PackageError + + // exportDataError is the error encountered reading export data, if any. + // Decoding export data should ordinarily be infallible, so this typically + // indicates a producer/consumer version skew. + exportDataError error +} + +// Module provides module information for a package. +// +// It also defines part of the JSON schema of [DriverResponse]. +// See the package documentation for an overview. +type Module struct { + Path string // module path + Version string // module version + Replace *Module // replaced by this module + Time *time.Time // time version was created + Main bool // is this the main module? + Indirect bool // is this module only an indirect dependency of main module? + Dir string // directory holding files for this module, if any + GoMod string // path to go.mod file used when loading this module, if any + GoVersion string // go version used in module + Error *ModuleError // error loading module +} + +// ModuleError holds errors loading a module. +type ModuleError struct { + Err string // the error itself +} + +func init() { + packagesinternal.GetDepsErrors = func(p any) []*packagesinternal.PackageError { + return p.(*Package).depsErrors + } + packagesinternal.TypecheckCgo = int(typecheckCgo) + packagesinternal.DepsErrors = int(needInternalDepsErrors) +} + +// An Error describes a problem with a package's metadata, syntax, or types. +type Error struct { + Pos string // "file:line:col" or "file:line" or "" or "-" + Msg string + Kind ErrorKind +} + +// ErrorKind describes the source of the error, allowing the user to +// differentiate between errors generated by the driver, the parser, or the +// type-checker. +type ErrorKind int + +const ( + UnknownError ErrorKind = iota + ListError + ParseError + TypeError +) + +func (err Error) Error() string { + pos := err.Pos + if pos == "" { + pos = "-" // like token.Position{}.String() + } + return pos + ": " + err.Msg +} + +// flatPackage is the JSON form of Package +// It drops all the type and syntax fields, and transforms the Imports +// +// TODO(adonovan): identify this struct with Package, effectively +// publishing the JSON protocol. +type flatPackage struct { + ID string + Name string `json:",omitempty"` + PkgPath string `json:",omitempty"` + Errors []Error `json:",omitempty"` + GoFiles []string `json:",omitempty"` + CompiledGoFiles []string `json:",omitempty"` + OtherFiles []string `json:",omitempty"` + EmbedFiles []string `json:",omitempty"` + EmbedPatterns []string `json:",omitempty"` + IgnoredFiles []string `json:",omitempty"` + ExportFile string `json:",omitempty"` + Imports map[string]string `json:",omitempty"` +} + +// MarshalJSON returns the Package in its JSON form. +// For the most part, the structure fields are written out unmodified, and +// the type and syntax fields are skipped. +// The imports are written out as just a map of path to package id. +// The errors are written using a custom type that tries to preserve the +// structure of error types we know about. +// +// This method exists to enable support for additional build systems. It is +// not intended for use by clients of the API and we may change the format. +func (p *Package) MarshalJSON() ([]byte, error) { + flat := &flatPackage{ + ID: p.ID, + Name: p.Name, + PkgPath: p.PkgPath, + Errors: p.Errors, + GoFiles: p.GoFiles, + CompiledGoFiles: p.CompiledGoFiles, + OtherFiles: p.OtherFiles, + EmbedFiles: p.EmbedFiles, + EmbedPatterns: p.EmbedPatterns, + IgnoredFiles: p.IgnoredFiles, + ExportFile: p.ExportFile, + } + if len(p.Imports) > 0 { + flat.Imports = make(map[string]string, len(p.Imports)) + for path, ipkg := range p.Imports { + flat.Imports[path] = ipkg.ID + } + } + return json.Marshal(flat) +} + +// UnmarshalJSON reads in a Package from its JSON format. +// See MarshalJSON for details about the format accepted. +func (p *Package) UnmarshalJSON(b []byte) error { + flat := &flatPackage{} + if err := json.Unmarshal(b, &flat); err != nil { + return err + } + *p = Package{ + ID: flat.ID, + Name: flat.Name, + PkgPath: flat.PkgPath, + Errors: flat.Errors, + GoFiles: flat.GoFiles, + CompiledGoFiles: flat.CompiledGoFiles, + OtherFiles: flat.OtherFiles, + EmbedFiles: flat.EmbedFiles, + EmbedPatterns: flat.EmbedPatterns, + IgnoredFiles: flat.IgnoredFiles, + ExportFile: flat.ExportFile, + } + if len(flat.Imports) > 0 { + p.Imports = make(map[string]*Package, len(flat.Imports)) + for path, id := range flat.Imports { + p.Imports[path] = &Package{ID: id} + } + } + return nil +} + +func (p *Package) String() string { return p.ID } + +// loaderPackage augments Package with state used during the loading phase +type loaderPackage struct { + *Package + importErrors map[string]error // maps each bad import to its error + preds []*loaderPackage // packages that import this one + unfinishedSuccs atomic.Int32 // number of direct imports not yet loaded + color uint8 // for cycle detection + needsrc bool // load from source (Mode >= LoadTypes) + needtypes bool // type information is either requested or depended on + initial bool // package was matched by a pattern + goVersion int // minor version number of go command on PATH +} + +// loader holds the working state of a single call to load. +type loader struct { + pkgs map[string]*loaderPackage // keyed by Package.ID + Config + sizes types.Sizes // non-nil if needed by mode + parseCache map[string]*parseValue + parseCacheMu sync.Mutex + exportMu sync.Mutex // enforces mutual exclusion of exportdata operations + externalDriver bool // true if an external GOPACKAGESDRIVER handled the request + + // Config.Mode contains the implied mode (see impliedLoadMode). + // Implied mode contains all the fields we need the data for. + // In requestedMode there are the actually requested fields. + // We'll zero them out before returning packages to the user. + // This makes it easier for us to get the conditions where + // we need certain modes right. + requestedMode LoadMode +} + +type parseValue struct { + f *ast.File + err error + ready chan struct{} +} + +func newLoader(cfg *Config) *loader { + ld := &loader{ + parseCache: map[string]*parseValue{}, + } + if cfg != nil { + ld.Config = *cfg + // If the user has provided a logger, use it. + ld.Config.Logf = cfg.Logf + } + if ld.Config.Logf == nil { + // If the GOPACKAGESDEBUG environment variable is set to true, + // but the user has not provided a logger, default to log.Printf. + if debug { + ld.Config.Logf = log.Printf + } else { + ld.Config.Logf = func(format string, args ...any) {} + } + } + if ld.Config.Mode == 0 { + ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles // Preserve zero behavior of Mode for backwards compatibility. + } + if ld.Config.Env == nil { + ld.Config.Env = os.Environ() + } + if ld.Context == nil { + ld.Context = context.Background() + } + if ld.Dir == "" { + if dir, err := os.Getwd(); err == nil { + ld.Dir = dir + } + } + + // Save the actually requested fields. We'll zero them out before returning packages to the user. + ld.requestedMode = ld.Mode + ld.Mode = impliedLoadMode(ld.Mode) + + if ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0 { + if ld.Fset == nil { + ld.Fset = token.NewFileSet() + } + + // ParseFile is required even in LoadTypes mode + // because we load source if export data is missing. + if ld.ParseFile == nil { + ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { + // We implicitly promise to keep doing ast.Object resolution. :( + const mode = parser.AllErrors | parser.ParseComments + return parser.ParseFile(fset, filename, src, mode) + } + } + } + + return ld +} + +// refine connects the supplied packages into a graph and then adds type +// and syntax information as requested by the LoadMode. +func (ld *loader) refine(response *DriverResponse) ([]*Package, error) { + roots := response.Roots + rootMap := make(map[string]int, len(roots)) + for i, root := range roots { + rootMap[root] = i + } + ld.pkgs = make(map[string]*loaderPackage) + // first pass, fixup and build the map and roots + var initial = make([]*loaderPackage, len(roots)) + for _, pkg := range response.Packages { + rootIndex := -1 + if i, found := rootMap[pkg.ID]; found { + rootIndex = i + } + + // Overlays can invalidate export data. + // TODO(matloob): make this check fine-grained based on dependencies on overlaid files + exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe" + // This package needs type information if the caller requested types and the package is + // either a root, or it's a non-root and the user requested dependencies ... + needtypes := (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) + // This package needs source if the call requested source (or types info, which implies source) + // and the package is either a root, or itas a non- root and the user requested dependencies... + needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) || + // ... or if we need types and the exportData is invalid. We fall back to (incompletely) + // typechecking packages from source if they fail to compile. + (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe" + lpkg := &loaderPackage{ + Package: pkg, + needtypes: needtypes, + needsrc: needsrc, + goVersion: response.GoVersion, + } + // Don't trust the driver to respond with duplicate-free + // package names (go.dev/issue/63822). + if _, ok := ld.pkgs[lpkg.ID]; ok { + return nil, fmt.Errorf("%s response contained duplicate packages for ID %q", + cond(ld.externalDriver, "go/packages driver", "go list"), lpkg.ID) + } + ld.pkgs[lpkg.ID] = lpkg + if rootIndex >= 0 { + initial[rootIndex] = lpkg + lpkg.initial = true + } + } + for i, root := range roots { + if initial[i] == nil { + return nil, fmt.Errorf("root package %v is missing", root) + } + } + + // Materialize the import graph if it is needed (NeedImports), + // or if we'll be using loadPackages (Need{Syntax|Types|TypesInfo}). + var leaves []*loaderPackage // packages with no unfinished successors + if ld.Mode&(NeedImports|NeedSyntax|NeedTypes|NeedTypesInfo) != 0 { + const ( + white = 0 // new + grey = 1 // in progress + black = 2 // complete + ) + + // visit traverses the import graph, depth-first, + // and materializes the graph as Packages.Imports. + // + // Valid imports are saved in the Packages.Import map. + // Invalid imports (cycles and missing nodes) are saved in the importErrors map. + // Thus, even in the presence of both kinds of errors, + // the Import graph remains a DAG. + // + // visit returns whether the package needs src or has a transitive + // dependency on a package that does. These are the only packages + // for which we load source code. + var stack []*loaderPackage + var visit func(from, lpkg *loaderPackage) bool + visit = func(from, lpkg *loaderPackage) bool { + if lpkg.color == grey { + panic("internal error: grey node") + } + if lpkg.color == white { + lpkg.color = grey + stack = append(stack, lpkg) // push + stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports + lpkg.Imports = make(map[string]*Package, len(stubs)) + for importPath, ipkg := range stubs { + var importErr error + imp := ld.pkgs[ipkg.ID] + if imp == nil { + // (includes package "C" when DisableCgo) + importErr = fmt.Errorf("missing package: %q", ipkg.ID) + } else if imp.color == grey { + importErr = fmt.Errorf("import cycle: %s", stack) + } + if importErr != nil { + if lpkg.importErrors == nil { + lpkg.importErrors = make(map[string]error) + } + lpkg.importErrors[importPath] = importErr + continue + } + + if visit(lpkg, imp) { + lpkg.needsrc = true + } + lpkg.Imports[importPath] = imp.Package + } + + // -- postorder -- + + // Complete type information is required for the + // immediate dependencies of each source package. + if lpkg.needsrc && ld.Mode&NeedTypes != 0 { + for _, ipkg := range lpkg.Imports { + ld.pkgs[ipkg.ID].needtypes = true + } + } + + // NeedTypeSizes causes TypeSizes to be set even + // on packages for which types aren't needed. + if ld.Mode&NeedTypesSizes != 0 { + lpkg.TypesSizes = ld.sizes + } + + // Add packages with no imports directly to the queue of leaves. + if len(lpkg.Imports) == 0 { + leaves = append(leaves, lpkg) + } + + stack = stack[:len(stack)-1] // pop + lpkg.color = black + } + + // Add edge from predecessor. + if from != nil { + from.unfinishedSuccs.Add(+1) // incref + lpkg.preds = append(lpkg.preds, from) + } + + return lpkg.needsrc + } + + // For each initial package, create its import DAG. + for _, lpkg := range initial { + visit(nil, lpkg) + } + + } else { + // !NeedImports: drop the stub (ID-only) import packages + // that we are not even going to try to resolve. + for _, lpkg := range initial { + lpkg.Imports = nil + } + } + + // Load type data and syntax if needed, starting at + // the initial packages (roots of the import DAG). + if ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0 { + + // We avoid using g.SetLimit to limit concurrency as + // it makes g.Go stop accepting work, which prevents + // workers from enqeuing, and thus finishing, and thus + // allowing the group to make progress: deadlock. + // + // Instead we use the ioLimit and cpuLimit semaphores. + g, _ := errgroup.WithContext(ld.Context) + + // enqueues adds a package to the type-checking queue. + // It must have no unfinished successors. + var enqueue func(*loaderPackage) + enqueue = func(lpkg *loaderPackage) { + g.Go(func() error { + // Parse and type-check. + ld.loadPackage(lpkg) + + // Notify each waiting predecessor, + // and enqueue it when it becomes a leaf. + for _, pred := range lpkg.preds { + if pred.unfinishedSuccs.Add(-1) == 0 { // decref + enqueue(pred) + } + } + + return nil + }) + } + + // Load leaves first, adding new packages + // to the queue as they become leaves. + for _, leaf := range leaves { + enqueue(leaf) + } + + if err := g.Wait(); err != nil { + return nil, err // cancelled + } + } + + // If the context is done, return its error and + // throw out [likely] incomplete packages. + if err := ld.Context.Err(); err != nil { + return nil, err + } + + result := make([]*Package, len(initial)) + for i, lpkg := range initial { + result[i] = lpkg.Package + } + for i := range ld.pkgs { + // Clear all unrequested fields, + // to catch programs that use more than they request. + if ld.requestedMode&NeedName == 0 { + ld.pkgs[i].Name = "" + ld.pkgs[i].PkgPath = "" + } + if ld.requestedMode&NeedFiles == 0 { + ld.pkgs[i].GoFiles = nil + ld.pkgs[i].OtherFiles = nil + ld.pkgs[i].IgnoredFiles = nil + } + if ld.requestedMode&NeedEmbedFiles == 0 { + ld.pkgs[i].EmbedFiles = nil + } + if ld.requestedMode&NeedEmbedPatterns == 0 { + ld.pkgs[i].EmbedPatterns = nil + } + if ld.requestedMode&NeedCompiledGoFiles == 0 { + ld.pkgs[i].CompiledGoFiles = nil + } + if ld.requestedMode&NeedImports == 0 { + ld.pkgs[i].Imports = nil + } + if ld.requestedMode&NeedExportFile == 0 { + ld.pkgs[i].ExportFile = "" + } + if ld.requestedMode&NeedTypes == 0 { + ld.pkgs[i].Types = nil + ld.pkgs[i].IllTyped = false + } + if ld.requestedMode&NeedSyntax == 0 { + ld.pkgs[i].Syntax = nil + } + if ld.requestedMode&(NeedSyntax|NeedTypes|NeedTypesInfo) == 0 { + ld.pkgs[i].Fset = nil + } + if ld.requestedMode&NeedTypesInfo == 0 { + ld.pkgs[i].TypesInfo = nil + } + if ld.requestedMode&NeedTypesSizes == 0 { + ld.pkgs[i].TypesSizes = nil + } + if ld.requestedMode&NeedModule == 0 { + ld.pkgs[i].Module = nil + } + } + + return result, nil +} + +// loadPackage loads/parses/typechecks the specified package. +// It must be called only once per Package, +// after immediate dependencies are loaded. +// Precondition: ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0. +func (ld *loader) loadPackage(lpkg *loaderPackage) { + if lpkg.PkgPath == "unsafe" { + // To avoid surprises, fill in the blanks consistent + // with other packages. (For example, some analyzers + // assert that each needed types.Info map is non-nil + // even when there is no syntax that would cause them + // to consult the map.) + lpkg.Types = types.Unsafe + lpkg.Fset = ld.Fset + lpkg.Syntax = []*ast.File{} + lpkg.TypesInfo = ld.newTypesInfo() + lpkg.TypesSizes = ld.sizes + return + } + + // Call NewPackage directly with explicit name. + // This avoids skew between golist and go/types when the files' + // package declarations are inconsistent. + lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name) + lpkg.Fset = ld.Fset + + // Start shutting down if the context is done and do not load + // source or export data files. + // Packages that import this one will have ld.Context.Err() != nil. + // ld.Context.Err() will be returned later by refine. + if ld.Context.Err() != nil { + return + } + + // Subtle: we populate all Types fields with an empty Package + // before loading export data so that export data processing + // never has to create a types.Package for an indirect dependency, + // which would then require that such created packages be explicitly + // inserted back into the Import graph as a final step after export data loading. + // (Hence this return is after the Types assignment.) + // The Diamond test exercises this case. + if !lpkg.needtypes && !lpkg.needsrc { + return + } + + // TODO(adonovan): this condition looks wrong: + // I think it should be lpkg.needtypes && !lpkg.needsrc, + // so that NeedSyntax without NeedTypes can be satisfied by export data. + if !lpkg.needsrc { + if err := ld.loadFromExportData(lpkg); err != nil { + lpkg.exportDataError = err + lpkg.Errors = append(lpkg.Errors, Error{ + Pos: "-", + Msg: err.Error(), + Kind: UnknownError, // e.g. can't find/open/parse export data + }) + } + return // not a source package, don't get syntax trees + } + + appendError := func(err error) { + // Convert various error types into the one true Error. + var errs []Error + switch err := err.(type) { + case Error: + // from driver + errs = append(errs, err) + + case *os.PathError: + // from parser + errs = append(errs, Error{ + Pos: err.Path + ":1", + Msg: err.Err.Error(), + Kind: ParseError, + }) + + case scanner.ErrorList: + // from parser + for _, err := range err { + errs = append(errs, Error{ + Pos: err.Pos.String(), + Msg: err.Msg, + Kind: ParseError, + }) + } + + case types.Error: + // from type checker + lpkg.TypeErrors = append(lpkg.TypeErrors, err) + errs = append(errs, Error{ + Pos: err.Fset.Position(err.Pos).String(), + Msg: err.Msg, + Kind: TypeError, + }) + + default: + // unexpected impoverished error from parser? + errs = append(errs, Error{ + Pos: "-", + Msg: err.Error(), + Kind: UnknownError, + }) + + // If you see this error message, please file a bug. + log.Printf("internal error: error %q (%T) without position", err, err) + } + + lpkg.Errors = append(lpkg.Errors, errs...) + } + + // If the go command on the PATH is newer than the runtime, + // then the go/{scanner,ast,parser,types} packages from the + // standard library may be unable to process the files + // selected by go list. + // + // There is currently no way to downgrade the effective + // version of the go command (see issue 52078), so we proceed + // with the newer go command but, in case of parse or type + // errors, we emit an additional diagnostic. + // + // See: + // - golang.org/issue/52078 (flag to set release tags) + // - golang.org/issue/50825 (gopls legacy version support) + // - golang.org/issue/55883 (go/packages confusing error) + // + // Should we assert a hard minimum of (currently) go1.16 here? + var runtimeVersion int + if _, err := fmt.Sscanf(runtime.Version(), "go1.%d", &runtimeVersion); err == nil && runtimeVersion < lpkg.goVersion { + defer func() { + if len(lpkg.Errors) > 0 { + appendError(Error{ + Pos: "-", + Msg: fmt.Sprintf("This application uses version go1.%d of the source-processing packages but runs version go1.%d of 'go list'. It may fail to process source files that rely on newer language features. If so, rebuild the application using a newer version of Go.", runtimeVersion, lpkg.goVersion), + Kind: UnknownError, + }) + } + }() + } + + if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" { + // The config requested loading sources and types, but sources are missing. + // Add an error to the package and fall back to loading from export data. + appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError}) + _ = ld.loadFromExportData(lpkg) // ignore any secondary errors + + return // can't get syntax trees for this package + } + + files, errs := ld.parseFiles(lpkg.CompiledGoFiles) + for _, err := range errs { + appendError(err) + } + + lpkg.Syntax = files + if ld.Config.Mode&(NeedTypes|NeedTypesInfo) == 0 { + return + } + + // Start shutting down if the context is done and do not type check. + // Packages that import this one will have ld.Context.Err() != nil. + // ld.Context.Err() will be returned later by refine. + if ld.Context.Err() != nil { + return + } + + lpkg.TypesInfo = ld.newTypesInfo() + lpkg.TypesSizes = ld.sizes + + importer := importerFunc(func(path string) (*types.Package, error) { + if path == "unsafe" { + return types.Unsafe, nil + } + + // The imports map is keyed by import path. + ipkg := lpkg.Imports[path] + if ipkg == nil { + if err := lpkg.importErrors[path]; err != nil { + return nil, err + } + // There was skew between the metadata and the + // import declarations, likely due to an edit + // race, or because the ParseFile feature was + // used to supply alternative file contents. + return nil, fmt.Errorf("no metadata for %s", path) + } + + if ipkg.Types != nil && ipkg.Types.Complete() { + return ipkg.Types, nil + } + + // If types are unavailable, there must be an export data error. + if ipkg.exportDataError != nil { + return nil, ipkg.exportDataError + } + + log.Fatalf("internal error: expected complete types for package %q", path) + panic("unreachable") + }) + + // type-check + tc := &types.Config{ + Importer: importer, + + // Type-check bodies of functions only in initial packages. + // Example: for import graph A->B->C and initial packages {A,C}, + // we can ignore function bodies in B. + IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial, + + Error: appendError, + Sizes: ld.sizes, // may be nil + } + if lpkg.Module != nil && lpkg.Module.GoVersion != "" { + tc.GoVersion = "go" + lpkg.Module.GoVersion + } else if ld.externalDriver && lpkg.goVersion != 0 { + // Module information is missing when GOPACKAGESDRIVER is used, + // so use the go version from the driver response. + tc.GoVersion = fmt.Sprintf("go1.%d", lpkg.goVersion) + } + if (ld.Mode & typecheckCgo) != 0 { + if !typesinternal.SetUsesCgo(tc) { + appendError(Error{ + Msg: "typecheckCgo requires Go 1.15+", + Kind: ListError, + }) + return + } + } + + // Type-checking is CPU intensive. + cpuLimit <- unit{} // acquire a token + defer func() { <-cpuLimit }() // release a token + + typErr := types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) + lpkg.importErrors = nil // no longer needed + + // In go/types go1.21 and go1.22, Checker.Files failed fast with a + // a "too new" error, without calling tc.Error and without + // proceeding to type-check the package (#66525). + // We rely on the runtimeVersion error to give the suggested remedy. + if typErr != nil && len(lpkg.Errors) == 0 && len(lpkg.Syntax) > 0 { + if msg := typErr.Error(); strings.HasPrefix(msg, "package requires newer Go version") { + appendError(types.Error{ + Fset: ld.Fset, + Pos: lpkg.Syntax[0].Package, + Msg: msg, + }) + } + } + + // If !Cgo, the type-checker uses FakeImportC mode, so + // it doesn't invoke the importer for import "C", + // nor report an error for the import, + // or for any undefined C.f reference. + // We must detect this explicitly and correctly + // mark the package as IllTyped (by reporting an error). + // TODO(adonovan): if these errors are annoying, + // we could just set IllTyped quietly. + if tc.FakeImportC { + outer: + for _, f := range lpkg.Syntax { + for _, imp := range f.Imports { + if imp.Path.Value == `"C"` { + err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`} + appendError(err) + break outer + } + } + } + } + + // If types.Checker.Files had an error that was unreported, + // make sure to report the unknown error so the package is illTyped. + if typErr != nil && len(lpkg.Errors) == 0 { + appendError(typErr) + } + + // Record accumulated errors. + illTyped := len(lpkg.Errors) > 0 + if !illTyped { + for _, imp := range lpkg.Imports { + if imp.IllTyped { + illTyped = true + break + } + } + } + lpkg.IllTyped = illTyped +} + +func (ld *loader) newTypesInfo() *types.Info { + // Populate TypesInfo only if needed, as it + // causes the type checker to work much harder. + if ld.Config.Mode&NeedTypesInfo == 0 { + return nil + } + return &types.Info{ + Types: make(map[ast.Expr]types.TypeAndValue), + Defs: make(map[*ast.Ident]types.Object), + Uses: make(map[*ast.Ident]types.Object), + Implicits: make(map[ast.Node]types.Object), + Instances: make(map[*ast.Ident]types.Instance), + Scopes: make(map[ast.Node]*types.Scope), + Selections: make(map[*ast.SelectorExpr]*types.Selection), + FileVersions: make(map[*ast.File]string), + } +} + +// An importFunc is an implementation of the single-method +// types.Importer interface based on a function value. +type importerFunc func(path string) (*types.Package, error) + +func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } + +// We use a counting semaphore to limit +// the number of parallel I/O calls or CPU threads per process. +var ( + ioLimit = make(chan unit, 20) + cpuLimit = make(chan unit, runtime.GOMAXPROCS(0)) +) + +func (ld *loader) parseFile(filename string) (*ast.File, error) { + ld.parseCacheMu.Lock() + v, ok := ld.parseCache[filename] + if ok { + // cache hit + ld.parseCacheMu.Unlock() + <-v.ready + } else { + // cache miss + v = &parseValue{ready: make(chan struct{})} + ld.parseCache[filename] = v + ld.parseCacheMu.Unlock() + + var src []byte + for f, contents := range ld.Config.Overlay { + // TODO(adonovan): Inefficient for large overlays. + // Do an exact name-based map lookup + // (for nonexistent files) followed by a + // FileID-based map lookup (for existing ones). + if sameFile(f, filename) { + src = contents + break + } + } + var err error + if src == nil { + ioLimit <- unit{} // acquire a token + src, err = os.ReadFile(filename) + <-ioLimit // release a token + } + if err != nil { + v.err = err + } else { + // Parsing is CPU intensive. + cpuLimit <- unit{} // acquire a token + v.f, v.err = ld.ParseFile(ld.Fset, filename, src) + <-cpuLimit // release a token + } + + close(v.ready) + } + return v.f, v.err +} + +// parseFiles reads and parses the Go source files and returns the ASTs +// of the ones that could be at least partially parsed, along with a +// list of I/O and parse errors encountered. +// +// Because files are scanned in parallel, the token.Pos +// positions of the resulting ast.Files are not ordered. +func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) { + var ( + n = len(filenames) + parsed = make([]*ast.File, n) + errors = make([]error, n) + ) + var g errgroup.Group + for i, filename := range filenames { + // This creates goroutines unnecessarily in the + // cache-hit case, but that case is uncommon. + g.Go(func() error { + parsed[i], errors[i] = ld.parseFile(filename) + return nil + }) + } + g.Wait() + + // Eliminate nils, preserving order. + var o int + for _, f := range parsed { + if f != nil { + parsed[o] = f + o++ + } + } + parsed = parsed[:o] + + o = 0 + for _, err := range errors { + if err != nil { + errors[o] = err + o++ + } + } + errors = errors[:o] + + return parsed, errors +} + +// sameFile returns true if x and y have the same basename and denote +// the same file. +func sameFile(x, y string) bool { + if x == y { + // It could be the case that y doesn't exist. + // For instance, it may be an overlay file that + // hasn't been written to disk. To handle that case + // let x == y through. (We added the exact absolute path + // string to the CompiledGoFiles list, so the unwritten + // overlay case implies x==y.) + return true + } + if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation) + if xi, err := os.Stat(x); err == nil { + if yi, err := os.Stat(y); err == nil { + return os.SameFile(xi, yi) + } + } + } + return false +} + +// loadFromExportData ensures that type information is present for the specified +// package, loading it from an export data file on the first request. +// On success it sets lpkg.Types to a new Package. +func (ld *loader) loadFromExportData(lpkg *loaderPackage) error { + if lpkg.PkgPath == "" { + log.Fatalf("internal error: Package %s has no PkgPath", lpkg) + } + + // Because gcexportdata.Read has the potential to create or + // modify the types.Package for each node in the transitive + // closure of dependencies of lpkg, all exportdata operations + // must be sequential. (Finer-grained locking would require + // changes to the gcexportdata API.) + // + // The exportMu lock guards the lpkg.Types field and the + // types.Package it points to, for each loaderPackage in the graph. + // + // Not all accesses to Package.Pkg need to be protected by exportMu: + // graph ordering ensures that direct dependencies of source + // packages are fully loaded before the importer reads their Pkg field. + ld.exportMu.Lock() + defer ld.exportMu.Unlock() + + if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() { + return nil // cache hit + } + + lpkg.IllTyped = true // fail safe + + if lpkg.ExportFile == "" { + // Errors while building export data will have been printed to stderr. + return fmt.Errorf("no export data file") + } + f, err := os.Open(lpkg.ExportFile) + if err != nil { + return err + } + defer f.Close() + + // Read gc or cmd/export export data. + // + // We don't currently support gccgo export data because all + // underlying workspaces use the gc toolchain. (Even build + // systems that support gccgo don't use it for workspace + // queries.) + r, err := gcexportdata.NewReader(f) + if err != nil { + return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) + } + + // Build the view. + // + // The gcexportdata machinery has no concept of package ID. + // It identifies packages by their PkgPath, which although not + // globally unique is unique within the scope of one invocation + // of the linker, type-checker, or gcexportdata. + // + // So, we must build a PkgPath-keyed view of the global + // (conceptually ID-keyed) cache of packages and pass it to + // gcexportdata. The view must contain every existing + // package that might possibly be mentioned by the + // current package---its transitive closure. + // + // In loadPackage, we unconditionally create a types.Package for + // each dependency so that export data loading does not + // create new ones. + // + // TODO(adonovan): it would be simpler and more efficient + // if the export data machinery invoked a callback to + // get-or-create a package instead of a map. + // + view := make(map[string]*types.Package) // view seen by gcexportdata + seen := make(map[*loaderPackage]bool) // all visited packages + var visit func(pkgs map[string]*Package) + visit = func(pkgs map[string]*Package) { + for _, p := range pkgs { + lpkg := ld.pkgs[p.ID] + if !seen[lpkg] { + seen[lpkg] = true + view[lpkg.PkgPath] = lpkg.Types + visit(lpkg.Imports) + } + } + } + visit(lpkg.Imports) + + viewLen := len(view) + 1 // adding the self package + // Parse the export data. + // (May modify incomplete packages in view but not create new ones.) + tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath) + if err != nil { + return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) + } + if _, ok := view["go.shape"]; ok { + // Account for the pseudopackage "go.shape" that gets + // created by generic code. + viewLen++ + } + if viewLen != len(view) { + log.Panicf("golang.org/x/tools/go/packages: unexpected new packages during load of %s", lpkg.PkgPath) + } + + lpkg.Types = tpkg + lpkg.IllTyped = false + return nil +} + +// impliedLoadMode returns loadMode with its dependencies. +func impliedLoadMode(loadMode LoadMode) LoadMode { + if loadMode&(NeedDeps|NeedTypes|NeedTypesInfo) != 0 { + // All these things require knowing the import graph. + loadMode |= NeedImports + } + if loadMode&NeedTypes != 0 { + // Types require the GoVersion from Module. + loadMode |= NeedModule + } + + return loadMode +} + +func usesExportData(cfg *Config) bool { + return cfg.Mode&NeedExportFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0 +} + +type unit struct{} + +func cond[T any](cond bool, t, f T) T { + if cond { + return t + } else { + return f + } +} diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go new file mode 100644 index 0000000..06747a9 --- /dev/null +++ b/vendor/golang.org/x/tools/go/packages/visit.go @@ -0,0 +1,108 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package packages + +import ( + "fmt" + "iter" + "os" + + "golang.org/x/tools/internal/moremaps" +) + +// Visit visits all the packages in the import graph whose roots are +// pkgs, calling the optional pre function the first time each package +// is encountered (preorder), and the optional post function after a +// package's dependencies have been visited (postorder). +// The boolean result of pre(pkg) determines whether +// the imports of package pkg are visited. +// +// Example: +// +// pkgs, err := Load(...) +// if err != nil { ... } +// Visit(pkgs, nil, func(pkg *Package) { +// log.Println(pkg) +// }) +// +// In most cases, it is more convenient to use [Postorder]: +// +// for pkg := range Postorder(pkgs) { +// log.Println(pkg) +// } +func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { + seen := make(map[*Package]bool) + var visit func(*Package) + visit = func(pkg *Package) { + if !seen[pkg] { + seen[pkg] = true + + if pre == nil || pre(pkg) { + for _, imp := range moremaps.Sorted(pkg.Imports) { // for determinism + visit(imp) + } + } + + if post != nil { + post(pkg) + } + } + } + for _, pkg := range pkgs { + visit(pkg) + } +} + +// PrintErrors prints to os.Stderr the accumulated errors of all +// packages in the import graph rooted at pkgs, dependencies first. +// PrintErrors returns the number of errors printed. +func PrintErrors(pkgs []*Package) int { + var n int + errModules := make(map[*Module]bool) + for pkg := range Postorder(pkgs) { + for _, err := range pkg.Errors { + fmt.Fprintln(os.Stderr, err) + n++ + } + + // Print pkg.Module.Error once if present. + mod := pkg.Module + if mod != nil && mod.Error != nil && !errModules[mod] { + errModules[mod] = true + fmt.Fprintln(os.Stderr, mod.Error.Err) + n++ + } + } + return n +} + +// Postorder returns an iterator over the packages in +// the import graph whose roots are pkg. +// Packages are enumerated in dependencies-first order. +func Postorder(pkgs []*Package) iter.Seq[*Package] { + return func(yield func(*Package) bool) { + seen := make(map[*Package]bool) + var visit func(*Package) bool + visit = func(pkg *Package) bool { + if !seen[pkg] { + seen[pkg] = true + for _, imp := range moremaps.Sorted(pkg.Imports) { // for determinism + if !visit(imp) { + return false + } + } + if !yield(pkg) { + return false + } + } + return true + } + for _, pkg := range pkgs { + if !visit(pkg) { + break + } + } + } +} diff --git a/vendor/golang.org/x/tools/go/ssa/TODO b/vendor/golang.org/x/tools/go/ssa/TODO new file mode 100644 index 0000000..6c35253 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/TODO @@ -0,0 +1,16 @@ +-*- text -*- + +SSA Generics to-do list +=========================== + +DOCUMENTATION: +- Read me for internals + +TYPE PARAMETERIZED GENERIC FUNCTIONS: +- sanity.go updates. +- Check source functions going to generics. +- Tests, tests, tests... + +USAGE: +- Back fill users for handling ssa.InstantiateGenerics being off. + diff --git a/vendor/golang.org/x/tools/go/ssa/block.go b/vendor/golang.org/x/tools/go/ssa/block.go new file mode 100644 index 0000000..28170c7 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/block.go @@ -0,0 +1,113 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +import "fmt" + +// This file implements the BasicBlock type. + +// addEdge adds a control-flow graph edge from from to to. +func addEdge(from, to *BasicBlock) { + from.Succs = append(from.Succs, to) + to.Preds = append(to.Preds, from) +} + +// Parent returns the function that contains block b. +func (b *BasicBlock) Parent() *Function { return b.parent } + +// String returns a human-readable label of this block. +// It is not guaranteed unique within the function. +func (b *BasicBlock) String() string { + return fmt.Sprintf("%d", b.Index) +} + +// emit appends an instruction to the current basic block. +// If the instruction defines a Value, it is returned. +func (b *BasicBlock) emit(i Instruction) Value { + i.setBlock(b) + b.Instrs = append(b.Instrs, i) + v, _ := i.(Value) + return v +} + +// predIndex returns the i such that b.Preds[i] == c or panics if +// there is none. +func (b *BasicBlock) predIndex(c *BasicBlock) int { + for i, pred := range b.Preds { + if pred == c { + return i + } + } + panic(fmt.Sprintf("no edge %s -> %s", c, b)) +} + +// hasPhi returns true if b.Instrs contains φ-nodes. +func (b *BasicBlock) hasPhi() bool { + _, ok := b.Instrs[0].(*Phi) + return ok +} + +// phis returns the prefix of b.Instrs containing all the block's φ-nodes. +func (b *BasicBlock) phis() []Instruction { + for i, instr := range b.Instrs { + if _, ok := instr.(*Phi); !ok { + return b.Instrs[:i] + } + } + return nil // unreachable in well-formed blocks +} + +// replacePred replaces all occurrences of p in b's predecessor list with q. +// Ordinarily there should be at most one. +func (b *BasicBlock) replacePred(p, q *BasicBlock) { + for i, pred := range b.Preds { + if pred == p { + b.Preds[i] = q + } + } +} + +// replaceSucc replaces all occurrences of p in b's successor list with q. +// Ordinarily there should be at most one. +func (b *BasicBlock) replaceSucc(p, q *BasicBlock) { + for i, succ := range b.Succs { + if succ == p { + b.Succs[i] = q + } + } +} + +// removePred removes all occurrences of p in b's +// predecessor list and φ-nodes. +// Ordinarily there should be at most one. +func (b *BasicBlock) removePred(p *BasicBlock) { + phis := b.phis() + + // We must preserve edge order for φ-nodes. + j := 0 + for i, pred := range b.Preds { + if pred != p { + b.Preds[j] = b.Preds[i] + // Strike out φ-edge too. + for _, instr := range phis { + phi := instr.(*Phi) + phi.Edges[j] = phi.Edges[i] + } + j++ + } + } + // Nil out b.Preds[j:] and φ-edges[j:] to aid GC. + for i := j; i < len(b.Preds); i++ { + b.Preds[i] = nil + for _, instr := range phis { + instr.(*Phi).Edges[i] = nil + } + } + b.Preds = b.Preds[:j] + for _, instr := range phis { + phi := instr.(*Phi) + phi.Edges = phi.Edges[:j] + } +} diff --git a/vendor/golang.org/x/tools/go/ssa/blockopt.go b/vendor/golang.org/x/tools/go/ssa/blockopt.go new file mode 100644 index 0000000..7dabce8 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/blockopt.go @@ -0,0 +1,183 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// Simple block optimizations to simplify the control flow graph. + +// TODO(adonovan): opt: instead of creating several "unreachable" blocks +// per function in the Builder, reuse a single one (e.g. at Blocks[1]) +// to reduce garbage. + +import ( + "fmt" + "os" +) + +// If true, perform sanity checking and show progress at each +// successive iteration of optimizeBlocks. Very verbose. +const debugBlockOpt = false + +// markReachable sets Index=-1 for all blocks reachable from b. +func markReachable(b *BasicBlock) { + b.Index = -1 + for _, succ := range b.Succs { + if succ.Index == 0 { + markReachable(succ) + } + } +} + +// deleteUnreachableBlocks marks all reachable blocks of f and +// eliminates (nils) all others, including possibly cyclic subgraphs. +func deleteUnreachableBlocks(f *Function) { + const white, black = 0, -1 + // We borrow b.Index temporarily as the mark bit. + for _, b := range f.Blocks { + b.Index = white + } + markReachable(f.Blocks[0]) + if f.Recover != nil { + markReachable(f.Recover) + } + for i, b := range f.Blocks { + if b.Index == white { + for _, c := range b.Succs { + if c.Index == black { + c.removePred(b) // delete white->black edge + } + } + if debugBlockOpt { + fmt.Fprintln(os.Stderr, "unreachable", b) + } + f.Blocks[i] = nil // delete b + } + } + f.removeNilBlocks() +} + +// jumpThreading attempts to apply simple jump-threading to block b, +// in which a->b->c become a->c if b is just a Jump. +// The result is true if the optimization was applied. +func jumpThreading(f *Function, b *BasicBlock) bool { + if b.Index == 0 { + return false // don't apply to entry block + } + if b.Instrs == nil { + return false + } + if _, ok := b.Instrs[0].(*Jump); !ok { + return false // not just a jump + } + c := b.Succs[0] + if c == b { + return false // don't apply to degenerate jump-to-self. + } + if c.hasPhi() { + return false // not sound without more effort + } + for j, a := range b.Preds { + a.replaceSucc(b, c) + + // If a now has two edges to c, replace its degenerate If by Jump. + if len(a.Succs) == 2 && a.Succs[0] == c && a.Succs[1] == c { + jump := new(Jump) + jump.setBlock(a) + a.Instrs[len(a.Instrs)-1] = jump + a.Succs = a.Succs[:1] + c.removePred(b) + } else { + if j == 0 { + c.replacePred(b, a) + } else { + c.Preds = append(c.Preds, a) + } + } + + if debugBlockOpt { + fmt.Fprintln(os.Stderr, "jumpThreading", a, b, c) + } + } + f.Blocks[b.Index] = nil // delete b + return true +} + +// fuseBlocks attempts to apply the block fusion optimization to block +// a, in which a->b becomes ab if len(a.Succs)==len(b.Preds)==1. +// The result is true if the optimization was applied. +func fuseBlocks(f *Function, a *BasicBlock) bool { + if len(a.Succs) != 1 { + return false + } + b := a.Succs[0] + if len(b.Preds) != 1 { + return false + } + + // Degenerate &&/|| ops may result in a straight-line CFG + // containing φ-nodes. (Ideally we'd replace such them with + // their sole operand but that requires Referrers, built later.) + if b.hasPhi() { + return false // not sound without further effort + } + + // Eliminate jump at end of A, then copy all of B across. + a.Instrs = append(a.Instrs[:len(a.Instrs)-1], b.Instrs...) + for _, instr := range b.Instrs { + instr.setBlock(a) + } + + // A inherits B's successors + a.Succs = append(a.succs2[:0], b.Succs...) + + // Fix up Preds links of all successors of B. + for _, c := range b.Succs { + c.replacePred(b, a) + } + + if debugBlockOpt { + fmt.Fprintln(os.Stderr, "fuseBlocks", a, b) + } + + f.Blocks[b.Index] = nil // delete b + return true +} + +// optimizeBlocks() performs some simple block optimizations on a +// completed function: dead block elimination, block fusion, jump +// threading. +func optimizeBlocks(f *Function) { + deleteUnreachableBlocks(f) + + // Loop until no further progress. + changed := true + for changed { + changed = false + + if debugBlockOpt { + f.WriteTo(os.Stderr) + mustSanityCheck(f, nil) + } + + for _, b := range f.Blocks { + // f.Blocks will temporarily contain nils to indicate + // deleted blocks; we remove them at the end. + if b == nil { + continue + } + + // Fuse blocks. b->c becomes bc. + if fuseBlocks(f, b) { + changed = true + } + + // a->b->c becomes a->c if b contains only a Jump. + if jumpThreading(f, b) { + changed = true + continue // (b was disconnected) + } + } + } + f.removeNilBlocks() +} diff --git a/vendor/golang.org/x/tools/go/ssa/builder.go b/vendor/golang.org/x/tools/go/ssa/builder.go new file mode 100644 index 0000000..a20b9ad --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/builder.go @@ -0,0 +1,3291 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file defines the builder, which builds SSA-form IR for function bodies. +// +// SSA construction has two phases, "create" and "build". First, one +// or more packages are created in any order by a sequence of calls to +// CreatePackage, either from syntax or from mere type information. +// Each created package has a complete set of Members (const, var, +// type, func) that can be accessed through methods like +// Program.FuncValue. +// +// It is not necessary to call CreatePackage for all dependencies of +// each syntax package, only for its direct imports. (In future +// perhaps even this restriction may be lifted.) +// +// Second, packages created from syntax are built, by one or more +// calls to Package.Build, which may be concurrent; or by a call to +// Program.Build, which builds all packages in parallel. Building +// traverses the type-annotated syntax tree of each function body and +// creates SSA-form IR, a control-flow graph of instructions, +// populating fields such as Function.Body, .Params, and others. +// +// Building may create additional methods, including: +// - wrapper methods (e.g. for embedding, or implicit &recv) +// - bound method closures (e.g. for use(recv.f)) +// - thunks (e.g. for use(I.f) or use(T.f)) +// - generic instances (e.g. to produce f[int] from f[any]). +// As these methods are created, they are added to the build queue, +// and then processed in turn, until a fixed point is reached, +// Since these methods might belong to packages that were not +// created (by a call to CreatePackage), their Pkg field is unset. +// +// Instances of generic functions may be either instantiated (f[int] +// is a copy of f[T] with substitutions) or wrapped (f[int] delegates +// to f[T]), depending on the availability of generic syntax and the +// InstantiateGenerics mode flag. +// +// Each package has an initializer function named "init" that calls +// the initializer functions of each direct import, computes and +// assigns the initial value of each global variable, and calls each +// source-level function named "init". (These generate SSA functions +// named "init#1", "init#2", etc.) +// +// Runtime types +// +// Each MakeInterface operation is a conversion from a non-interface +// type to an interface type. The semantics of this operation requires +// a runtime type descriptor, which is the type portion of an +// interface, and the value abstracted by reflect.Type. +// +// The program accumulates all non-parameterized types that are +// encountered as MakeInterface operands, along with all types that +// may be derived from them using reflection. This set is available as +// Program.RuntimeTypes, and the methods of these types may be +// reachable via interface calls or reflection even if they are never +// referenced from the SSA IR. (In practice, algorithms such as RTA +// that compute reachability from package main perform their own +// tracking of runtime types at a finer grain, so this feature is not +// very useful.) +// +// Function literals +// +// Anonymous functions must be built as soon as they are encountered, +// as it may affect locals of the enclosing function, but they are not +// marked 'built' until the end of the outermost enclosing function. +// (Among other things, this causes them to be logged in top-down order.) +// +// The Function.build fields determines the algorithm for building the +// function body. It is cleared to mark that building is complete. + +import ( + "fmt" + "go/ast" + "go/constant" + "go/token" + "go/types" + "os" + "runtime" + "sync" + + "slices" + + "golang.org/x/tools/internal/typeparams" + "golang.org/x/tools/internal/typesinternal" + "golang.org/x/tools/internal/versions" +) + +var ( + varOk = newVar("ok", tBool) + varIndex = newVar("index", tInt) + + // Type constants. + tBool = types.Typ[types.Bool] + tByte = types.Typ[types.Byte] + tRune = types.Universe.Lookup("rune").Type() // prints as "rune" (Typ[Rune] is same as Int32) + tInt = types.Typ[types.Int] + tInvalid = types.Typ[types.Invalid] + tString = types.Typ[types.String] + tUntypedNil = types.Typ[types.UntypedNil] + tUnsafePointer = types.Typ[types.UnsafePointer] + tRangeIter = ssaNamedType("rangeIter", tUnsafePointer) // the type of all "range" iterators + tDeferStack = ssaNamedType("deferStack", tUnsafePointer) // the type of a "deferStack" from ssa:deferstack() + tEface = types.NewInterfaceType(nil, nil).Complete() + + // Fake package for fake ssa types. + ssaFakeTypesPackage = types.NewPackage("$ssa", "ssa") + + // SSA Value constants. + vZero = intConst(0) + vOne = intConst(1) + vTrue = NewConst(constant.MakeBool(true), tBool) + vFalse = NewConst(constant.MakeBool(false), tBool) + vNoReturn = NewConst(constant.MakeString("noreturn"), tString) + + jReady = intConst(0) // range-over-func jump is READY + jBusy = intConst(-1) // range-over-func jump is BUSY + jDone = intConst(-2) // range-over-func jump is DONE + + // The ssa:deferstack intrinsic returns the current function's defer stack. + vDeferStack = &Builtin{ + name: "ssa:deferstack", + sig: types.NewSignatureType(nil, nil, nil, nil, typesinternal.TupleOf(tDeferStack), false), + } +) + +func ssaNamedType(name string, underlying types.Type) *types.Named { + obj := types.NewTypeName(token.NoPos, ssaFakeTypesPackage, name, nil) + return types.NewNamed(obj, underlying, nil) +} + +// builder holds state associated with the package currently being built. +// Its methods contain all the logic for AST-to-SSA conversion. +// +// All Functions belong to the same Program. +// +// builders are not thread-safe. +type builder struct { + fns []*Function // Functions that have finished their CREATE phases. + + finished int // finished is the length of the prefix of fns containing built functions. + + // The task of building shared functions within the builder. + // Shared functions are ones the builder may either create or lookup. + // These may be built by other builders in parallel. + // The task is done when the builder has finished iterating, and it + // waits for all shared functions to finish building. + // nil implies there are no hared functions to wait on. + buildshared *task +} + +// shared is done when the builder has built all of the +// enqueued functions to a fixed-point. +func (b *builder) shared() *task { + if b.buildshared == nil { // lazily-initialize + b.buildshared = &task{done: make(chan unit)} + } + return b.buildshared +} + +// enqueue fn to be built by the builder. +func (b *builder) enqueue(fn *Function) { + b.fns = append(b.fns, fn) +} + +// waitForSharedFunction indicates that the builder should wait until +// the potentially shared function fn has finished building. +// +// This should include any functions that may be built by other +// builders. +func (b *builder) waitForSharedFunction(fn *Function) { + // Check whether fn is already built before calling b.shared(), + // which allocates a task and a channel that b.iterate() would + // then have to close and wait on. The common case, a lookup of + // a method that was created and built long ago, needs neither. + if t := fn.buildshared; t != nil && !t.isTransitivelyDone() { // maybe need to wait? + b.shared().addEdge(t) + } +} + +// cond emits to fn code to evaluate boolean condition e and jump +// to t or f depending on its value, performing various simplifications. +// +// Postcondition: fn.currentBlock is nil. +func (b *builder) cond(fn *Function, e ast.Expr, t, f *BasicBlock) { + switch e := e.(type) { + case *ast.ParenExpr: + b.cond(fn, e.X, t, f) + return + + case *ast.BinaryExpr: + switch e.Op { + case token.LAND: + ltrue := fn.newBasicBlock("cond.true") + b.cond(fn, e.X, ltrue, f) + fn.currentBlock = ltrue + b.cond(fn, e.Y, t, f) + return + + case token.LOR: + lfalse := fn.newBasicBlock("cond.false") + b.cond(fn, e.X, t, lfalse) + fn.currentBlock = lfalse + b.cond(fn, e.Y, t, f) + return + } + + case *ast.UnaryExpr: + if e.Op == token.NOT { + b.cond(fn, e.X, f, t) + return + } + } + + // A traditional compiler would simplify "if false" (etc) here + // but we do not, for better fidelity to the source code. + // + // The value of a constant condition may be platform-specific, + // and may cause blocks that are reachable in some configuration + // to be hidden from subsequent analyses such as bug-finding tools. + emitIf(fn, b.expr(fn, e), t, f) +} + +// logicalBinop emits code to fn to evaluate e, a &&- or +// ||-expression whose reified boolean value is wanted. +// The value is returned. +func (b *builder) logicalBinop(fn *Function, e *ast.BinaryExpr) Value { + rhs := fn.newBasicBlock("binop.rhs") + done := fn.newBasicBlock("binop.done") + + // T(e) = T(e.X) = T(e.Y) after untyped constants have been + // eliminated. + // TODO(adonovan): not true; MyBool==MyBool yields UntypedBool. + t := fn.typeOf(e) + + var short Value // value of the short-circuit path + switch e.Op { + case token.LAND: + b.cond(fn, e.X, rhs, done) + short = NewConst(constant.MakeBool(false), t) + + case token.LOR: + b.cond(fn, e.X, done, rhs) + short = NewConst(constant.MakeBool(true), t) + } + + // Is rhs unreachable? + if rhs.Preds == nil { + // Simplify false&&y to false, true||y to true. + fn.currentBlock = done + return short + } + + // Is done unreachable? + if done.Preds == nil { + // Simplify true&&y (or false||y) to y. + fn.currentBlock = rhs + return b.expr(fn, e.Y) + } + + // All edges from e.X to done carry the short-circuit value. + var edges []Value + for range done.Preds { + edges = append(edges, short) + } + + // The edge from e.Y to done carries the value of e.Y. + fn.currentBlock = rhs + edges = append(edges, b.expr(fn, e.Y)) + emitJump(fn, done) + fn.currentBlock = done + + phi := &Phi{Edges: edges, Comment: e.Op.String()} + phi.pos = e.OpPos + phi.typ = t + return done.emit(phi) +} + +// exprN lowers a multi-result expression e to SSA form, emitting code +// to fn and returning a single Value whose type is a *types.Tuple. +// The caller must access the components via Extract. +// +// Multi-result expressions include CallExprs in a multi-value +// assignment or return statement, and "value,ok" uses of +// TypeAssertExpr, IndexExpr (when X is a map), and UnaryExpr (when Op +// is token.ARROW). +func (b *builder) exprN(fn *Function, e ast.Expr) Value { + typ := fn.typeOf(e).(*types.Tuple) + switch e := e.(type) { + case *ast.ParenExpr: + return b.exprN(fn, e.X) + + case *ast.CallExpr: + // Currently, no built-in function nor type conversion + // has multiple results, so we can avoid some of the + // cases for single-valued CallExpr. + var c Call + b.setCall(fn, e, &c.Call) + c.typ = typ + return emitCall(fn, &c) + + case *ast.IndexExpr: + mapt := typeparams.CoreType(fn.typeOf(e.X)).(*types.Map) // ,ok must be a map. + lookup := &Lookup{ + X: b.expr(fn, e.X), + Index: emitConv(fn, b.expr(fn, e.Index), mapt.Key()), + CommaOk: true, + } + lookup.setType(typ) + lookup.setPos(e.Lbrack) + return fn.emit(lookup) + + case *ast.TypeAssertExpr: + return emitTypeTest(fn, b.expr(fn, e.X), typ.At(0).Type(), e.Lparen) + + case *ast.UnaryExpr: // must be receive <- + unop := &UnOp{ + Op: token.ARROW, + X: b.expr(fn, e.X), + CommaOk: true, + } + unop.setType(typ) + unop.setPos(e.OpPos) + return fn.emit(unop) + } + panic(fmt.Sprintf("exprN(%T) in %s", e, fn)) +} + +// builtin emits to fn SSA instructions to implement a call to the +// built-in function obj with the specified arguments +// and return type. It returns the value defined by the result. +// +// The result is nil if no special handling was required; in this case +// the caller should treat this like an ordinary library function +// call. +func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ types.Type, pos token.Pos) Value { + typ = fn.typ(typ) + switch obj.Name() { + case "make": + switch ct := typeparams.CoreType(typ).(type) { + case *types.Slice: + n := b.expr(fn, args[1]) + m := n + if len(args) == 3 { + m = b.expr(fn, args[2]) + } + if m, ok := m.(*Const); ok { + // treat make([]T, n, m) as new([m]T)[:n] + cap := m.Int64() + at := types.NewArray(ct.Elem(), cap) + v := &Slice{ + X: emitNew(fn, at, pos, "makeslice"), + High: n, + } + v.setPos(pos) + v.setType(typ) + return fn.emit(v) + } + v := &MakeSlice{ + Len: n, + Cap: m, + } + v.setPos(pos) + v.setType(typ) + return fn.emit(v) + + case *types.Map: + var res Value + if len(args) == 2 { + res = b.expr(fn, args[1]) + } + v := &MakeMap{Reserve: res} + v.setPos(pos) + v.setType(typ) + return fn.emit(v) + + case *types.Chan: + var sz Value = vZero + if len(args) == 2 { + sz = b.expr(fn, args[1]) + } + v := &MakeChan{Size: sz} + v.setPos(pos) + v.setType(typ) + return fn.emit(v) + } + + case "new": + alloc := emitNew(fn, typeparams.MustDeref(typ), pos, "new") + if !fn.info.Types[args[0]].IsType() { + // new(expr), requires go1.26 + v := b.expr(fn, args[0]) + emitStore(fn, alloc, v, pos) + } + return alloc + + case "len", "cap": + // Special case: len or cap of an array or *array is + // based on the type, not the value which may be nil. + // We must still evaluate the value, though. (If it + // was side-effect free, the whole call would have + // been constant-folded.) + t := typeparams.Deref(fn.typeOf(args[0])) + if at, ok := typeparams.CoreType(t).(*types.Array); ok { + b.expr(fn, args[0]) // for effects only + return intConst(at.Len()) + } + // Otherwise treat as normal. + + case "panic": + fn.emit(&Panic{ + X: emitConv(fn, b.expr(fn, args[0]), tEface), + pos: pos, + }) + fn.currentBlock = fn.newBasicBlock("unreachable") + return vTrue // any non-nil Value will do + } + return nil // treat all others as a regular function call +} + +// addr lowers a single-result addressable expression e to SSA form, +// emitting code to fn and returning the location (an lvalue) defined +// by the expression. +// +// If escaping is true, addr marks the base variable of the +// addressable expression e as being a potentially escaping pointer +// value. For example, in this code: +// +// a := A{ +// b: [1]B{B{c: 1}} +// } +// return &a.b[0].c +// +// the application of & causes a.b[0].c to have its address taken, +// which means that ultimately the local variable a must be +// heap-allocated. This is a simple but very conservative escape +// analysis. +// +// Operations forming potentially escaping pointers include: +// - &x, including when implicit in method call or composite literals. +// - a[:] iff a is an array (not *array) +// - references to variables in lexically enclosing functions. +func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue { + switch e := e.(type) { + case *ast.Ident: + if isBlankIdent(e) { + return blank{} + } + obj := fn.objectOf(e).(*types.Var) + var v Value + if g := fn.Prog.packageLevelMember(obj); g != nil { + v = g.(*Global) // var (address) + } else { + v = fn.lookup(obj, escaping) + } + return &address{addr: v, pos: e.Pos(), expr: e} + + case *ast.CompositeLit: + typ := typeparams.Deref(fn.typeOf(e)) + var v *Alloc + if escaping { + v = emitNew(fn, typ, e.Lbrace, "complit") + } else { + v = emitLocal(fn, typ, e.Lbrace, "complit") + } + b.compLit(fn, v, e) + return &address{addr: v, pos: e.Lbrace, expr: e} + + case *ast.ParenExpr: + return b.addr(fn, e.X, escaping) + + case *ast.SelectorExpr: + sel := fn.selection(e) + if sel == nil { + // qualified identifier + return b.addr(fn, e.Sel, escaping) + } + if sel.kind != types.FieldVal { + panic(sel) + } + wantAddr := true + v := b.receiver(fn, e.X, wantAddr, escaping, sel) + index := sel.index[len(sel.index)-1] + fld := fieldOf(typeparams.MustDeref(v.Type()), index) // v is an addr. + + // Due to the two phases of resolving AssignStmt, a panic from x.f = p() + // when x is nil is required to come after the side-effects of + // evaluating x and p(). + emit := func(fn *Function) Value { + return emitFieldSelection(fn, v, index, true, e.Sel) + } + return &lazyAddress{addr: emit, t: fld.Type(), pos: e.Sel.Pos(), expr: e.Sel} + + case *ast.IndexExpr: + xt := fn.typeOf(e.X) + elem, mode := indexType(xt) + var x Value + var et types.Type + switch mode { + case ixArrVar: // array, array|slice, array|*array, or array|*array|slice. + x = b.addr(fn, e.X, escaping).address(fn) + et = types.NewPointer(elem) + case ixVar: // *array, slice, *array|slice + x = b.expr(fn, e.X) + et = types.NewPointer(elem) + case ixMap: + mt := typeparams.CoreType(xt).(*types.Map) + return &element{ + m: b.expr(fn, e.X), + k: emitConv(fn, b.expr(fn, e.Index), mt.Key()), + t: mt.Elem(), + pos: e.Lbrack, + } + default: + panic("unexpected container type in IndexExpr: " + xt.String()) + } + index := b.expr(fn, e.Index) + if isUntyped(index.Type()) { + index = emitConv(fn, index, tInt) + } + // Due to the two phases of resolving AssignStmt, a panic from x[i] = p() + // when x is nil or i is out-of-bounds is required to come after the + // side-effects of evaluating x, i and p(). + emit := func(fn *Function) Value { + v := &IndexAddr{ + X: x, + Index: index, + } + v.setPos(e.Lbrack) + v.setType(et) + return fn.emit(v) + } + return &lazyAddress{addr: emit, t: typeparams.MustDeref(et), pos: e.Lbrack, expr: e} + + case *ast.StarExpr: + return &address{addr: b.expr(fn, e.X), pos: e.Star, expr: e} + } + + panic(fmt.Sprintf("unexpected address expression: %T", e)) +} + +type store struct { + lhs lvalue + rhs Value +} + +type storebuf struct{ stores []store } + +func (sb *storebuf) store(lhs lvalue, rhs Value) { + sb.stores = append(sb.stores, store{lhs, rhs}) +} + +func (sb *storebuf) emit(fn *Function) { + for _, s := range sb.stores { + s.lhs.store(fn, s.rhs) + } +} + +// assign emits to fn code to initialize the lvalue loc with the value +// of expression e. +// +// This is equivalent to loc.store(fn, b.expr(fn, e)). +// +// If sb is not nil, assign generates code to evaluate expression e, but +// not to update loc. Instead, the necessary stores are appended to the +// storebuf sb so that they can be executed later. This allows correct +// in-place update of existing variables when the RHS is a composite +// literal that may reference parts of the LHS. +func (b *builder) assign(fn *Function, loc lvalue, e ast.Expr, sb *storebuf) { + // A pointer-typed CompositeLit (var _ *MyStruct = {}) + // implies an &-operation; expr handles this. + rhs := b.expr(fn, e) + if sb != nil { + sb.store(loc, rhs) + } else { + loc.store(fn, rhs) + } +} + +// expr lowers a single-result expression e to SSA form, emitting code +// to fn and returning the Value defined by the expression. +func (b *builder) expr(fn *Function, e ast.Expr) Value { + e = ast.Unparen(e) + + tv := fn.info.Types[e] + + // Is expression a constant? + if tv.Value != nil { + return NewConst(tv.Value, fn.typ(tv.Type)) + } + + var v Value + if tv.Addressable() { + // Prefer pointer arithmetic ({Index,Field}Addr) followed + // by Load over subelement extraction (e.g. Index, Field), + // to avoid large copies. + v = b.addr(fn, e, false).load(fn) + } else { + v = b.expr0(fn, e, tv) + } + if fn.debugInfo() { + emitDebugRef(fn, e, v, false) + } + return v +} + +// expr0 compiles the non-constant unparenthesized r-value expression e. +// +// A composite literal is not addressable, so it is handled here. +// If its implicit type is a pointer *T, it denotes &T{...}, +// so it allocates a new T and returns its address. Otherwise +// it builds the literal in a temporary and loads its value. +func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value { + switch e := e.(type) { + case *ast.BasicLit: + panic("non-constant BasicLit") // unreachable + + case *ast.FuncLit: + /* function literal */ + anon := &Function{ + name: fmt.Sprintf("%s$%d", fn.Name(), 1+len(fn.AnonFuncs)), + Signature: fn.typeOf(e.Type).(*types.Signature), + pos: e.Type.Func, + parent: fn, + anonIdx: int32(len(fn.AnonFuncs)), + Pkg: fn.Pkg, + Prog: fn.Prog, + syntax: e, + info: fn.info, + goversion: fn.goversion, + build: (*builder).buildFromSyntax, + topLevelOrigin: nil, // use anonIdx to lookup an anon instance's origin. + recvtypeparams: fn.recvtypeparams, // share the parent's receiver type parameters. + recvtypeargs: fn.recvtypeargs, // share the parent's receiver type arguments. + typeparams: fn.typeparams, // share the parent's type parameters. + typeargs: fn.typeargs, // share the parent's type arguments. + subst: fn.subst, // share the parent's type substitutions. + uniq: fn.uniq, // start from parent's unique values + } + fn.AnonFuncs = append(fn.AnonFuncs, anon) + // Build anon immediately, as it may cause fn's locals to escape. + // (It is not marked 'built' until the end of the enclosing FuncDecl.) + anon.build(b, anon) + fn.uniq = anon.uniq // resume after anon's unique values + if anon.FreeVars == nil { + return anon + } + v := &MakeClosure{Fn: anon} + v.setType(fn.typ(tv.Type)) + for _, fv := range anon.FreeVars { + v.Bindings = append(v.Bindings, fv.outer) + fv.outer = nil + } + return fn.emit(v) + + case *ast.TypeAssertExpr: // single-result form only + return emitTypeAssert(fn, b.expr(fn, e.X), fn.typ(tv.Type), e.Lparen) + + case *ast.CallExpr: + if fn.info.Types[e.Fun].IsType() { + // Explicit type conversion, e.g. string(x) or big.Int(x) + x := b.expr(fn, e.Args[0]) + y := emitConv(fn, x, fn.typ(tv.Type)) + if y != x { + switch y := y.(type) { + case *Convert: + y.pos = e.Lparen + case *ChangeType: + y.pos = e.Lparen + case *MakeInterface: + y.pos = e.Lparen + case *SliceToArrayPointer: + y.pos = e.Lparen + case *UnOp: // conversion from slice to array. + y.pos = e.Lparen + } + } + return y + } + // Call to "intrinsic" built-ins, e.g. new, make, panic. + if id, ok := ast.Unparen(e.Fun).(*ast.Ident); ok { + if obj, ok := fn.info.Uses[id].(*types.Builtin); ok { + if v := b.builtin(fn, obj, e.Args, fn.typ(tv.Type), e.Lparen); v != nil { + return v + } + } + } + // Regular function call. + var v Call + b.setCall(fn, e, &v.Call) + v.setType(fn.typ(tv.Type)) + return emitCall(fn, &v) + + case *ast.UnaryExpr: + switch e.Op { + case token.AND: // &X --- potentially escaping. + addr := b.addr(fn, e.X, true) + if _, ok := ast.Unparen(e.X).(*ast.StarExpr); ok { + // &*p must panic if p is nil (http://golang.org/s/go12nil). + // For simplicity, we'll just (suboptimally) rely + // on the side effects of a load. + // TODO(adonovan): emit dedicated nilcheck. + addr.load(fn) + } + return addr.address(fn) + case token.ADD: + return b.expr(fn, e.X) + case token.NOT, token.ARROW, token.SUB, token.XOR: // ! <- - ^ + v := &UnOp{ + Op: e.Op, + X: b.expr(fn, e.X), + } + v.setPos(e.OpPos) + v.setType(fn.typ(tv.Type)) + return fn.emit(v) + default: + panic(e.Op) + } + + case *ast.BinaryExpr: + switch e.Op { + case token.LAND, token.LOR: + return b.logicalBinop(fn, e) + case token.SHL, token.SHR: + fallthrough + case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT: + return emitArith(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), fn.typ(tv.Type), e.OpPos) + + case token.EQL, token.NEQ, token.GTR, token.LSS, token.LEQ, token.GEQ: + cmp := emitCompare(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), e.OpPos) + // The type of x==y may be UntypedBool. + return emitConv(fn, cmp, types.Default(fn.typ(tv.Type))) + default: + panic("illegal op in BinaryExpr: " + e.Op.String()) + } + + case *ast.SliceExpr: + var low, high, max Value + var x Value + xtyp := fn.typeOf(e.X) + switch typeparams.CoreType(xtyp).(type) { + case *types.Array: + // Potentially escaping. + x = b.addr(fn, e.X, true).address(fn) + case *types.Basic, *types.Slice, *types.Pointer: // *array + x = b.expr(fn, e.X) + default: + // core type exception? + if isBytestring(xtyp) { + x = b.expr(fn, e.X) // bytestring is handled as string and []byte. + } else { + panic("unexpected sequence type in SliceExpr") + } + } + if e.Low != nil { + low = b.expr(fn, e.Low) + } + if e.High != nil { + high = b.expr(fn, e.High) + } + if e.Slice3 { + max = b.expr(fn, e.Max) + } + v := &Slice{ + X: x, + Low: low, + High: high, + Max: max, + } + v.setPos(e.Lbrack) + v.setType(fn.typ(tv.Type)) + return fn.emit(v) + + case *ast.Ident: + obj := fn.info.Uses[e] + // Universal built-in or nil? + switch obj := obj.(type) { + case *types.Builtin: + return &Builtin{name: obj.Name(), sig: fn.instanceType(e).(*types.Signature)} + case *types.Nil: + return zeroConst(fn.instanceType(e)) + } + + // Package-level func or var? + // (obj must belong to same package or a direct import.) + if v := fn.Prog.packageLevelMember(obj); v != nil { + if g, ok := v.(*Global); ok { + return emitLoad(fn, g) // var (address) + } + callee := v.(*Function) // (func) + if callee.typeparams.Len() > 0 { + targs := fn.subtargs(e) + callee = callee.instance(nil, targs, b) + } + return callee + } + // Local var. + return emitLoad(fn, fn.lookup(obj.(*types.Var), false)) // var (address) + + case *ast.SelectorExpr: + sel := fn.selection(e) + if sel == nil { + // builtin unsafe.{Add,Slice} + if obj, ok := fn.info.Uses[e.Sel].(*types.Builtin); ok { + return &Builtin{name: obj.Name(), sig: fn.typ(tv.Type).(*types.Signature)} + } + // qualified identifier + return b.expr(fn, e.Sel) + } + switch sel.kind { + case types.MethodExpr: + // (*T).f or T.f, the method f from the method-set of type T. + // The result is a "thunk". + targs := fn.subtargs(e.Sel) + thunk := createThunk(fn.Prog, sel, targs) + b.enqueue(thunk) + return thunk + + case types.MethodVal: + // e.f where e is an expression and f is a method. + // The result is a "bound". + m := sel.obj.(*types.Func) + rt := fn.typ(recvType(m)) + wantAddr := isPointer(rt) + escaping := true + v := b.receiver(fn, e.X, wantAddr, escaping, sel) + + if types.IsInterface(rt) { + // If v may be an interface type I (after instantiating), + // we must emit a check that v is non-nil. + if recv, ok := types.Unalias(sel.recv).(*types.TypeParam); ok { + // Emit a nil check if any possible instantiation of the + // type parameter is an interface type. + if !typeSetIsEmpty(recv) { + // recv has a concrete term its typeset. + // So it cannot be instantiated as an interface. + // + // Example: + // func _[T interface{~int; Foo()}] () { + // var v T + // _ = v.Foo // <-- MethodVal + // } + } else { + // rt may be instantiated as an interface. + // Emit nil check: typeassert (any(v)).(any). + emitTypeAssert(fn, emitConv(fn, v, tEface), tEface, token.NoPos) + } + } else { + // non-type param interface + // Emit nil check: typeassert v.(I). + emitTypeAssert(fn, v, rt, e.Sel.Pos()) + } + } + + if rtargs := fn.subrtargs(m); len(rtargs) > 0 { + m = fn.Prog.canon.instantiateMethod(m, rtargs, fn.Prog.ctxt) + } + + targs := fn.subtargs(e.Sel) + bound := createBound(fn.Prog, m, targs) + b.enqueue(bound) + + // The assignment may widen a type parameter to its + // interface bound (case #3 of go.dev/issue.78110). + v = emitConv(fn, v, bound.FreeVars[0].Type()) + + c := &MakeClosure{ + Fn: bound, + Bindings: []Value{v}, + } + c.setPos(e.Sel.Pos()) + c.setType(bound.Signature) + return fn.emit(c) + + case types.FieldVal: + indices := sel.index + last := len(indices) - 1 + v := b.expr(fn, e.X) + v = emitImplicitSelections(fn, v, indices[:last], e.Pos()) + v = emitFieldSelection(fn, v, indices[last], false, e.Sel) + return v + } + + panic("unexpected expression-relative selector") + + case *ast.IndexListExpr: + // f[X, Y] must be a generic function + if !instance(fn.info, e.X) { + panic("unexpected expression-could not match index list to instantiation") + } + return b.expr(fn, e.X) // Handle instantiation within the *Ident or *SelectorExpr cases. + + case *ast.IndexExpr: + if instance(fn.info, e.X) { + return b.expr(fn, e.X) // Handle instantiation within the *Ident or *SelectorExpr cases. + } + // not a generic instantiation. + xt := fn.typeOf(e.X) + switch et, mode := indexType(xt); mode { + case ixVar: + // Addressable slice/array; use IndexAddr and Load. + return b.addr(fn, e, false).load(fn) + + case ixArrVar, ixValue: + // An array in a register, a string or a combined type that contains + // either an [_]array (ixArrVar) or string (ixValue). + + // Note: for ixArrVar and CoreType(xt)==nil can be IndexAddr and Load. + index := b.expr(fn, e.Index) + if isUntyped(index.Type()) { + index = emitConv(fn, index, tInt) + } + v := &Index{ + X: b.expr(fn, e.X), + Index: index, + } + v.setPos(e.Lbrack) + v.setType(et) + return fn.emit(v) + + case ixMap: + ct := typeparams.CoreType(xt).(*types.Map) + v := &Lookup{ + X: b.expr(fn, e.X), + Index: emitConv(fn, b.expr(fn, e.Index), ct.Key()), + } + v.setPos(e.Lbrack) + v.setType(ct.Elem()) + return fn.emit(v) + default: + panic("unexpected container type in IndexExpr: " + xt.String()) + } + + case *ast.CompositeLit: + // A composite literal with no explicit type whose + // (inferred) type is a pointer *T is equivalent to &T{...}. + // This occurs for nested literals (e.g. []*T{{}}) and, + // since go1.28, in any assignment context (e.g. f({})). + if isPointerCore(fn.typeOf(e)) { + return b.addr(fn, e, true).address(fn) + } + // Value-typed literal: build in a temporary and load. + return b.addr(fn, e, false).load(fn) + + case *ast.StarExpr: + // Addressable types (lvalues) + return b.addr(fn, e, false).load(fn) + } + + panic(fmt.Sprintf("unexpected expr: %T", e)) +} + +// stmtList emits to fn code for all statements in list. +func (b *builder) stmtList(fn *Function, list []ast.Stmt) { + for _, s := range list { + b.stmt(fn, s) + } +} + +// receiver emits to fn code for expression e in the "receiver" +// position of selection e.f (where f may be a field or a method) and +// returns the effective receiver after applying the implicit field +// selections of sel. +// +// wantAddr requests that the result is an address. If +// !sel.indirect, this may require that e be built in addr() mode; it +// must thus be addressable. +// +// escaping is defined as per builder.addr(). +func (b *builder) receiver(fn *Function, e ast.Expr, wantAddr, escaping bool, sel *selection) Value { + var v Value + if wantAddr && !sel.indirect && !isPointerCore(fn.typeOf(e)) { + v = b.addr(fn, e, escaping).address(fn) + } else { + v = b.expr(fn, e) + } + + last := len(sel.index) - 1 + // The position of implicit selection is the position of the inducing receiver expression. + v = emitImplicitSelections(fn, v, sel.index[:last], e.Pos()) + if types.IsInterface(v.Type()) { + // When v is an interface, sel.Kind()==MethodValue and v.f is invoked. + // So v is not loaded, even if v has a pointer core type. + } else if !wantAddr && isPointerCore(v.Type()) { + v = emitLoad(fn, v) + } + return v +} + +// setCallFunc populates the function parts of a CallCommon structure +// (Func, Method, Recv, Args[0]) based on the kind of invocation +// occurring in e. +func (b *builder) setCallFunc(fn *Function, e *ast.CallExpr, c *CallCommon) { + c.pos = e.Lparen + + // Is this a (possibly generic) method call? + m := ast.Unparen(e.Fun) + switch e := m.(type) { + case *ast.IndexExpr: + m = e.X + case *ast.IndexListExpr: + m = e.X + } + if selector, ok := m.(*ast.SelectorExpr); ok { + sel := fn.selection(selector) + if sel != nil && sel.kind == types.MethodVal { + obj := sel.obj.(*types.Func) + recv := recvType(obj) + + wantAddr := isPointer(recv) + escaping := true + v := b.receiver(fn, selector.X, wantAddr, escaping, sel) + if types.IsInterface(recv) { + // Invoke-mode call. + c.Value = v // possibly type param + c.Method = obj + } else { + // "Call"-mode call. + targs := fn.subtargs(selector.Sel) + c.Value = fn.Prog.objectMethod(obj, targs, b) + c.Args = append(c.Args, v) + } + return + } + + // sel.kind==MethodExpr indicates T.f() or (*T).f(): + // a statically dispatched call to the method f in the + // method-set of T or *T. T may be an interface. + // + // e.Fun would evaluate to a concrete method, interface + // wrapper function, or promotion wrapper. + // + // For now, we evaluate it in the usual way. + // + // TODO(adonovan): opt: inline expr() here, to make the + // call static and to avoid generation of wrappers. + // It's somewhat tricky as it may consume the first + // actual parameter if the call is "invoke" mode. + // + // Examples: + // type T struct{}; func (T) f() {} // "call" mode + // type T interface { f() } // "invoke" mode + // + // type S struct{ T } + // + // var s S + // S.f(s) + // (*S).f(&s) + // + // Suggested approach: + // - consume the first actual parameter expression + // and build it with b.expr(). + // - apply implicit field selections. + // - use MethodVal logic to populate fields of c. + } + + // Evaluate the function operand in the usual way. + c.Value = b.expr(fn, e.Fun) +} + +// emitCallArgs emits to f code for the actual parameters of call e to +// a (possibly built-in) function of effective type sig. +// The argument values are appended to args, which is then returned. +func (b *builder) emitCallArgs(fn *Function, sig *types.Signature, e *ast.CallExpr, args []Value) []Value { + // f(x, y, z...): pass slice z straight through. + if e.Ellipsis != 0 { + for i, arg := range e.Args { + v := emitConv(fn, b.expr(fn, arg), sig.Params().At(i).Type()) + args = append(args, v) + } + return args + } + + offset := len(args) // 1 if call has receiver, 0 otherwise + + // Evaluate actual parameter expressions. + // + // If this is a chained call of the form f(g()) where g has + // multiple return values (MRV), they are flattened out into + // args; a suffix of them may end up in a varargs slice. + for _, arg := range e.Args { + v := b.expr(fn, arg) + if ttuple, ok := v.Type().(*types.Tuple); ok { // MRV chain + for i, n := 0, ttuple.Len(); i < n; i++ { + args = append(args, emitExtract(fn, v, i)) + } + } else { + args = append(args, v) + } + } + + // Actual->formal assignability conversions for normal parameters. + np := sig.Params().Len() // number of normal parameters + if sig.Variadic() { + np-- + } + for i := 0; i < np; i++ { + args[offset+i] = emitConv(fn, args[offset+i], sig.Params().At(i).Type()) + } + + // Actual->formal assignability conversions for variadic parameter, + // and construction of slice. + if sig.Variadic() { + varargs := args[offset+np:] + st := sig.Params().At(np).Type().(*types.Slice) + vt := st.Elem() + if len(varargs) == 0 { + args = append(args, zeroConst(st)) + } else { + // Replace a suffix of args with a slice containing it. + at := types.NewArray(vt, int64(len(varargs))) + a := emitNew(fn, at, token.NoPos, "varargs") + a.setPos(e.Rparen) + for i, arg := range varargs { + iaddr := &IndexAddr{ + X: a, + Index: intConst(int64(i)), + } + iaddr.setType(types.NewPointer(vt)) + fn.emit(iaddr) + emitStore(fn, iaddr, arg, arg.Pos()) + } + s := &Slice{X: a} + s.setType(st) + args[offset+np] = fn.emit(s) + args = args[:offset+np+1] + } + } + return args +} + +// setCall emits to fn code to evaluate all the parameters of a function +// call e, and populates *c with those values. +func (b *builder) setCall(fn *Function, e *ast.CallExpr, c *CallCommon) { + // First deal with the f(...) part and optional receiver. + b.setCallFunc(fn, e, c) + + // Then append the other actual parameters. + sig, ok := typeparams.CoreType(fn.typeOf(e.Fun)).(*types.Signature) + if !ok { + panic(fmt.Sprintf("no signature for call of %s", e.Fun)) + } + c.Args = b.emitCallArgs(fn, sig, e, c.Args) +} + +// assignOp emits to fn code to perform loc = val. +func (b *builder) assignOp(fn *Function, loc lvalue, val Value, op token.Token, pos token.Pos) { + loc.store(fn, emitArith(fn, op, loc.load(fn), val, loc.typ(), pos)) +} + +// localValueSpec emits to fn code to define all of the vars in the +// function-local ValueSpec, spec. +func (b *builder) localValueSpec(fn *Function, spec *ast.ValueSpec) { + switch { + case len(spec.Values) == len(spec.Names): + // e.g. var x, y = 0, 1 + // 1:1 assignment + for i, id := range spec.Names { + if !isBlankIdent(id) { + emitLocalVar(fn, identVar(fn, id)) + } + lval := b.addr(fn, id, false) // non-escaping + b.assign(fn, lval, spec.Values[i], nil) + } + + case len(spec.Values) == 0: + // e.g. var x, y int + // Locals are implicitly zero-initialized. + for _, id := range spec.Names { + if !isBlankIdent(id) { + lhs := emitLocalVar(fn, identVar(fn, id)) + if fn.debugInfo() { + emitDebugRef(fn, id, lhs, true) + } + } + } + + default: + // e.g. var x, y = pos() + tuple := b.exprN(fn, spec.Values[0]) + for i, id := range spec.Names { + if !isBlankIdent(id) { + emitLocalVar(fn, identVar(fn, id)) + lhs := b.addr(fn, id, false) // non-escaping + lhs.store(fn, emitExtract(fn, tuple, i)) + } + } + } +} + +// assignStmt emits code to fn for a parallel assignment of rhss to lhss. +// isDef is true if this is a short variable declaration (:=). +// +// Note the similarity with localValueSpec. +func (b *builder) assignStmt(fn *Function, lhss, rhss []ast.Expr, isDef bool) { + // Side effects of all LHSs and RHSs must occur in left-to-right order. + lvals := b.assignLHS(fn, lhss, isDef) + if len(lhss) == len(rhss) { + // Simple assignment: x = f() (!isDef) + // Parallel assignment: x, y = f(), g() (!isDef) + // or short var decl: x, y := f(), g() (isDef) + // + // In all cases, the RHSs may refer to the LHSs, + // so we need a storebuf. + var sb storebuf + for i := range rhss { + b.assign(fn, lvals[i], rhss[i], &sb) + } + sb.emit(fn) + } else { + // e.g. x, y = pos() + tuple := b.exprN(fn, rhss[0]) + emitDebugRef(fn, rhss[0], tuple, false) + for i, lval := range lvals { + lval.store(fn, emitExtract(fn, tuple, i)) + } + } +} + +func (b *builder) assignLHS(fn *Function, lhss []ast.Expr, isDef bool) []lvalue { + lvals := make([]lvalue, len(lhss)) + for i, lhs := range lhss { + var lval lvalue = blank{} + if !isBlankIdent(lhs) { + if isDef { + if obj, ok := fn.info.Defs[lhs.(*ast.Ident)].(*types.Var); ok { + emitLocalVar(fn, obj) + } + } + lval = b.addr(fn, lhs, false) // non-escaping + } + lvals[i] = lval + } + return lvals +} + +// assignSelectRecvStmt emits a receive assignment from a single-case select. +// Unlike an ordinary assignment, its (single expression) right-hand side is +// evaluated and the receive is performed before its left-hand side is evaluated. +func (b *builder) assignSelectRecvStmt(fn *Function, assign *ast.AssignStmt) { + var values []Value + if len(assign.Lhs) == 1 { + values = append(values, b.expr(fn, assign.Rhs[0])) + } else { + tuple := b.exprN(fn, assign.Rhs[0]) + emitDebugRef(fn, assign.Rhs[0], tuple, false) + for i := range assign.Lhs { + values = append(values, emitExtract(fn, tuple, i)) + } + } + + lvals := b.assignLHS(fn, assign.Lhs, assign.Tok == token.DEFINE) + for i, lval := range lvals { + lval.store(fn, values[i]) + } +} + +// arrayLen returns the length of the array whose composite literal elements are elts. +func (b *builder) arrayLen(fn *Function, elts []ast.Expr) int64 { + var max int64 = -1 + var i int64 = -1 + for _, e := range elts { + if kv, ok := e.(*ast.KeyValueExpr); ok { + i = b.expr(fn, kv.Key).(*Const).Int64() + } else { + i++ + } + if i > max { + max = i + } + } + return max + 1 +} + +// compLit emits to fn code to initialize a composite literal e at +// address addr with type typ. +// +// The variable addr must be a fresh zero-valued Alloc. Since it is +// not reachable from any element expression, stores to it may be +// interleaved with evaluation of the elements and need not be +// deferred using a storebuf. In an assignment such as +// +// x = T{a: x.a} +// +// the literal is built in a temporary and then copied to x +// (see assignStmt), so all reads of x still precede the write. +// +// A CompositeLit may have pointer type only when the type name is +// implicit, e.g. in []*T{{}}, the inner literal has type *T and +// behaves like &T{}. (Since go1.28 the type may be omitted in any +// assignment context, e.g. f({}) where f's parameter is *T.) +// In that case, addr must hold a T, not a *T. +func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit) { + typ := typeparams.Deref(fn.typeOf(e)) // retain the named/alias/param type, if any + switch t := typeparams.CoreType(typ).(type) { + case *types.Struct: + var fIndices []int + for i, e := range e.Elts { + var ( + pos token.Pos + fType types.Type + ) + + if kv, ok := e.(*ast.KeyValueExpr); ok { // tagged field + fname := kv.Key.(*ast.Ident).Name + obj, index, _ := types.LookupFieldOrMethod(t, true, fn.declaredPackage().Pkg, fname) + fIndices = append(fIndices[:0], index...) + pos = kv.Colon + e = kv.Value + fType = obj.Type() + } else { // untagged field + fIndices = append(fIndices[:0], i) + pos = e.Pos() + fType = t.Field(i).Type() + } + + last := len(fIndices) - 1 + v := emitImplicitSelections(fn, addr, fIndices[:last], pos) + + faddr := &FieldAddr{ + X: v, + Field: fIndices[last], + } + faddr.setPos(pos) + faddr.setType(types.NewPointer(fType)) + fn.emit(faddr) + b.assign(fn, &address{addr: faddr, pos: pos, expr: e}, e, nil) + } + + case *types.Array, *types.Slice: + var at *types.Array + var array Value + switch t := t.(type) { + case *types.Slice: + at = types.NewArray(t.Elem(), b.arrayLen(fn, e.Elts)) + array = emitNew(fn, at, e.Lbrace, "slicelit") + case *types.Array: + at = t + array = addr + } + + var idx *Const + for _, e := range e.Elts { + pos := e.Pos() + if kv, ok := e.(*ast.KeyValueExpr); ok { + idx = b.expr(fn, kv.Key).(*Const) + pos = kv.Colon + e = kv.Value + } else { + var idxval int64 + if idx != nil { + idxval = idx.Int64() + 1 + } + idx = intConst(idxval) + } + iaddr := &IndexAddr{ + X: array, + Index: idx, + } + iaddr.setType(types.NewPointer(at.Elem())) + fn.emit(iaddr) + b.assign(fn, &address{addr: iaddr, pos: pos, expr: e}, e, nil) + } + + if t != at { // slice + s := &Slice{X: array} + s.setPos(e.Lbrace) + s.setType(typ) + (&address{addr: addr, pos: e.Lbrace, expr: e}).store(fn, fn.emit(s)) + } + + case *types.Map: + m := &MakeMap{Reserve: intConst(int64(len(e.Elts)))} + m.setPos(e.Lbrace) + m.setType(typ) + fn.emit(m) + for _, e := range e.Elts { + e := e.(*ast.KeyValueExpr) + + loc := &element{ + m: m, + k: emitConv(fn, b.expr(fn, e.Key), t.Key()), + t: t.Elem(), + pos: e.Colon, + } + b.assign(fn, loc, e.Value, nil) + } + (&address{addr: addr, pos: e.Lbrace, expr: e}).store(fn, m) + + default: + panic("unexpected CompositeLit type: " + typ.String()) + } +} + +// switchStmt emits to fn code for the switch statement s, optionally +// labelled by label. +func (b *builder) switchStmt(fn *Function, s *ast.SwitchStmt, label *lblock) { + // We treat SwitchStmt like a sequential if-else chain. + // Multiway dispatch can be recovered later by ssautil.Switches() + // to those cases that are free of side effects. + if s.Init != nil { + b.stmt(fn, s.Init) + } + var tag Value = vTrue + if s.Tag != nil { + tag = b.expr(fn, s.Tag) + } + done := fn.newBasicBlock("switch.done") + if label != nil { + label._break = done + } + // We pull the default case (if present) down to the end. + // But each fallthrough label must point to the next + // body block in source order, so we preallocate a + // body block (fallthru) for the next case. + // Unfortunately this makes for a confusing block order. + var dfltBody *[]ast.Stmt + var dfltFallthrough *BasicBlock + var fallthru, dfltBlock *BasicBlock + ncases := len(s.Body.List) + for i, clause := range s.Body.List { + body := fallthru + if body == nil { + body = fn.newBasicBlock("switch.body") // first case only + } + + // Preallocate body block for the next case. + fallthru = done + if i+1 < ncases { + fallthru = fn.newBasicBlock("switch.body") + } + + cc := clause.(*ast.CaseClause) + if cc.List == nil { + // Default case. + dfltBody = &cc.Body + dfltFallthrough = fallthru + dfltBlock = body + continue + } + + var nextCond *BasicBlock + for _, cond := range cc.List { + nextCond = fn.newBasicBlock("switch.next") + // For boolean switches, emit short-circuit control flow, + // just like an if/else-chain. + if tag == vTrue && !isNonTypeParamInterface(fn.info.Types[cond].Type) { + b.cond(fn, cond, body, nextCond) + } else { + c := emitCompare(fn, token.EQL, tag, b.expr(fn, cond), cond.Pos()) + emitIf(fn, c, body, nextCond) + } + fn.currentBlock = nextCond + } + fn.currentBlock = body + fn.targets = &targets{ + tail: fn.targets, + _break: done, + _fallthrough: fallthru, + } + b.stmtList(fn, cc.Body) + fn.targets = fn.targets.tail + emitJump(fn, done) + fn.currentBlock = nextCond + } + if dfltBlock != nil { + emitJump(fn, dfltBlock) + fn.currentBlock = dfltBlock + fn.targets = &targets{ + tail: fn.targets, + _break: done, + _fallthrough: dfltFallthrough, + } + b.stmtList(fn, *dfltBody) + fn.targets = fn.targets.tail + } + emitJump(fn, done) + fn.currentBlock = done +} + +// typeSwitchStmt emits to fn code for the type switch statement s, optionally +// labelled by label. +func (b *builder) typeSwitchStmt(fn *Function, s *ast.TypeSwitchStmt, label *lblock) { + // We treat TypeSwitchStmt like a sequential if-else chain. + // Multiway dispatch can be recovered later by ssautil.Switches(). + + // Typeswitch lowering: + // + // var x X + // switch y := x.(type) { + // case T1, T2: S1 // >1 (y := x) + // case nil: SN // nil (y := x) + // default: SD // 0 types (y := x) + // case T3: S3 // 1 type (y := x.(T3)) + // } + // + // ...s.Init... + // x := eval x + // .caseT1: + // t1, ok1 := typeswitch,ok x + // if ok1 then goto S1 else goto .caseT2 + // .caseT2: + // t2, ok2 := typeswitch,ok x + // if ok2 then goto S1 else goto .caseNil + // .S1: + // y := x + // ...S1... + // goto done + // .caseNil: + // if t2, ok2 := typeswitch,ok x + // if x == nil then goto SN else goto .caseT3 + // .SN: + // y := x + // ...SN... + // goto done + // .caseT3: + // t3, ok3 := typeswitch,ok x + // if ok3 then goto S3 else goto default + // .S3: + // y := t3 + // ...S3... + // goto done + // .default: + // y := x + // ...SD... + // goto done + // .done: + if s.Init != nil { + b.stmt(fn, s.Init) + } + + var x Value + switch ass := s.Assign.(type) { + case *ast.ExprStmt: // x.(type) + x = b.expr(fn, ast.Unparen(ass.X).(*ast.TypeAssertExpr).X) + case *ast.AssignStmt: // y := x.(type) + x = b.expr(fn, ast.Unparen(ass.Rhs[0]).(*ast.TypeAssertExpr).X) + } + + done := fn.newBasicBlock("typeswitch.done") + if label != nil { + label._break = done + } + var default_ *ast.CaseClause + for _, clause := range s.Body.List { + cc := clause.(*ast.CaseClause) + if cc.List == nil { + default_ = cc + continue + } + body := fn.newBasicBlock("typeswitch.body") + var next *BasicBlock + var casetype types.Type + var ti Value // ti, ok := typeassert,ok x + for _, cond := range cc.List { + next = fn.newBasicBlock("typeswitch.next") + casetype = fn.typeOf(cond) + var condv Value + if casetype == tUntypedNil { + condv = emitCompare(fn, token.EQL, x, zeroConst(x.Type()), cond.Pos()) + ti = x + } else { + yok := emitTypeTest(fn, x, casetype, cc.Case) + ti = emitExtract(fn, yok, 0) + condv = emitExtract(fn, yok, 1) + } + emitIf(fn, condv, body, next) + fn.currentBlock = next + } + if len(cc.List) != 1 { + ti = x + } + fn.currentBlock = body + b.typeCaseBody(fn, cc, ti, done) + fn.currentBlock = next + } + if default_ != nil { + b.typeCaseBody(fn, default_, x, done) + } else { + emitJump(fn, done) + } + fn.currentBlock = done +} + +func (b *builder) typeCaseBody(fn *Function, cc *ast.CaseClause, x Value, done *BasicBlock) { + if obj, ok := fn.info.Implicits[cc].(*types.Var); ok { + // In a switch y := x.(type), each case clause + // implicitly declares a distinct object y. + // In a single-type case, y has that type. + // In multi-type cases, 'case nil' and default, + // y has the same type as the interface operand. + emitStore(fn, emitLocalVar(fn, obj), x, obj.Pos()) + } + fn.targets = &targets{ + tail: fn.targets, + _break: done, + } + b.stmtList(fn, cc.Body) + fn.targets = fn.targets.tail + emitJump(fn, done) +} + +// selectStmt emits to fn code for the select statement s, optionally +// labelled by label. +func (b *builder) selectStmt(fn *Function, s *ast.SelectStmt, label *lblock) { + // A blocking select of a single case degenerates to a + // simple send or receive. + // TODO(adonovan): opt: is this optimization worth its weight? + if len(s.Body.List) == 1 { + clause := s.Body.List[0].(*ast.CommClause) + if clause.Comm != nil { + if recvAssign, ok := clause.Comm.(*ast.AssignStmt); ok { + b.assignSelectRecvStmt(fn, recvAssign) + } else { + b.stmt(fn, clause.Comm) + } + done := fn.newBasicBlock("select.done") + if label != nil { + label._break = done + } + fn.targets = &targets{ + tail: fn.targets, + _break: done, + } + b.stmtList(fn, clause.Body) + fn.targets = fn.targets.tail + emitJump(fn, done) + fn.currentBlock = done + return + } + } + + // First evaluate all channels in all cases, and find + // the directions of each state. + var states []*SelectState + blocking := true + debugInfo := fn.debugInfo() + for _, clause := range s.Body.List { + var st *SelectState + switch comm := clause.(*ast.CommClause).Comm.(type) { + case nil: // default case + blocking = false + continue + + case *ast.SendStmt: // ch<- i + ch := b.expr(fn, comm.Chan) + chtyp := typeparams.CoreType(fn.typ(ch.Type())).(*types.Chan) + st = &SelectState{ + Dir: types.SendOnly, + Chan: ch, + Send: emitConv(fn, b.expr(fn, comm.Value), chtyp.Elem()), + Pos: comm.Arrow, + } + if debugInfo { + st.DebugNode = comm + } + + case *ast.AssignStmt: // x := <-ch + recv := ast.Unparen(comm.Rhs[0]).(*ast.UnaryExpr) + st = &SelectState{ + Dir: types.RecvOnly, + Chan: b.expr(fn, recv.X), + Pos: recv.OpPos, + } + if debugInfo { + st.DebugNode = recv + } + + case *ast.ExprStmt: // <-ch + recv := ast.Unparen(comm.X).(*ast.UnaryExpr) + st = &SelectState{ + Dir: types.RecvOnly, + Chan: b.expr(fn, recv.X), + Pos: recv.OpPos, + } + if debugInfo { + st.DebugNode = recv + } + } + states = append(states, st) + } + + // We dispatch on the (fair) result of Select using a + // sequential if-else chain, in effect: + // + // idx, recvOk, r0...r_n-1 := select(...) + // if idx == 0 { // receive on channel 0 (first receive => r0) + // x, ok := r0, recvOk + // ...state0... + // } else if v == 1 { // send on channel 1 + // ...state1... + // } else { + // ...default... + // } + sel := &Select{ + States: states, + Blocking: blocking, + } + sel.setPos(s.Select) + var vars []*types.Var + vars = append(vars, varIndex, varOk) + for _, st := range states { + if st.Dir == types.RecvOnly { + chtyp := typeparams.CoreType(fn.typ(st.Chan.Type())).(*types.Chan) + vars = append(vars, newVar("", chtyp.Elem())) + } + } + sel.setType(types.NewTuple(vars...)) + + fn.emit(sel) + idx := emitExtract(fn, sel, 0) + + done := fn.newBasicBlock("select.done") + if label != nil { + label._break = done + } + + var defaultBody *[]ast.Stmt + state := 0 + r := 2 // index in 'sel' tuple of value; increments if st.Dir==RECV + for _, cc := range s.Body.List { + clause := cc.(*ast.CommClause) + if clause.Comm == nil { + defaultBody = &clause.Body + continue + } + body := fn.newBasicBlock("select.body") + next := fn.newBasicBlock("select.next") + emitIf(fn, emitCompare(fn, token.EQL, idx, intConst(int64(state)), token.NoPos), body, next) + fn.currentBlock = body + fn.targets = &targets{ + tail: fn.targets, + _break: done, + } + switch comm := clause.Comm.(type) { + case *ast.ExprStmt: // <-ch + if debugInfo { + v := emitExtract(fn, sel, r) + emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false) + } + r++ + + case *ast.AssignStmt: // x := <-states[state].Chan + if comm.Tok == token.DEFINE { + emitLocalVar(fn, identVar(fn, comm.Lhs[0].(*ast.Ident))) + } + x := b.addr(fn, comm.Lhs[0], false) // non-escaping + v := emitExtract(fn, sel, r) + if debugInfo { + emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false) + } + x.store(fn, v) + + if len(comm.Lhs) == 2 { // x, ok := ... + if comm.Tok == token.DEFINE { + emitLocalVar(fn, identVar(fn, comm.Lhs[1].(*ast.Ident))) + } + ok := b.addr(fn, comm.Lhs[1], false) // non-escaping + ok.store(fn, emitExtract(fn, sel, 1)) + } + r++ + } + b.stmtList(fn, clause.Body) + fn.targets = fn.targets.tail + emitJump(fn, done) + fn.currentBlock = next + state++ + } + if defaultBody != nil { + fn.targets = &targets{ + tail: fn.targets, + _break: done, + } + b.stmtList(fn, *defaultBody) + fn.targets = fn.targets.tail + } else { + // A blocking select must match some case. + // (This should really be a runtime.errorString, not a string.) + fn.emit(&Panic{ + X: emitConv(fn, stringConst("blocking select matched no case"), tEface), + }) + fn.currentBlock = fn.newBasicBlock("unreachable") + } + emitJump(fn, done) + fn.currentBlock = done +} + +// forStmt emits to fn code for the for statement s, optionally +// labelled by label. +func (b *builder) forStmt(fn *Function, s *ast.ForStmt, label *lblock) { + // Use forStmtGo122 instead if it applies. + if s.Init != nil { + if assign, ok := s.Init.(*ast.AssignStmt); ok && assign.Tok == token.DEFINE { + if versions.AtLeast(fn.goversion, versions.Go1_22) { + b.forStmtGo122(fn, s, label) + return + } + } + } + + // ...init... + // jump loop + // loop: + // if cond goto body else done + // body: + // ...body... + // jump post + // post: (target of continue) + // ...post... + // jump loop + // done: (target of break) + if s.Init != nil { + b.stmt(fn, s.Init) + } + + body := fn.newBasicBlock("for.body") + done := fn.newBasicBlock("for.done") // target of 'break' + loop := body // target of back-edge + if s.Cond != nil { + loop = fn.newBasicBlock("for.loop") + } + cont := loop // target of 'continue' + if s.Post != nil { + cont = fn.newBasicBlock("for.post") + } + if label != nil { + label._break = done + label._continue = cont + } + emitJump(fn, loop) + fn.currentBlock = loop + if loop != body { + b.cond(fn, s.Cond, body, done) + fn.currentBlock = body + } + fn.targets = &targets{ + tail: fn.targets, + _break: done, + _continue: cont, + } + b.stmt(fn, s.Body) + fn.targets = fn.targets.tail + emitJump(fn, cont) + + if s.Post != nil { + fn.currentBlock = cont + b.stmt(fn, s.Post) + emitJump(fn, loop) // back-edge + } + fn.currentBlock = done +} + +// forStmtGo122 emits to fn code for the for statement s, optionally +// labelled by label. s must define its variables. +// +// This allocates once per loop iteration. This is only correct in +// GoVersions >= go1.22. +func (b *builder) forStmtGo122(fn *Function, s *ast.ForStmt, label *lblock) { + // i_outer = alloc[T] + // *i_outer = ...init... // under objects[i] = i_outer + // jump loop + // loop: + // i = phi [head: i_outer, loop: i_next] + // ...cond... // under objects[i] = i + // if cond goto body else done + // body: + // ...body... // under objects[i] = i (same as loop) + // jump post + // post: + // tmp = *i + // i_next = alloc[T] + // *i_next = tmp + // ...post... // under objects[i] = i_next + // goto loop + // done: + + init := s.Init.(*ast.AssignStmt) + startingBlocks := len(fn.Blocks) + + pre := fn.currentBlock // current block before starting + loop := fn.newBasicBlock("for.loop") // target of back-edge + body := fn.newBasicBlock("for.body") + post := fn.newBasicBlock("for.post") // target of 'continue' + done := fn.newBasicBlock("for.done") // target of 'break' + + // For each of the n loop variables, we create five SSA values, + // outer, phi, next, load, and store in pre, loop, and post. + // There is no limit on n. + type loopVar struct { + obj *types.Var + outer *Alloc + phi *Phi + load *UnOp + next *Alloc + store *Store + } + vars := make([]loopVar, len(init.Lhs)) + for i, lhs := range init.Lhs { + v := identVar(fn, lhs.(*ast.Ident)) + typ := fn.typ(v.Type()) + + fn.currentBlock = pre + outer := emitLocal(fn, typ, v.Pos(), v.Name()) + + fn.currentBlock = loop + phi := &Phi{Comment: v.Name()} + phi.pos = v.Pos() + phi.typ = outer.Type() + fn.emit(phi) + + fn.currentBlock = post + // If next is local, it reuses the address and zeroes the old value so + // load before allocating next. + load := emitLoad(fn, phi) + next := emitLocal(fn, typ, v.Pos(), v.Name()) + store := emitStore(fn, next, load, token.NoPos) + + phi.Edges = []Value{outer, next} // pre edge is emitted before post edge. + + vars[i] = loopVar{v, outer, phi, load, next, store} + } + + // ...init... under fn.objects[v] = i_outer + fn.currentBlock = pre + for _, v := range vars { + fn.vars[v.obj] = v.outer + } + const isDef = false // assign to already-allocated outers + b.assignStmt(fn, init.Lhs, init.Rhs, isDef) + if label != nil { + label._break = done + label._continue = post + } + emitJump(fn, loop) + + // ...cond... under fn.objects[v] = i + fn.currentBlock = loop + for _, v := range vars { + fn.vars[v.obj] = v.phi + } + if s.Cond != nil { + b.cond(fn, s.Cond, body, done) + } else { + emitJump(fn, body) + } + + // ...body... under fn.objects[v] = i + fn.currentBlock = body + fn.targets = &targets{ + tail: fn.targets, + _break: done, + _continue: post, + } + b.stmt(fn, s.Body) + fn.targets = fn.targets.tail + emitJump(fn, post) + + // ...post... under fn.objects[v] = i_next + for _, v := range vars { + fn.vars[v.obj] = v.next + } + fn.currentBlock = post + if s.Post != nil { + b.stmt(fn, s.Post) + } + emitJump(fn, loop) // back-edge + fn.currentBlock = done + + // For each loop variable that does not escape, + // (the common case), fuse its next cells into its + // (local) outer cell as they have disjoint live ranges. + // + // It is sufficient to test whether i_next escapes, + // because its Heap flag will be marked true if either + // the cond or post expression causes i to escape + // (because escape distributes over phi). + var nlocals int + for _, v := range vars { + if !v.next.Heap { + nlocals++ + } + } + if nlocals > 0 { + replace := make(map[Value]Value, 2*nlocals) + dead := make(map[Instruction]bool, 4*nlocals) + for _, v := range vars { + if !v.next.Heap { + replace[v.next] = v.outer + replace[v.phi] = v.outer + dead[v.phi], dead[v.next], dead[v.load], dead[v.store] = true, true, true, true + } + } + + // Replace all uses of i_next and phi with i_outer. + // Referrers have not been built for fn yet so only update Instruction operands. + // We need only look within the blocks added by the loop. + var operands []*Value // recycle storage + for _, b := range fn.Blocks[startingBlocks:] { + for _, instr := range b.Instrs { + operands = instr.Operands(operands[:0]) + for _, ptr := range operands { + k := *ptr + if v := replace[k]; v != nil { + *ptr = v + } + } + } + } + + // Remove instructions for phi, load, and store. + // lift() will remove the unused i_next *Alloc. + isDead := func(i Instruction) bool { return dead[i] } + loop.Instrs = slices.DeleteFunc(loop.Instrs, isDead) + post.Instrs = slices.DeleteFunc(post.Instrs, isDead) + } +} + +// rangeIndexed emits to fn the header for an integer-indexed loop +// over array, *array or slice value x. +// The v result is defined only if tv is non-nil. +// forPos is the position of the "for" token. +func (b *builder) rangeIndexed(fn *Function, x Value, tv types.Type, pos token.Pos) (k, v Value, loop, done *BasicBlock) { + // + // length = len(x) + // index = -1 + // loop: (target of continue) + // index++ + // if index < length goto body else done + // body: + // k = index + // v = x[index] + // ...body... + // jump loop + // done: (target of break) + + // Determine number of iterations. + var length Value + dt := typeparams.Deref(x.Type()) + if arr, ok := typeparams.CoreType(dt).(*types.Array); ok { + // For array or *array, the number of iterations is + // known statically thanks to the type. We avoid a + // data dependence upon x, permitting later dead-code + // elimination if x is pure, static unrolling, etc. + // Ranging over a nil *array may have >0 iterations. + // We still generate code for x, in case it has effects. + length = intConst(arr.Len()) + } else { + // length = len(x). + var c Call + c.Call.Value = makeLen(x.Type()) + c.Call.Args = []Value{x} + c.setType(tInt) + length = fn.emit(&c) + } + + index := emitLocal(fn, tInt, token.NoPos, "rangeindex") + emitStore(fn, index, intConst(-1), pos) + + loop = fn.newBasicBlock("rangeindex.loop") + emitJump(fn, loop) + fn.currentBlock = loop + + incr := &BinOp{ + Op: token.ADD, + X: emitLoad(fn, index), + Y: vOne, + } + incr.setType(tInt) + emitStore(fn, index, fn.emit(incr), pos) + + body := fn.newBasicBlock("rangeindex.body") + done = fn.newBasicBlock("rangeindex.done") + emitIf(fn, emitCompare(fn, token.LSS, incr, length, token.NoPos), body, done) + fn.currentBlock = body + + k = emitLoad(fn, index) + if tv != nil { + switch t := typeparams.CoreType(x.Type()).(type) { + case *types.Array: + instr := &Index{ + X: x, + Index: k, + } + instr.setType(t.Elem()) + instr.setPos(x.Pos()) + v = fn.emit(instr) + + case *types.Pointer: // *array + instr := &IndexAddr{ + X: x, + Index: k, + } + instr.setType(types.NewPointer(t.Elem().Underlying().(*types.Array).Elem())) + instr.setPos(x.Pos()) + v = emitLoad(fn, fn.emit(instr)) + + case *types.Slice: + instr := &IndexAddr{ + X: x, + Index: k, + } + instr.setType(types.NewPointer(t.Elem())) + instr.setPos(x.Pos()) + v = emitLoad(fn, fn.emit(instr)) + + default: + panic("rangeIndexed x:" + t.String()) + } + } + return +} + +// rangeIter emits to fn the header for a loop using +// Range/Next/Extract to iterate over map or string value x. +// tk and tv are the types of the key/value results k and v, or nil +// if the respective component is not wanted. +func (b *builder) rangeIter(fn *Function, x Value, tk, tv types.Type, pos token.Pos) (k, v Value, loop, done *BasicBlock) { + // + // it = range x + // loop: (target of continue) + // okv = next it (ok, key, value) + // ok = extract okv #0 + // if ok goto body else done + // body: + // k = extract okv #1 + // v = extract okv #2 + // ...body... + // jump loop + // done: (target of break) + // + + rng := &Range{X: x} + rng.setPos(pos) + rng.setType(tRangeIter) + it := fn.emit(rng) + + loop = fn.newBasicBlock("rangeiter.loop") + emitJump(fn, loop) + fn.currentBlock = loop + + var ak, av types.Type + isString := false + if m, ok := typeparams.CoreType(x.Type()).(*types.Map); ok { + ak, av = m.Key(), m.Elem() + } else { + isString = true + ak, av = tInt, tRune + } + if tk == nil { + ak = tInvalid + } + if tv == nil { + av = tInvalid + } + + okv := &Next{ + Iter: it, + IsString: isString, + } + okv.setType(types.NewTuple( + varOk, + newVar("k", ak), + newVar("v", av), + )) + fn.emit(okv) + + body := fn.newBasicBlock("rangeiter.body") + done = fn.newBasicBlock("rangeiter.done") + emitIf(fn, emitExtract(fn, okv, 0), body, done) + fn.currentBlock = body + + // The assignment may widen a map or string + // key/value to a variable's interface type + // (cases #1 and #2 of go.dev/issue/78110). + if tk != nil { + k = emitConv(fn, emitExtract(fn, okv, 1), tk) + } + if tv != nil { + v = emitConv(fn, emitExtract(fn, okv, 2), tv) + } + return +} + +// rangeChan emits to fn the header for a loop that receives from +// channel x until it fails. +// tk is the channel's element type, or nil if the k result is +// not wanted +// pos is the position of the '=' or ':=' token. +func (b *builder) rangeChan(fn *Function, x Value, tk types.Type, pos token.Pos) (k Value, loop, done *BasicBlock) { + // + // loop: (target of continue) + // ko = <-x (key, ok) + // ok = extract ko #1 + // if ok goto body else done + // body: + // k = extract ko #0 + // ...body... + // goto loop + // done: (target of break) + + loop = fn.newBasicBlock("rangechan.loop") + emitJump(fn, loop) + fn.currentBlock = loop + recv := &UnOp{ + Op: token.ARROW, + X: x, + CommaOk: true, + } + recv.setPos(pos) + recv.setType(types.NewTuple( + newVar("k", typeparams.CoreType(x.Type()).(*types.Chan).Elem()), + varOk, + )) + ko := fn.emit(recv) + body := fn.newBasicBlock("rangechan.body") + done = fn.newBasicBlock("rangechan.done") + emitIf(fn, emitExtract(fn, ko, 1), body, done) + fn.currentBlock = body + if tk != nil { + k = emitExtract(fn, ko, 0) + } + return +} + +// rangeInt emits to fn the header for a range loop with an integer operand. +// tk is the key value's type, or nil if the k result is not wanted. +// pos is the position of the "for" token. +func (b *builder) rangeInt(fn *Function, x Value, tk types.Type, pos token.Pos) (k Value, loop, done *BasicBlock) { + // + // iter = 0 + // if 0 < x goto body else done + // loop: (target of continue) + // iter++ + // if iter < x goto body else done + // body: + // k = x + // ...body... + // jump loop + // done: (target of break) + + if isUntyped(x.Type()) { + x = emitConv(fn, x, tInt) + } + + T := x.Type() + iter := emitLocal(fn, T, token.NoPos, "rangeint.iter") + // x may be unsigned. Avoid initializing x to -1. + + body := fn.newBasicBlock("rangeint.body") + done = fn.newBasicBlock("rangeint.done") + emitIf(fn, emitCompare(fn, token.LSS, zeroConst(T), x, token.NoPos), body, done) + + loop = fn.newBasicBlock("rangeint.loop") + fn.currentBlock = loop + + incr := &BinOp{ + Op: token.ADD, + X: emitLoad(fn, iter), + Y: emitConv(fn, vOne, T), + } + incr.setType(T) + emitStore(fn, iter, fn.emit(incr), pos) + emitIf(fn, emitCompare(fn, token.LSS, incr, x, token.NoPos), body, done) + fn.currentBlock = body + + if tk != nil { + // Integer types (int, uint8, etc.) are named and + // we know that k is assignable to x when tk != nil. + // This implies tk and T are identical so no conversion is needed. + k = emitLoad(fn, iter) + } + + return +} + +// rangeStmt emits to fn code for the range statement s, optionally +// labelled by label. +func (b *builder) rangeStmt(fn *Function, s *ast.RangeStmt, label *lblock) { + var tk, tv types.Type + if s.Key != nil && !isBlankIdent(s.Key) { + tk = fn.typeOf(s.Key) + } + if s.Value != nil && !isBlankIdent(s.Value) { + tv = fn.typeOf(s.Value) + } + + // create locals for s.Key and s.Value. + createVars := func() { + // Unlike a short variable declaration, a RangeStmt + // using := never redeclares an existing variable; it + // always creates a new one. + if tk != nil { + emitLocalVar(fn, identVar(fn, s.Key.(*ast.Ident))) + } + if tv != nil { + emitLocalVar(fn, identVar(fn, s.Value.(*ast.Ident))) + } + } + + afterGo122 := versions.AtLeast(fn.goversion, versions.Go1_22) + if s.Tok == token.DEFINE && !afterGo122 { + // pre-go1.22: If iteration variables are defined (:=), this + // occurs once outside the loop. + createVars() + } + + x := b.expr(fn, s.X) + + var k, v Value + var loop, done *BasicBlock + switch rt := typeparams.CoreType(x.Type()).(type) { + case *types.Slice, *types.Array, *types.Pointer: // *array + k, v, loop, done = b.rangeIndexed(fn, x, tv, s.For) + + case *types.Chan: + k, loop, done = b.rangeChan(fn, x, tk, s.For) + + case *types.Map: + k, v, loop, done = b.rangeIter(fn, x, tk, tv, s.For) + + case *types.Basic: + switch { + case rt.Info()&types.IsString != 0: + k, v, loop, done = b.rangeIter(fn, x, tk, tv, s.For) + + case rt.Info()&types.IsInteger != 0: + k, loop, done = b.rangeInt(fn, x, tk, s.For) + + default: + panic("Cannot range over basic type: " + rt.String()) + } + + case *types.Signature: + // Special case rewrite (fn.goversion >= go1.23): + // for x := range f { ... } + // into + // f(func(x T) bool { ... }) + b.rangeFunc(fn, x, s, label) + return + + default: + panic("Cannot range over: " + rt.String()) + } + + if s.Tok == token.DEFINE && afterGo122 { + // go1.22: If iteration variables are defined (:=), this occurs inside the loop. + createVars() + } + + // Evaluate both LHS expressions before we update either. + var kl, vl lvalue + if tk != nil { + kl = b.addr(fn, s.Key, false) // non-escaping + } + if tv != nil { + vl = b.addr(fn, s.Value, false) // non-escaping + } + if tk != nil { + kl.store(fn, k) + } + if tv != nil { + vl.store(fn, v) + } + + if label != nil { + label._break = done + label._continue = loop + } + + fn.targets = &targets{ + tail: fn.targets, + _break: done, + _continue: loop, + } + b.stmt(fn, s.Body) + fn.targets = fn.targets.tail + emitJump(fn, loop) // back-edge + fn.currentBlock = done +} + +// rangeFunc emits to fn code for the range-over-func rng.Body of the iterator +// function x, optionally labelled by label. It creates a new anonymous function +// yield for rng and builds the function. +func (b *builder) rangeFunc(fn *Function, x Value, rng *ast.RangeStmt, label *lblock) { + // Consider the SSA code for the outermost range-over-func in fn: + // + // func fn(...) (ret R) { + // ... + // for k, v = range x { + // ... + // } + // ... + // } + // + // The code emitted into fn will look something like this. + // + // loop: + // jump := READY + // y := make closure yield [ret, deferstack, jump, k, v] + // x(y) + // switch jump { + // [see resuming execution] + // } + // goto done + // done: + // ... + // + // where yield is a new synthetic yield function: + // + // func yield(_k tk, _v tv) bool + // free variables: [ret, stack, jump, k, v] + // { + // entry: + // if jump != READY then goto invalid else valid + // invalid: + // panic("iterator called when it is not in a ready state") + // valid: + // jump = BUSY + // k = _k + // v = _v + // ... + // cont: + // jump = READY + // return true + // } + // + // Yield state: + // + // Each range loop has an associated jump variable that records + // the state of the iterator. A yield function is initially + // in a READY (0) and callable state. If the yield function is called + // and is not in READY state, it panics. When it is called in a callable + // state, it becomes BUSY. When execution reaches the end of the body + // of the loop (or a continue statement targeting the loop is executed), + // the yield function returns true and resumes being in a READY state. + // After the iterator function x(y) returns, then if the yield function + // is in a READY state, the yield enters the DONE state. + // + // Each lowered control statement (break X, continue X, goto Z, or return) + // that exits the loop sets the variable to a unique positive EXIT value, + // before returning false from the yield function. + // + // If the yield function returns abruptly due to a panic or GoExit, + // it remains in a BUSY state. The generated code asserts that, after + // the iterator call x(y) returns normally, the jump variable state + // is DONE. + // + // Resuming execution: + // + // The code generated for the range statement checks the jump + // variable to determine how to resume execution. + // + // switch jump { + // case BUSY: panic("...") + // case DONE: goto done + // case READY: state = DONE; goto done + // case 123: ... // action for exit 123. + // case 456: ... // action for exit 456. + // ... + // } + // + // Forward goto statements within a yield are jumps to labels that + // have not yet been traversed in fn. They may be in the Body of the + // function. What we emit for these is: + // + // goto target + // target: + // ... + // + // We leave an unresolved exit in yield.exits to check at the end + // of building yield if it encountered target in the body. If it + // encountered target, no additional work is required. Otherwise, + // the yield emits a new early exit in the basic block for target. + // We expect that blockopt will fuse the early exit into the case + // block later. The unresolved exit is then added to yield.parent.exits. + + loop := fn.newBasicBlock("rangefunc.loop") + done := fn.newBasicBlock("rangefunc.done") + + // These are targets within y. + fn.targets = &targets{ + tail: fn.targets, + _break: done, + // _continue is within y. + } + if label != nil { + label._break = done + // _continue is within y + } + + emitJump(fn, loop) + fn.currentBlock = loop + + // loop: + // jump := READY + + anonIdx := len(fn.AnonFuncs) + + jump := newVar(fmt.Sprintf("jump$%d", anonIdx+1), tInt) + emitLocalVar(fn, jump) // zero value is READY + + xsig := typeparams.CoreType(x.Type()).(*types.Signature) + ysig := typeparams.CoreType(xsig.Params().At(0).Type()).(*types.Signature) + + /* synthetic yield function for body of range-over-func loop */ + y := &Function{ + name: fmt.Sprintf("%s$%d", fn.Name(), anonIdx+1), + Signature: ysig, + Synthetic: "range-over-func yield", + pos: rng.Range, + parent: fn, + anonIdx: int32(len(fn.AnonFuncs)), + Pkg: fn.Pkg, + Prog: fn.Prog, + syntax: rng, + info: fn.info, + goversion: fn.goversion, + build: (*builder).buildYieldFunc, + topLevelOrigin: nil, + recvtypeparams: fn.recvtypeparams, + recvtypeargs: fn.recvtypeargs, + typeparams: fn.typeparams, + typeargs: fn.typeargs, + subst: fn.subst, + jump: jump, + deferstack: fn.deferstack, + returnVars: fn.returnVars, // use the parent's return variables + uniq: fn.uniq, // start from parent's unique values + } + + // If the RangeStmt has a label, this is how it is passed to buildYieldFunc. + if label != nil { + y.lblocks = map[*types.Label]*lblock{label.label: nil} + } + fn.AnonFuncs = append(fn.AnonFuncs, y) + + // Build y immediately. It may: + // * cause fn's locals to escape, and + // * create new exit nodes in exits. + // (y is not marked 'built' until the end of the enclosing FuncDecl.) + unresolved := len(fn.exits) + y.build(b, y) + fn.uniq = y.uniq // resume after y's unique values + + // Emit the call of y. + // c := MakeClosure y + // x(c) + c := &MakeClosure{Fn: y} + c.setType(ysig) + for _, fv := range y.FreeVars { + c.Bindings = append(c.Bindings, fv.outer) + fv.outer = nil + } + fn.emit(c) + call := Call{ + Call: CallCommon{ + Value: x, + Args: []Value{c}, + pos: token.NoPos, + }, + } + call.setType(xsig.Results()) + fn.emit(&call) + + exits := fn.exits[unresolved:] + b.buildYieldResume(fn, jump, exits, done) + + emitJump(fn, done) + fn.currentBlock = done + // pop the stack for the range-over-func + fn.targets = fn.targets.tail +} + +// buildYieldResume emits to fn code for how to resume execution once a call to +// the iterator function over the yield function returns x(y). It does this by building +// a switch over the value of jump for when it is READY, BUSY, or EXIT(id). +func (b *builder) buildYieldResume(fn *Function, jump *types.Var, exits []*exit, done *BasicBlock) { + // v := *jump + // switch v { + // case BUSY: panic("...") + // case READY: jump = DONE; goto done + // case EXIT(a): ... + // case EXIT(b): ... + // ... + // } + v := emitLoad(fn, fn.lookup(jump, false)) + + // case BUSY: panic("...") + isbusy := fn.newBasicBlock("rangefunc.resume.busy") + ifready := fn.newBasicBlock("rangefunc.resume.ready.check") + emitIf(fn, emitCompare(fn, token.EQL, v, jBusy, token.NoPos), isbusy, ifready) + fn.currentBlock = isbusy + fn.emit(&Panic{ + X: emitConv(fn, stringConst("iterator call did not preserve panic"), tEface), + }) + fn.currentBlock = ifready + + // case READY: jump = DONE; goto done + isready := fn.newBasicBlock("rangefunc.resume.ready") + ifexit := fn.newBasicBlock("rangefunc.resume.exits") + emitIf(fn, emitCompare(fn, token.EQL, v, jReady, token.NoPos), isready, ifexit) + fn.currentBlock = isready + storeVar(fn, jump, jDone, token.NoPos) + emitJump(fn, done) + fn.currentBlock = ifexit + + for _, e := range exits { + id := intConst(e.id) + + // case EXIT(id): { /* do e */ } + cond := emitCompare(fn, token.EQL, v, id, e.pos) + matchb := fn.newBasicBlock("rangefunc.resume.match") + cndb := fn.newBasicBlock("rangefunc.resume.cnd") + emitIf(fn, cond, matchb, cndb) + fn.currentBlock = matchb + + // Cases to fill in the { /* do e */ } bit. + switch { + case e.label != nil: // forward goto? + // case EXIT(id): goto lb // label + lb := fn.lblockOf(e.label) + // Do not mark lb as resolved. + // If fn does not contain label, lb remains unresolved and + // fn must itself be a range-over-func function. lb will be: + // lb: + // fn.jump = id + // return false + emitJump(fn, lb._goto) + + case e.to != fn: // e jumps to an ancestor of fn? + // case EXIT(id): { fn.jump = id; return false } + // fn is a range-over-func function. + storeVar(fn, fn.jump, id, token.NoPos) + fn.emit(&Return{Results: []Value{vFalse}, pos: e.pos}) + + case e.block == nil && e.label == nil: // return from fn? + // case EXIT(id): { return ... } + fn.emit(new(RunDefers)) + results := make([]Value, len(fn.results)) + for i, r := range fn.results { + results[i] = emitLoad(fn, r) + } + fn.emit(&Return{Results: results, pos: e.pos}) + + case e.block != nil: + // case EXIT(id): goto block + emitJump(fn, e.block) + + default: + panic("unreachable") + } + fn.currentBlock = cndb + } +} + +// stmt lowers statement s to SSA form, emitting code to fn. +func (b *builder) stmt(fn *Function, _s ast.Stmt) { + // The label of the current statement. If non-nil, its _goto + // target is always set; its _break and _continue are set only + // within the body of switch/typeswitch/select/for/range. + // It is effectively an additional default-nil parameter of stmt(). + var label *lblock +start: + switch s := _s.(type) { + case *ast.EmptyStmt: + // ignore. (Usually removed by gofmt.) + + case *ast.DeclStmt: // Con, Var or Typ + d := s.Decl.(*ast.GenDecl) + if d.Tok == token.VAR { + for _, spec := range d.Specs { + if vs, ok := spec.(*ast.ValueSpec); ok { + b.localValueSpec(fn, vs) + } + } + } + + case *ast.LabeledStmt: + if s.Label.Name == "_" { + // Blank labels can't be the target of a goto, break, + // or continue statement, so we don't need a new block. + _s = s.Stmt + goto start + } + label = fn.lblockOf(fn.label(s.Label)) + label.resolved = true + emitJump(fn, label._goto) + fn.currentBlock = label._goto + _s = s.Stmt + goto start // effectively: tailcall stmt(fn, s.Stmt, label) + + case *ast.ExprStmt: + b.expr(fn, s.X) + + case *ast.SendStmt: + chtyp := typeparams.CoreType(fn.typeOf(s.Chan)).(*types.Chan) + fn.emit(&Send{ + Chan: b.expr(fn, s.Chan), + X: emitConv(fn, b.expr(fn, s.Value), chtyp.Elem()), + pos: s.Arrow, + }) + + case *ast.IncDecStmt: + op := token.ADD + if s.Tok == token.DEC { + op = token.SUB + } + loc := b.addr(fn, s.X, false) + b.assignOp(fn, loc, NewConst(constant.MakeInt64(1), loc.typ()), op, s.Pos()) + + case *ast.AssignStmt: + switch s.Tok { + case token.ASSIGN, token.DEFINE: + b.assignStmt(fn, s.Lhs, s.Rhs, s.Tok == token.DEFINE) + + default: // +=, etc. + op := s.Tok + token.ADD - token.ADD_ASSIGN + b.assignOp(fn, b.addr(fn, s.Lhs[0], false), b.expr(fn, s.Rhs[0]), op, s.Pos()) + } + + case *ast.GoStmt: + // The "intrinsics" new/make/len/cap are forbidden here. + // panic is treated like an ordinary function call. + v := Go{pos: s.Go} + b.setCall(fn, s.Call, &v.Call) + fn.emit(&v) + + case *ast.DeferStmt: + // The "intrinsics" new/make/len/cap are forbidden here. + // panic is treated like an ordinary function call. + deferstack := emitLoad(fn, fn.lookup(fn.deferstack, false)) + v := Defer{pos: s.Defer, DeferStack: deferstack} + b.setCall(fn, s.Call, &v.Call) + fn.emit(&v) + + // A deferred call can cause recovery from panic, + // and control resumes at the Recover block. + createRecoverBlock(fn.source) + + case *ast.ReturnStmt: + b.returnStmt(fn, s) + + case *ast.BranchStmt: + b.branchStmt(fn, s) + + case *ast.BlockStmt: + b.stmtList(fn, s.List) + + case *ast.IfStmt: + if s.Init != nil { + b.stmt(fn, s.Init) + } + then := fn.newBasicBlock("if.then") + done := fn.newBasicBlock("if.done") + els := done + if s.Else != nil { + els = fn.newBasicBlock("if.else") + } + b.cond(fn, s.Cond, then, els) + fn.currentBlock = then + b.stmt(fn, s.Body) + emitJump(fn, done) + + if s.Else != nil { + fn.currentBlock = els + b.stmt(fn, s.Else) + emitJump(fn, done) + } + + fn.currentBlock = done + + case *ast.SwitchStmt: + b.switchStmt(fn, s, label) + + case *ast.TypeSwitchStmt: + b.typeSwitchStmt(fn, s, label) + + case *ast.SelectStmt: + b.selectStmt(fn, s, label) + + case *ast.ForStmt: + b.forStmt(fn, s, label) + + case *ast.RangeStmt: + b.rangeStmt(fn, s, label) + + default: + panic(fmt.Sprintf("unexpected statement kind: %T", s)) + } +} + +func (b *builder) branchStmt(fn *Function, s *ast.BranchStmt) { + var block *BasicBlock + if s.Label == nil { + block = targetedBlock(fn, s.Tok) + } else { + target := fn.label(s.Label) + block = labelledBlock(fn, target, s.Tok) + if block == nil { // forward goto + lb := fn.lblockOf(target) + block = lb._goto // jump to lb._goto + if fn.jump != nil { + // fn is a range-over-func and the goto may exit fn. + // Create an exit and resolve it at the end of + // builder.buildYieldFunc. + labelExit(fn, target, s.Pos()) + } + } + } + to := block.parent + + if to == fn { + emitJump(fn, block) + } else { // break outside of fn. + // fn must be a range-over-func + e := blockExit(fn, block, s.Pos()) + storeVar(fn, fn.jump, intConst(e.id), e.pos) + fn.emit(&Return{Results: []Value{vFalse}, pos: e.pos}) + } + fn.currentBlock = fn.newBasicBlock("unreachable") +} + +func (b *builder) returnStmt(fn *Function, s *ast.ReturnStmt) { + var results []Value + + sig := fn.source.Signature // signature of the enclosing source function + + // Convert return operands to result type. + if len(s.Results) == 1 && sig.Results().Len() > 1 { + // Return of one expression in a multi-valued function. + tuple := b.exprN(fn, s.Results[0]) + ttuple := tuple.Type().(*types.Tuple) + for i, n := 0, ttuple.Len(); i < n; i++ { + results = append(results, + emitConv(fn, emitExtract(fn, tuple, i), + sig.Results().At(i).Type())) + } + } else { + // 1:1 return, or no-arg return in non-void function. + for i, r := range s.Results { + v := emitConv(fn, b.expr(fn, r), sig.Results().At(i).Type()) + results = append(results, v) + } + } + + // Store the results. + for i, r := range results { + var result Value // fn.source.result[i] conceptually + if fn == fn.source { + result = fn.results[i] + } else { // lookup needed? + result = fn.lookup(fn.returnVars[i], false) + } + emitStore(fn, result, r, s.Return) + } + + if fn.jump != nil { + // Return from body of a range-over-func. + // The return statement is syntactically within the loop, + // but the generated code is in the 'switch jump {...}' after it. + e := returnExit(fn, s.Pos()) + storeVar(fn, fn.jump, intConst(e.id), e.pos) + fn.emit(&Return{Results: []Value{vFalse}, pos: e.pos}) + fn.currentBlock = fn.newBasicBlock("unreachable") + return + } + + // Run function calls deferred in this + // function when explicitly returning from it. + fn.emit(new(RunDefers)) + // Reload (potentially) named result variables to form the result tuple. + results = results[:0] + for _, nr := range fn.results { + results = append(results, emitLoad(fn, nr)) + } + fn.emit(&Return{Results: results, pos: s.Return}) + fn.currentBlock = fn.newBasicBlock("unreachable") +} + +// A buildFunc is a strategy for building the SSA body for a function. +type buildFunc = func(*builder, *Function) + +// iterate causes all created but unbuilt functions to be built. As +// this may create new methods, the process is iterated until it +// converges. +// +// Waits for any dependencies to finish building. +func (b *builder) iterate() { + for ; b.finished < len(b.fns); b.finished++ { + fn := b.fns[b.finished] + b.buildFunction(fn) + } + + b.buildshared.markDone() + b.buildshared.wait() +} + +// buildFunction builds SSA code for the body of function fn. Idempotent. +func (b *builder) buildFunction(fn *Function) { + if fn.build != nil { + assert(fn.parent == nil, "anonymous functions should not be built by buildFunction()") + + if fn.Prog.mode&LogSource != 0 { + defer logStack("build %s @ %s", fn, fn.Prog.Fset.Position(fn.pos))() + } + fn.build(b, fn) + fn.done() + } +} + +// buildParamsOnly builds fn.Params from fn.Signature, but does not build fn.Body. +func (b *builder) buildParamsOnly(fn *Function) { + // For external (C, asm) functions or functions loaded from + // export data, we must set fn.Params even though there is no + // body code to reference them. + if recv := fn.Signature.Recv(); recv != nil { + fn.addParamVar(recv) + } + params := fn.Signature.Params() + for i, n := 0, params.Len(); i < n; i++ { + fn.addParamVar(params.At(i)) + } + + // clear out other function state (keep consistent with finishBody) + fn.subst = nil + if !fn.isGenericOrigin() { + fn.info = nil + } +} + +// buildFromSyntax builds fn.Body from fn.syntax, which must be non-nil. +func (b *builder) buildFromSyntax(fn *Function) { + var ( + recvField *ast.FieldList + body *ast.BlockStmt + functype *ast.FuncType + ) + switch syntax := fn.syntax.(type) { + case *ast.FuncDecl: + functype = syntax.Type + recvField = syntax.Recv + body = syntax.Body + if body == nil { + b.buildParamsOnly(fn) // no body (non-Go function) + return + } + case *ast.FuncLit: + functype = syntax.Type + body = syntax.Body + case nil: + panic("no syntax") + default: + panic(syntax) // unexpected syntax + } + fn.source = fn + fn.startBody() + fn.createSyntacticParams(recvField, functype) + fn.createDeferStack() + b.stmt(fn, body) + if cb := fn.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb == fn.Recover || cb.Preds != nil) { + // Control fell off the end of the function's body block. + // + // Block optimizations eliminate the current block, if + // unreachable. It is a builder invariant that + // if this no-arg return is ill-typed for + // fn.Signature.Results, this block must be + // unreachable. The sanity checker checks this. + fn.emit(new(RunDefers)) + fn.emit(new(Return)) + } + fn.finishBody() +} + +// buildYieldFunc builds the body of the yield function created +// from a range-over-func *ast.RangeStmt. +func (b *builder) buildYieldFunc(fn *Function) { + // See builder.rangeFunc for detailed documentation on how fn is set up. + // + // In pseudo-Go this roughly builds: + // func yield(_k tk, _v tv) bool { + // if jump != READY { panic("yield function called after range loop exit") } + // jump = BUSY + // k, v = _k, _v // assign the iterator variable (if needed) + // ... // rng.Body + // continue: + // jump = READY + // return true + // } + s := fn.syntax.(*ast.RangeStmt) + fn.source = fn.parent.source + fn.startBody() + params := fn.Signature.Params() + for v := range params.Variables() { + fn.addParamVar(v) + } + + // Initial targets + ycont := fn.newBasicBlock("yield-continue") + // lblocks is either {} or is {label: nil} where label is the label of syntax. + for label := range fn.lblocks { + fn.lblocks[label] = &lblock{ + label: label, + resolved: true, + _continue: ycont, + // `goto label` searches the parent lblock, and + // `break label` targets fn.parent.targets._break. + } + } + fn.targets = &targets{ + tail: fn.targets, + _continue: ycont, + // `break` statement targets fn.parent.targets._break. + } + + // continue: + // jump = READY + // return true + saved := fn.currentBlock + fn.currentBlock = ycont + storeVar(fn, fn.jump, jReady, s.Body.Rbrace) + // A yield function's own deferstack is always empty, so rundefers is not needed. + fn.emit(&Return{Results: []Value{vTrue}, pos: token.NoPos}) + + // Emit header: + // + // if jump != READY { panic("yield iterator accessed after exit") } + // jump = BUSY + // k, v = _k, _v + fn.currentBlock = saved + yloop := fn.newBasicBlock("yield-loop") + invalid := fn.newBasicBlock("yield-invalid") + + jumpVal := emitLoad(fn, fn.lookup(fn.jump, true)) + emitIf(fn, emitCompare(fn, token.EQL, jumpVal, jReady, token.NoPos), yloop, invalid) + fn.currentBlock = invalid + fn.emit(&Panic{ + X: emitConv(fn, stringConst("yield function called after range loop exit"), tEface), + }) + + fn.currentBlock = yloop + storeVar(fn, fn.jump, jBusy, s.Body.Rbrace) + + // Initialize k and v from params. + var tk, tv types.Type + if s.Key != nil && !isBlankIdent(s.Key) { + tk = fn.typeOf(s.Key) // fn.parent.typeOf is identical + } + if s.Value != nil && !isBlankIdent(s.Value) { + tv = fn.typeOf(s.Value) + } + if s.Tok == token.DEFINE { + if tk != nil { + emitLocalVar(fn, identVar(fn, s.Key.(*ast.Ident))) + } + if tv != nil { + emitLocalVar(fn, identVar(fn, s.Value.(*ast.Ident))) + } + } + var k, v Value + if len(fn.Params) > 0 { + k = fn.Params[0] + } + if len(fn.Params) > 1 { + v = fn.Params[1] + } + var kl, vl lvalue + if tk != nil { + kl = b.addr(fn, s.Key, false) // non-escaping + } + if tv != nil { + vl = b.addr(fn, s.Value, false) // non-escaping + } + if tk != nil { + kl.store(fn, k) + } + if tv != nil { + vl.store(fn, v) + } + + // Build the body of the range loop. + b.stmt(fn, s.Body) + if cb := fn.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb == fn.Recover || cb.Preds != nil) { + // Control fell off the end of the function's body block. + // Block optimizations eliminate the current block, if + // unreachable. + emitJump(fn, ycont) + } + // pop the stack for the yield function + fn.targets = fn.targets.tail + + // Clean up exits and promote any unresolved exits to fn.parent. + for _, e := range fn.exits { + if e.label != nil { + lb := fn.lblocks[e.label] + if lb.resolved { + // label was resolved. Do not turn lb into an exit. + // e does not need to be handled by the parent. + continue + } + + // _goto becomes an exit. + // _goto: + // jump = id + // return false + fn.currentBlock = lb._goto + id := intConst(e.id) + storeVar(fn, fn.jump, id, e.pos) + fn.emit(&Return{Results: []Value{vFalse}, pos: e.pos}) + } + + if e.to != fn { // e needs to be handled by the parent too. + fn.parent.exits = append(fn.parent.exits, e) + } + } + + fn.finishBody() +} + +// addMakeInterfaceType records non-interface type t as the type of +// the operand a MakeInterface operation, for [Program.RuntimeTypes]. +// +// Acquires prog.makeInterfaceTypesMu. +func addMakeInterfaceType(prog *Program, t types.Type) { + prog.makeInterfaceTypesMu.Lock() + defer prog.makeInterfaceTypesMu.Unlock() + if prog.makeInterfaceTypes == nil { + prog.makeInterfaceTypes = make(map[types.Type]unit) + } + prog.makeInterfaceTypes[t] = unit{} +} + +// Build calls Package.Build for each package in prog. +// Building occurs in parallel unless the BuildSerially mode flag was set. +// +// Build is intended for whole-program analysis; a typical compiler +// need only build a single package. +// +// Build is idempotent and thread-safe. +func (prog *Program) Build() { + var wg sync.WaitGroup + for _, p := range prog.packages { + if prog.mode&BuildSerially != 0 { + p.Build() + } else { + wg.Add(1) + cpuLimit <- unit{} // acquire a token + go func(p *Package) { + p.Build() + wg.Done() + <-cpuLimit // release a token + }(p) + } + } + wg.Wait() +} + +// cpuLimit is a counting semaphore to limit CPU parallelism. +var cpuLimit = make(chan unit, runtime.GOMAXPROCS(0)) + +// Build builds SSA code for all functions and vars in package p. +// +// CreatePackage must have been called for all of p's direct imports +// (and hence its direct imports must have been error-free). It is not +// necessary to call CreatePackage for indirect dependencies. +// Functions will be created for all necessary methods in those +// packages on demand. +// +// Build is idempotent and thread-safe. +func (p *Package) Build() { p.buildOnce.Do(p.build) } + +func (p *Package) build() { + if p.info == nil { + return // synthetic package, e.g. "testmain" + } + if p.Prog.mode&LogSource != 0 { + defer logStack("build %s", p)() + } + + b := builder{fns: p.created} + b.iterate() + + // We no longer need transient information: ASTs or go/types deductions. + p.info = nil + p.created = nil + p.files = nil + p.initVersion = nil + + if p.Prog.mode&SanityCheckFunctions != 0 { + sanityCheckPackage(p) + } +} + +// buildPackageInit builds fn.Body for the synthetic package initializer. +func (b *builder) buildPackageInit(fn *Function) { + p := fn.Pkg + fn.startBody() + + var done *BasicBlock + + if p.Prog.mode&BareInits == 0 { + // Make init() skip if package is already initialized. + initguard := p.Var("init$guard") + doinit := fn.newBasicBlock("init.start") + done = fn.newBasicBlock("init.done") + emitIf(fn, emitLoad(fn, initguard), done, doinit) + fn.currentBlock = doinit + emitStore(fn, initguard, vTrue, token.NoPos) + + // Call the init() function of each package we import. + for _, pkg := range p.Pkg.Imports() { + prereq := p.Prog.packages[pkg] + if prereq == nil { + panic(fmt.Sprintf("Package(%q).Build(): unsatisfied import: Program.CreatePackage(%q) was not called", p.Pkg.Path(), pkg.Path())) + } + var v Call + v.Call.Value = prereq.init + v.Call.pos = fn.pos + v.setType(types.NewTuple()) + fn.emit(&v) + } + } + + // Initialize package-level vars in correct order. + if len(p.info.InitOrder) > 0 && len(p.files) == 0 { + panic("no source files provided for package. cannot initialize globals") + } + + for _, varinit := range p.info.InitOrder { + if fn.Prog.mode&LogSource != 0 { + fmt.Fprintf(os.Stderr, "build global initializer %v @ %s\n", + varinit.Lhs, p.Prog.Fset.Position(varinit.Rhs.Pos())) + } + // Initializers for global vars are evaluated in dependency + // order, but may come from arbitrary files of the package + // with different versions, so we transiently update + // fn.goversion for each one. (Since init is a synthetic + // function it has no syntax of its own that needs a version.) + fn.goversion = p.initVersion[varinit.Rhs] + if len(varinit.Lhs) == 1 { + // 1:1 initialization: var x, y = a(), b() + var lval lvalue + if v := varinit.Lhs[0]; v.Name() != "_" { + lval = &address{addr: p.objects[v].(*Global), pos: v.Pos()} + } else { + lval = blank{} + } + b.assign(fn, lval, varinit.Rhs, nil) + } else { + // n:1 initialization: var x, y := f() + tuple := b.exprN(fn, varinit.Rhs) + for i, v := range varinit.Lhs { + if v.Name() == "_" { + continue + } + emitStore(fn, p.objects[v].(*Global), emitExtract(fn, tuple, i), v.Pos()) + } + } + } + + // The rest of the init function is synthetic: + // no syntax, info, goversion. + fn.info = nil + fn.goversion = "" + + // Call all of the declared init() functions in source order. + for _, file := range p.files { + for _, decl := range file.Decls { + if decl, ok := decl.(*ast.FuncDecl); ok { + id := decl.Name + if !isBlankIdent(id) && id.Name == "init" && decl.Recv == nil { + declaredInit := p.objects[p.info.Defs[id]].(*Function) + var v Call + v.Call.Value = declaredInit + v.setType(types.NewTuple()) + p.init.emit(&v) + } + } + } + } + + // Finish up init(). + if p.Prog.mode&BareInits == 0 { + emitJump(fn, done) + fn.currentBlock = done + } + fn.emit(new(Return)) + fn.finishBody() +} diff --git a/vendor/golang.org/x/tools/go/ssa/const.go b/vendor/golang.org/x/tools/go/ssa/const.go new file mode 100644 index 0000000..73a8213 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/const.go @@ -0,0 +1,195 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file defines the Const SSA value type. + +import ( + "fmt" + "go/constant" + "go/token" + "go/types" + "strconv" + + "golang.org/x/tools/internal/typeparams" + "golang.org/x/tools/internal/typesinternal" +) + +// NewConst returns a new constant of the specified value and type. +// val must be valid according to the specification of Const.Value. +func NewConst(val constant.Value, typ types.Type) *Const { + if val == nil { + switch soleTypeKind(typ) { + case types.IsBoolean: + val = constant.MakeBool(false) + case types.IsInteger: + val = constant.MakeInt64(0) + case types.IsString: + val = constant.MakeString("") + } + } + return &Const{typ, val} +} + +// soleTypeKind returns a BasicInfo for which constant.Value can +// represent all zero values for the types in the type set. +// +// types.IsBoolean for false is a representative. +// types.IsInteger for 0 +// types.IsString for "" +// 0 otherwise. +func soleTypeKind(typ types.Type) types.BasicInfo { + // State records the set of possible zero values (false, 0, ""). + // Candidates (perhaps all) are eliminated during the type-set + // iteration, which executes at least once. + state := types.IsBoolean | types.IsInteger | types.IsString + underIs(typ, func(ut types.Type) bool { + var c types.BasicInfo + if t, ok := ut.(*types.Basic); ok { + c = t.Info() + } + if c&types.IsNumeric != 0 { // int/float/complex + c = types.IsInteger + } + state = state & c + return state != 0 + }) + return state +} + +// intConst returns an 'int' constant that evaluates to i. +// (i is an int64 in case the host is narrower than the target.) +func intConst(i int64) *Const { + return NewConst(constant.MakeInt64(i), tInt) +} + +// stringConst returns a 'string' constant that evaluates to s. +func stringConst(s string) *Const { + return NewConst(constant.MakeString(s), tString) +} + +// zeroConst returns a new "zero" constant of the specified type. +func zeroConst(t types.Type) *Const { + return NewConst(nil, t) +} + +func (c *Const) RelString(from *types.Package) string { + var s string + if c.Value == nil { + s, _ = typesinternal.ZeroString(c.typ, types.RelativeTo(from)) + } else if c.Value.Kind() == constant.String { + s = constant.StringVal(c.Value) + const max = 20 + // TODO(adonovan): don't cut a rune in half. + if len(s) > max { + s = s[:max-3] + "..." // abbreviate + } + s = strconv.Quote(s) + } else { + s = c.Value.String() + } + return s + ":" + relType(c.Type(), from) +} + +func (c *Const) Name() string { + return c.RelString(nil) +} + +func (c *Const) String() string { + return c.Name() +} + +func (c *Const) Type() types.Type { + return c.typ +} + +func (c *Const) Referrers() *[]Instruction { + return nil +} + +func (c *Const) Parent() *Function { return nil } + +func (c *Const) Pos() token.Pos { + return token.NoPos +} + +// IsNil returns true if this constant is a nil value of +// a nillable reference type (pointer, slice, channel, map, or function), +// a basic interface type, or +// a type parameter all of whose possible instantiations are themselves nillable. +func (c *Const) IsNil() bool { + return c.Value == nil && nillable(c.typ) +} + +// nillable reports whether *new(T) == nil is legal for type T. +func nillable(t types.Type) bool { + if typeparams.IsTypeParam(t) { + return underIs(t, func(u types.Type) bool { + // empty type set (u==nil) => any underlying types => not nillable + return u != nil && nillable(u) + }) + } + switch t := t.Underlying().(type) { + case *types.Basic: + return t.Kind() == types.UnsafePointer + case *types.Pointer, *types.Slice, *types.Chan, *types.Map, *types.Signature: + return true + case *types.Interface: + return true // basic interface. + default: + return false + } +} + +// TODO(adonovan): move everything below into golang.org/x/tools/go/ssa/interp. + +// Int64 returns the numeric value of this constant truncated to fit +// a signed 64-bit integer. +func (c *Const) Int64() int64 { + switch x := constant.ToInt(c.Value); x.Kind() { + case constant.Int: + if i, ok := constant.Int64Val(x); ok { + return i + } + return 0 + case constant.Float: + f, _ := constant.Float64Val(x) + return int64(f) + } + panic(fmt.Sprintf("unexpected constant value: %T", c.Value)) +} + +// Uint64 returns the numeric value of this constant truncated to fit +// an unsigned 64-bit integer. +func (c *Const) Uint64() uint64 { + switch x := constant.ToInt(c.Value); x.Kind() { + case constant.Int: + if u, ok := constant.Uint64Val(x); ok { + return u + } + return 0 + case constant.Float: + f, _ := constant.Float64Val(x) + return uint64(f) + } + panic(fmt.Sprintf("unexpected constant value: %T", c.Value)) +} + +// Float64 returns the numeric value of this constant truncated to fit +// a float64. +func (c *Const) Float64() float64 { + x := constant.ToFloat(c.Value) // (c.Value == nil) => x.Kind() == Unknown + f, _ := constant.Float64Val(x) + return f +} + +// Complex128 returns the complex value of this constant truncated to +// fit a complex128. +func (c *Const) Complex128() complex128 { + x := constant.ToComplex(c.Value) // (c.Value == nil) => x.Kind() == Unknown + re, _ := constant.Float64Val(constant.Real(x)) + im, _ := constant.Float64Val(constant.Imag(x)) + return complex(re, im) +} diff --git a/vendor/golang.org/x/tools/go/ssa/create.go b/vendor/golang.org/x/tools/go/ssa/create.go new file mode 100644 index 0000000..3d20e55 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/create.go @@ -0,0 +1,318 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file implements the CREATE phase of SSA construction. +// See builder.go for explanation. + +import ( + "fmt" + "go/ast" + "go/token" + "go/types" + "os" + "sync" + + "golang.org/x/tools/internal/versions" +) + +// NewProgram returns a new SSA Program. +// +// mode controls diagnostics and checking during SSA construction. +// +// To construct an SSA program: +// +// - Call NewProgram to create an empty Program. +// - Call CreatePackage providing typed syntax for each package +// you want to build, and call it with types but not +// syntax for each of those package's direct dependencies. +// - Call [Package.Build] on each syntax package you wish to build, +// or [Program.Build] to build all of them. +// +// See the Example tests for simple examples. +func NewProgram(fset *token.FileSet, mode BuilderMode) *Program { + return &Program{ + Fset: fset, + imported: make(map[string]*Package), + packages: make(map[*types.Package]*Package), + mode: mode, + canon: newCanonizer(), + ctxt: types.NewContext(), + } +} + +// memberFromObject populates package pkg with a member for the +// typechecker object obj. +// +// For objects from Go source code, syntax is the associated syntax +// tree (for funcs and vars only) and goversion defines the +// appropriate interpretation; they will be used during the build +// phase. +func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node, goversion string) { + name := obj.Name() + switch obj := obj.(type) { + case *types.Builtin: + if pkg.Pkg != types.Unsafe { + panic("unexpected builtin object: " + obj.String()) + } + + case *types.TypeName: + if name != "_" { + pkg.Members[name] = &Type{ + object: obj, + pkg: pkg, + } + } + + case *types.Const: + c := &NamedConst{ + object: obj, + Value: NewConst(obj.Val(), obj.Type()), + pkg: pkg, + } + pkg.objects[obj] = c + if name != "_" { + pkg.Members[name] = c + } + + case *types.Var: + g := &Global{ + Pkg: pkg, + name: name, + object: obj, + typ: types.NewPointer(obj.Type()), // address + pos: obj.Pos(), + } + pkg.objects[obj] = g + if name != "_" { + pkg.Members[name] = g + } + + case *types.Func: + sig := obj.Type().(*types.Signature) + if sig.Recv() == nil && name == "init" { + pkg.ninit++ + name = fmt.Sprintf("init#%d", pkg.ninit) + } + fn := createFunction(pkg.Prog, obj, name, syntax, pkg.info, goversion) + fn.Pkg = pkg + pkg.created = append(pkg.created, fn) + pkg.objects[obj] = fn + if name != "_" && sig.Recv() == nil { + pkg.Members[name] = fn // package-level function + } + + default: // (incl. *types.Package) + panic("unexpected Object type: " + obj.String()) + } +} + +// createFunction creates a function or method. It supports both +// CreatePackage (with or without syntax) and the on-demand creation +// of methods in non-created packages based on their types.Func. +func createFunction(prog *Program, obj *types.Func, name string, syntax ast.Node, info *types.Info, goversion string) *Function { + sig := obj.Type().(*types.Signature) + + /* declared function/method (from syntax or export data) */ + fn := &Function{ + name: name, + object: obj, + Signature: sig, + build: (*builder).buildFromSyntax, + syntax: syntax, + info: info, + goversion: goversion, + pos: obj.Pos(), + Pkg: nil, // may be set by caller + Prog: prog, + recvtypeparams: sig.RecvTypeParams(), + typeparams: sig.TypeParams(), + } + if fn.syntax == nil { + fn.Synthetic = "from type information" + fn.build = (*builder).buildParamsOnly + } + if fn.hasTypeParams() { + fn.generic = new(generic) + } + return fn +} + +// membersFromDecl populates package pkg with members for each +// typechecker object (var, func, const or type) associated with the +// specified decl. +func membersFromDecl(pkg *Package, decl ast.Decl, goversion string) { + switch decl := decl.(type) { + case *ast.GenDecl: // import, const, type or var + switch decl.Tok { + case token.CONST: + for _, spec := range decl.Specs { + for _, id := range spec.(*ast.ValueSpec).Names { + memberFromObject(pkg, pkg.info.Defs[id], nil, "") + } + } + + case token.VAR: + for _, spec := range decl.Specs { + for _, rhs := range spec.(*ast.ValueSpec).Values { + pkg.initVersion[rhs] = goversion + } + for _, id := range spec.(*ast.ValueSpec).Names { + memberFromObject(pkg, pkg.info.Defs[id], spec, goversion) + } + } + + case token.TYPE: + for _, spec := range decl.Specs { + id := spec.(*ast.TypeSpec).Name + memberFromObject(pkg, pkg.info.Defs[id], nil, "") + } + } + + case *ast.FuncDecl: + id := decl.Name + memberFromObject(pkg, pkg.info.Defs[id], decl, goversion) + } +} + +// CreatePackage creates and returns an SSA Package from the +// specified type-checked, error-free file ASTs, and populates its +// Members mapping. +// +// importable determines whether this package should be returned by a +// subsequent call to ImportedPackage(pkg.Path()). +// +// The real work of building SSA form for each function is not done +// until a subsequent call to Package.Build. +func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *types.Info, importable bool) *Package { + if pkg == nil { + panic("nil pkg") // otherwise pkg.Scope below returns types.Universe! + } + p := &Package{ + Prog: prog, + Members: make(map[string]Member), + objects: make(map[types.Object]Member), + Pkg: pkg, + syntax: info != nil, + // transient values (cleared after Package.Build) + info: info, + files: files, + initVersion: make(map[ast.Expr]string), + } + + /* synthesized package initializer */ + p.init = &Function{ + name: "init", + Signature: new(types.Signature), + Synthetic: "package initializer", + Pkg: p, + Prog: prog, + build: (*builder).buildPackageInit, + info: p.info, + goversion: "", // See Package.build for details. + } + p.Members[p.init.name] = p.init + p.created = append(p.created, p.init) + + // Allocate all package members: vars, funcs, consts and types. + if len(files) > 0 { + // Go source package. + for _, file := range files { + goversion := versions.Lang(versions.FileVersion(p.info, file)) + for _, decl := range file.Decls { + membersFromDecl(p, decl, goversion) + } + } + } else { + // GC-compiled binary package (or "unsafe") + // No code. + // No position information. + scope := p.Pkg.Scope() + for _, name := range scope.Names() { + obj := scope.Lookup(name) + memberFromObject(p, obj, nil, "") + if obj, ok := obj.(*types.TypeName); ok { + // No Unalias: aliases should not duplicate methods. + if named, ok := obj.Type().(*types.Named); ok { + for i, n := 0, named.NumMethods(); i < n; i++ { + memberFromObject(p, named.Method(i), nil, "") + } + } + } + } + } + + if prog.mode&BareInits == 0 { + // Add initializer guard variable. + initguard := &Global{ + Pkg: p, + name: "init$guard", + typ: types.NewPointer(tBool), + } + p.Members[initguard.Name()] = initguard + } + + if prog.mode&GlobalDebug != 0 { + p.SetDebugMode(true) + } + + if prog.mode&PrintPackages != 0 { + printMu.Lock() + p.WriteTo(os.Stdout) + printMu.Unlock() + } + + if importable { + prog.imported[p.Pkg.Path()] = p + } + prog.packages[p.Pkg] = p + + return p +} + +// printMu serializes printing of Packages/Functions to stdout. +var printMu sync.Mutex + +// AllPackages returns a new slice containing all packages created by +// prog.CreatePackage in unspecified order. +func (prog *Program) AllPackages() []*Package { + pkgs := make([]*Package, 0, len(prog.packages)) + for _, pkg := range prog.packages { + pkgs = append(pkgs, pkg) + } + return pkgs +} + +// ImportedPackage returns the importable Package whose PkgPath +// is path, or nil if no such Package has been created. +// +// A parameter to CreatePackage determines whether a package should be +// considered importable. For example, no import declaration can resolve +// to the ad-hoc main package created by 'go build foo.go'. +// +// TODO(adonovan): rethink this function and the "importable" concept; +// most packages are importable. This function assumes that all +// types.Package.Path values are unique within the ssa.Program, which is +// false---yet this function remains very convenient. +// Clients should use (*Program).Package instead where possible. +// SSA doesn't really need a string-keyed map of packages. +// +// Furthermore, the graph of packages may contain multiple variants +// (e.g. "p" vs "p as compiled for q.test"), and each has a different +// view of its dependencies. +func (prog *Program) ImportedPackage(path string) *Package { + return prog.imported[path] +} + +// SetNoReturn sets the predicate used when building the ssa.Program +// prog that reports whether a given function cannot return. +// This may be used to prune spurious control flow edges +// after (e.g.) log.Fatal, improving the precision of analyses. +// +// A typical implementation is the [ctrlflow.CFGs.NoReturn] method from +// [golang.org/x/tools/go/analysis/passes/ctrlflow]. +func (prog *Program) SetNoReturn(noReturn func(*types.Func) bool) { + prog.noReturn = noReturn +} diff --git a/vendor/golang.org/x/tools/go/ssa/doc.go b/vendor/golang.org/x/tools/go/ssa/doc.go new file mode 100644 index 0000000..3310b55 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/doc.go @@ -0,0 +1,122 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ssa defines a representation of the elements of Go programs +// (packages, types, functions, variables and constants) using a +// static single-assignment (SSA) form intermediate representation +// (IR) for the bodies of functions. +// +// For an introduction to SSA form, see +// http://en.wikipedia.org/wiki/Static_single_assignment_form. +// This page provides a broader reading list: +// http://www.dcs.gla.ac.uk/~jsinger/ssa.html. +// +// The level of abstraction of the SSA form is intentionally close to +// the source language to facilitate construction of source analysis +// tools. It is not intended for machine code generation. +// +// All looping, branching and switching constructs are replaced with +// unstructured control flow. Higher-level control flow constructs +// such as multi-way branch can be reconstructed as needed; see +// [golang.org/x/tools/go/ssa/ssautil.Switches] for an example. +// +// The simplest way to create the SSA representation of a package is +// to load typed syntax trees using [golang.org/x/tools/go/packages], then +// invoke the [golang.org/x/tools/go/ssa/ssautil.Packages] helper function. +// (See the package-level Examples named LoadPackages and LoadWholeProgram.) +// The resulting [ssa.Program] contains all the packages and their +// members, but SSA code is not created for function bodies until a +// subsequent call to [Package.Build] or [Program.Build]. +// +// The builder initially builds a naive SSA form in which all local +// variables are addresses of stack locations with explicit loads and +// stores. Registerisation of eligible locals and φ-node insertion +// using dominance and dataflow are then performed as a second pass +// called "lifting" to improve the accuracy and performance of +// subsequent analyses; this pass can be skipped by setting the +// NaiveForm builder flag. +// +// The primary interfaces of this package are: +// +// - [Member]: a named member of a Go package. +// - [Value]: an expression that yields a value. +// - [Instruction]: a statement that consumes values and performs computation. +// - [Node]: a [Value] or [Instruction] (emphasizing its membership in the SSA value graph) +// +// A computation that yields a result implements both the [Value] and +// [Instruction] interfaces. The following table shows for each +// concrete type which of these interfaces it implements. +// +// Value? Instruction? Member? +// *Alloc ✔ ✔ +// *BinOp ✔ ✔ +// *Builtin ✔ +// *Call ✔ ✔ +// *ChangeInterface ✔ ✔ +// *ChangeType ✔ ✔ +// *Const ✔ +// *Convert ✔ ✔ +// *DebugRef ✔ +// *Defer ✔ +// *Extract ✔ ✔ +// *Field ✔ ✔ +// *FieldAddr ✔ ✔ +// *FreeVar ✔ +// *Function ✔ ✔ (func) +// *Global ✔ ✔ (var) +// *Go ✔ +// *If ✔ +// *Index ✔ ✔ +// *IndexAddr ✔ ✔ +// *Jump ✔ +// *Lookup ✔ ✔ +// *MakeChan ✔ ✔ +// *MakeClosure ✔ ✔ +// *MakeInterface ✔ ✔ +// *MakeMap ✔ ✔ +// *MakeSlice ✔ ✔ +// *MapUpdate ✔ +// *MultiConvert ✔ ✔ +// *NamedConst ✔ (const) +// *Next ✔ ✔ +// *Panic ✔ +// *Parameter ✔ +// *Phi ✔ ✔ +// *Range ✔ ✔ +// *Return ✔ +// *RunDefers ✔ +// *Select ✔ ✔ +// *Send ✔ +// *Slice ✔ ✔ +// *SliceToArrayPointer ✔ ✔ +// *Store ✔ +// *Type ✔ (type) +// *TypeAssert ✔ ✔ +// *UnOp ✔ ✔ +// +// Other key types in this package include: [Program], [Package], [Function] +// and [BasicBlock]. +// +// The program representation constructed by this package is fully +// resolved internally, i.e. it does not rely on the names of Values, +// Packages, Functions, Types or BasicBlocks for the correct +// interpretation of the program. Only the identities of objects and +// the topology of the SSA and type graphs are semantically +// significant. (There is one exception: [types.Id] values, which identify field +// and method names, contain strings.) Avoidance of name-based +// operations simplifies the implementation of subsequent passes and +// can make them very efficient. Many objects are nonetheless named +// to aid in debugging, but it is not essential that the names be +// either accurate or unambiguous. The public API exposes a number of +// name-based maps for client convenience. +// +// The [golang.org/x/tools/go/ssa/ssautil] package provides various +// helper functions, for example to simplify loading a Go program into +// SSA form. +// +// TODO(adonovan): write a how-to document for all the various cases +// of trying to determine corresponding elements across the four +// domains of source locations, ast.Nodes, types.Objects, +// ssa.Values/Instructions. +package ssa // import "golang.org/x/tools/go/ssa" diff --git a/vendor/golang.org/x/tools/go/ssa/dom.go b/vendor/golang.org/x/tools/go/ssa/dom.go new file mode 100644 index 0000000..78f651c --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/dom.go @@ -0,0 +1,342 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file defines algorithms related to dominance. + +// Dominator tree construction ---------------------------------------- +// +// We use the algorithm described in Lengauer & Tarjan. 1979. A fast +// algorithm for finding dominators in a flowgraph. +// http://doi.acm.org/10.1145/357062.357071 +// +// We also apply the optimizations to SLT described in Georgiadis et +// al, Finding Dominators in Practice, JGAA 2006, +// http://jgaa.info/accepted/2006/GeorgiadisTarjanWerneck2006.10.1.pdf +// to avoid the need for buckets of size > 1. + +import ( + "bytes" + "fmt" + "math/big" + "os" + "slices" + "sort" +) + +// Idom returns the block that immediately dominates b: +// its parent in the dominator tree, if any. +// Neither the entry node (b.Index==0) nor recover node +// (b==b.Parent().Recover()) have a parent. +func (b *BasicBlock) Idom() *BasicBlock { return b.dom.idom } + +// Dominees returns the list of blocks that b immediately dominates: +// its children in the dominator tree. +func (b *BasicBlock) Dominees() []*BasicBlock { return b.dom.children } + +// Dominates reports whether b dominates c. +func (b *BasicBlock) Dominates(c *BasicBlock) bool { + return b.dom.pre <= c.dom.pre && c.dom.post <= b.dom.post +} + +// DomPreorder returns a new slice containing the blocks of f +// in a preorder traversal of the dominator tree. +func (f *Function) DomPreorder() []*BasicBlock { + slice := slices.Clone(f.Blocks) + sort.Slice(slice, func(i, j int) bool { + return slice[i].dom.pre < slice[j].dom.pre + }) + return slice +} + +// DomPostorder returns a new slice containing the blocks of f +// in a postorder traversal of the dominator tree. +// (This is not the same as a postdominance order.) +func (f *Function) DomPostorder() []*BasicBlock { + slice := slices.Clone(f.Blocks) + sort.Slice(slice, func(i, j int) bool { + return slice[i].dom.post < slice[j].dom.post + }) + return slice +} + +// domInfo contains a BasicBlock's dominance information. +type domInfo struct { + idom *BasicBlock // immediate dominator (parent in domtree) + children []*BasicBlock // nodes immediately dominated by this one + pre, post int32 // pre- and post-order numbering within domtree +} + +// ltState holds the working state for Lengauer-Tarjan algorithm +// (during which domInfo.pre is repurposed for CFG DFS preorder number). +type ltState struct { + // Each slice is indexed by b.Index. + sdom []*BasicBlock // b's semidominator + parent []*BasicBlock // b's parent in DFS traversal of CFG + ancestor []*BasicBlock // b's ancestor with least sdom +} + +// dfs implements the depth-first search part of the LT algorithm. +func (lt *ltState) dfs(v *BasicBlock, i int32, preorder []*BasicBlock) int32 { + preorder[i] = v + v.dom.pre = i // For now: DFS preorder of spanning tree of CFG + i++ + lt.sdom[v.Index] = v + lt.link(nil, v) + for _, w := range v.Succs { + if lt.sdom[w.Index] == nil { + lt.parent[w.Index] = v + i = lt.dfs(w, i, preorder) + } + } + return i +} + +// eval implements the EVAL part of the LT algorithm. +func (lt *ltState) eval(v *BasicBlock) *BasicBlock { + // TODO(adonovan): opt: do path compression per simple LT. + u := v + for ; lt.ancestor[v.Index] != nil; v = lt.ancestor[v.Index] { + if lt.sdom[v.Index].dom.pre < lt.sdom[u.Index].dom.pre { + u = v + } + } + return u +} + +// link implements the LINK part of the LT algorithm. +func (lt *ltState) link(v, w *BasicBlock) { + lt.ancestor[w.Index] = v +} + +// buildDomTree computes the dominator tree of f using the LT algorithm. +// Precondition: all blocks are reachable (e.g. optimizeBlocks has been run). +func buildDomTree(f *Function) { + // The step numbers refer to the original LT paper; the + // reordering is due to Georgiadis. + + // Clear any previous domInfo. + for _, b := range f.Blocks { + b.dom = domInfo{} + } + + n := len(f.Blocks) + // Allocate space for 5 contiguous [n]*BasicBlock arrays: + // sdom, parent, ancestor, preorder, buckets. + space := make([]*BasicBlock, 5*n) + lt := ltState{ + sdom: space[0:n], + parent: space[n : 2*n], + ancestor: space[2*n : 3*n], + } + + // Step 1. Number vertices by depth-first preorder. + preorder := space[3*n : 4*n] + root := f.Blocks[0] + prenum := lt.dfs(root, 0, preorder) + recover := f.Recover + if recover != nil { + lt.dfs(recover, prenum, preorder) + } + + buckets := space[4*n : 5*n] + copy(buckets, preorder) + + // In reverse preorder... + for i := int32(n) - 1; i > 0; i-- { + w := preorder[i] + + // Step 3. Implicitly define the immediate dominator of each node. + for v := buckets[i]; v != w; v = buckets[v.dom.pre] { + u := lt.eval(v) + if lt.sdom[u.Index].dom.pre < i { + v.dom.idom = u + } else { + v.dom.idom = w + } + } + + // Step 2. Compute the semidominators of all nodes. + lt.sdom[w.Index] = lt.parent[w.Index] + for _, v := range w.Preds { + u := lt.eval(v) + if lt.sdom[u.Index].dom.pre < lt.sdom[w.Index].dom.pre { + lt.sdom[w.Index] = lt.sdom[u.Index] + } + } + + lt.link(lt.parent[w.Index], w) + + if lt.parent[w.Index] == lt.sdom[w.Index] { + w.dom.idom = lt.parent[w.Index] + } else { + buckets[i] = buckets[lt.sdom[w.Index].dom.pre] + buckets[lt.sdom[w.Index].dom.pre] = w + } + } + + // The final 'Step 3' is now outside the loop. + for v := buckets[0]; v != root; v = buckets[v.dom.pre] { + v.dom.idom = root + } + + // Step 4. Explicitly define the immediate dominator of each + // node, in preorder. + for _, w := range preorder[1:] { + if w == root || w == recover { + w.dom.idom = nil + } else { + if w.dom.idom != lt.sdom[w.Index] { + w.dom.idom = w.dom.idom.dom.idom + } + // Calculate Children relation as inverse of Idom. + w.dom.idom.dom.children = append(w.dom.idom.dom.children, w) + } + } + + pre, post := numberDomTree(root, 0, 0) + if recover != nil { + numberDomTree(recover, pre, post) + } + + // printDomTreeDot(os.Stderr, f) // debugging + // printDomTreeText(os.Stderr, root, 0) // debugging + + if f.Prog.mode&SanityCheckFunctions != 0 { + sanityCheckDomTree(f) + } +} + +// numberDomTree sets the pre- and post-order numbers of a depth-first +// traversal of the dominator tree rooted at v. These are used to +// answer dominance queries in constant time. +func numberDomTree(v *BasicBlock, pre, post int32) (int32, int32) { + v.dom.pre = pre + pre++ + for _, child := range v.dom.children { + pre, post = numberDomTree(child, pre, post) + } + v.dom.post = post + post++ + return pre, post +} + +// Testing utilities ---------------------------------------- + +// sanityCheckDomTree checks the correctness of the dominator tree +// computed by the LT algorithm by comparing against the dominance +// relation computed by a naive Kildall-style forward dataflow +// analysis (Algorithm 10.16 from the "Dragon" book). +func sanityCheckDomTree(f *Function) { + n := len(f.Blocks) + + // D[i] is the set of blocks that dominate f.Blocks[i], + // represented as a bit-set of block indices. + D := make([]big.Int, n) + + one := big.NewInt(1) + + // all is the set of all blocks; constant. + var all big.Int + all.Set(one).Lsh(&all, uint(n)).Sub(&all, one) + + // Initialization. + for i, b := range f.Blocks { + if i == 0 || b == f.Recover { + // A root is dominated only by itself. + D[i].SetBit(&D[0], 0, 1) + } else { + // All other blocks are (initially) dominated + // by every block. + D[i].Set(&all) + } + } + + // Iteration until fixed point. + for changed := true; changed; { + changed = false + for i, b := range f.Blocks { + if i == 0 || b == f.Recover { + continue + } + // Compute intersection across predecessors. + var x big.Int + x.Set(&all) + for _, pred := range b.Preds { + x.And(&x, &D[pred.Index]) + } + x.SetBit(&x, i, 1) // a block always dominates itself. + if D[i].Cmp(&x) != 0 { + D[i].Set(&x) + changed = true + } + } + } + + // Check the entire relation. O(n^2). + // The Recover block (if any) must be treated specially so we skip it. + ok := true + for i := range n { + for j := range n { + b, c := f.Blocks[i], f.Blocks[j] + if c == f.Recover { + continue + } + actual := b.Dominates(c) + expected := D[j].Bit(i) == 1 + if actual != expected { + fmt.Fprintf(os.Stderr, "dominates(%s, %s)==%t, want %t\n", b, c, actual, expected) + ok = false + } + } + } + + preorder := f.DomPreorder() + for _, b := range f.Blocks { + if got := preorder[b.dom.pre]; got != b { + fmt.Fprintf(os.Stderr, "preorder[%d]==%s, want %s\n", b.dom.pre, got, b) + ok = false + } + } + + if !ok { + panic("sanityCheckDomTree failed for " + f.String()) + } + +} + +// Printing functions ---------------------------------------- + +// printDomTreeText prints the dominator tree as text, using indentation. +func printDomTreeText(buf *bytes.Buffer, v *BasicBlock, indent int) { + fmt.Fprintf(buf, "%*s%s\n", 4*indent, "", v) + for _, child := range v.dom.children { + printDomTreeText(buf, child, indent+1) + } +} + +// printDomTreeDot prints the dominator tree of f in AT&T GraphViz +// (.dot) format. +// (unused; retained for debugging) +func printDomTreeDot(buf *bytes.Buffer, f *Function) { + fmt.Fprintln(buf, "//", f) + fmt.Fprintln(buf, "digraph domtree {") + for i, b := range f.Blocks { + v := b.dom + fmt.Fprintf(buf, "\tn%d [label=\"%s (%d, %d)\",shape=\"rectangle\"];\n", v.pre, b, v.pre, v.post) + // TODO(adonovan): improve appearance of edges + // belonging to both dominator tree and CFG. + + // Dominator tree edge. + if i != 0 { + fmt.Fprintf(buf, "\tn%d -> n%d [style=\"solid\",weight=100];\n", v.idom.dom.pre, v.pre) + } + // CFG edges. + for _, pred := range b.Preds { + fmt.Fprintf(buf, "\tn%d -> n%d [style=\"dotted\",weight=0];\n", pred.dom.pre, v.pre) + } + } + fmt.Fprintln(buf, "}") +} diff --git a/vendor/golang.org/x/tools/go/ssa/emit.go b/vendor/golang.org/x/tools/go/ssa/emit.go new file mode 100644 index 0000000..fd54b3d --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/emit.go @@ -0,0 +1,629 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// Helpers for emitting SSA instructions. + +import ( + "fmt" + "go/ast" + "go/token" + "go/types" + + "golang.org/x/tools/internal/typeparams" +) + +// emitAlloc emits to f a new Alloc instruction allocating a variable +// of type typ. +// +// The caller must set Alloc.Heap=true (for a heap-allocated variable) +// or add the Alloc to f.Locals (for a frame-allocated variable). +// +// During building, a variable in f.Locals may have its Heap flag +// set when it is discovered that its address is taken. +// These Allocs are removed from f.Locals at the end. +// +// The builder should generally call one of the emit{New,Local,LocalVar} wrappers instead. +func emitAlloc(f *Function, typ types.Type, pos token.Pos, comment string) *Alloc { + v := &Alloc{Comment: comment} + v.setType(types.NewPointer(typ)) + v.setPos(pos) + f.emit(v) + return v +} + +// emitNew emits to f a new Alloc instruction heap-allocating a +// variable of type typ. pos is the optional source location. +func emitNew(f *Function, typ types.Type, pos token.Pos, comment string) *Alloc { + alloc := emitAlloc(f, typ, pos, comment) + alloc.Heap = true + return alloc +} + +// emitLocal creates a local var for (t, pos, comment) and +// emits an Alloc instruction for it. +// +// (Use this function or emitNew for synthetic variables; +// for source-level variables in the same function, use emitLocalVar.) +func emitLocal(f *Function, t types.Type, pos token.Pos, comment string) *Alloc { + local := emitAlloc(f, t, pos, comment) + f.Locals = append(f.Locals, local) + return local +} + +// emitLocalVar creates a local var for v and emits an Alloc instruction for it. +// Subsequent calls to f.lookup(v) return it. +// It applies the appropriate generic instantiation to the type. +func emitLocalVar(f *Function, v *types.Var) *Alloc { + alloc := emitLocal(f, f.typ(v.Type()), v.Pos(), v.Name()) + f.vars[v] = alloc + return alloc +} + +// emitLoad emits to f an instruction to load the address addr into a +// new temporary, and returns the value so defined. +func emitLoad(f *Function, addr Value) *UnOp { + v := &UnOp{Op: token.MUL, X: addr} + v.setType(typeparams.MustDeref(addr.Type())) + f.emit(v) + return v +} + +// emitDebugRef emits to f a DebugRef pseudo-instruction associating +// expression e with value v. +func emitDebugRef(f *Function, e ast.Expr, v Value, isAddr bool) { + if !f.debugInfo() { + return // debugging not enabled + } + if v == nil || e == nil { + panic("nil") + } + var obj types.Object + e = ast.Unparen(e) + if id, ok := e.(*ast.Ident); ok { + if isBlankIdent(id) { + return + } + obj = f.objectOf(id) + switch obj.(type) { + case *types.Nil, *types.Const, *types.Builtin: + return + } + } + f.emit(&DebugRef{ + X: v, + Expr: e, + IsAddr: isAddr, + object: obj, + }) +} + +// emitArith emits to f code to compute the binary operation op(x, y) +// where op is an eager shift, logical or arithmetic operation. +// (Use emitCompare() for comparisons and Builder.logicalBinop() for +// non-eager operations.) +func emitArith(f *Function, op token.Token, x, y Value, t types.Type, pos token.Pos) Value { + switch op { + case token.SHL, token.SHR: + x = emitConv(f, x, t) + // y may be signed or an 'untyped' constant. + + // There is a runtime panic if y is signed and <0. Instead of inserting a check for y<0 + // and converting to an unsigned value (like the compiler) leave y as is. + + if isUntyped(y.Type().Underlying()) { + // Untyped conversion: + // Spec https://go.dev/ref/spec#Operators: + // The right operand in a shift expression must have integer type or be an untyped constant + // representable by a value of type uint. + y = emitConv(f, y, types.Typ[types.Uint]) + } + + case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT: + x = emitConv(f, x, t) + y = emitConv(f, y, t) + + default: + panic("illegal op in emitArith: " + op.String()) + + } + v := &BinOp{ + Op: op, + X: x, + Y: y, + } + v.setPos(pos) + v.setType(t) + return f.emit(v) +} + +// emitCompare emits to f code compute the boolean result of +// comparison 'x op y'. +func emitCompare(f *Function, op token.Token, x, y Value, pos token.Pos) Value { + xt := x.Type().Underlying() + yt := y.Type().Underlying() + + // Special case to optimise a tagless SwitchStmt so that + // these are equivalent + // switch { case e: ...} + // switch true { case e: ... } + // if e==true { ... } + // even in the case when e's type is an interface. + // TODO(adonovan): opt: generalise to x==true, false!=y, etc. + if x == vTrue && op == token.EQL { + if yt, ok := yt.(*types.Basic); ok && yt.Info()&types.IsBoolean != 0 { + return y + } + } + + if types.Identical(xt, yt) { + // no conversion necessary + } else if isNonTypeParamInterface(x.Type()) { + y = emitConv(f, y, x.Type()) + } else if isNonTypeParamInterface(y.Type()) { + x = emitConv(f, x, y.Type()) + } else if _, ok := x.(*Const); ok { + x = emitConv(f, x, y.Type()) + } else if _, ok := y.(*Const); ok { + y = emitConv(f, y, x.Type()) + } else { + // other cases, e.g. channels. No-op. + } + + v := &BinOp{ + Op: op, + X: x, + Y: y, + } + v.setPos(pos) + v.setType(tBool) + return f.emit(v) +} + +// isValuePreserving returns true if a conversion from ut_src to +// ut_dst is value-preserving, i.e. just a change of type. +// Precondition: neither argument is a named or alias type. +func isValuePreserving(ut_src, ut_dst types.Type) bool { + // Identical underlying types? + if types.IdenticalIgnoreTags(ut_dst, ut_src) { + return true + } + + switch ut_dst.(type) { + case *types.Chan: + // Conversion between channel types? + _, ok := ut_src.(*types.Chan) + return ok + + case *types.Pointer: + // Conversion between pointers with identical base types? + _, ok := ut_src.(*types.Pointer) + return ok + } + return false +} + +// emitConv emits to f code to convert Value val to exactly type typ, +// and returns the converted value. Implicit conversions are required +// by language assignability rules in assignments, parameter passing, +// etc. +func emitConv(f *Function, val Value, typ types.Type) Value { + t_src := val.Type() + + // Identical types? Conversion is a no-op. + if types.Identical(t_src, typ) { + return val + } + ut_dst := typ.Underlying() + ut_src := t_src.Underlying() + + // Conversion to, or construction of a value of, an interface type? + if isNonTypeParamInterface(typ) { + // Interface name change? + if isValuePreserving(ut_src, ut_dst) { + c := &ChangeType{X: val} + c.setType(typ) + return f.emit(c) + } + + // Assignment from one interface type to another? + if isNonTypeParamInterface(t_src) { + c := &ChangeInterface{X: val} + c.setType(typ) + return f.emit(c) + } + + // Untyped nil constant? Return interface-typed nil constant. + if ut_src == tUntypedNil { + return zeroConst(typ) + } + + // Convert (non-nil) "untyped" literals to their default type. + if t, ok := ut_src.(*types.Basic); ok && t.Info()&types.IsUntyped != 0 { + val = emitConv(f, val, types.Default(ut_src)) + } + + // Record the types of operands to MakeInterface, if + // non-parameterized, as they are the set of runtime types. + t := val.Type() + if !f.Prog.isParameterized(t) { + addMakeInterfaceType(f.Prog, t) + } + + mi := &MakeInterface{X: val} + mi.setType(typ) + return f.emit(mi) + } + + // conversionCase describes an instruction pattern that maybe emitted to + // model d <- s for d in dst_terms and s in src_terms. + // Multiple conversions can match the same pattern. + type conversionCase uint8 + const ( + changeType conversionCase = 1 << iota + sliceToArray + sliceToArrayPtr + sliceTo0Array + sliceTo0ArrayPtr + convert + ) + // classify the conversion case of a source type us to a destination type ud. + // us and ud are underlying types (not *Named or *Alias) + classify := func(us, ud types.Type) conversionCase { + // Just a change of type, but not value or representation? + if isValuePreserving(us, ud) { + return changeType + } + + // Conversion from slice to array or slice to array pointer? + if slice, ok := us.(*types.Slice); ok { + var arr *types.Array + var ptr bool + // Conversion from slice to array pointer? + switch d := ud.(type) { + case *types.Array: + arr = d + case *types.Pointer: + arr, _ = d.Elem().Underlying().(*types.Array) + ptr = true + } + if arr != nil && types.Identical(slice.Elem(), arr.Elem()) { + if arr.Len() == 0 { + if ptr { + return sliceTo0ArrayPtr + } else { + return sliceTo0Array + } + } + if ptr { + return sliceToArrayPtr + } else { + return sliceToArray + } + } + } + + // The only remaining case in well-typed code is a representation- + // changing conversion of basic types (possibly with []byte/[]rune). + if !isBasic(us) && !isBasic(ud) { + panic(fmt.Sprintf("in %s: cannot convert term %s (%s [within %s]) to type %s [within %s]", f, val, val.Type(), us, typ, ud)) + } + return convert + } + + var classifications conversionCase + underIs(ut_src, func(us types.Type) bool { + return underIs(ut_dst, func(ud types.Type) bool { + if us != nil && ud != nil { + classifications |= classify(us, ud) + } + return classifications != 0 + }) + }) + if classifications == 0 { + panic(fmt.Sprintf("in %s: cannot convert %s (%s) to %s", f, val, val.Type(), typ)) + } + + // Conversion of a compile-time constant value? + if c, ok := val.(*Const); ok { + // Conversion to a basic type? + if isBasic(ut_dst) { + // Conversion of a compile-time constant to + // another constant type results in a new + // constant of the destination type and + // (initially) the same abstract value. + // We don't truncate the value yet. + return NewConst(c.Value, typ) + } + // Can we always convert from zero value without panicking? + const mayPanic = sliceToArray | sliceToArrayPtr + if c.Value == nil && classifications&mayPanic == 0 { + return NewConst(nil, typ) + } + + // We're converting from constant to non-constant type, + // e.g. string -> []byte/[]rune. + } + + switch classifications { + case changeType: // representation-preserving change + c := &ChangeType{X: val} + c.setType(typ) + return f.emit(c) + + case sliceToArrayPtr, sliceTo0ArrayPtr: // slice to array pointer + c := &SliceToArrayPointer{X: val} + c.setType(typ) + return f.emit(c) + + case sliceToArray: // slice to arrays (not zero-length) + ptype := types.NewPointer(typ) + p := &SliceToArrayPointer{X: val} + p.setType(ptype) + x := f.emit(p) + unOp := &UnOp{Op: token.MUL, X: x} + unOp.setType(typ) + return f.emit(unOp) + + case sliceTo0Array: // slice to zero-length arrays (constant) + return zeroConst(typ) + + case convert: // representation-changing conversion + c := &Convert{X: val} + c.setType(typ) + return f.emit(c) + + default: // The conversion represents a cross product. + c := &MultiConvert{X: val, from: t_src, to: typ} + c.setType(typ) + return f.emit(c) + } +} + +// emitTypeCoercion emits to f code to coerce the type of a +// Value v to exactly type typ, and returns the coerced value. +// +// Requires that coercing v.Typ() to typ is a value preserving change. +// +// Currently used only when v.Type() is a type instance of typ or vice versa. +// A type v is a type instance of a type t if there exists a +// type parameter substitution σ s.t. σ(v) == t. Example: +// +// σ(func(T) T) == func(int) int for σ == [T ↦ int] +// +// This happens in instantiation wrappers for conversion +// from an instantiation to a parameterized type (and vice versa) +// with σ substituting f.typeparams by f.typeargs. +func emitTypeCoercion(f *Function, v Value, typ types.Type) Value { + if types.Identical(v.Type(), typ) { + return v // no coercion needed + } + // TODO(taking): for instances should we record which side is the instance? + c := &ChangeType{ + X: v, + } + c.setType(typ) + f.emit(c) + return c +} + +// emitStore emits to f an instruction to store value val at location +// addr, applying implicit conversions as required by assignability rules. +func emitStore(f *Function, addr, val Value, pos token.Pos) *Store { + typ := typeparams.MustDeref(addr.Type()) + s := &Store{ + Addr: addr, + Val: emitConv(f, val, typ), + pos: pos, + } + f.emit(s) + return s +} + +// emitJump emits to f a jump to target, and updates the control-flow graph. +// Postcondition: f.currentBlock is nil. +func emitJump(f *Function, target *BasicBlock) { + b := f.currentBlock + b.emit(new(Jump)) + addEdge(b, target) + f.currentBlock = nil +} + +// emitIf emits to f a conditional jump to tblock or fblock based on +// cond, and updates the control-flow graph. +// Postcondition: f.currentBlock is nil. +func emitIf(f *Function, cond Value, tblock, fblock *BasicBlock) { + b := f.currentBlock + b.emit(&If{Cond: cond}) + addEdge(b, tblock) + addEdge(b, fblock) + f.currentBlock = nil +} + +// emitExtract emits to f an instruction to extract the index'th +// component of tuple. It returns the extracted value. +func emitExtract(f *Function, tuple Value, index int) Value { + e := &Extract{Tuple: tuple, Index: index} + e.setType(tuple.Type().(*types.Tuple).At(index).Type()) + return f.emit(e) +} + +// emitTypeAssert emits to f a type assertion value := x.(t) and +// returns the value. x.Type() must be an interface. +func emitTypeAssert(f *Function, x Value, t types.Type, pos token.Pos) Value { + a := &TypeAssert{X: x, AssertedType: t} + a.setPos(pos) + a.setType(t) + return f.emit(a) +} + +// emitTypeTest emits to f a type test value,ok := x.(t) and returns +// a (value, ok) tuple. x.Type() must be an interface. +func emitTypeTest(f *Function, x Value, t types.Type, pos token.Pos) Value { + a := &TypeAssert{ + X: x, + AssertedType: t, + CommaOk: true, + } + a.setPos(pos) + a.setType(types.NewTuple( + newVar("value", t), + varOk, + )) + return f.emit(a) +} + +// emitTailCall emits to f a function call in tail position. The +// caller is responsible for all fields of 'call' except its type. +// Intended for wrapper methods. +// Precondition: f does/will not use deferred procedure calls. +// Postcondition: f.currentBlock is nil. +func emitTailCall(f *Function, call *Call) { + tresults := f.Signature.Results() + nr := tresults.Len() + if nr == 1 { + call.typ = tresults.At(0).Type() + } else { + call.typ = tresults + } + tuple := emitCall(f, call) + var ret Return + switch nr { + case 0: + // no-op + case 1: + ret.Results = []Value{tuple} + default: + for i := range nr { + v := emitExtract(f, tuple, i) + // TODO(adonovan): in principle, this is required: + // v = emitConv(f, o.Type, f.Signature.Results[i].Type) + // but in practice emitTailCall is only used when + // the types exactly match. + ret.Results = append(ret.Results, v) + } + } + f.emit(&ret) + f.currentBlock = nil +} + +// emitCall emits a call instruction. If the callee is "no return", +// it also emits a panic to eliminate infeasible CFG edges. +func emitCall(fn *Function, call *Call) Value { + res := fn.emit(call) + + callee := call.Call.StaticCallee() + if callee != nil && + callee.object != nil && + fn.Prog.noReturn != nil && + fn.Prog.noReturn(callee.object) { + // Call cannot return. Insert a panic after it. + fn.emit(&Panic{ + X: emitConv(fn, vNoReturn, tEface), + pos: call.Pos(), + }) + fn.currentBlock = fn.newBasicBlock("unreachable.noreturn") + } + + return res +} + +// emitImplicitSelections emits to f code to apply the sequence of +// implicit field selections specified by indices to base value v, and +// returns the selected value. +// +// If v is the address of a struct, the result will be the address of +// a field; if it is the value of a struct, the result will be the +// value of a field. +func emitImplicitSelections(f *Function, v Value, indices []int, pos token.Pos) Value { + for _, index := range indices { + if isPointerCore(v.Type()) { + fld := fieldOf(typeparams.MustDeref(v.Type()), index) + instr := &FieldAddr{ + X: v, + Field: index, + } + instr.setPos(pos) + instr.setType(types.NewPointer(fld.Type())) + v = f.emit(instr) + // Load the field's value iff indirectly embedded. + if isPointerCore(fld.Type()) { + v = emitLoad(f, v) + } + } else { + fld := fieldOf(v.Type(), index) + instr := &Field{ + X: v, + Field: index, + } + instr.setPos(pos) + instr.setType(fld.Type()) + v = f.emit(instr) + } + } + return v +} + +// emitFieldSelection emits to f code to select the index'th field of v. +// +// If wantAddr, the input must be a pointer-to-struct and the result +// will be the field's address; otherwise the result will be the +// field's value. +// Ident id is used for position and debug info. +func emitFieldSelection(f *Function, v Value, index int, wantAddr bool, id *ast.Ident) Value { + if isPointerCore(v.Type()) { + fld := fieldOf(typeparams.MustDeref(v.Type()), index) + instr := &FieldAddr{ + X: v, + Field: index, + } + instr.setPos(id.Pos()) + instr.setType(types.NewPointer(fld.Type())) + v = f.emit(instr) + // Load the field's value iff we don't want its address. + if !wantAddr { + v = emitLoad(f, v) + } + } else { + fld := fieldOf(v.Type(), index) + instr := &Field{ + X: v, + Field: index, + } + instr.setPos(id.Pos()) + instr.setType(fld.Type()) + v = f.emit(instr) + } + emitDebugRef(f, id, v, wantAddr) + return v +} + +// createRecoverBlock emits to f a block of code to return after a +// recovered panic, and sets f.Recover to it. +// +// If f's result parameters are named, the code loads and returns +// their current values, otherwise it returns the zero values of their +// type. +// +// Idempotent. +func createRecoverBlock(f *Function) { + if f.Recover != nil { + return // already created + } + saved := f.currentBlock + + f.Recover = f.newBasicBlock("recover") + f.currentBlock = f.Recover + + var results []Value + // Reload NRPs to form value tuple. + for _, nr := range f.results { + results = append(results, emitLoad(f, nr)) + } + + f.emit(&Return{Results: results}) + + f.currentBlock = saved +} diff --git a/vendor/golang.org/x/tools/go/ssa/func.go b/vendor/golang.org/x/tools/go/ssa/func.go new file mode 100644 index 0000000..553363a --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/func.go @@ -0,0 +1,849 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file implements the Function type. + +import ( + "bytes" + "fmt" + "go/ast" + "go/token" + "go/types" + "io" + "iter" + "os" + "strings" + + "golang.org/x/tools/internal/typeparams" +) + +// Like ObjectOf, but panics instead of returning nil. +// Only valid during f's create and build phases. +func (f *Function) objectOf(id *ast.Ident) types.Object { + if o := f.info.ObjectOf(id); o != nil { + return o + } + panic(fmt.Sprintf("no types.Object for ast.Ident %s @ %s", + id.Name, f.Prog.Fset.Position(id.Pos()))) +} + +// Like TypeOf, but panics instead of returning nil. +// Only valid during f's create and build phases. +func (f *Function) typeOf(e ast.Expr) types.Type { + if T := f.info.TypeOf(e); T != nil { + return f.typ(T) + } + panic(fmt.Sprintf("no type for %T @ %s", e, f.Prog.Fset.Position(e.Pos()))) +} + +// typ is the locally instantiated type of T. +// If f is not an instantiation, then f.typ(T)==T. +func (f *Function) typ(T types.Type) types.Type { + return f.subst.typ(T) +} + +// If id is an Instance, returns info.Instances[id].Type. +// Otherwise returns f.typeOf(id). +func (f *Function) instanceType(id *ast.Ident) types.Type { + if t, ok := f.info.Instances[id]; ok { + return t.Type + } + return f.typeOf(id) +} + +// selection returns a *selection corresponding to f.info.Selections[selector] +// with potential updates for type substitution. +func (f *Function) selection(selector *ast.SelectorExpr) *selection { + sel := f.info.Selections[selector] + if sel == nil { + return nil + } + + switch sel.Kind() { + case types.MethodExpr, types.MethodVal: + if recv := f.typ(sel.Recv()); recv != sel.Recv() { + // recv changed during type substitution. + pkg := f.declaredPackage().Pkg + obj, index, indirect := types.LookupFieldOrMethod(recv, true, pkg, sel.Obj().Name()) + + // sig replaces sel.Type(). See (types.Selection).Typ() for details. + sig := obj.Type().(*types.Signature) + sig = changeRecv(sig, newVar(sig.Recv().Name(), recv)) + if sel.Kind() == types.MethodExpr { + sig = recvAsFirstArg(sig) + } + return &selection{ + kind: sel.Kind(), + recv: recv, + typ: sig, + obj: obj, + index: index, + indirect: indirect, + } + } + } + return toSelection(sel) +} + +// Destinations associated with unlabelled for/switch/select stmts. +// We push/pop one of these as we enter/leave each construct and for +// each BranchStmt we scan for the innermost target of the right type. +type targets struct { + tail *targets // rest of stack + _break *BasicBlock + _continue *BasicBlock + _fallthrough *BasicBlock +} + +// Destinations associated with a labelled block. +// We populate these as labels are encountered in forward gotos or +// labelled statements. +// Forward gotos are resolved once it is known which statement they +// are associated with inside the Function. +type lblock struct { + label *types.Label // Label targeted by the blocks. + resolved bool // _goto block encountered (back jump or resolved fwd jump) + _goto *BasicBlock + _break *BasicBlock + _continue *BasicBlock +} + +// label returns the symbol denoted by a label identifier. +// +// label should be a non-blank identifier (label.Name != "_"). +func (f *Function) label(label *ast.Ident) *types.Label { + return f.objectOf(label).(*types.Label) +} + +// lblockOf returns the branch target associated with the +// specified label, creating it if needed. +func (f *Function) lblockOf(label *types.Label) *lblock { + lb := f.lblocks[label] + if lb == nil { + lb = &lblock{ + label: label, + _goto: f.newBasicBlock(label.Name()), + } + if f.lblocks == nil { + f.lblocks = make(map[*types.Label]*lblock) + } + f.lblocks[label] = lb + } + return lb +} + +// labelledBlock searches f for the block of the specified label. +// +// If f is a yield function, it additionally searches ancestor Functions +// corresponding to enclosing range-over-func statements within the +// same source function, so the returned block may belong to a different Function. +func labelledBlock(f *Function, label *types.Label, tok token.Token) *BasicBlock { + if lb := f.lblocks[label]; lb != nil { + var block *BasicBlock + switch tok { + case token.BREAK: + block = lb._break + case token.CONTINUE: + block = lb._continue + case token.GOTO: + block = lb._goto + } + if block != nil { + return block + } + } + // Search ancestors if this is a yield function. + if f.jump != nil { + return labelledBlock(f.parent, label, tok) + } + return nil +} + +// targetedBlock looks for the nearest block in f.targets +// (and f's ancestors) that matches tok's type, and returns +// the block and function it was found in. +func targetedBlock(f *Function, tok token.Token) *BasicBlock { + if f == nil { + return nil + } + for t := f.targets; t != nil; t = t.tail { + var block *BasicBlock + switch tok { + case token.BREAK: + block = t._break + case token.CONTINUE: + block = t._continue + case token.FALLTHROUGH: + block = t._fallthrough + } + if block != nil { + return block + } + } + // Search f's ancestors (in case f is a yield function). + return targetedBlock(f.parent, tok) +} + +// instrs returns an iterator that returns each reachable instruction of the SSA function. +func (f *Function) instrs() iter.Seq[Instruction] { + return func(yield func(i Instruction) bool) { + for _, block := range f.Blocks { + for _, instr := range block.Instrs { + if !yield(instr) { + return + } + } + } + } +} + +// addResultVar adds a result for a variable v to f.results and v to f.returnVars. +func (f *Function) addResultVar(v *types.Var) { + result := emitLocalVar(f, v) + f.results = append(f.results, result) + f.returnVars = append(f.returnVars, v) +} + +// addParamVar adds a parameter to f.Params. +func (f *Function) addParamVar(v *types.Var) *Parameter { + name := v.Name() + if name == "" { + name = fmt.Sprintf("arg%d", len(f.Params)) + } + param := &Parameter{ + name: name, + object: v, + typ: f.typ(v.Type()), + parent: f, + } + f.Params = append(f.Params, param) + return param +} + +// addSpilledParam declares a parameter that is pre-spilled to the +// stack; the function body will load/store the spilled location. +// Subsequent lifting will eliminate spills where possible. +func (f *Function) addSpilledParam(obj *types.Var) { + param := f.addParamVar(obj) + spill := emitLocalVar(f, obj) + f.emit(&Store{Addr: spill, Val: param}) +} + +// startBody initializes the function prior to generating SSA code for its body. +// Precondition: f.Type() already set. +func (f *Function) startBody() { + f.currentBlock = f.newBasicBlock("entry") + f.vars = make(map[*types.Var]Value) // needed for some synthetics, e.g. init +} + +// createSyntacticParams populates f.Params and generates code (spills +// and named result locals) for all the parameters declared in the +// syntax. In addition it populates the f.objects mapping. +// +// Preconditions: +// f.startBody() was called. f.info != nil. +// Postcondition: +// len(f.Params) == len(f.Signature.Params) + (f.Signature.Recv() ? 1 : 0) +func (f *Function) createSyntacticParams(recv *ast.FieldList, functype *ast.FuncType) { + // Receiver (at most one inner iteration). + if recv != nil { + for _, field := range recv.List { + for _, n := range field.Names { + f.addSpilledParam(identVar(f, n)) + } + // Anonymous receiver? No need to spill. + if field.Names == nil { + f.addParamVar(f.Signature.Recv()) + } + } + } + + // Parameters. + if functype.Params != nil { + n := len(f.Params) // 1 if has recv, 0 otherwise + for _, field := range functype.Params.List { + for _, n := range field.Names { + f.addSpilledParam(identVar(f, n)) + } + // Anonymous parameter? No need to spill. + if field.Names == nil { + f.addParamVar(f.Signature.Params().At(len(f.Params) - n)) + } + } + } + + // Results. + if functype.Results != nil { + for _, field := range functype.Results.List { + // Implicit "var" decl of locals for named results. + for _, n := range field.Names { + v := identVar(f, n) + f.addResultVar(v) + } + // Implicit "var" decl of local for an unnamed result. + if field.Names == nil { + v := f.Signature.Results().At(len(f.results)) + f.addResultVar(v) + } + } + } +} + +// createDeferStack initializes fn.deferstack to local variable +// initialized to a ssa:deferstack() call. +func (fn *Function) createDeferStack() { + // Each syntactic function makes a call to ssa:deferstack, + // which is spilled to a local. Unused ones are later removed. + fn.deferstack = newVar("defer$stack", tDeferStack) + call := &Call{Call: CallCommon{Value: vDeferStack}} + call.setType(tDeferStack) + deferstack := fn.emit(call) + spill := emitLocalVar(fn, fn.deferstack) + emitStore(fn, spill, deferstack, token.NoPos) +} + +type setNumable interface { + setNum(int) +} + +// numberRegisters assigns numbers to all SSA registers +// (value-defining Instructions) in f, to aid debugging. +// (Non-Instruction Values are named at construction.) +func numberRegisters(f *Function) { + v := 0 + for _, b := range f.Blocks { + for _, instr := range b.Instrs { + switch instr.(type) { + case Value: + instr.(setNumable).setNum(v) + v++ + } + } + } +} + +// buildReferrers populates the def/use information in all non-nil +// Value.Referrers slice. +// Precondition: all such slices are initially empty. +func buildReferrers(f *Function) { + var rands []*Value + for _, b := range f.Blocks { + for _, instr := range b.Instrs { + rands = instr.Operands(rands[:0]) // recycle storage + for _, rand := range rands { + if r := *rand; r != nil { + if ref := r.Referrers(); ref != nil { + *ref = append(*ref, instr) + } + } + } + } + } +} + +// finishBody() finalizes the contents of the function after SSA code generation of its body. +// +// The function is not done being built until done() is called. +func (f *Function) finishBody() { + f.currentBlock = nil + f.lblocks = nil + f.returnVars = nil + f.jump = nil + f.source = nil + f.exits = nil + + // Remove from f.Locals any Allocs that escape to the heap. + j := 0 + for _, l := range f.Locals { + if !l.Heap { + f.Locals[j] = l + j++ + } + } + // Nil out f.Locals[j:] to aid GC. + for i := j; i < len(f.Locals); i++ { + f.Locals[i] = nil + } + f.Locals = f.Locals[:j] + + optimizeBlocks(f) + + buildReferrers(f) + + buildDomTree(f) + + if f.Prog.mode&NaiveForm == 0 { + // For debugging pre-state of lifting pass: + // numberRegisters(f) + // f.WriteTo(os.Stderr) + lift(f) + } + + // clear remaining builder state + f.results = nil // (used by lifting) + f.deferstack = nil // (used by lifting) + f.vars = nil // (used by lifting) + + // clear out other function state (keep consistent with buildParamsOnly) + f.subst = nil + + // Release the package's type information, unless + // instances of f will later be built from it. + if !f.isGenericOrigin() { + f.info = nil + } + + numberRegisters(f) // uses f.namedRegisters +} + +// done marks the building of f's SSA body complete, +// along with any nested functions, and optionally prints them. +func (f *Function) done() { + assert(f.parent == nil, "done called on an anonymous function") + + var visit func(*Function) + visit = func(f *Function) { + for _, anon := range f.AnonFuncs { + visit(anon) // anon is done building before f. + } + + f.uniq = 0 // done with uniq + f.build = nil // function is built + + if f.Prog.mode&PrintFunctions != 0 { + printMu.Lock() + f.WriteTo(os.Stdout) + printMu.Unlock() + } + + if f.Prog.mode&SanityCheckFunctions != 0 { + mustSanityCheck(f, nil) + } + } + visit(f) +} + +// removeNilBlocks eliminates nils from f.Blocks and updates each +// BasicBlock.Index. Use this after any pass that may delete blocks. +func (f *Function) removeNilBlocks() { + j := 0 + for _, b := range f.Blocks { + if b != nil { + b.Index = j + f.Blocks[j] = b + j++ + } + } + // Nil out f.Blocks[j:] to aid GC. + for i := j; i < len(f.Blocks); i++ { + f.Blocks[i] = nil + } + f.Blocks = f.Blocks[:j] +} + +// SetDebugMode sets the debug mode for package pkg. If true, all its +// functions will include full debug info. This greatly increases the +// size of the instruction stream, and causes Functions to depend upon +// the ASTs, potentially keeping them live in memory for longer. +func (pkg *Package) SetDebugMode(debug bool) { + pkg.debug = debug +} + +// debugInfo reports whether debug info is wanted for this function. +func (f *Function) debugInfo() bool { + // debug info for instantiations follows the debug info of their origin. + p := f.declaredPackage() + return p != nil && p.debug +} + +// lookup returns the address of the named variable identified by obj +// that is local to function f or one of its enclosing functions. +// If escaping, the reference comes from a potentially escaping pointer +// expression and the referent must be heap-allocated. +// We assume the referent is a *Alloc or *Phi. +// (The only Phis at this stage are those created directly by go1.22 "for" loops.) +func (f *Function) lookup(obj *types.Var, escaping bool) Value { + if v, ok := f.vars[obj]; ok { + if escaping { + switch v := v.(type) { + case *Alloc: + v.Heap = true + case *Phi: + for _, edge := range v.Edges { + if alloc, ok := edge.(*Alloc); ok { + alloc.Heap = true + } + } + } + } + return v // function-local var (address) + } + + // Definition must be in an enclosing function; + // plumb it through intervening closures. + if f.parent == nil { + panic("no ssa.Value for " + obj.String()) + } + outer := f.parent.lookup(obj, true) // escaping + v := &FreeVar{ + name: obj.Name(), + typ: outer.Type(), + pos: outer.Pos(), + outer: outer, + parent: f, + } + f.vars[obj] = v + f.FreeVars = append(f.FreeVars, v) + return v +} + +// emit emits the specified instruction to function f. +func (f *Function) emit(instr Instruction) Value { + return f.currentBlock.emit(instr) +} + +// RelString returns the full name of this function, qualified by +// package name, receiver type, etc. +// +// The specific formatting rules are not guaranteed and may change. +// +// Examples: +// +// "math.IsNaN" // a package-level function +// "(*bytes.Buffer).Bytes" // a declared method or a wrapper +// "(*bytes.Buffer).Bytes$thunk" // thunk (func wrapping method; receiver is param 0) +// "(*bytes.Buffer).Bytes$bound" // bound (func wrapping method; receiver supplied by closure) +// "main.main$1" // an anonymous function in main +// "main.init#1" // a declared init function +// "main.init" // the synthesized package initializer +// +// When these functions are referred to from within the same package +// (i.e. from == f.Pkg.Object), they are rendered without the package path. +// For example: "IsNaN", "(*Buffer).Bytes", etc. +// +// All non-synthetic functions have distinct package-qualified names. +// (But two methods may have the same name "(T).f" if one is a synthetic +// wrapper promoting a non-exported method "f" from another package; in +// that case, the strings are equal but the identifiers "f" are distinct.) +func (f *Function) RelString(from *types.Package) string { + // Anonymous? + if f.parent != nil { + // An anonymous function's Name() looks like "parentName$1", + // but its String() should include the type/package/etc. + parent := f.parent.RelString(from) + for i, anon := range f.parent.AnonFuncs { + if anon == f { + return fmt.Sprintf("%s$%d", parent, 1+i) + } + } + + return f.name // should never happen + } + + // Method (declared or wrapper)? + if recv := f.Signature.Recv(); recv != nil { + return f.relMethod(from, recv.Type()) + } + + // Thunk? + if f.method != nil { + return f.relMethod(from, f.method.recv) + } + + // Bound? + if len(f.FreeVars) == 1 && strings.HasSuffix(f.name, "$bound") { + return f.relMethod(from, f.FreeVars[0].Type()) + } + + // Package-level function? + // Prefix with package name for cross-package references only. + if p := f.relPkg(); p != nil && p != from { + return fmt.Sprintf("%s.%s", p.Path(), f.name) + } + + // Unknown. + return f.name +} + +func (f *Function) relMethod(from *types.Package, recv types.Type) string { + return fmt.Sprintf("(%s).%s", relType(recv, from), f.name) +} + +// writeSignature writes to buf the signature sig in declaration syntax. +func writeSignature(buf *bytes.Buffer, from *types.Package, name string, sig *types.Signature) { + buf.WriteString("func ") + if recv := sig.Recv(); recv != nil { + buf.WriteString("(") + if name := recv.Name(); name != "" { + buf.WriteString(name) + buf.WriteString(" ") + } + types.WriteType(buf, recv.Type(), types.RelativeTo(from)) + buf.WriteString(") ") + } + buf.WriteString(name) + types.WriteSignature(buf, sig, types.RelativeTo(from)) +} + +// declaredPackage returns the package fn is declared in or nil if the +// function is not declared in a package. +func (fn *Function) declaredPackage() *Package { + switch { + case fn.Pkg != nil: + return fn.Pkg // non-generic function (does that follow??) + case fn.topLevelOrigin != nil: + return fn.topLevelOrigin.Pkg // instance of a named generic function + case fn.parent != nil: + return fn.parent.declaredPackage() // instance of an anonymous [generic] function + default: + return nil // function is not declared in a package, e.g. a wrapper. + } +} + +// relPkg returns types.Package fn is printed in relationship to. +func (fn *Function) relPkg() *types.Package { + if p := fn.declaredPackage(); p != nil { + return p.Pkg + } + return nil +} + +var _ io.WriterTo = (*Function)(nil) // *Function implements io.Writer + +func (f *Function) WriteTo(w io.Writer) (int64, error) { + var buf bytes.Buffer + WriteFunction(&buf, f) + n, err := w.Write(buf.Bytes()) + return int64(n), err +} + +// WriteFunction writes to buf a human-readable "disassembly" of f. +func WriteFunction(buf *bytes.Buffer, f *Function) { + fmt.Fprintf(buf, "# Name: %s\n", f.String()) + if f.Pkg != nil { + fmt.Fprintf(buf, "# Package: %s\n", f.Pkg.Pkg.Path()) + } + if syn := f.Synthetic; syn != "" { + fmt.Fprintln(buf, "# Synthetic:", syn) + } + if pos := f.Pos(); pos.IsValid() { + fmt.Fprintf(buf, "# Location: %s\n", f.Prog.Fset.Position(pos)) + } + + if f.parent != nil { + fmt.Fprintf(buf, "# Parent: %s\n", f.parent.Name()) + } + + if f.Recover != nil { + fmt.Fprintf(buf, "# Recover: %s\n", f.Recover) + } + + from := f.relPkg() + + if f.FreeVars != nil { + buf.WriteString("# Free variables:\n") + for i, fv := range f.FreeVars { + fmt.Fprintf(buf, "# % 3d:\t%s %s\n", i, fv.Name(), relType(fv.Type(), from)) + } + } + + if len(f.Locals) > 0 { + buf.WriteString("# Locals:\n") + for i, l := range f.Locals { + fmt.Fprintf(buf, "# % 3d:\t%s %s\n", i, l.Name(), relType(typeparams.MustDeref(l.Type()), from)) + } + } + writeSignature(buf, from, f.Name(), f.Signature) + buf.WriteString(":\n") + + if f.Blocks == nil { + buf.WriteString("\t(external)\n") + } + + // NB. column calculations are confused by non-ASCII + // characters and assume 8-space tabs. + const punchcard = 80 // for old time's sake. + const tabwidth = 8 + for _, b := range f.Blocks { + if b == nil { + // Corrupt CFG. + fmt.Fprintf(buf, ".nil:\n") + continue + } + n, _ := fmt.Fprintf(buf, "%d:", b.Index) + // (|predecessors|, |successors|, immediate dominator) + bmsg := fmt.Sprintf("%s P:%d S:%d", b.Comment, len(b.Preds), len(b.Succs)) + if b.Idom() != nil { + bmsg = fmt.Sprintf("%s idom:%d", bmsg, b.Idom().Index) + } + fmt.Fprintf(buf, "%*s%s\n", punchcard-1-n-len(bmsg), "", bmsg) + + if false { // CFG debugging + fmt.Fprintf(buf, "\t# CFG: %s --> %s --> %s\n", b.Preds, b, b.Succs) + } + for _, instr := range b.Instrs { + buf.WriteString("\t") + switch v := instr.(type) { + case Value: + l := punchcard - tabwidth + // Left-align the instruction. + if name := v.Name(); name != "" { + n, _ := fmt.Fprintf(buf, "%s = ", name) + l -= n + } + n, _ := buf.WriteString(instr.String()) + l -= n + // Right-align the type if there's space. + if t := v.Type(); t != nil { + buf.WriteByte(' ') + ts := relType(t, from) + l -= len(ts) + len(" ") // (spaces before and after type) + if l > 0 { + fmt.Fprintf(buf, "%*s", l, "") + } + buf.WriteString(ts) + } + case nil: + // Be robust against bad transforms. + buf.WriteString("") + default: + buf.WriteString(instr.String()) + } + // -mode=S: show line numbers + if f.Prog.mode&LogSource != 0 { + if pos := instr.Pos(); pos.IsValid() { + fmt.Fprintf(buf, " L%d", f.Prog.Fset.Position(pos).Line) + } + } + buf.WriteString("\n") + } + } + fmt.Fprintf(buf, "\n") +} + +// newBasicBlock adds to f a new basic block and returns it. It does +// not automatically become the current block for subsequent calls to emit. +// comment is an optional string for more readable debugging output. +func (f *Function) newBasicBlock(comment string) *BasicBlock { + b := &BasicBlock{ + Index: len(f.Blocks), + Comment: comment, + parent: f, + } + b.Succs = b.succs2[:0] + f.Blocks = append(f.Blocks, b) + return b +} + +// NewFunction returns a new synthetic Function instance belonging to +// prog, with its name and signature fields set as specified. +// +// The caller is responsible for initializing the remaining fields of +// the function object, e.g. Pkg, Params, Blocks. +// +// It is practically impossible for clients to construct well-formed +// SSA functions/packages/programs directly, so we assume this is the +// job of the Builder alone. NewFunction exists to provide clients a +// little flexibility. For example, analysis tools may wish to +// construct fake Functions for the root of the callgraph, a fake +// "reflect" package, etc. +// +// TODO(adonovan): think harder about the API here. +func (prog *Program) NewFunction(name string, sig *types.Signature, provenance string) *Function { + return &Function{Prog: prog, name: name, Signature: sig, Synthetic: provenance} +} + +// Syntax returns the function's syntax (*ast.Func{Decl,Lit}) +// if it was produced from syntax or an *ast.RangeStmt if +// it is a range-over-func yield function. +func (f *Function) Syntax() ast.Node { return f.syntax } + +// identVar returns the variable defined by id. +func identVar(fn *Function, id *ast.Ident) *types.Var { + return fn.info.Defs[id].(*types.Var) +} + +// unique returns a unique positive int within the source tree of f. +// The source tree of f includes all of f's ancestors by parent and all +// of the AnonFuncs contained within these. +func unique(f *Function) int64 { + f.uniq++ + return f.uniq +} + +// exit is a change of control flow going from a range-over-func +// yield function to an ancestor function caused by a break, continue, +// goto, or return statement. +// +// There are 3 types of exits: +// * return from the source function (from ReturnStmt), +// * jump to a block (from break and continue statements [labelled/unlabelled]), +// * go to a label (from goto statements). +// +// As the builder does one pass over the ast, it is unclear whether +// a forward goto statement will leave a range-over-func body. +// The function being exited to is unresolved until the end +// of building the range-over-func body. +type exit struct { + id int64 // unique value for exit within from and to + from *Function // the function the exit starts from + to *Function // the function being exited to (nil if unresolved) + pos token.Pos + + block *BasicBlock // basic block within to being jumped to. + label *types.Label // forward label being jumped to via goto. + // block == nil && label == nil => return +} + +// storeVar emits to function f code to store a value v to a *types.Var x. +func storeVar(f *Function, x *types.Var, v Value, pos token.Pos) { + emitStore(f, f.lookup(x, true), v, pos) +} + +// labelExit creates a new exit to a yield fn to exit the function using a label. +func labelExit(fn *Function, label *types.Label, pos token.Pos) *exit { + e := &exit{ + id: unique(fn), + from: fn, + to: nil, + pos: pos, + label: label, + } + fn.exits = append(fn.exits, e) + return e +} + +// blockExit creates a new exit to a yield fn that jumps to a basic block. +func blockExit(fn *Function, block *BasicBlock, pos token.Pos) *exit { + e := &exit{ + id: unique(fn), + from: fn, + to: block.parent, + pos: pos, + block: block, + } + fn.exits = append(fn.exits, e) + return e +} + +// returnExit creates a new exit to a yield fn that returns the source function. +func returnExit(fn *Function, pos token.Pos) *exit { + e := &exit{ + id: unique(fn), + from: fn, + to: fn.source, + pos: pos, + } + fn.exits = append(fn.exits, e) + return e +} + +// isGenericOrigin reports whether f is an uninstantiated generic +// function or a method of an uninstantiated generic type. +func (f *Function) isGenericOrigin() bool { + return (f.typeparams.Len() > 0 && len(f.typeargs) == 0) || + (f.recvtypeparams.Len() > 0 && len(f.recvtypeargs) == 0) +} diff --git a/vendor/golang.org/x/tools/go/ssa/instantiate.go b/vendor/golang.org/x/tools/go/ssa/instantiate.go new file mode 100644 index 0000000..4eb53aa --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/instantiate.go @@ -0,0 +1,160 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +import ( + "fmt" + "go/types" + "slices" + "sync" +) + +// A generic records information about a generic origin function, +// including a cache of existing instantiations. +type generic struct { + instancesMu sync.Mutex + instances map[*typeList]*Function // canonical type arguments to an instance. +} + +// instance returns a Function that is the instantiation of generic +// origin function fn with the type arguments rtargs and targs. +// +// Any created instance is added to cr. +// +// Acquires fn.generic.instancesMu. +func (fn *Function) instance(rtargs, targs []types.Type, b *builder) *Function { + key := fn.Prog.canon.List(slices.Concat(rtargs, targs)) + + gen := fn.generic + + gen.instancesMu.Lock() + defer gen.instancesMu.Unlock() + inst, ok := gen.instances[key] + if !ok { + inst = createInstance(fn, rtargs, targs) + inst.buildshared = b.shared() + b.enqueue(inst) + + if gen.instances == nil { + gen.instances = make(map[*typeList]*Function) + } + gen.instances[key] = inst + } else { + b.waitForSharedFunction(inst) + } + return inst +} + +// createInstance returns the instantiation of generic function fn using targs. +// If fn is a method on a generic type, fn's receiver type will be instantiated +// using rtargs. +// +// Requires fn.generic.instancesMu. +func createInstance(fn *Function, rtargs, targs []types.Type) *Function { + prog := fn.Prog + + // Compute signature. + var sig *types.Signature + var obj *types.Func + if recv := fn.Signature.Recv(); recv != nil { + // method, len(rtargs) > 0 || len(targs) > 0 + if len(rtargs) > 0 { + // possibly generic method on generic type + obj = prog.canon.instantiateMethod(fn.object, rtargs, prog.ctxt) + } else { + // generic method on non-generic type + obj = fn.object // instantiation does not exist yet + } + if len(targs) > 0 { + // generic method + instSig, err := types.Instantiate(prog.ctxt, obj.Signature(), targs, false) + if err != nil { + panic(err) + } + instance, ok := instSig.(*types.Signature) + if !ok { + panic("Instantiate of a Signature returned a non-signature") + } + // Do not canonicalize generic methods, because the receiver is not + // part of a Signature's type identity. For example, + // (*G[int]).m[int] and (G[int]).n[int] may be identical types even + // though their receiver types differ. + sig = instance + } else { + // non-generic method on generic type + sig = obj.Signature() + } + } else { + // function, len(rtargs) == 0 && len(targs) > 0 + instSig, err := types.Instantiate(prog.ctxt, fn.Signature, targs, false) + if err != nil { + panic(err) + } + instance, ok := instSig.(*types.Signature) + if !ok { + panic("Instantiate of a Signature returned a non-signature") + } + obj = fn.object // instantiation does not exist yet + sig = prog.canon.Type(instance).(*types.Signature) + } + + // Choose strategy (instance or wrapper). + var ( + synthetic string + subst *subster + build buildFunc + ) + if prog.mode&InstantiateGenerics != 0 && !prog.isParameterized(slices.Concat(rtargs, targs)...) { + synthetic = fmt.Sprintf("instance of %s", fn.Name()) + if fn.syntax != nil { + subst = makeSubster(prog.ctxt, obj, fn.recvtypeparams, rtargs, fn.typeparams, targs) + build = (*builder).buildFromSyntax + } else { + build = (*builder).buildParamsOnly + } + } else { + synthetic = fmt.Sprintf("instantiation wrapper of %s", fn.Name()) + build = (*builder).buildInstantiationWrapper + } + + name := fn.Name() + if len(targs) > 0 { + name = fmt.Sprintf("%s%s", name, targstr(targs)) // may not be unique + } + + /* generic instance or instantiation wrapper */ + return &Function{ + name: name, + object: obj, + Signature: sig, + Synthetic: synthetic, + syntax: fn.syntax, // \ + info: fn.info, // } empty for non-created packages + goversion: fn.goversion, // / + build: build, + topLevelOrigin: fn, + pos: obj.Pos(), + Pkg: nil, + Prog: fn.Prog, + recvtypeparams: fn.recvtypeparams, // share with origin + recvtypeargs: rtargs, + typeparams: fn.typeparams, // share with origin + typeargs: targs, + subst: subst, + } +} + +// isParameterized reports whether any of the specified types contains +// a free type parameter. It is safe to call concurrently. +func (prog *Program) isParameterized(ts ...types.Type) bool { + prog.hasParamsMu.Lock() + defer prog.hasParamsMu.Unlock() + + // TODO(adonovan): profile. If this operation is expensive, + // handle the most common but shallow cases such as T, pkg.T, + // *T without consulting the cache under the lock. + + return slices.ContainsFunc(ts, prog.hasParams.Has) +} diff --git a/vendor/golang.org/x/tools/go/ssa/lift.go b/vendor/golang.org/x/tools/go/ssa/lift.go new file mode 100644 index 0000000..d7c1bf5 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/lift.go @@ -0,0 +1,671 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file defines the lifting pass which tries to "lift" Alloc +// cells (new/local variables) into SSA registers, replacing loads +// with the dominating stored value, eliminating loads and stores, and +// inserting φ-nodes as needed. + +// Cited papers and resources: +// +// Ron Cytron et al. 1991. Efficiently computing SSA form... +// http://doi.acm.org/10.1145/115372.115320 +// +// Cooper, Harvey, Kennedy. 2001. A Simple, Fast Dominance Algorithm. +// Software Practice and Experience 2001, 4:1-10. +// http://www.hipersoft.rice.edu/grads/publications/dom14.pdf +// +// Daniel Berlin, llvmdev mailing list, 2012. +// http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-January/046638.html +// (Be sure to expand the whole thread.) + +// TODO(adonovan): opt: there are many optimizations worth evaluating, and +// the conventional wisdom for SSA construction is that a simple +// algorithm well engineered often beats those of better asymptotic +// complexity on all but the most egregious inputs. +// +// Danny Berlin suggests that the Cooper et al. algorithm for +// computing the dominance frontier is superior to Cytron et al. +// Furthermore he recommends that rather than computing the DF for the +// whole function then renaming all alloc cells, it may be cheaper to +// compute the DF for each alloc cell separately and throw it away. +// +// Consider exploiting liveness information to avoid creating dead +// φ-nodes which we then immediately remove. +// +// Also see many other "TODO: opt" suggestions in the code. + +import ( + "fmt" + "go/token" + "math/big" + "os" + "slices" + + "golang.org/x/tools/internal/typeparams" +) + +// If true, show diagnostic information at each step of lifting. +// Very verbose. +const debugLifting = false + +// domFrontier maps each block to the set of blocks in its dominance +// frontier. The outer slice is conceptually a map keyed by +// Block.Index. The inner slice is conceptually a set, possibly +// containing duplicates. +// +// TODO(adonovan): opt: measure impact of dups; consider a packed bit +// representation, e.g. big.Int, and bitwise parallel operations for +// the union step in the Children loop. +// +// domFrontier's methods mutate the slice's elements but not its +// length, so their receivers needn't be pointers. +type domFrontier [][]*BasicBlock + +func (df domFrontier) add(u, v *BasicBlock) { + p := &df[u.Index] + *p = append(*p, v) +} + +// build builds the dominance frontier df for the dominator (sub)tree +// rooted at u, using the Cytron et al. algorithm. +// +// TODO(adonovan): opt: consider Berlin approach, computing pruned SSA +// by pruning the entire IDF computation, rather than merely pruning +// the DF -> IDF step. +func (df domFrontier) build(u *BasicBlock) { + // Encounter each node u in postorder of dom tree. + for _, child := range u.dom.children { + df.build(child) + } + for _, vb := range u.Succs { + if v := vb.dom; v.idom != u { + df.add(u, vb) + } + } + for _, w := range u.dom.children { + for _, vb := range df[w.Index] { + // TODO(adonovan): opt: use word-parallel bitwise union. + if v := vb.dom; v.idom != u { + df.add(u, vb) + } + } + } +} + +func buildDomFrontier(fn *Function) domFrontier { + df := make(domFrontier, len(fn.Blocks)) + df.build(fn.Blocks[0]) + if fn.Recover != nil { + df.build(fn.Recover) + } + return df +} + +func removeInstr(refs []Instruction, instr Instruction) []Instruction { + return slices.DeleteFunc(refs, func(i Instruction) bool { return i == instr }) +} + +// lift replaces local and new Allocs accessed only with +// load/store by SSA registers, inserting φ-nodes where necessary. +// The result is a program in classical pruned SSA form. +// +// Preconditions: +// - fn has no dead blocks (blockopt has run). +// - Def/use info (Operands and Referrers) is up-to-date. +// - The dominator tree is up-to-date. +func lift(fn *Function) { + // TODO(adonovan): opt: lots of little optimizations may be + // worthwhile here, especially if they cause us to avoid + // buildDomFrontier. For example: + // + // - Alloc never loaded? Eliminate. + // - Alloc never stored? Replace all loads with a zero constant. + // - Alloc stored once? Replace loads with dominating store; + // don't forget that an Alloc is itself an effective store + // of zero. + // - Alloc used only within a single block? + // Use degenerate algorithm avoiding φ-nodes. + // - Consider synergy with scalar replacement of aggregates (SRA). + // e.g. *(&x.f) where x is an Alloc. + // Perhaps we'd get better results if we generated this as x.f + // i.e. Field(x, .f) instead of Load(FieldIndex(x, .f)). + // Unclear. + // + // But we will start with the simplest correct code. + df := buildDomFrontier(fn) + + if debugLifting { + title := false + for i, blocks := range df { + if blocks != nil { + if !title { + fmt.Fprintf(os.Stderr, "Dominance frontier of %s:\n", fn) + title = true + } + fmt.Fprintf(os.Stderr, "\t%s: %s\n", fn.Blocks[i], blocks) + } + } + } + + newPhis := make(newPhiMap) + + // During this pass we will replace some BasicBlock.Instrs + // (allocs, loads and stores) with nil, keeping a count in + // BasicBlock.gaps. At the end we will reset Instrs to the + // concatenation of all non-dead newPhis and non-nil Instrs + // for the block, reusing the original array if space permits. + + // While we're here, we also eliminate 'rundefers' + // instructions and ssa:deferstack() in functions that contain no + // 'defer' instructions. For now, we also eliminate + // 's = ssa:deferstack()' calls if s doesn't escape, replacing s + // with nil in Defer{DeferStack: s}. This has the same meaning, + // but allows eliminating the intrinsic function `ssa:deferstack()` + // (unless it is needed due to range-over-func instances). This gives + // ssa users more time to support range-over-func. + usesDefer := false + deferstackAlloc, deferstackCall := deferstackPreamble(fn) + eliminateDeferStack := deferstackAlloc != nil && !deferstackAlloc.Heap + + // A counter used to generate ~unique ids for Phi nodes, as an + // aid to debugging. We use large numbers to make them highly + // visible. All nodes are renumbered later. + fresh := 1000 + + // Determine which allocs we can lift and number them densely. + // The renaming phase uses this numbering for compact maps. + numAllocs := 0 + for _, b := range fn.Blocks { + b.gaps = 0 + b.rundefers = 0 + for _, instr := range b.Instrs { + switch instr := instr.(type) { + case *Alloc: + index := -1 + if liftAlloc(df, instr, newPhis, &fresh) { + index = numAllocs + numAllocs++ + } + instr.index = index + case *Defer: + usesDefer = true + if eliminateDeferStack { + // Clear DeferStack and remove references to loads + if instr.DeferStack != nil { + if refs := instr.DeferStack.Referrers(); refs != nil { + *refs = removeInstr(*refs, instr) + } + instr.DeferStack = nil + } + } + case *RunDefers: + b.rundefers++ + } + } + } + + // renaming maps an alloc (keyed by index) to its replacement + // value. Initially the renaming contains nil, signifying the + // zero constant of the appropriate type; we construct the + // Const lazily at most once on each path through the domtree. + // TODO(adonovan): opt: cache per-function not per subtree. + renaming := make([]Value, numAllocs) + + // Renaming. + rename(fn.Blocks[0], renaming, newPhis) + + // Eliminate dead φ-nodes. + removeDeadPhis(fn.Blocks, newPhis) + + // Eliminate ssa:deferstack() call. + if eliminateDeferStack { + b := deferstackCall.block + for i, instr := range b.Instrs { + if instr == deferstackCall { + b.Instrs[i] = nil + b.gaps++ + break + } + } + } + + // Prepend remaining live φ-nodes to each block. + for _, b := range fn.Blocks { + nps := newPhis[b] + j := len(nps) + + rundefersToKill := b.rundefers + if usesDefer { + rundefersToKill = 0 + } + + if j+b.gaps+rundefersToKill == 0 { + continue // fast path: no new phis or gaps + } + + // Compact nps + non-nil Instrs into a new slice. + // TODO(adonovan): opt: compact in situ (rightwards) + // if Instrs has sufficient space or slack. + dst := make([]Instruction, len(b.Instrs)+j-b.gaps-rundefersToKill) + for i, np := range nps { + dst[i] = np.phi + } + for _, instr := range b.Instrs { + if instr == nil { + continue + } + if !usesDefer { + if _, ok := instr.(*RunDefers); ok { + continue + } + } + dst[j] = instr + j++ + } + b.Instrs = dst + } + + // Remove any fn.Locals that were lifted. + j := 0 + for _, l := range fn.Locals { + if l.index < 0 { + fn.Locals[j] = l + j++ + } + } + // Nil out fn.Locals[j:] to aid GC. + for i := j; i < len(fn.Locals); i++ { + fn.Locals[i] = nil + } + fn.Locals = fn.Locals[:j] +} + +// removeDeadPhis removes φ-nodes not transitively needed by a +// non-Phi, non-DebugRef instruction. +func removeDeadPhis(blocks []*BasicBlock, newPhis newPhiMap) { + // First pass: find the set of "live" φ-nodes: those reachable + // from some non-Phi instruction. + // + // We compute reachability in reverse, starting from each φ, + // rather than forwards, starting from each live non-Phi + // instruction, because this way visits much less of the + // Value graph. + livePhis := make(map[*Phi]bool) + for _, npList := range newPhis { + for _, np := range npList { + phi := np.phi + if !livePhis[phi] && phiHasDirectReferrer(phi) { + markLivePhi(livePhis, phi) + } + } + } + + // Existing φ-nodes due to && and || operators + // are all considered live (see Go issue 19622). + for _, b := range blocks { + for _, phi := range b.phis() { + markLivePhi(livePhis, phi.(*Phi)) + } + } + + // Second pass: eliminate unused phis from newPhis. + for block, npList := range newPhis { + j := 0 + for _, np := range npList { + if livePhis[np.phi] { + npList[j] = np + j++ + } else { + // discard it, first removing it from referrers + for _, val := range np.phi.Edges { + if refs := val.Referrers(); refs != nil { + *refs = removeInstr(*refs, np.phi) + } + } + np.phi.block = nil + } + } + newPhis[block] = npList[:j] + } +} + +// markLivePhi marks phi, and all φ-nodes transitively reachable via +// its Operands, live. +func markLivePhi(livePhis map[*Phi]bool, phi *Phi) { + livePhis[phi] = true + for _, rand := range phi.Operands(nil) { + if q, ok := (*rand).(*Phi); ok { + if !livePhis[q] { + markLivePhi(livePhis, q) + } + } + } +} + +// phiHasDirectReferrer reports whether phi is directly referred to by +// a non-Phi instruction. Such instructions are the +// roots of the liveness traversal. +func phiHasDirectReferrer(phi *Phi) bool { + for _, instr := range *phi.Referrers() { + if _, ok := instr.(*Phi); !ok { + return true + } + } + return false +} + +type blockSet struct{ big.Int } // (inherit methods from Int) + +// add adds b to the set and returns true if the set changed. +func (s *blockSet) add(b *BasicBlock) bool { + i := b.Index + if s.Bit(i) != 0 { + return false + } + s.SetBit(&s.Int, i, 1) + return true +} + +// take removes an arbitrary element from a set s and +// returns its index, or returns -1 if empty. +func (s *blockSet) take() int { + l := s.BitLen() + for i := range l { + if s.Bit(i) == 1 { + s.SetBit(&s.Int, i, 0) + return i + } + } + return -1 +} + +// newPhi is a pair of a newly introduced φ-node and the lifted Alloc +// it replaces. +type newPhi struct { + phi *Phi + alloc *Alloc +} + +// newPhiMap records for each basic block, the set of newPhis that +// must be prepended to the block. +type newPhiMap map[*BasicBlock][]newPhi + +// liftAlloc determines whether alloc can be lifted into registers, +// and if so, it populates newPhis with all the φ-nodes it may require +// and returns true. +// +// fresh is a source of fresh ids for phi nodes. +func liftAlloc(df domFrontier, alloc *Alloc, newPhis newPhiMap, fresh *int) bool { + // Don't lift result values in functions that defer + // calls that may recover from panic. + if fn := alloc.Parent(); fn.Recover != nil { + if slices.Contains(fn.results, alloc) { + return false + } + } + + // Compute defblocks, the set of blocks containing a + // definition of the alloc cell. + var defblocks blockSet + for _, instr := range *alloc.Referrers() { + // Bail out if we discover the alloc is not liftable; + // the only operations permitted to use the alloc are + // loads/stores into the cell, and DebugRef. + switch instr := instr.(type) { + case *Store: + if instr.Val == alloc { + return false // address used as value + } + if instr.Addr != alloc { + panic("Alloc.Referrers is inconsistent") + } + defblocks.add(instr.Block()) + case *UnOp: + if instr.Op != token.MUL { + return false // not a load + } + if instr.X != alloc { + panic("Alloc.Referrers is inconsistent") + } + case *DebugRef: + // ok + default: + return false // some other instruction + } + } + // The Alloc itself counts as a (zero) definition of the cell. + defblocks.add(alloc.Block()) + + if debugLifting { + fmt.Fprintln(os.Stderr, "\tlifting ", alloc, alloc.Name()) + } + + fn := alloc.Parent() + + // Φ-insertion. + // + // What follows is the body of the main loop of the insert-φ + // function described by Cytron et al, but instead of using + // counter tricks, we just reset the 'hasAlready' and 'work' + // sets each iteration. These are bitmaps so it's pretty cheap. + // + // TODO(adonovan): opt: recycle slice storage for W, + // hasAlready, defBlocks across liftAlloc calls. + var hasAlready blockSet + + // Initialize W and work to defblocks. + var work blockSet = defblocks // blocks seen + var W blockSet // blocks to do + W.Set(&defblocks.Int) + + // Traverse iterated dominance frontier, inserting φ-nodes. + for i := W.take(); i != -1; i = W.take() { + u := fn.Blocks[i] + for _, v := range df[u.Index] { + if hasAlready.add(v) { + // Create φ-node. + // It will be prepended to v.Instrs later, if needed. + phi := &Phi{ + Edges: make([]Value, len(v.Preds)), + Comment: alloc.Comment, + } + // This is merely a debugging aid: + phi.setNum(*fresh) + *fresh++ + + phi.pos = alloc.Pos() + phi.setType(typeparams.MustDeref(alloc.Type())) + phi.block = v + if debugLifting { + fmt.Fprintf(os.Stderr, "\tplace %s = %s at block %s\n", phi.Name(), phi, v) + } + newPhis[v] = append(newPhis[v], newPhi{phi, alloc}) + + if work.add(v) { + W.add(v) + } + } + } + } + + return true +} + +// replaceAll replaces all intraprocedural uses of x with y, +// updating x.Referrers and y.Referrers. +// Precondition: x.Referrers() != nil, i.e. x must be local to some function. +func replaceAll(x, y Value) { + var rands []*Value + pxrefs := x.Referrers() + pyrefs := y.Referrers() + for _, instr := range *pxrefs { + rands = instr.Operands(rands[:0]) // recycle storage + for _, rand := range rands { + if *rand != nil { + if *rand == x { + *rand = y + } + } + } + if pyrefs != nil { + *pyrefs = append(*pyrefs, instr) // dups ok + } + } + *pxrefs = nil // x is now unreferenced +} + +// renamed returns the value to which alloc is being renamed, +// constructing it lazily if it's the implicit zero initialization. +func renamed(renaming []Value, alloc *Alloc) Value { + v := renaming[alloc.index] + if v == nil { + v = zeroConst(typeparams.MustDeref(alloc.Type())) + renaming[alloc.index] = v + } + return v +} + +// rename implements the (Cytron et al) SSA renaming algorithm, a +// preorder traversal of the dominator tree replacing all loads of +// Alloc cells with the value stored to that cell by the dominating +// store instruction. For lifting, we need only consider loads, +// stores and φ-nodes. +// +// renaming is a map from *Alloc (keyed by index number) to its +// dominating stored value; newPhis[x] is the set of new φ-nodes to be +// prepended to block x. +func rename(u *BasicBlock, renaming []Value, newPhis newPhiMap) { + // Each φ-node becomes the new name for its associated Alloc. + for _, np := range newPhis[u] { + phi := np.phi + alloc := np.alloc + renaming[alloc.index] = phi + } + + // Rename loads and stores of allocs. + for i, instr := range u.Instrs { + switch instr := instr.(type) { + case *Alloc: + if instr.index >= 0 { // store of zero to Alloc cell + // Replace dominated loads by the zero value. + renaming[instr.index] = nil + if debugLifting { + fmt.Fprintf(os.Stderr, "\tkill alloc %s\n", instr) + } + // Delete the Alloc. + u.Instrs[i] = nil + u.gaps++ + } + + case *Store: + if alloc, ok := instr.Addr.(*Alloc); ok && alloc.index >= 0 { // store to Alloc cell + // Replace dominated loads by the stored value. + renaming[alloc.index] = instr.Val + if debugLifting { + fmt.Fprintf(os.Stderr, "\tkill store %s; new value: %s\n", + instr, instr.Val.Name()) + } + // Remove the store from the referrer list of the stored value. + if refs := instr.Val.Referrers(); refs != nil { + *refs = removeInstr(*refs, instr) + } + // Delete the Store. + u.Instrs[i] = nil + u.gaps++ + } + + case *UnOp: + if instr.Op == token.MUL { + if alloc, ok := instr.X.(*Alloc); ok && alloc.index >= 0 { // load of Alloc cell + newval := renamed(renaming, alloc) + if debugLifting { + fmt.Fprintf(os.Stderr, "\tupdate load %s = %s with %s\n", + instr.Name(), instr, newval.Name()) + } + // Replace all references to + // the loaded value by the + // dominating stored value. + replaceAll(instr, newval) + // Delete the Load. + u.Instrs[i] = nil + u.gaps++ + } + } + + case *DebugRef: + if alloc, ok := instr.X.(*Alloc); ok && alloc.index >= 0 { // ref of Alloc cell + if instr.IsAddr { + instr.X = renamed(renaming, alloc) + instr.IsAddr = false + + // Add DebugRef to instr.X's referrers. + if refs := instr.X.Referrers(); refs != nil { + *refs = append(*refs, instr) + } + } else { + // A source expression denotes the address + // of an Alloc that was optimized away. + instr.X = nil + + // Delete the DebugRef. + u.Instrs[i] = nil + u.gaps++ + } + } + } + } + + // For each φ-node in a CFG successor, rename the edge. + for _, v := range u.Succs { + phis := newPhis[v] + if len(phis) == 0 { + continue + } + i := v.predIndex(u) + for _, np := range phis { + phi := np.phi + alloc := np.alloc + newval := renamed(renaming, alloc) + if debugLifting { + fmt.Fprintf(os.Stderr, "\tsetphi %s edge %s -> %s (#%d) (alloc=%s) := %s\n", + phi.Name(), u, v, i, alloc.Name(), newval.Name()) + } + phi.Edges[i] = newval + if prefs := newval.Referrers(); prefs != nil { + *prefs = append(*prefs, phi) + } + } + } + + // Continue depth-first recursion over domtree, pushing a + // fresh copy of the renaming map for each subtree. + for i, v := range u.dom.children { + r := renaming + if i < len(u.dom.children)-1 { + // On all but the final iteration, we must make + // a copy to avoid destructive update. + r = make([]Value, len(renaming)) + copy(r, renaming) + } + rename(v, r, newPhis) + } + +} + +// deferstackPreamble returns the *Alloc and ssa:deferstack() call for fn.deferstack. +func deferstackPreamble(fn *Function) (*Alloc, *Call) { + if alloc, _ := fn.vars[fn.deferstack].(*Alloc); alloc != nil { + for _, ref := range *alloc.Referrers() { + if ref, _ := ref.(*Store); ref != nil && ref.Addr == alloc { + if call, _ := ref.Val.(*Call); call != nil { + return alloc, call + } + } + } + } + return nil, nil +} diff --git a/vendor/golang.org/x/tools/go/ssa/lvalue.go b/vendor/golang.org/x/tools/go/ssa/lvalue.go new file mode 100644 index 0000000..eede307 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/lvalue.go @@ -0,0 +1,155 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// lvalues are the union of addressable expressions and map-index +// expressions. + +import ( + "go/ast" + "go/token" + "go/types" + + "golang.org/x/tools/internal/typeparams" +) + +// An lvalue represents an assignable location that may appear on the +// left-hand side of an assignment. This is a generalization of a +// pointer to permit updates to elements of maps. +type lvalue interface { + store(fn *Function, v Value) // stores v into the location + load(fn *Function) Value // loads the contents of the location + address(fn *Function) Value // address of the location + typ() types.Type // returns the type of the location +} + +// An address is an lvalue represented by a true pointer. +type address struct { + addr Value // must have a pointer core type. + pos token.Pos // source position + expr ast.Expr // source syntax of the value (not address) [debug mode] +} + +func (a *address) load(fn *Function) Value { + load := emitLoad(fn, a.addr) + load.pos = a.pos + return load +} + +func (a *address) store(fn *Function, v Value) { + store := emitStore(fn, a.addr, v, a.pos) + if a.expr != nil { + // store.Val is v, converted for assignability. + emitDebugRef(fn, a.expr, store.Val, false) + } +} + +func (a *address) address(fn *Function) Value { + if a.expr != nil { + emitDebugRef(fn, a.expr, a.addr, true) + } + return a.addr +} + +func (a *address) typ() types.Type { + return typeparams.MustDeref(a.addr.Type()) +} + +// An element is an lvalue represented by m[k], the location of an +// element of a map. These locations are not addressable +// since pointers cannot be formed from them, but they do support +// load() and store(). +type element struct { + m, k Value // map + t types.Type // map element type + pos token.Pos // source position of colon ({k:v}) or lbrack (m[k]=v) +} + +func (e *element) load(fn *Function) Value { + l := &Lookup{ + X: e.m, + Index: e.k, + } + l.setPos(e.pos) + l.setType(e.t) + return fn.emit(l) +} + +func (e *element) store(fn *Function, v Value) { + up := &MapUpdate{ + Map: e.m, + Key: e.k, + Value: emitConv(fn, v, e.t), + } + up.pos = e.pos + fn.emit(up) +} + +func (e *element) address(fn *Function) Value { + panic("map elements are not addressable") +} + +func (e *element) typ() types.Type { + return e.t +} + +// A lazyAddress is an lvalue whose address is the result of an instruction. +// These work like an *address except a new address.address() Value +// is created on each load, store and address call. +// A lazyAddress can be used to control when a side effect (nil pointer +// dereference, index out of bounds) of using a location happens. +type lazyAddress struct { + addr func(fn *Function) Value // emit to fn the computation of the address + t types.Type // type of the location + pos token.Pos // source position + expr ast.Expr // source syntax of the value (not address) [debug mode] +} + +func (l *lazyAddress) load(fn *Function) Value { + load := emitLoad(fn, l.addr(fn)) + load.pos = l.pos + return load +} + +func (l *lazyAddress) store(fn *Function, v Value) { + store := emitStore(fn, l.addr(fn), v, l.pos) + if l.expr != nil { + // store.Val is v, converted for assignability. + emitDebugRef(fn, l.expr, store.Val, false) + } +} + +func (l *lazyAddress) address(fn *Function) Value { + addr := l.addr(fn) + if l.expr != nil { + emitDebugRef(fn, l.expr, addr, true) + } + return addr +} + +func (l *lazyAddress) typ() types.Type { return l.t } + +// A blank is a dummy variable whose name is "_". +// It is not reified: loads are illegal and stores are ignored. +type blank struct{} + +func (bl blank) load(fn *Function) Value { + panic("blank.load is illegal") +} + +func (bl blank) store(fn *Function, v Value) { + // no-op +} + +func (bl blank) address(fn *Function) Value { + panic("blank var is not addressable") +} + +func (bl blank) typ() types.Type { + // This should be the type of the blank Ident; the typechecker + // doesn't provide this yet, but fortunately, we don't need it + // yet either. + panic("blank.typ is unimplemented") +} diff --git a/vendor/golang.org/x/tools/go/ssa/methods.go b/vendor/golang.org/x/tools/go/ssa/methods.go new file mode 100644 index 0000000..30fcf8b --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/methods.go @@ -0,0 +1,249 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file defines utilities for population of method sets. + +import ( + "fmt" + "go/token" + "go/types" + + "golang.org/x/tools/go/types/typeutil" + "golang.org/x/tools/internal/typesinternal" +) + +// MethodValue returns the Function implementing method sel, building +// wrapper methods on demand. It returns nil if sel denotes an +// interface or generic method, or a method of a generic type. +// +// Precondition: sel.Kind() == MethodVal. +// +// Thread-safe. +// +// Acquires prog.methodsMu. +func (prog *Program) MethodValue(sel *types.Selection) *Function { + if sel.Kind() != types.MethodVal { + panic(fmt.Sprintf("MethodValue(%s) kind != MethodVal", sel)) + } + + method := sel.Obj().(*types.Func) + if method.Signature().TypeParams().Len() > 0 { + return nil // generic method + } + + T := sel.Recv() + if types.IsInterface(T) { + return nil // interface method or type parameter + } + + // We can avoid materializing sel.Type(): it will be parameterized iff + // the receiver type T is too (see go.dev/issue/81308). + if prog.isParameterized(T) { + return nil // method on generic type + } + + if prog.mode&LogSource != 0 { + defer logStack("MethodValue %s %v", T, sel)() + } + + key := methodKeyOf(method.Pkg(), method.Name()) + + // The critical section returns a builder only if it created a + // new Function. In the common case, a method created by an + // earlier call, it allocates nothing: a builder declared out + // here would escape to the heap on every call. + fn, b := func() (*Function, *builder) { + prog.methodsMu.Lock() + defer prog.methodsMu.Unlock() + + // Get or create SSA method set. + mset, ok := prog.methodSets.At(T).(*methodSet) + if !ok { + mset = &methodSet{mapping: make(map[methodKey]*Function)} + prog.methodSets.Set(T, mset) + } + + // Get or create SSA method. + if fn, ok := mset.mapping[key]; ok { + return fn, nil + } + b := new(builder) + var fn *Function + needsPromotion := len(sel.Index()) > 1 + needsIndirection := !isPointer(recvType(method)) && isPointer(T) + if needsPromotion || needsIndirection { + fn = createWrapper(prog, toSelection(sel), nil) + fn.buildshared = b.shared() + b.enqueue(fn) + } else { + fn = prog.objectMethod(method, nil, b) + } + if fn.Signature.Recv() == nil { + panic(fn) + } + mset.mapping[key] = fn + return fn, b + }() + + if b != nil { + b.iterate() + } else if !fn.buildshared.isTransitivelyDone() { + // fn was created by an earlier call and another builder + // is still building it: wait for that to finish. + var b builder + b.waitForSharedFunction(fn) + b.iterate() + } + + return fn +} + +// objectMethod returns the Function for a given method symbol. +// The symbol may be an instance of a generic function. It need not +// belong to an existing SSA package created by a call to +// prog.CreatePackage. +// +// objectMethod panics if the function is not a method. +// +// Acquires prog.objectMethodsMu. +func (prog *Program) objectMethod(obj *types.Func, targs []types.Type, b *builder) *Function { + sig := obj.Type().(*types.Signature) + if sig.Recv() == nil { + panic("not a method: " + obj.String()) + } + + // Instantiation of generic? + if orig := obj.Origin(); orig != obj || len(targs) > 0 { + return prog.objectMethod(orig, nil, b).instance(receiverTypeArgs(obj), targs, b) + } + + // Belongs to a created package? + if fn := prog.FuncValue(obj); fn != nil { + return fn + } + + // Consult/update cache of methods created from types.Func. + prog.objectMethodsMu.Lock() + defer prog.objectMethodsMu.Unlock() + fn, ok := prog.objectMethods[obj] + if !ok { + fn = createFunction(prog, obj, obj.Name(), nil, nil, "") + fn.Synthetic = "from type information (on demand)" + fn.buildshared = b.shared() + b.enqueue(fn) + + if prog.objectMethods == nil { + prog.objectMethods = make(map[*types.Func]*Function) + } + prog.objectMethods[obj] = fn + } else { + b.waitForSharedFunction(fn) + } + return fn +} + +// LookupMethod returns the implementation of the method of type T +// identified by (pkg, name). It returns nil if the method exists but +// is an interface method or generic method, and panics if T has no such method. +func (prog *Program) LookupMethod(T types.Type, pkg *types.Package, name string) *Function { + // Fast path: the method was created and built by an earlier + // call. RTA calls LookupMethod once per (call site, concrete + // type) pair, so this is the common case; it avoids computing + // the method set of T and searching it, which dominates the + // cost of the slow path below. + if fn := prog.existingMethod(T, methodKeyOf(pkg, name)); fn != nil { + return fn + } + + sel := prog.MethodSets.MethodSet(T).Lookup(pkg, name) + if sel == nil { + panic(fmt.Sprintf("%s has no method %s", T, types.Id(pkg, name))) + } + return prog.MethodValue(sel) +} + +// existingMethod returns the Function implementing the method of +// the concrete type T identified by key, if it has already been +// created and built, or nil. A recorded method implies that T was +// found to be concrete and non-parameterized and the method +// non-generic when it was created. +// +// Acquires prog.methodsMu. +func (prog *Program) existingMethod(T types.Type, key methodKey) *Function { + prog.methodsMu.Lock() + defer prog.methodsMu.Unlock() + if mset, ok := prog.methodSets.At(T).(*methodSet); ok { + if fn := mset.mapping[key]; fn != nil && fn.buildshared.isTransitivelyDone() { + return fn + } + } + return nil +} + +// methodSet contains the (concrete) methods of a concrete type (non-interface, non-parameterized). +type methodSet struct { + mapping map[methodKey]*Function // populated lazily +} + +// methodKey identifies a method within a method set the same way +// types.Id does, by name for exported methods and by package path +// and name for unexported ones, without building a string. +type methodKey struct { + path string // package path, or "" if name is exported + name string +} + +func methodKeyOf(pkg *types.Package, name string) methodKey { + if token.IsExported(name) { + return methodKey{"", name} + } + path := "_" // as types.Id does when pkg is nil + if pkg != nil { + path = pkg.Path() + } + return methodKey{path, name} +} + +// RuntimeTypes returns a new unordered slice containing all types in +// the program for which a runtime type is required. +// +// A runtime type is required for any non-parameterized, non-interface +// type that is converted to an interface, or for any type (including +// interface types) derivable from one through reflection. +// +// The methods of such types may be reachable through reflection or +// interface calls even if they are never called directly. +// +// Thread-safe. +// +// Acquires prog.makeInterfaceTypesMu. +func (prog *Program) RuntimeTypes() []types.Type { + prog.makeInterfaceTypesMu.Lock() + defer prog.makeInterfaceTypesMu.Unlock() + + // Compute the derived types on demand, since many SSA clients + // never call RuntimeTypes, and those that do typically call + // it once (often within ssautil.AllFunctions, which will + // eventually not use it; see Go issue #69291.) This + // eliminates the need to eagerly compute all the element + // types during SSA building. + var runtimeTypes []types.Type + var set typeutil.Map // for de-duping identical types + for t := range prog.makeInterfaceTypes { + typesinternal.ForEachElement(prog.MethodSets.MethodSet, t, func(t types.Type, access bool) bool { + if !access { + return false // inaccessible to reflection + } + seen, _ := set.Set(t, true).(bool) + if !seen { + runtimeTypes = append(runtimeTypes, t) + } + return seen + }) + } + + return runtimeTypes +} diff --git a/vendor/golang.org/x/tools/go/ssa/mode.go b/vendor/golang.org/x/tools/go/ssa/mode.go new file mode 100644 index 0000000..61c9145 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/mode.go @@ -0,0 +1,111 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file defines the BuilderMode type and its command-line flag. + +import ( + "bytes" + "fmt" +) + +// BuilderMode is a bitmask of options for diagnostics and checking. +// +// *BuilderMode satisfies the flag.Value interface. Example: +// +// var mode = ssa.BuilderMode(0) +// func init() { flag.Var(&mode, "build", ssa.BuilderModeDoc) } +type BuilderMode uint + +const ( + PrintPackages BuilderMode = 1 << iota // Print package inventory to stdout + PrintFunctions // Print function SSA code to stdout + LogSource // Log source locations as SSA builder progresses + SanityCheckFunctions // Perform sanity checking of function bodies + NaiveForm // Build naïve SSA form: don't replace local loads/stores with registers + BuildSerially // Build packages serially, not in parallel. + GlobalDebug // Enable debug info for all packages + BareInits // Build init functions without guards or calls to dependent inits + InstantiateGenerics // Instantiate generics functions (monomorphize) while building +) + +const BuilderModeDoc = `Options controlling the SSA builder. +The value is a sequence of zero or more of these letters: +C perform sanity [C]hecking of the SSA form. +D include [D]ebug info for every function. +P print [P]ackage inventory. +F print [F]unction SSA code. +S log [S]ource locations as SSA builder progresses. +L build distinct packages seria[L]ly instead of in parallel. +N build [N]aive SSA form: don't replace local loads/stores with registers. +I build bare [I]nit functions: no init guards or calls to dependent inits. +G instantiate [G]eneric function bodies via monomorphization +` + +func (m BuilderMode) String() string { + var buf bytes.Buffer + if m&GlobalDebug != 0 { + buf.WriteByte('D') + } + if m&PrintPackages != 0 { + buf.WriteByte('P') + } + if m&PrintFunctions != 0 { + buf.WriteByte('F') + } + if m&LogSource != 0 { + buf.WriteByte('S') + } + if m&SanityCheckFunctions != 0 { + buf.WriteByte('C') + } + if m&NaiveForm != 0 { + buf.WriteByte('N') + } + if m&BuildSerially != 0 { + buf.WriteByte('L') + } + if m&BareInits != 0 { + buf.WriteByte('I') + } + if m&InstantiateGenerics != 0 { + buf.WriteByte('G') + } + return buf.String() +} + +// Set parses the flag characters in s and updates *m. +func (m *BuilderMode) Set(s string) error { + var mode BuilderMode + for _, c := range s { + switch c { + case 'D': + mode |= GlobalDebug + case 'P': + mode |= PrintPackages + case 'F': + mode |= PrintFunctions + case 'S': + mode |= LogSource | BuildSerially + case 'C': + mode |= SanityCheckFunctions + case 'N': + mode |= NaiveForm + case 'L': + mode |= BuildSerially + case 'I': + mode |= BareInits + case 'G': + mode |= InstantiateGenerics + default: + return fmt.Errorf("unknown BuilderMode option: %q", c) + } + } + *m = mode + return nil +} + +// Get returns m. +func (m BuilderMode) Get() any { return m } diff --git a/vendor/golang.org/x/tools/go/ssa/print.go b/vendor/golang.org/x/tools/go/ssa/print.go new file mode 100644 index 0000000..8b92d08 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/print.go @@ -0,0 +1,462 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file implements the String() methods for all Value and +// Instruction types. + +import ( + "bytes" + "fmt" + "go/types" + "io" + "reflect" + "sort" + "strings" + + "golang.org/x/tools/go/types/typeutil" + "golang.org/x/tools/internal/typeparams" +) + +// relName returns the name of v relative to i. +// In most cases, this is identical to v.Name(), but references to +// Functions (including methods) and Globals use RelString and +// all types are displayed with relType, so that only cross-package +// references are package-qualified. +func relName(v Value, i Instruction) string { + var from *types.Package + if i != nil { + from = i.Parent().relPkg() + } + switch v := v.(type) { + case Member: // *Function or *Global + return v.RelString(from) + case *Const: + return v.RelString(from) + } + return v.Name() +} + +func relType(t types.Type, from *types.Package) string { + return types.TypeString(t, types.RelativeTo(from)) +} + +func relTerm(term *types.Term, from *types.Package) string { + s := relType(term.Type(), from) + if term.Tilde() { + return "~" + s + } + return s +} + +func relString(m Member, from *types.Package) string { + // NB: not all globals have an Object (e.g. init$guard), + // so use Package().Object not Object.Package(). + if pkg := m.Package().Pkg; pkg != nil && pkg != from { + return fmt.Sprintf("%s.%s", pkg.Path(), m.Name()) + } + return m.Name() +} + +// Value.String() +// +// This method is provided only for debugging. +// It never appears in disassembly, which uses Value.Name(). + +func (v *Parameter) String() string { + from := v.Parent().relPkg() + return fmt.Sprintf("parameter %s : %s", v.Name(), relType(v.Type(), from)) +} + +func (v *FreeVar) String() string { + from := v.Parent().relPkg() + return fmt.Sprintf("freevar %s : %s", v.Name(), relType(v.Type(), from)) +} + +func (v *Builtin) String() string { + return fmt.Sprintf("builtin %s", v.Name()) +} + +// Instruction.String() + +func (v *Alloc) String() string { + op := "local" + if v.Heap { + op = "new" + } + from := v.Parent().relPkg() + return fmt.Sprintf("%s %s (%s)", op, relType(typeparams.MustDeref(v.Type()), from), v.Comment) +} + +func (v *Phi) String() string { + var b bytes.Buffer + b.WriteString("phi [") + for i, edge := range v.Edges { + if i > 0 { + b.WriteString(", ") + } + // Be robust against malformed CFG. + if v.block == nil { + b.WriteString("??") + continue + } + block := -1 + if i < len(v.block.Preds) { + block = v.block.Preds[i].Index + } + fmt.Fprintf(&b, "%d: ", block) + edgeVal := "" // be robust + if edge != nil { + edgeVal = relName(edge, v) + } + b.WriteString(edgeVal) + } + b.WriteString("]") + if v.Comment != "" { + b.WriteString(" #") + b.WriteString(v.Comment) + } + return b.String() +} + +func printCall(v *CallCommon, prefix string, instr Instruction) string { + var b bytes.Buffer + b.WriteString(prefix) + if !v.IsInvoke() { + b.WriteString(relName(v.Value, instr)) + } else { + fmt.Fprintf(&b, "invoke %s.%s", relName(v.Value, instr), v.Method.Name()) + } + b.WriteString("(") + for i, arg := range v.Args { + if i > 0 { + b.WriteString(", ") + } + b.WriteString(relName(arg, instr)) + } + if v.Signature().Variadic() { + b.WriteString("...") + } + b.WriteString(")") + return b.String() +} + +func (c *CallCommon) String() string { + return printCall(c, "", nil) +} + +func (v *Call) String() string { + return printCall(&v.Call, "", v) +} + +func (v *BinOp) String() string { + return fmt.Sprintf("%s %s %s", relName(v.X, v), v.Op.String(), relName(v.Y, v)) +} + +func (v *UnOp) String() string { + return fmt.Sprintf("%s%s%s", v.Op, relName(v.X, v), commaOk(v.CommaOk)) +} + +func printConv(prefix string, v, x Value) string { + from := v.Parent().relPkg() + return fmt.Sprintf("%s %s <- %s (%s)", + prefix, + relType(v.Type(), from), + relType(x.Type(), from), + relName(x, v.(Instruction))) +} + +func (v *ChangeType) String() string { return printConv("changetype", v, v.X) } +func (v *Convert) String() string { return printConv("convert", v, v.X) } +func (v *ChangeInterface) String() string { return printConv("change interface", v, v.X) } +func (v *SliceToArrayPointer) String() string { return printConv("slice to array pointer", v, v.X) } +func (v *MakeInterface) String() string { return printConv("make", v, v.X) } + +func (v *MultiConvert) String() string { + from := v.Parent().relPkg() + + var b strings.Builder + b.WriteString(printConv("multiconvert", v, v.X)) + b.WriteString(" [") + for i, s := range termListOf(v.from) { + for j, d := range termListOf(v.to) { + if i != 0 || j != 0 { + b.WriteString(" | ") + } + fmt.Fprintf(&b, "%s <- %s", relTerm(d, from), relTerm(s, from)) + } + } + b.WriteString("]") + return b.String() +} + +func (v *MakeClosure) String() string { + var b bytes.Buffer + fmt.Fprintf(&b, "make closure %s", relName(v.Fn, v)) + if v.Bindings != nil { + b.WriteString(" [") + for i, c := range v.Bindings { + if i > 0 { + b.WriteString(", ") + } + b.WriteString(relName(c, v)) + } + b.WriteString("]") + } + return b.String() +} + +func (v *MakeSlice) String() string { + from := v.Parent().relPkg() + return fmt.Sprintf("make %s %s %s", + relType(v.Type(), from), + relName(v.Len, v), + relName(v.Cap, v)) +} + +func (v *Slice) String() string { + var b bytes.Buffer + b.WriteString("slice ") + b.WriteString(relName(v.X, v)) + b.WriteString("[") + if v.Low != nil { + b.WriteString(relName(v.Low, v)) + } + b.WriteString(":") + if v.High != nil { + b.WriteString(relName(v.High, v)) + } + if v.Max != nil { + b.WriteString(":") + b.WriteString(relName(v.Max, v)) + } + b.WriteString("]") + return b.String() +} + +func (v *MakeMap) String() string { + res := "" + if v.Reserve != nil { + res = relName(v.Reserve, v) + } + from := v.Parent().relPkg() + return fmt.Sprintf("make %s %s", relType(v.Type(), from), res) +} + +func (v *MakeChan) String() string { + from := v.Parent().relPkg() + return fmt.Sprintf("make %s %s", relType(v.Type(), from), relName(v.Size, v)) +} + +func (v *FieldAddr) String() string { + // Be robust against a bad index. + name := "?" + if fld := fieldOf(typeparams.MustDeref(v.X.Type()), v.Field); fld != nil { + name = fld.Name() + } + return fmt.Sprintf("&%s.%s [#%d]", relName(v.X, v), name, v.Field) +} + +func (v *Field) String() string { + // Be robust against a bad index. + name := "?" + if fld := fieldOf(v.X.Type(), v.Field); fld != nil { + name = fld.Name() + } + return fmt.Sprintf("%s.%s [#%d]", relName(v.X, v), name, v.Field) +} + +func (v *IndexAddr) String() string { + return fmt.Sprintf("&%s[%s]", relName(v.X, v), relName(v.Index, v)) +} + +func (v *Index) String() string { + return fmt.Sprintf("%s[%s]", relName(v.X, v), relName(v.Index, v)) +} + +func (v *Lookup) String() string { + return fmt.Sprintf("%s[%s]%s", relName(v.X, v), relName(v.Index, v), commaOk(v.CommaOk)) +} + +func (v *Range) String() string { + return "range " + relName(v.X, v) +} + +func (v *Next) String() string { + return "next " + relName(v.Iter, v) +} + +func (v *TypeAssert) String() string { + from := v.Parent().relPkg() + return fmt.Sprintf("typeassert%s %s.(%s)", commaOk(v.CommaOk), relName(v.X, v), relType(v.AssertedType, from)) +} + +func (v *Extract) String() string { + return fmt.Sprintf("extract %s #%d", relName(v.Tuple, v), v.Index) +} + +func (s *Jump) String() string { + // Be robust against malformed CFG. + block := -1 + if s.block != nil && len(s.block.Succs) == 1 { + block = s.block.Succs[0].Index + } + return fmt.Sprintf("jump %d", block) +} + +func (s *If) String() string { + // Be robust against malformed CFG. + tblock, fblock := -1, -1 + if s.block != nil && len(s.block.Succs) == 2 { + tblock = s.block.Succs[0].Index + fblock = s.block.Succs[1].Index + } + return fmt.Sprintf("if %s goto %d else %d", relName(s.Cond, s), tblock, fblock) +} + +func (s *Go) String() string { + return printCall(&s.Call, "go ", s) +} + +func (s *Panic) String() string { + return "panic " + relName(s.X, s) +} + +func (s *Return) String() string { + var b bytes.Buffer + b.WriteString("return") + for i, r := range s.Results { + if i == 0 { + b.WriteString(" ") + } else { + b.WriteString(", ") + } + b.WriteString(relName(r, s)) + } + return b.String() +} + +func (*RunDefers) String() string { + return "rundefers" +} + +func (s *Send) String() string { + return fmt.Sprintf("send %s <- %s", relName(s.Chan, s), relName(s.X, s)) +} + +func (s *Defer) String() string { + prefix := "defer " + if s.DeferStack != nil { + prefix += "[" + relName(s.DeferStack, s) + "] " + } + c := printCall(&s.Call, prefix, s) + return c +} + +func (s *Select) String() string { + var b bytes.Buffer + for i, st := range s.States { + if i > 0 { + b.WriteString(", ") + } + if st.Dir == types.RecvOnly { + b.WriteString("<-") + b.WriteString(relName(st.Chan, s)) + } else { + b.WriteString(relName(st.Chan, s)) + b.WriteString("<-") + b.WriteString(relName(st.Send, s)) + } + } + non := "" + if !s.Blocking { + non = "non" + } + return fmt.Sprintf("select %sblocking [%s]", non, b.String()) +} + +func (s *Store) String() string { + return fmt.Sprintf("*%s = %s", relName(s.Addr, s), relName(s.Val, s)) +} + +func (s *MapUpdate) String() string { + return fmt.Sprintf("%s[%s] = %s", relName(s.Map, s), relName(s.Key, s), relName(s.Value, s)) +} + +func (s *DebugRef) String() string { + p := s.Parent().Prog.Fset.Position(s.Pos()) + var descr any + if s.object != nil { + descr = s.object // e.g. "var x int" + } else { + descr = reflect.TypeOf(s.Expr) // e.g. "*ast.CallExpr" + } + var addr string + if s.IsAddr { + addr = "address of " + } + return fmt.Sprintf("; %s%s @ %d:%d is %s", addr, descr, p.Line, p.Column, s.X.Name()) +} + +func (p *Package) String() string { + return "package " + p.Pkg.Path() +} + +var _ io.WriterTo = (*Package)(nil) // *Package implements io.Writer + +func (p *Package) WriteTo(w io.Writer) (int64, error) { + var buf bytes.Buffer + WritePackage(&buf, p) + n, err := w.Write(buf.Bytes()) + return int64(n), err +} + +// WritePackage writes to buf a human-readable summary of p. +func WritePackage(buf *bytes.Buffer, p *Package) { + fmt.Fprintf(buf, "%s:\n", p) + + var names []string + maxname := 0 + for name := range p.Members { + if l := len(name); l > maxname { + maxname = l + } + names = append(names, name) + } + + from := p.Pkg + sort.Strings(names) + for _, name := range names { + switch mem := p.Members[name].(type) { + case *NamedConst: + fmt.Fprintf(buf, " const %-*s %s = %s\n", + maxname, name, mem.Name(), mem.Value.RelString(from)) + + case *Function: + fmt.Fprintf(buf, " func %-*s %s\n", + maxname, name, relType(mem.Type(), from)) + + case *Type: + fmt.Fprintf(buf, " type %-*s %s\n", + maxname, name, relType(mem.Type().Underlying(), from)) + for _, meth := range typeutil.IntuitiveMethodSet(mem.Type(), &p.Prog.MethodSets) { + fmt.Fprintf(buf, " %s\n", types.SelectionString(meth, types.RelativeTo(from))) + } + + case *Global: + fmt.Fprintf(buf, " var %-*s %s\n", + maxname, name, relType(typeparams.MustDeref(mem.Type()), from)) + } + } + + fmt.Fprintf(buf, "\n") +} + +func commaOk(x bool) string { + if x { + return ",ok" + } + return "" +} diff --git a/vendor/golang.org/x/tools/go/ssa/sanity.go b/vendor/golang.org/x/tools/go/ssa/sanity.go new file mode 100644 index 0000000..668a017 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/sanity.go @@ -0,0 +1,672 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// An optional pass for sanity-checking invariants of the SSA representation. +// Currently it checks CFG invariants but little at the instruction level. + +import ( + "bytes" + "fmt" + "go/ast" + "go/types" + "io" + "os" + "slices" + "strings" + + "golang.org/x/tools/internal/typeparams" +) + +type sanity struct { + reporter io.Writer + fn *Function + block *BasicBlock + instrs map[Instruction]unit + insane bool +} + +// sanityCheck performs integrity checking of the SSA representation +// of the function fn (which must have been "built") and returns true +// if it was valid. Diagnostics are written to reporter if non-nil, +// os.Stderr otherwise. Some diagnostics are only warnings and do not +// imply a negative result. +// +// Sanity-checking is intended to facilitate the debugging of code +// transformation passes. +func sanityCheck(fn *Function, reporter io.Writer) bool { + if reporter == nil { + reporter = os.Stderr + } + return (&sanity{reporter: reporter}).checkFunction(fn) +} + +// mustSanityCheck is like sanityCheck but panics instead of returning +// a negative result. +func mustSanityCheck(fn *Function, reporter io.Writer) { + if !sanityCheck(fn, reporter) { + fn.WriteTo(os.Stderr) + panic("SanityCheck failed") + } +} + +func (s *sanity) diagnostic(prefix, format string, args ...any) { + fmt.Fprintf(s.reporter, "%s: function %s", prefix, s.fn) + if s.block != nil { + fmt.Fprintf(s.reporter, ", block %s", s.block) + } + io.WriteString(s.reporter, ": ") + fmt.Fprintf(s.reporter, format, args...) + io.WriteString(s.reporter, "\n") +} + +func (s *sanity) errorf(format string, args ...any) { + s.insane = true + s.diagnostic("Error", format, args...) +} + +func (s *sanity) warnf(format string, args ...any) { + s.diagnostic("Warning", format, args...) +} + +// findDuplicate returns an arbitrary basic block that appeared more +// than once in blocks, or nil if all were unique. +func findDuplicate(blocks []*BasicBlock) *BasicBlock { + if len(blocks) < 2 { + return nil + } + if blocks[0] == blocks[1] { + return blocks[0] + } + // Slow path: + m := make(map[*BasicBlock]bool) + for _, b := range blocks { + if m[b] { + return b + } + m[b] = true + } + return nil +} + +func (s *sanity) checkInstr(idx int, instr Instruction) { + switch instr := instr.(type) { + case *If, *Jump, *Return, *Panic: + s.errorf("control flow instruction not at end of block") + case *Phi: + if idx == 0 { + // It suffices to apply this check to just the first phi node. + if dup := findDuplicate(s.block.Preds); dup != nil { + s.errorf("phi node in block with duplicate predecessor %s", dup) + } + } else { + prev := s.block.Instrs[idx-1] + if _, ok := prev.(*Phi); !ok { + s.errorf("Phi instruction follows a non-Phi: %T", prev) + } + } + if ne, np := len(instr.Edges), len(s.block.Preds); ne != np { + s.errorf("phi node has %d edges but %d predecessors", ne, np) + + } else { + for i, e := range instr.Edges { + if e == nil { + s.errorf("phi node '%s' has no value for edge #%d from %s", instr.Comment, i, s.block.Preds[i]) + } else if !types.Identical(instr.typ, e.Type()) { + s.errorf("phi node '%s' has a different type (%s) for edge #%d from %s (%s)", + instr.Comment, instr.Type(), i, s.block.Preds[i], e.Type()) + } + } + } + + case *Alloc: + if !instr.Heap { + found := slices.Contains(s.fn.Locals, instr) + if !found { + s.errorf("local alloc %s = %s does not appear in Function.Locals", instr.Name(), instr) + } + } + + case *BinOp: + case *Call: + if common := instr.Call; common.IsInvoke() { + if !types.IsInterface(common.Value.Type()) { + s.errorf("invoke on %s (%s) which is not an interface type (or type param)", common.Value, common.Value.Type()) + } + } + case *ChangeInterface: + case *ChangeType: + case *SliceToArrayPointer: + case *Convert: + if from := instr.X.Type(); !isBasicConvTypes(from) { + if to := instr.Type(); !isBasicConvTypes(to) { + s.errorf("convert %s -> %s: at least one type must be basic (or all basic, []byte, or []rune)", from, to) + } + } + case *MultiConvert: + case *Defer: + case *Extract: + case *Field: + case *FieldAddr: + case *Go: + case *Index: + case *IndexAddr: + case *Lookup: + case *MakeChan: + case *MakeClosure: + fn := instr.Fn.(*Function) + if numFree, numBind := len(fn.FreeVars), len(instr.Bindings); numFree != numBind { + s.errorf("MakeClosure has %d Bindings for function %s with %d free vars", + numBind, instr.Fn, numFree) + } else { + for i, fv := range fn.FreeVars { + if !types.Identical(instr.Bindings[i].Type(), fv.Type()) { + s.errorf("MakeClosure binding %d for %s has type %s, expected %s", + i, fv.Name(), instr.Bindings[i].Type(), fv.Type()) + } + } + } + if recv := instr.Type().(*types.Signature).Recv(); recv != nil { + s.errorf("MakeClosure's type includes receiver %s", recv.Type()) + } + + case *MakeInterface: + case *MakeMap: + case *MakeSlice: + case *MapUpdate: + case *Next: + rng, ok := instr.Iter.(*Range) + if !ok { + s.errorf("Next: Iter is %T, not *Range", instr.Iter) + } + if rng.Type() != tRangeIter { + s.errorf("Next: Iter has type %s, expected %s", rng.Type(), tRangeIter) + } + var ek, ev types.Type + switch xt := typeparams.CoreType(rng.X.Type()).(type) { + case *types.Basic: + if types.Default(xt) != tString { + s.errorf("Next: basic operand of Next.Iter (Range) is %s, want string or untyped string", xt) + } + ek, ev = tInt, tRune + case *types.Map: + ek, ev = xt.Key(), xt.Elem() + } + + res := instr.Type().(*types.Tuple) // (ok bool, k K, v V), but K or V may be invalid if unused + if !types.Identical(res.At(1).Type(), ek) && res.At(1).Type() != tInvalid { + s.errorf("Next: key type %s does not match map key type %s", res.At(1).Type(), ek) + } + if !types.Identical(res.At(2).Type(), ev) && res.At(2).Type() != tInvalid { + s.errorf("Next: value type %s does not match map value type %s", res.At(2).Type(), ev) + } + + case *Range: + case *RunDefers: + case *Select: + case *Send: + case *Slice: + case *Store: + if !types.Identical(instr.Val.Type(), typeparams.CoreType(instr.Addr.Type()).(*types.Pointer).Elem()) { + s.errorf("Store: value type %s does not match address type %s", + instr.Val.Type(), instr.Addr.Type()) + } + case *TypeAssert: + case *UnOp: + case *DebugRef: + // TODO(adonovan): implement checks. + default: + panic(fmt.Sprintf("Unknown instruction type: %T", instr)) + } + + if call, ok := instr.(CallInstruction); ok { + if call.Common().Signature() == nil { + s.errorf("nil signature: %s", call) + } + } + + // Check that value-defining instructions have valid types + // and a valid referrer list. + if v, ok := instr.(Value); ok { + t := v.Type() + if t == nil { + s.errorf("no type: %s = %s", v.Name(), v) + } else if b, ok := t.Underlying().(*types.Basic); ok && b.Info()&types.IsUntyped != 0 { + s.errorf("instruction has 'untyped' result: %s = %s : %s", v.Name(), v, t) + } + s.checkReferrerList(v) + } + + // Untyped constants are legal as instruction Operands(), + // for example: + // _ = "foo"[0] + // or: + // if wordsize==64 {...} + + // All other non-Instruction Values can be found via their + // enclosing Function or Package. +} + +func (s *sanity) checkFinalInstr(instr Instruction) { + switch instr := instr.(type) { + case *If: + if nsuccs := len(s.block.Succs); nsuccs != 2 { + s.errorf("If-terminated block has %d successors; expected 2", nsuccs) + return + } + if s.block.Succs[0] == s.block.Succs[1] { + s.errorf("If-instruction has same True, False target blocks: %s", s.block.Succs[0]) + return + } + + case *Jump: + if nsuccs := len(s.block.Succs); nsuccs != 1 { + s.errorf("Jump-terminated block has %d successors; expected 1", nsuccs) + return + } + + case *Return: + if nsuccs := len(s.block.Succs); nsuccs != 0 { + s.errorf("Return-terminated block has %d successors; expected none", nsuccs) + return + } + if na, nf := len(instr.Results), s.fn.Signature.Results().Len(); nf != na { + s.errorf("%d-ary return in %d-ary function", na, nf) + } + + case *Panic: + if nsuccs := len(s.block.Succs); nsuccs != 0 { + s.errorf("Panic-terminated block has %d successors; expected none", nsuccs) + return + } + + default: + s.errorf("non-control flow instruction at end of block") + } +} + +func (s *sanity) checkBlock(b *BasicBlock, index int) { + s.block = b + + if b.Index != index { + s.errorf("block has incorrect Index %d", b.Index) + } + if b.parent != s.fn { + s.errorf("block has incorrect parent %s", b.parent) + } + + // Check all blocks are reachable. + // (The entry block is always implicitly reachable, + // as is the Recover block, if any.) + if (index > 0 && b != b.parent.Recover) && len(b.Preds) == 0 { + s.warnf("unreachable block") + if b.Instrs == nil { + // Since this block is about to be pruned, + // tolerating transient problems in it + // simplifies other optimizations. + return + } + } + + // Check predecessor and successor relations are dual, + // and that all blocks in CFG belong to same function. + for _, a := range b.Preds { + found := slices.Contains(a.Succs, b) + if !found { + s.errorf("expected successor edge in predecessor %s; found only: %s", a, a.Succs) + } + if a.parent != s.fn { + s.errorf("predecessor %s belongs to different function %s", a, a.parent) + } + } + for _, c := range b.Succs { + found := slices.Contains(c.Preds, b) + if !found { + s.errorf("expected predecessor edge in successor %s; found only: %s", c, c.Preds) + } + if c.parent != s.fn { + s.errorf("successor %s belongs to different function %s", c, c.parent) + } + } + + // Check each instruction is sane. + n := len(b.Instrs) + if n == 0 { + s.errorf("basic block contains no instructions") + } + var rands [10]*Value // reuse storage + for j, instr := range b.Instrs { + if instr == nil { + s.errorf("nil instruction at index %d", j) + continue + } + if b2 := instr.Block(); b2 == nil { + s.errorf("nil Block() for instruction at index %d", j) + continue + } else if b2 != b { + s.errorf("wrong Block() (%s) for instruction at index %d ", b2, j) + continue + } + if j < n-1 { + s.checkInstr(j, instr) + } else { + s.checkFinalInstr(instr) + } + + // Check Instruction.Operands. + operands: + for i, op := range instr.Operands(rands[:0]) { + if op == nil { + s.errorf("nil operand pointer %d of %s", i, instr) + continue + } + val := *op + if val == nil { + continue // a nil operand is ok + } + + // Check that "untyped" types only appear on constant operands. + if _, ok := (*op).(*Const); !ok { + if basic, ok := (*op).Type().Underlying().(*types.Basic); ok { + if basic.Info()&types.IsUntyped != 0 { + s.errorf("operand #%d of %s is untyped: %s", i, instr, basic) + } + } + } + + // Check that Operands that are also Instructions belong to same function. + // TODO(adonovan): also check their block dominates block b. + if val, ok := val.(Instruction); ok { + if val.Block() == nil { + s.errorf("operand %d of %s is an instruction (%s) that belongs to no block", i, instr, val) + } else if val.Parent() != s.fn { + s.errorf("operand %d of %s is an instruction (%s) from function %s", i, instr, val, val.Parent()) + } + } + + // Check that each function-local operand of + // instr refers back to instr. (NB: quadratic) + switch val := val.(type) { + case *Const, *Global, *Builtin: + continue // not local + case *Function: + if val.parent == nil { + continue // only anon functions are local + } + } + + // TODO(adonovan): check val.Parent() != nil <=> val.Referrers() is defined. + + if refs := val.Referrers(); refs != nil { + for _, ref := range *refs { + if ref == instr { + continue operands + } + } + s.errorf("operand %d of %s (%s) does not refer to us", i, instr, val) + } else { + s.errorf("operand %d of %s (%s) has no referrers", i, instr, val) + } + } + } +} + +func (s *sanity) checkReferrerList(v Value) { + refs := v.Referrers() + if refs == nil { + s.errorf("%s has missing referrer list", v.Name()) + return + } + for i, ref := range *refs { + if _, ok := s.instrs[ref]; !ok { + s.errorf("%s.Referrers()[%d] = %s is not an instruction belonging to this function", v.Name(), i, ref) + } + } +} + +func (s *sanity) checkFunctionParams() { + signature := s.fn.Signature + params := s.fn.Params + + // startSigParams is the start of signature.Params() within params. + startSigParams := 0 + if signature.Recv() != nil { + startSigParams = 1 + } + + if startSigParams+signature.Params().Len() != len(params) { + s.errorf("function has %d parameters in signature but has %d after building", + startSigParams+signature.Params().Len(), len(params)) + return + } + + for i, param := range params { + var sigType types.Type + si := i - startSigParams + if si < 0 { + sigType = signature.Recv().Type() + } else { + sigType = signature.Params().At(si).Type() + } + + if !types.Identical(sigType, param.Type()) { + s.errorf("expect type %s in signature but got type %s in param %d", sigType, param.Type(), i) + } + } +} + +// checkTransientFields checks whether all transient fields of Function are cleared. +func (s *sanity) checkTransientFields() { + fn := s.fn + if fn.build != nil { + s.errorf("function transient field 'build' is not nil") + } + if fn.currentBlock != nil { + s.errorf("function transient field 'currentBlock' is not nil") + } + if fn.vars != nil { + s.errorf("function transient field 'vars' is not nil") + } + if fn.results != nil { + s.errorf("function transient field 'results' is not nil") + } + if fn.returnVars != nil { + s.errorf("function transient field 'returnVars' is not nil") + } + if fn.targets != nil { + s.errorf("function transient field 'targets' is not nil") + } + if fn.lblocks != nil { + s.errorf("function transient field 'lblocks' is not nil") + } + if fn.subst != nil { + s.errorf("function transient field 'subst' is not nil") + } + if fn.jump != nil { + s.errorf("function transient field 'jump' is not nil") + } + if fn.deferstack != nil { + s.errorf("function transient field 'deferstack' is not nil") + } + if fn.source != nil { + s.errorf("function transient field 'source' is not nil") + } + if fn.exits != nil { + s.errorf("function transient field 'exits' is not nil") + } + if fn.uniq != 0 { + s.errorf("function transient field 'uniq' is not zero") + } +} + +func (s *sanity) checkFunction(fn *Function) bool { + s.fn = fn + s.checkFunctionParams() + s.checkTransientFields() + + // TODO(taking): Sanity check origin, typeparams, and typeargs. + if fn.Prog == nil { + s.errorf("nil Prog") + } + + var buf bytes.Buffer + _ = fn.String() // must not crash + _ = fn.RelString(fn.relPkg()) // must not crash + WriteFunction(&buf, fn) // must not crash + + // All functions have a package, except delegates (which are + // shared across packages, or duplicated as weak symbols in a + // separate-compilation model), and error.Error. + if fn.Pkg == nil { + if strings.HasPrefix(fn.Synthetic, "from type information (on demand)") || + strings.HasPrefix(fn.Synthetic, "wrapper ") || + strings.HasPrefix(fn.Synthetic, "bound ") || + strings.HasPrefix(fn.Synthetic, "thunk ") || + strings.HasSuffix(fn.name, "Error") || + strings.HasPrefix(fn.Synthetic, "instance ") || + strings.HasPrefix(fn.Synthetic, "instantiation ") || + fn.parent != nil && fn.parent.hasTypeArgs() /* anon fun in instance */ { + // ok + } else { + s.errorf("nil Pkg") + } + } + if src, syn := fn.Synthetic == "", fn.Syntax() != nil; src != syn { + if fn.hasTypeArgs() && fn.Prog.mode&InstantiateGenerics != 0 { + // ok (instantiation with InstantiateGenerics on) + } else if fn.hasTypeArgs() && fn.topLevelOrigin != nil { + // ok (we always have the syntax set for instantiation) + } else if _, rng := fn.syntax.(*ast.RangeStmt); rng && fn.Synthetic == "range-over-func yield" { + // ok (range-func-yields are both synthetic and keep syntax) + } else { + s.errorf("got fromSource=%t, hasSyntax=%t; want same values", src, syn) + } + } + + // Build the set of valid referrers. + s.instrs = make(map[Instruction]unit) + + // instrs are the instructions that are present in the function. + for instr := range fn.instrs() { + s.instrs[instr] = unit{} + } + + // Check all Locals allocations appear in the function instruction. + for i, l := range fn.Locals { + if _, present := s.instrs[l]; !present { + s.warnf("function doesn't contain Local alloc %s", l.Name()) + } + + if l.Parent() != fn { + s.errorf("Local %s at index %d has wrong parent", l.Name(), i) + } + if l.Heap { + s.errorf("Local %s at index %d has Heap flag set", l.Name(), i) + } + } + for i, p := range fn.Params { + if p.Parent() != fn { + s.errorf("Param %s at index %d has wrong parent", p.Name(), i) + } + // Check common suffix of Signature and Params match type. + if sig := fn.Signature; sig != nil { + j := i - len(fn.Params) + sig.Params().Len() // index within sig.Params + if j < 0 { + continue + } + if !types.Identical(p.Type(), sig.Params().At(j).Type()) { + s.errorf("Param %s at index %d has wrong type (%s, versus %s in Signature)", p.Name(), i, p.Type(), sig.Params().At(j).Type()) + + } + } + s.checkReferrerList(p) + } + for i, fv := range fn.FreeVars { + if fv.Parent() != fn { + s.errorf("FreeVar %s at index %d has wrong parent", fv.Name(), i) + } + s.checkReferrerList(fv) + } + + if fn.Blocks != nil && len(fn.Blocks) == 0 { + // Function _had_ blocks (so it's not external) but + // they were "optimized" away, even the entry block. + s.errorf("Blocks slice is non-nil but empty") + } + for i, b := range fn.Blocks { + if b == nil { + s.warnf("nil *BasicBlock at f.Blocks[%d]", i) + continue + } + s.checkBlock(b, i) + } + if fn.Recover != nil && fn.Blocks[fn.Recover.Index] != fn.Recover { + s.errorf("Recover block is not in Blocks slice") + } + + s.block = nil + for i, anon := range fn.AnonFuncs { + if anon.Parent() != fn { + s.errorf("AnonFuncs[%d]=%s but %s.Parent()=%s", i, anon, anon, anon.Parent()) + } + if i != int(anon.anonIdx) { + s.errorf("AnonFuncs[%d]=%s but %s.anonIdx=%d", i, anon, anon, anon.anonIdx) + } + } + s.fn = nil + return !s.insane +} + +// sanityCheckPackage checks invariants of packages upon creation. +// It does not require that the package is built. +// Unlike sanityCheck (for functions), it just panics at the first error. +func sanityCheckPackage(pkg *Package) { + if pkg.Pkg == nil { + panic(fmt.Sprintf("Package %s has no Object", pkg)) + } + if pkg.info != nil { + panic(fmt.Sprintf("package %s field 'info' is not cleared", pkg)) + } + if pkg.files != nil { + panic(fmt.Sprintf("package %s field 'files' is not cleared", pkg)) + } + if pkg.created != nil { + panic(fmt.Sprintf("package %s field 'created' is not cleared", pkg)) + } + if pkg.initVersion != nil { + panic(fmt.Sprintf("package %s field 'initVersion' is not cleared", pkg)) + } + + _ = pkg.String() // must not crash + + for name, mem := range pkg.Members { + if name != mem.Name() { + panic(fmt.Sprintf("%s: %T.Name() = %s, want %s", + pkg.Pkg.Path(), mem, mem.Name(), name)) + } + obj := mem.Object() + if obj == nil { + // This check is sound because fields + // {Global,Function}.object have type + // types.Object. (If they were declared as + // *types.{Var,Func}, we'd have a non-empty + // interface containing a nil pointer.) + + continue // not all members have typechecker objects + } + if obj.Name() != name { + if obj.Name() == "init" && strings.HasPrefix(mem.Name(), "init#") { + // Ok. The name of a declared init function varies between + // its types.Func ("init") and its ssa.Function ("init#%d"). + } else { + panic(fmt.Sprintf("%s: %T.Object().Name() = %s, want %s", + pkg.Pkg.Path(), mem, obj.Name(), name)) + } + } + if obj.Pos() != mem.Pos() { + panic(fmt.Sprintf("%s Pos=%d obj.Pos=%d", mem, mem.Pos(), obj.Pos())) + } + } +} diff --git a/vendor/golang.org/x/tools/go/ssa/source.go b/vendor/golang.org/x/tools/go/ssa/source.go new file mode 100644 index 0000000..d0cc1f4 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/source.go @@ -0,0 +1,288 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file defines utilities for working with source positions +// or source-level named entities ("objects"). + +// TODO(adonovan): test that {Value,Instruction}.Pos() positions match +// the originating syntax, as specified. + +import ( + "go/ast" + "go/token" + "go/types" +) + +// EnclosingFunction returns the function that contains the syntax +// node denoted by path. +// +// Syntax associated with package-level variable specifications is +// enclosed by the package's init() function. +// +// Returns nil if not found; reasons might include: +// - the node is not enclosed by any function. +// - the node is within an anonymous function (FuncLit) and +// its SSA function has not been created yet +// (pkg.Build() has not yet been called). +func EnclosingFunction(pkg *Package, path []ast.Node) *Function { + // Start with package-level function... + fn := findEnclosingPackageLevelFunction(pkg, path) + if fn == nil { + return nil // not in any function + } + + // ...then walk down the nested anonymous functions. + n := len(path) +outer: + for i := range path { + if lit, ok := path[n-1-i].(*ast.FuncLit); ok { + for _, anon := range fn.AnonFuncs { + if anon.Pos() == lit.Type.Func { + fn = anon + continue outer + } + } + // SSA function not found: + // - package not yet built, or maybe + // - builder skipped FuncLit in dead block + // (in principle; but currently the Builder + // generates even dead FuncLits). + return nil + } + } + return fn +} + +// HasEnclosingFunction returns true if the AST node denoted by path +// is contained within the declaration of some function or +// package-level variable. +// +// Unlike EnclosingFunction, the behaviour of this function does not +// depend on whether SSA code for pkg has been built, so it can be +// used to quickly reject check inputs that will cause +// EnclosingFunction to fail, prior to SSA building. +func HasEnclosingFunction(pkg *Package, path []ast.Node) bool { + return findEnclosingPackageLevelFunction(pkg, path) != nil +} + +// findEnclosingPackageLevelFunction returns the Function +// corresponding to the package-level function enclosing path. +func findEnclosingPackageLevelFunction(pkg *Package, path []ast.Node) *Function { + if n := len(path); n >= 2 { // [... {Gen,Func}Decl File] + switch decl := path[n-2].(type) { + case *ast.GenDecl: + if decl.Tok == token.VAR && n >= 3 { + // Package-level 'var' initializer. + return pkg.init + } + + case *ast.FuncDecl: + if decl.Recv == nil && decl.Name.Name == "init" { + // Explicit init() function. + for _, b := range pkg.init.Blocks { + for _, instr := range b.Instrs { + if instr, ok := instr.(*Call); ok { + if callee, ok := instr.Call.Value.(*Function); ok && callee.Pkg == pkg && callee.Pos() == decl.Name.NamePos { + return callee + } + } + } + } + // Hack: return non-nil when SSA is not yet + // built so that HasEnclosingFunction works. + return pkg.init + } + // Declared function/method. + return findNamedFunc(pkg, decl.Name.NamePos) + } + } + return nil // not in any function +} + +// findNamedFunc returns the named function whose FuncDecl.Ident is at +// position pos. +func findNamedFunc(pkg *Package, pos token.Pos) *Function { + // Look at all package members and method sets of named types. + // Not very efficient. + for _, mem := range pkg.Members { + switch mem := mem.(type) { + case *Function: + if mem.Pos() == pos { + return mem + } + case *Type: + mset := pkg.Prog.MethodSets.MethodSet(types.NewPointer(mem.Type())) + for i, n := 0, mset.Len(); i < n; i++ { + // Don't call Program.Method: avoid creating wrappers. + obj := mset.At(i).Obj().(*types.Func) + if obj.Pos() == pos { + // obj from MethodSet may not be the origin type. + m := obj.Origin() + return pkg.objects[m].(*Function) + } + } + } + } + return nil +} + +// ValueForExpr returns the SSA Value that corresponds to non-constant +// expression e. +// +// It returns nil if no value was found, e.g. +// - the expression is not lexically contained within f; +// - f was not built with debug information; or +// - e is a constant expression. (For efficiency, no debug +// information is stored for constants. Use +// go/types.Info.Types[e].Value instead.) +// - e is a reference to nil or a built-in function. +// - the value was optimised away. +// +// If e is an addressable expression used in an lvalue context, +// value is the address denoted by e, and isAddr is true. +// +// The types of e (or &e, if isAddr) and the result are equal +// (modulo "untyped" bools resulting from comparisons). +// +// (Tip: to find the ssa.Value given a source position, use +// astutil.PathEnclosingInterval to locate the ast.Node, then +// EnclosingFunction to locate the Function, then ValueForExpr to find +// the ssa.Value.) +func (f *Function) ValueForExpr(e ast.Expr) (value Value, isAddr bool) { + if f.debugInfo() { // (opt) + e = ast.Unparen(e) + for _, b := range f.Blocks { + for _, instr := range b.Instrs { + if ref, ok := instr.(*DebugRef); ok { + if ref.Expr == e { + return ref.X, ref.IsAddr + } + } + } + } + } + return +} + +// --- Lookup functions for source-level named entities (types.Objects) --- + +// Package returns the SSA Package corresponding to the specified +// type-checker package. It returns nil if no such Package was +// created by a prior call to prog.CreatePackage. +func (prog *Program) Package(pkg *types.Package) *Package { + return prog.packages[pkg] +} + +// packageLevelMember returns the package-level member corresponding +// to the specified symbol, which may be a package-level const +// (*NamedConst), var (*Global) or func/method (*Function) of some +// package in prog. +// +// It returns nil if the object belongs to a package that has not been +// created by prog.CreatePackage. +func (prog *Program) packageLevelMember(obj types.Object) Member { + if pkg, ok := prog.packages[obj.Pkg()]; ok { + return pkg.objects[obj] + } + return nil +} + +// FuncValue returns the SSA function or (non-interface) method +// denoted by the specified func symbol. It returns nil if the symbol +// denotes an interface method, or belongs to a package that was not +// created by prog.CreatePackage. +func (prog *Program) FuncValue(obj *types.Func) *Function { + fn, _ := prog.packageLevelMember(obj).(*Function) + return fn +} + +// ConstValue returns the SSA constant denoted by the specified const symbol. +func (prog *Program) ConstValue(obj *types.Const) *Const { + // TODO(adonovan): opt: share (don't reallocate) + // Consts for const objects and constant ast.Exprs. + + // Universal constant? {true,false,nil} + if obj.Parent() == types.Universe { + return NewConst(obj.Val(), obj.Type()) + } + // Package-level named constant? + if v := prog.packageLevelMember(obj); v != nil { + return v.(*NamedConst).Value + } + return NewConst(obj.Val(), obj.Type()) +} + +// VarValue returns the SSA Value that corresponds to a specific +// identifier denoting the specified var symbol. +// +// VarValue returns nil if a local variable was not found, perhaps +// because its package was not built, the debug information was not +// requested during SSA construction, or the value was optimized away. +// +// ref is the path to an ast.Ident (e.g. from PathEnclosingInterval), +// and that ident must resolve to obj. +// +// pkg is the package enclosing the reference. (A reference to a var +// always occurs within a function, so we need to know where to find it.) +// +// If the identifier is a field selector and its base expression is +// non-addressable, then VarValue returns the value of that field. +// For example: +// +// func f() struct {x int} +// f().x // VarValue(x) returns a *Field instruction of type int +// +// All other identifiers denote addressable locations (variables). +// For them, VarValue may return either the variable's address or its +// value, even when the expression is evaluated only for its value; the +// situation is reported by isAddr, the second component of the result. +// +// If !isAddr, the returned value is the one associated with the +// specific identifier. For example, +// +// var x int // VarValue(x) returns Const 0 here +// x = 1 // VarValue(x) returns Const 1 here +// +// It is not specified whether the value or the address is returned in +// any particular case, as it may depend upon optimizations performed +// during SSA code generation, such as registerization, constant +// folding, avoidance of materialization of subexpressions, etc. +func (prog *Program) VarValue(obj *types.Var, pkg *Package, ref []ast.Node) (value Value, isAddr bool) { + // All references to a var are local to some function, possibly init. + fn := EnclosingFunction(pkg, ref) + if fn == nil { + return // e.g. def of struct field; SSA not built? + } + + id := ref[0].(*ast.Ident) + + // Defining ident of a parameter? + if id.Pos() == obj.Pos() { + for _, param := range fn.Params { + if param.Object() == obj { + return param, false + } + } + } + + // Other ident? + for _, b := range fn.Blocks { + for _, instr := range b.Instrs { + if dr, ok := instr.(*DebugRef); ok { + if dr.Pos() == id.Pos() { + return dr.X, dr.IsAddr + } + } + } + } + + // Defining ident of package-level var? + if v := prog.packageLevelMember(obj); v != nil { + return v.(*Global), true + } + + return // e.g. debug info not requested, or var optimized away +} diff --git a/vendor/golang.org/x/tools/go/ssa/ssa.go b/vendor/golang.org/x/tools/go/ssa/ssa.go new file mode 100644 index 0000000..514ba2b --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/ssa.go @@ -0,0 +1,1970 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This package defines a high-level intermediate representation for +// Go programs using static single-assignment (SSA) form. + +import ( + "fmt" + "go/ast" + "go/constant" + "go/token" + "go/types" + "reflect" + "slices" + "strings" + "sync" + "unsafe" + + "golang.org/x/tools/go/types/typeutil" + "golang.org/x/tools/internal/typeparams" +) + +// A Program is a partial or complete Go program converted to SSA form. +type Program struct { + Fset *token.FileSet // position information for the files of this Program + imported map[string]*Package // all importable Packages, keyed by import path + packages map[*types.Package]*Package // all created Packages + mode BuilderMode // set of mode bits for SSA construction + MethodSets typeutil.MethodSetCache // cache of type-checker's method-sets + + canon *canonizer // type canonicalization map + ctxt *types.Context // cache for type checking instantiations + + methodsMu sync.Mutex + methodSets typeutil.Map // maps type to its concrete *methodSet + + // memoization of whether a type refers to type parameters + hasParamsMu sync.Mutex + hasParams typeparams.Free + + // set of concrete types used as MakeInterface operands + makeInterfaceTypesMu sync.Mutex + makeInterfaceTypes map[types.Type]unit // (may contain redundant identical types) + + // objectMethods is a memoization of objectMethod + // to avoid creation of duplicate methods from type information. + objectMethodsMu sync.Mutex + objectMethods map[*types.Func]*Function + + noReturn func(*types.Func) bool // (optional) predicate that decides whether a given call cannot return +} + +// A Package is a single analyzed Go package containing Members for +// all package-level functions, variables, constants and types it +// declares. These may be accessed directly via Members, or via the +// type-specific accessor methods Func, Type, Var and Const. +// +// Members also contains entries for "init" (the synthetic package +// initializer) and "init#%d", the nth declared init function, +// and unspecified other things too. +type Package struct { + Prog *Program // the owning program + Pkg *types.Package // the corresponding go/types.Package + Members map[string]Member // all package members keyed by name (incl. init and init#%d) + objects map[types.Object]Member // mapping of package objects to members (incl. methods). Contains *NamedConst, *Global, *Function (values but not types) + init *Function // Func("init"); the package's init function + debug bool // include full debug info in this package + syntax bool // package was loaded from syntax + + // The following fields are set transiently, then cleared + // after building. + buildOnce sync.Once // ensures package building occurs once + ninit int32 // number of init functions + info *types.Info // package type information + files []*ast.File // package ASTs + created []*Function // members created as a result of building this package (includes declared functions, wrappers) + initVersion map[ast.Expr]string // goversion to use for each global var init expr +} + +// A Member is a member of a Go package, implemented by *NamedConst, +// *Global, *Function, or *Type; they are created by package-level +// const, var, func and type declarations respectively. +type Member interface { + Name() string // declared name of the package member + String() string // package-qualified name of the package member + RelString(*types.Package) string // like String, but relative refs are unqualified + Object() types.Object // typechecker's object for this member, if any + Pos() token.Pos // position of member's declaration, if known + Type() types.Type // type of the package member + Token() token.Token // token.{VAR,FUNC,CONST,TYPE} + Package() *Package // the containing package +} + +// A Type is a Member of a Package representing a package-level named type. +type Type struct { + object *types.TypeName + pkg *Package +} + +// A NamedConst is a Member of a Package representing a package-level +// named constant. +// +// Pos() returns the position of the declaring ast.ValueSpec.Names[*] +// identifier. +// +// NB: a NamedConst is not a Value; it contains a constant Value, which +// it augments with the name and position of its 'const' declaration. +type NamedConst struct { + object *types.Const + Value *Const + pkg *Package +} + +// A Value is an SSA value that can be referenced by an instruction. +type Value interface { + // Name returns the name of this value, and determines how + // this Value appears when used as an operand of an + // Instruction. + // + // This is the same as the source name for Parameters, + // Builtins, Functions, FreeVars, Globals. + // For constants, it is a representation of the constant's value + // and type. For all other Values this is the name of the + // virtual register defined by the instruction. + // + // The name of an SSA Value is not semantically significant, + // and may not even be unique within a function. + Name() string + + // If this value is an Instruction, String returns its + // disassembled form; otherwise it returns unspecified + // human-readable information about the Value, such as its + // kind, name and type. + String() string + + // Type returns the type of this value. Many instructions + // (e.g. IndexAddr) change their behaviour depending on the + // types of their operands. + Type() types.Type + + // Parent returns the function to which this Value belongs. + // It returns nil for named Functions, Builtin, Const and Global. + Parent() *Function + + // Referrers returns the list of instructions that have this + // value as one of their operands; it may contain duplicates + // if an instruction has a repeated operand. + // + // Referrers actually returns a pointer through which the + // caller may perform mutations to the object's state. + // + // Referrers is currently only defined if Parent()!=nil, + // i.e. for the function-local values FreeVar, Parameter, + // Functions (iff anonymous) and all value-defining instructions. + // It returns nil for named Functions, Builtin, Const and Global. + // + // Instruction.Operands contains the inverse of this relation. + Referrers() *[]Instruction + + // Pos returns the location of the AST token most closely + // associated with the operation that gave rise to this value, + // or token.NoPos if it was not explicit in the source. + // + // For each ast.Node type, a particular token is designated as + // the closest location for the expression, e.g. the Lparen + // for an *ast.CallExpr. This permits a compact but + // approximate mapping from Values to source positions for use + // in diagnostic messages, for example. + // + // (Do not use this position to determine which Value + // corresponds to an ast.Expr; use Function.ValueForExpr + // instead. NB: it requires that the function was built with + // debug information.) + Pos() token.Pos +} + +// An Instruction is an SSA instruction that computes a new Value or +// has some effect. +// +// An Instruction that defines a value (e.g. BinOp) also implements +// the Value interface; an Instruction that only has an effect (e.g. Store) +// does not. +type Instruction interface { + // String returns the disassembled form of this value. + // + // Examples of Instructions that are Values: + // "x + y" (BinOp) + // "len([])" (Call) + // Note that the name of the Value is not printed. + // + // Examples of Instructions that are not Values: + // "return x" (Return) + // "*y = x" (Store) + // + // (The separation Value.Name() from Value.String() is useful + // for some analyses which distinguish the operation from the + // value it defines, e.g., 'y = local int' is both an allocation + // of memory 'local int' and a definition of a pointer y.) + String() string + + // Parent returns the function to which this instruction + // belongs. + Parent() *Function + + // Block returns the basic block to which this instruction + // belongs. + Block() *BasicBlock + + // setBlock sets the basic block to which this instruction belongs. + setBlock(*BasicBlock) + + // Operands returns the operands of this instruction: the + // set of Values it references. + // + // Specifically, it appends their addresses to rands, a + // user-provided slice, and returns the resulting slice, + // permitting avoidance of memory allocation. + // + // The operands are appended in undefined order, but the order + // is consistent for a given Instruction; the addresses are + // always non-nil but may point to a nil Value. Clients may + // store through the pointers, e.g. to effect a value + // renaming. + // + // Value.Referrers is a subset of the inverse of this + // relation. (Referrers are not tracked for all types of + // Values.) + Operands(rands []*Value) []*Value + + // Pos returns the location of the AST token most closely + // associated with the operation that gave rise to this + // instruction, or token.NoPos if it was not explicit in the + // source. + // + // For each ast.Node type, a particular token is designated as + // the closest location for the expression, e.g. the Go token + // for an *ast.GoStmt. This permits a compact but approximate + // mapping from Instructions to source positions for use in + // diagnostic messages, for example. + // + // (Do not use this position to determine which Instruction + // corresponds to an ast.Expr; see the notes for Value.Pos. + // This position may be used to determine which non-Value + // Instruction corresponds to some ast.Stmts, but not all: If + // and Jump instructions have no Pos(), for example.) + Pos() token.Pos +} + +// A Node is a node in the SSA value graph. Every concrete type that +// implements Node is also either a Value, an Instruction, or both. +// +// Node contains the methods common to Value and Instruction, plus the +// Operands and Referrers methods generalized to return nil for +// non-Instructions and non-Values, respectively. +// +// Node is provided to simplify SSA graph algorithms. Clients should +// use the more specific and informative Value or Instruction +// interfaces where appropriate. +type Node interface { + // Common methods: + String() string + Pos() token.Pos + Parent() *Function + + // Partial methods: + Operands(rands []*Value) []*Value // nil for non-Instructions + Referrers() *[]Instruction // nil for non-Values +} + +// Function represents the parameters, results, and code of a function +// or method. +// +// If Blocks is nil, this indicates an external function for which no +// Go source code is available. In this case, FreeVars, Locals, and +// Params are nil too. Clients performing whole-program analysis must +// handle external functions specially. +// +// Blocks contains the function's control-flow graph (CFG). +// Blocks[0] is the function entry point; block order is not otherwise +// semantically significant, though it may affect the readability of +// the disassembly. +// To iterate over the blocks in dominance order, use DomPreorder(). +// +// Recover is an optional second entry point to which control resumes +// after a recovered panic. The Recover block may contain only a return +// statement, preceded by a load of the function's named return +// parameters, if any. +// +// A nested function (Parent()!=nil) that refers to one or more +// lexically enclosing local variables ("free variables") has FreeVars. +// Such functions cannot be called directly but require a +// value created by MakeClosure which, via its Bindings, supplies +// values for these parameters. +// +// If the function is a method (Signature.Recv() != nil) then the first +// element of Params is the receiver parameter. +// +// A Go package may declare many functions called "init". +// For each one, Object().Name() returns "init" but Name() returns +// "init#1", etc, in declaration order. +// +// Pos() returns the declaring ast.FuncLit.Type.Func or the position +// of the ast.FuncDecl.Name, if the function was explicit in the +// source. Synthetic wrappers, for which Synthetic != "", may share +// the same position as the function they wrap. +// Syntax.Pos() always returns the position of the declaring "func" token. +// +// When the operand of a range statement is an iterator function, +// the loop body is transformed into a synthetic anonymous function +// that is passed as the yield argument in a call to the iterator. +// In that case, Function.Pos is the position of the "range" token, +// and Function.Syntax is the ast.RangeStmt. +// +// Synthetic functions, for which Synthetic != "", are functions +// that do not appear in the source AST. These include: +// - method wrappers, +// - thunks, +// - bound functions, +// - empty functions built from loaded type information, +// - yield functions created from range-over-func loops, +// - package init functions, and +// - instantiations of generic functions. +// +// Synthetic wrapper functions may share the same position +// as the function they wrap. +// +// Type() returns the function's Signature. +// +// A generic function is a function or method that has uninstantiated type +// parameters (TypeParams() != nil). Consider a hypothetical generic +// method, (*Map[K,V]).Get. It may be instantiated with all +// non-parameterized types as (*Map[string,int]).Get or with +// parameterized types as (*Map[string,U]).Get, where U is a type parameter. +// In both instantiations, Origin() refers to the instantiated generic +// method, (*Map[K,V]).Get, TypeParams() refers to the parameters [K,V] of +// the generic method. TypeArgs() refers to [string,U] or [string,int], +// respectively, and is nil in the generic method. +type Function struct { + name string + object *types.Func // symbol for declared function (nil for FuncLit or synthetic init) + method *selection // info about provenance of synthetic methods; thunk => non-nil + Signature *types.Signature + pos token.Pos + + // source information + Synthetic string // provenance of synthetic function; "" for true source functions + syntax ast.Node // *ast.Func{Decl,Lit}, if from syntax (incl. generic instances) or (*ast.RangeStmt if a yield function) + info *types.Info // type annotations (if syntax != nil) + goversion string // Go version of syntax (NB: init is special) + + parent *Function // enclosing function if anon; nil if global + Pkg *Package // enclosing package; nil for shared funcs (wrappers and error.Error) + Prog *Program // enclosing program + + buildshared *task // wait for a shared function to be done building (may be nil if <=1 builder ever needs to wait) + + // These fields are populated only when the function body is built: + + Params []*Parameter // function parameters; for methods, includes receiver + FreeVars []*FreeVar // free variables whose values must be supplied by closure + Locals []*Alloc // frame-allocated variables of this function + Blocks []*BasicBlock // basic blocks of the function; nil => external + Recover *BasicBlock // optional; control transfers here after recovered panic + AnonFuncs []*Function // anonymous functions (from FuncLit,RangeStmt) directly beneath this one + referrers []Instruction // referring instructions (iff Parent() != nil) + anonIdx int32 // position of a nested function in parent's AnonFuncs. fn.Parent()!=nil => fn.Parent().AnonFunc[fn.anonIdx] == fn. + + recvtypeparams *types.TypeParamList // receiver type parameters of this function. recvtypeparams.Len() > 0 => method on generic or instance of generic type + recvtypeargs []types.Type // type arguments that instantiated recvtypeparams. len(recvtypeargs) > 0 => method on instance of generic type + typeparams *types.TypeParamList // type parameters of this function. typeparams.Len() > 0 => generic or instance of generic function or method + typeargs []types.Type // type arguments that instantiated typeparams. len(typeargs) > 0 => instance of generic function or method + topLevelOrigin *Function // the origin function if this is an instance of a source function. nil if Parent()!=nil. + generic *generic // instances of this function, if generic + + // The following fields are cleared after building. + build buildFunc // algorithm to build function body (nil => built) + currentBlock *BasicBlock // where to emit code + vars map[*types.Var]Value // addresses of local variables + results []*Alloc // result allocations of the current function + returnVars []*types.Var // variables for a return statement. Either results or for range-over-func a parent's results + targets *targets // linked stack of branch targets + lblocks map[*types.Label]*lblock // labelled blocks + subst *subster // type parameter substitutions (if non-nil) + jump *types.Var // synthetic variable for the yield state (non-nil => range-over-func) + deferstack *types.Var // synthetic variable holding enclosing ssa:deferstack() + source *Function // nearest enclosing source function + exits []*exit // exits of the function that need to be resolved + uniq int64 // source of unique ints within the source tree while building +} + +// BasicBlock represents an SSA basic block. +// +// The final element of Instrs is always an explicit transfer of +// control (If, Jump, Return, or Panic). +// +// A block may contain no Instructions only if it is unreachable, +// i.e., Preds is nil. Empty blocks are typically pruned. +// +// BasicBlocks and their Preds/Succs relation form a (possibly cyclic) +// graph independent of the SSA Value graph: the control-flow graph or +// CFG. It is illegal for multiple edges to exist between the same +// pair of blocks. +// +// Each BasicBlock is also a node in the dominator tree of the CFG. +// The tree may be navigated using Idom()/Dominees() and queried using +// Dominates(). +// +// The order of Preds and Succs is significant (to Phi and If +// instructions, respectively). +type BasicBlock struct { + Index int // index of this block within Parent().Blocks + Comment string // optional label; no semantic significance + parent *Function // parent function + Instrs []Instruction // instructions in order + Preds, Succs []*BasicBlock // predecessors and successors + succs2 [2]*BasicBlock // initial space for Succs + dom domInfo // dominator tree info + gaps int // number of nil Instrs (transient) + rundefers int // number of rundefers (transient) +} + +// Pure values ---------------------------------------- + +// A FreeVar represents a free variable of the function to which it +// belongs. +// +// FreeVars are used to implement anonymous functions, whose free +// variables are lexically captured in a closure formed by +// MakeClosure. The value of such a free var is an Alloc or another +// FreeVar and is considered a potentially escaping heap address, with +// pointer type. +// +// FreeVars are also used to implement bound method closures. Such a +// free var represents the receiver value and may be of any type that +// has concrete methods. +// +// Pos() returns the position of the value that was captured, which +// belongs to an enclosing function. +type FreeVar struct { + name string + typ types.Type + pos token.Pos + parent *Function + referrers []Instruction + + // Transiently needed during building. + outer Value // the Value captured from the enclosing context. +} + +// A Parameter represents an input parameter of a function. +type Parameter struct { + name string + object *types.Var // non-nil + typ types.Type + parent *Function + referrers []Instruction +} + +// A Const represents a value known at build time. +// +// Consts include true constants of boolean, numeric, and string types, as +// defined by the Go spec; these are represented by a non-nil Value field. +// +// Consts also include the "zero" value of any type, of which the nil values +// of various pointer-like types are a special case; these are represented +// by a nil Value field. +// +// Pos() returns token.NoPos. +// +// Example printed forms: +// +// 42:int +// "hello":untyped string +// 3+4i:MyComplex +// nil:*int +// nil:[]string +// [3]int{}:[3]int +// struct{x string}{}:struct{x string} +// 0:interface{int|int64} +// nil:interface{bool|int} // no go/constant representation +type Const struct { + typ types.Type + Value constant.Value +} + +// A Global is a named Value holding the address of a package-level +// variable. +// +// Pos() returns the position of the ast.ValueSpec.Names[*] +// identifier. +type Global struct { + name string + object types.Object // a *types.Var; may be nil for synthetics e.g. init$guard + typ types.Type + pos token.Pos + + Pkg *Package +} + +// A Builtin represents a specific use of a built-in function, e.g. len. +// +// Builtins are immutable values. Builtins do not have addresses. +// Builtins can only appear in CallCommon.Value. +// +// Name() indicates the function: one of the built-in functions from the +// Go spec (excluding "make" and "new") or one of these ssa-defined +// intrinsics: +// +// // wrapnilchk returns ptr if non-nil, panics otherwise. +// // (For use in indirection wrappers.) +// func ssa:wrapnilchk(ptr *T, recvType, methodName string) *T +// +// Object() returns a *types.Builtin for built-ins defined by the spec, +// nil for others. +// +// Type() returns a *types.Signature representing the effective +// signature of the built-in for this call. +type Builtin struct { + name string + sig *types.Signature +} + +// Value-defining instructions ---------------------------------------- + +// The Alloc instruction reserves space for a variable of the given type, +// zero-initializes it, and yields its address. +// +// Alloc values are always addresses, and have pointer types, so the +// type of the allocated variable is actually +// Type().Underlying().(*types.Pointer).Elem(). +// +// If Heap is false, Alloc zero-initializes the same local variable in +// the call frame and returns its address; in this case the Alloc must +// be present in Function.Locals. We call this a "local" alloc. +// +// If Heap is true, Alloc allocates a new zero-initialized variable +// each time the instruction is executed. We call this a "new" alloc. +// +// When Alloc is applied to a channel, map or slice type, it returns +// the address of an uninitialized (nil) reference of that kind; store +// the result of MakeSlice, MakeMap or MakeChan in that location to +// instantiate these types. +// +// Pos() returns the ast.CompositeLit.Lbrace for a composite literal, +// or the ast.CallExpr.Rparen for a call to new() or for a call that +// allocates a varargs slice. +// +// Example printed form: +// +// t0 = local int +// t1 = new int +type Alloc struct { + register + Comment string + Heap bool + index int // dense numbering; for lifting +} + +// The Phi instruction represents an SSA φ-node, which combines values +// that differ across incoming control-flow edges and yields a new +// value. Within a block, all φ-nodes must appear before all non-φ +// nodes. +// +// Pos() returns the position of the && or || for short-circuit +// control-flow joins, or that of the *Alloc for φ-nodes inserted +// during SSA renaming. +// +// Example printed form: +// +// t2 = phi [0: t0, 1: t1] +type Phi struct { + register + Comment string // a hint as to its purpose + Edges []Value // Edges[i] is value for Block().Preds[i] +} + +// The Call instruction represents a function or method call. +// +// The Call instruction yields the function result if there is exactly +// one. Otherwise it returns a tuple, the components of which are +// accessed via Extract. +// +// See CallCommon for generic function call documentation. +// +// Pos() returns the ast.CallExpr.Lparen, if explicit in the source. +// +// Example printed form: +// +// t2 = println(t0, t1) +// t4 = t3() +// t7 = invoke t5.Println(...t6) +type Call struct { + register + Call CallCommon +} + +// The BinOp instruction yields the result of binary operation X Op Y. +// +// Pos() returns the ast.BinaryExpr.OpPos, if explicit in the source. +// +// Example printed form: +// +// t1 = t0 + 1:int +type BinOp struct { + register + // One of: + // ADD SUB MUL QUO REM + - * / % + // AND OR XOR SHL SHR AND_NOT & | ^ << >> &^ + // EQL NEQ LSS LEQ GTR GEQ == != < <= < >= + Op token.Token + X, Y Value +} + +// The UnOp instruction yields the result of Op X. +// ARROW is channel receive. +// MUL is pointer indirection (load). +// XOR is bitwise complement. +// SUB is negation. +// NOT is logical negation. +// +// If CommaOk and Op=ARROW, the result is a 2-tuple of the value above +// and a boolean indicating the success of the receive. The +// components of the tuple are accessed using Extract. +// +// Pos() returns the ast.UnaryExpr.OpPos, if explicit in the source. +// For receive operations (ARROW) implicit in ranging over a channel, +// Pos() returns the ast.RangeStmt.For. +// For implicit memory loads (STAR), Pos() returns the position of the +// most closely associated source-level construct; the details are not +// specified. +// +// Example printed form: +// +// t0 = *x +// t2 = <-t1,ok +type UnOp struct { + register + Op token.Token // One of: NOT SUB ARROW MUL XOR ! - <- * ^ + X Value + CommaOk bool +} + +// The ChangeType instruction applies to X a value-preserving type +// change to Type(). +// +// Type changes are permitted: +// - between a named type and its underlying type. +// - between two named types of the same underlying type. +// - between (possibly named) pointers to identical base types. +// - from a bidirectional channel to a read- or write-channel, +// optionally adding/removing a name. +// - between a type (t) and an instance of the type (tσ), i.e. +// Type() == σ(X.Type()) (or X.Type()== σ(Type())) where +// σ is the type substitution of Parent().TypeParams by +// Parent().TypeArgs. +// +// This operation cannot fail dynamically. +// +// Type changes may to be to or from a type parameter (or both). All +// types in the type set of X.Type() have a value-preserving type +// change to all types in the type set of Type(). +// +// Pos() returns the ast.CallExpr.Lparen, if the instruction arose +// from an explicit conversion in the source. +// +// Example printed form: +// +// t1 = changetype *int <- IntPtr (t0) +type ChangeType struct { + register + X Value +} + +// The Convert instruction yields the conversion of value X to type +// Type(). One or both of those types is basic (but possibly named). +// +// A conversion may change the value and representation of its operand. +// Conversions are permitted: +// - between real numeric types. +// - between complex numeric types. +// - between string and []byte or []rune. +// - between pointers and unsafe.Pointer. +// - between unsafe.Pointer and uintptr. +// - from (Unicode) integer to (UTF-8) string. +// +// A conversion may imply a type name change also. +// +// Conversions may to be to or from a type parameter. All types in +// the type set of X.Type() can be converted to all types in the type +// set of Type(). +// +// This operation cannot fail dynamically. +// +// Conversions of untyped string/number/bool constants to a specific +// representation are eliminated during SSA construction. +// +// Pos() returns the ast.CallExpr.Lparen, if the instruction arose +// from an explicit conversion in the source. +// +// Example printed form: +// +// t1 = convert []byte <- string (t0) +type Convert struct { + register + X Value +} + +// The MultiConvert instruction yields the conversion of value X to type +// Type(). Either X.Type() or Type() must be a type parameter. Each +// type in the type set of X.Type() can be converted to each type in the +// type set of Type(). +// +// See the documentation for Convert, ChangeType, and SliceToArrayPointer +// for the conversions that are permitted. Additionally conversions of +// slices to arrays are permitted. +// +// This operation can fail dynamically (see SliceToArrayPointer). +// +// Pos() returns the ast.CallExpr.Lparen, if the instruction arose +// from an explicit conversion in the source. +// +// Example printed form: +// +// t1 = multiconvert D <- S (t0) [*[2]rune <- []rune | string <- []rune] +type MultiConvert struct { + register + X Value + from, to types.Type +} + +// ChangeInterface constructs a value of one interface type from a +// value of another interface type known to be assignable to it. +// This operation cannot fail. +// +// Pos() returns the ast.CallExpr.Lparen if the instruction arose from +// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the +// instruction arose from an explicit e.(T) operation; or token.NoPos +// otherwise. +// +// Example printed form: +// +// t1 = change interface interface{} <- I (t0) +type ChangeInterface struct { + register + X Value +} + +// The SliceToArrayPointer instruction yields the conversion of slice X to +// array pointer. +// +// Pos() returns the ast.CallExpr.Lparen, if the instruction arose +// from an explicit conversion in the source. +// +// Conversion may to be to or from a type parameter. All types in +// the type set of X.Type() must be a slice types that can be converted to +// all types in the type set of Type() which must all be pointer to array +// types. +// +// This operation can fail dynamically if the length of the slice is less +// than the length of the array. +// +// Example printed form: +// +// t1 = slice to array pointer *[4]byte <- []byte (t0) +type SliceToArrayPointer struct { + register + X Value +} + +// MakeInterface constructs an instance of an interface type from a +// value of a concrete type. +// +// Use Program.MethodSets.MethodSet(X.Type()) to find the method-set +// of X, and Program.MethodValue(m) to find the implementation of a method. +// +// To construct the zero value of an interface type T, use: +// +// NewConst(constant.MakeNil(), T, pos) +// +// Pos() returns the ast.CallExpr.Lparen, if the instruction arose +// from an explicit conversion in the source. +// +// Example printed form: +// +// t1 = make interface{} <- int (42:int) +// t2 = make Stringer <- t0 +type MakeInterface struct { + register + X Value +} + +// The MakeClosure instruction yields a closure value whose code is +// Fn and whose free variables' values are supplied by Bindings. +// +// Type() returns a (possibly named) *types.Signature. +// +// Pos() returns the ast.FuncLit.Type.Func for a function literal +// closure or the ast.SelectorExpr.Sel for a bound method closure. +// +// Example printed form: +// +// t0 = make closure anon@1.2 [x y z] +// t1 = make closure bound$(main.I).add [i] +type MakeClosure struct { + register + Fn Value // always a *Function + Bindings []Value // values for each free variable in Fn.FreeVars +} + +// The MakeMap instruction creates a new hash-table-based map object +// and yields a value of kind map. +// +// Type() returns a (possibly named) *types.Map. +// +// Pos() returns the ast.CallExpr.Lparen, if created by make(map), or +// the ast.CompositeLit.Lbrack if created by a literal. +// +// Example printed form: +// +// t1 = make map[string]int t0 +// t1 = make StringIntMap t0 +type MakeMap struct { + register + Reserve Value // initial space reservation; nil => default +} + +// The MakeChan instruction creates a new channel object and yields a +// value of kind chan. +// +// Type() returns a (possibly named) *types.Chan. +// +// Pos() returns the ast.CallExpr.Lparen for the make(chan) that +// created it. +// +// Example printed form: +// +// t0 = make chan int 0 +// t0 = make IntChan 0 +type MakeChan struct { + register + Size Value // int; size of buffer; zero => synchronous. +} + +// The MakeSlice instruction yields a slice of length Len backed by a +// newly allocated array of length Cap. +// +// Both Len and Cap must be non-nil Values of integer type. +// +// (Alloc(types.Array) followed by Slice will not suffice because +// Alloc can only create arrays of constant length.) +// +// Type() returns a (possibly named) *types.Slice. +// +// Pos() returns the ast.CallExpr.Lparen for the make([]T) that +// created it. +// +// Example printed form: +// +// t1 = make []string 1:int t0 +// t1 = make StringSlice 1:int t0 +type MakeSlice struct { + register + Len Value + Cap Value +} + +// The Slice instruction yields a slice of an existing string, slice +// or *array X between optional integer bounds Low and High. +// +// Dynamically, this instruction panics if X evaluates to a nil *array +// pointer. +// +// Type() returns string if the type of X was string, otherwise a +// *types.Slice with the same element type as X. +// +// Pos() returns the ast.SliceExpr.Lbrack if created by a x[:] slice +// operation, the ast.CompositeLit.Lbrace if created by a literal, or +// NoPos if not explicit in the source (e.g. a variadic argument slice). +// +// Example printed form: +// +// t1 = slice t0[1:] +type Slice struct { + register + X Value // slice, string, or *array + Low, High, Max Value // each may be nil +} + +// The FieldAddr instruction yields the address of Field of *struct X. +// +// The field is identified by its index within the field list of the +// struct type of X. +// +// Dynamically, this instruction panics if X evaluates to a nil +// pointer. +// +// Type() returns a (possibly named) *types.Pointer. +// +// Pos() returns the position of the ast.SelectorExpr.Sel for the +// field, if explicit in the source. For implicit selections, returns +// the position of the inducing explicit selection. If produced for a +// struct literal S{f: e}, it returns the position of the colon; for +// S{e} it returns the start of expression e. +// +// Example printed form: +// +// t1 = &t0.name [#1] +type FieldAddr struct { + register + X Value // *struct + Field int // index into CoreType(CoreType(X.Type()).(*types.Pointer).Elem()).(*types.Struct).Fields +} + +// The Field instruction yields the Field of struct X. +// +// The field is identified by its index within the field list of the +// struct type of X; by using numeric indices we avoid ambiguity of +// package-local identifiers and permit compact representations. +// +// Pos() returns the position of the ast.SelectorExpr.Sel for the +// field, if explicit in the source. For implicit selections, returns +// the position of the inducing explicit selection. + +// Example printed form: +// +// t1 = t0.name [#1] +type Field struct { + register + X Value // struct + Field int // index into CoreType(X.Type()).(*types.Struct).Fields +} + +// The IndexAddr instruction yields the address of the element at +// index Index of collection X. Index is an integer expression. +// +// The elements of maps and strings are not addressable; use Lookup (map), +// Index (string), or MapUpdate instead. +// +// Dynamically, this instruction panics if X evaluates to a nil *array +// pointer. +// +// Type() returns a (possibly named) *types.Pointer. +// +// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if +// explicit in the source. +// +// Example printed form: +// +// t2 = &t0[t1] +type IndexAddr struct { + register + X Value // *array, slice or type parameter with types array, *array, or slice. + Index Value // numeric index +} + +// The Index instruction yields element Index of collection X, an array, +// string or type parameter containing an array, a string, a pointer to an, +// array or a slice. +// +// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if +// explicit in the source. +// +// Example printed form: +// +// t2 = t0[t1] +type Index struct { + register + X Value // array, string or type parameter with types array, *array, slice, or string. + Index Value // integer index +} + +// The Lookup instruction yields element Index of collection map X. +// Index is the appropriate key type. +// +// If CommaOk, the result is a 2-tuple of the value above and a +// boolean indicating the result of a map membership test for the key. +// The components of the tuple are accessed using Extract. +// +// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source. +// +// Example printed form: +// +// t2 = t0[t1] +// t5 = t3[t4],ok +type Lookup struct { + register + X Value // map + Index Value // key-typed index + CommaOk bool // return a value,ok pair +} + +// SelectState is a helper for Select. +// It represents one goal state and its corresponding communication. +type SelectState struct { + Dir types.ChanDir // direction of case (SendOnly or RecvOnly) + Chan Value // channel to use (for send or receive) + Send Value // value to send (for send) + Pos token.Pos // position of token.ARROW + DebugNode ast.Node // ast.SendStmt or ast.UnaryExpr(<-) [debug mode] +} + +// The Select instruction tests whether (or blocks until) one +// of the specified sent or received states is entered. +// +// Let n be the number of States for which Dir==RECV and T_i (0<=i string iterator; false => map iterator. +} + +// The TypeAssert instruction tests whether interface value X has type +// AssertedType. +// +// If !CommaOk, on success it returns v, the result of the conversion +// (defined below); on failure it panics. +// +// If CommaOk: on success it returns a pair (v, true) where v is the +// result of the conversion; on failure it returns (z, false) where z +// is AssertedType's zero value. The components of the pair must be +// accessed using the Extract instruction. +// +// If Underlying: tests whether interface value X has the underlying +// type AssertedType. +// +// If AssertedType is a concrete type, TypeAssert checks whether the +// dynamic type in interface X is equal to it, and if so, the result +// of the conversion is a copy of the value in the interface. +// +// If AssertedType is an interface, TypeAssert checks whether the +// dynamic type of the interface is assignable to it, and if so, the +// result of the conversion is a copy of the interface value X. +// If AssertedType is a superinterface of X.Type(), the operation will +// fail iff the operand is nil. (Contrast with ChangeInterface, which +// performs no nil-check.) +// +// Type() reflects the actual type of the result, possibly a +// 2-types.Tuple; AssertedType is the asserted type. +// +// Depending on the TypeAssert's purpose, Pos may return: +// - the ast.CallExpr.Lparen of an explicit T(e) conversion; +// - the ast.TypeAssertExpr.Lparen of an explicit e.(T) operation; +// - the ast.CaseClause.Case of a case of a type-switch statement; +// - the Ident(m).NamePos of an interface method value i.m +// (for which TypeAssert may be used to effect the nil check). +// +// Example printed form: +// +// t1 = typeassert t0.(int) +// t3 = typeassert,ok t2.(T) +type TypeAssert struct { + register + X Value + AssertedType types.Type + CommaOk bool +} + +// The Extract instruction yields component Index of Tuple. +// +// This is used to access the results of instructions with multiple +// return values, such as Call, TypeAssert, Next, UnOp(ARROW) and +// IndexExpr(Map). +// +// Example printed form: +// +// t1 = extract t0 #1 +type Extract struct { + register + Tuple Value + Index int +} + +// Instructions executed for effect. They do not yield a value. -------------------- + +// The Jump instruction transfers control to the sole successor of its +// owning block. +// +// A Jump must be the last instruction of its containing BasicBlock. +// +// Pos() returns NoPos. +// +// Example printed form: +// +// jump done +type Jump struct { + anInstruction +} + +// The If instruction transfers control to one of the two successors +// of its owning block, depending on the boolean Cond: the first if +// true, the second if false. +// +// An If instruction must be the last instruction of its containing +// BasicBlock. +// +// Pos() returns NoPos. +// +// Example printed form: +// +// if t0 goto done else body +type If struct { + anInstruction + Cond Value +} + +// The Return instruction returns values and control back to the calling +// function. +// +// len(Results) is always equal to the number of results in the +// function's signature. +// +// If len(Results) > 1, Return returns a tuple value with the specified +// components which the caller must access using Extract instructions. +// +// There is no instruction to return a ready-made tuple like those +// returned by a "value,ok"-mode TypeAssert, Lookup or UnOp(ARROW) or +// a tail-call to a function with multiple result parameters. +// +// Return must be the last instruction of its containing BasicBlock. +// Such a block has no successors. +// +// Pos() returns the ast.ReturnStmt.Return, if explicit in the source. +// +// Example printed form: +// +// return +// return nil:I, 2:int +type Return struct { + anInstruction + Results []Value + pos token.Pos +} + +// The RunDefers instruction pops and invokes the entire stack of +// procedure calls pushed by Defer instructions in this function. +// +// It is legal to encounter multiple 'rundefers' instructions in a +// single control-flow path through a function; this is useful in +// the combined init() function, for example. +// +// Pos() returns NoPos. +// +// Example printed form: +// +// rundefers +type RunDefers struct { + anInstruction +} + +// The Panic instruction initiates a panic with value X. +// +// A Panic instruction must be the last instruction of its containing +// BasicBlock, which must have no successors. +// +// NB: 'go panic(x)' and 'defer panic(x)' do not use this instruction; +// they are treated as calls to a built-in function. +// +// Pos() returns the ast.CallExpr.Lparen if this panic was explicit +// in the source. +// +// Example printed form: +// +// panic t0 +type Panic struct { + anInstruction + X Value // an interface{} + pos token.Pos +} + +// The Go instruction creates a new goroutine and calls the specified +// function within it. +// +// See CallCommon for generic function call documentation. +// +// Pos() returns the ast.GoStmt.Go. +// +// Example printed form: +// +// go println(t0, t1) +// go t3() +// go invoke t5.Println(...t6) +type Go struct { + anInstruction + Call CallCommon + pos token.Pos +} + +// The Defer instruction pushes the specified call onto a stack of +// functions to be called by a RunDefers instruction or by a panic. +// +// If DeferStack != nil, it indicates the defer list that the defer is +// added to. Defer list values come from the Builtin function +// ssa:deferstack. Calls to ssa:deferstack() produces the defer stack +// of the current function frame. DeferStack allows for deferring into an +// alternative function stack than the current function. +// +// See CallCommon for generic function call documentation. +// +// Pos() returns the ast.DeferStmt.Defer. +// +// Example printed form: +// +// defer println(t0, t1) +// defer t3() +// defer invoke t5.Println(...t6) +type Defer struct { + anInstruction + Call CallCommon + DeferStack Value // stack of deferred functions (from ssa:deferstack() intrinsic) onto which this function is pushed + pos token.Pos +} + +// The Send instruction sends X on channel Chan. +// +// Pos() returns the ast.SendStmt.Arrow, if explicit in the source. +// +// Example printed form: +// +// send t0 <- t1 +type Send struct { + anInstruction + Chan, X Value + pos token.Pos +} + +// The Store instruction stores Val at address Addr. +// Stores can be of arbitrary types. +// +// Pos() returns the position of the source-level construct most closely +// associated with the memory store operation. +// Since implicit memory stores are numerous and varied and depend upon +// implementation choices, the details are not specified. +// +// Example printed form: +// +// *x = y +type Store struct { + anInstruction + Addr Value + Val Value + pos token.Pos +} + +// The MapUpdate instruction updates the association of Map[Key] to +// Value. +// +// Pos() returns the ast.KeyValueExpr.Colon or ast.IndexExpr.Lbrack, +// if explicit in the source. +// +// Example printed form: +// +// t0[t1] = t2 +type MapUpdate struct { + anInstruction + Map Value + Key Value + Value Value + pos token.Pos +} + +// A DebugRef instruction maps a source-level expression Expr to the +// SSA value X that represents the value (!IsAddr) or address (IsAddr) +// of that expression. +// +// DebugRef is a pseudo-instruction: it has no dynamic effect. +// +// Pos() returns Expr.Pos(), the start position of the source-level +// expression. This is not the same as the "designated" token as +// documented at Value.Pos(). e.g. CallExpr.Pos() does not return the +// position of the ("designated") Lparen token. +// +// If Expr is an *ast.Ident denoting a var or func, Object() returns +// the object; though this information can be obtained from the type +// checker, including it here greatly facilitates debugging. +// For non-Ident expressions, Object() returns nil. +// +// DebugRefs are generated only for functions built with debugging +// enabled; see Package.SetDebugMode() and the GlobalDebug builder +// mode flag. +// +// DebugRefs are not emitted for ast.Idents referring to constants or +// predeclared identifiers, since they are trivial and numerous. +// Nor are they emitted for ast.ParenExprs. +// +// (By representing these as instructions, rather than out-of-band, +// consistency is maintained during transformation passes by the +// ordinary SSA renaming machinery.) +// +// Example printed form: +// +// ; *ast.CallExpr @ 102:9 is t5 +// ; var x float64 @ 109:72 is x +// ; address of *ast.CompositeLit @ 216:10 is t0 +type DebugRef struct { + // TODO(generics): Reconsider what DebugRefs are for generics. + anInstruction + Expr ast.Expr // the referring expression (never *ast.ParenExpr) + object types.Object // the identity of the source var/func + IsAddr bool // Expr is addressable and X is the address it denotes + X Value // the value or address of Expr +} + +// Embeddable mix-ins and helpers for common parts of other structs. ----------- + +// register is a mix-in embedded by all SSA values that are also +// instructions, i.e. virtual registers, and provides a uniform +// implementation of most of the Value interface: Value.Name() is a +// numbered register (e.g. "t0"); the other methods are field accessors. +// +// Temporary names are automatically assigned to each register on +// completion of building a function in SSA form. +// +// Clients must not assume that the 'id' value (and the Name() derived +// from it) is unique within a function. As always in this API, +// semantics are determined only by identity; names exist only to +// facilitate debugging. +type register struct { + anInstruction + num int // "name" of virtual register, e.g. "t0". Not guaranteed unique. + typ types.Type // type of virtual register + pos token.Pos // position of source expression, or NoPos + referrers []Instruction +} + +// anInstruction is a mix-in embedded by all Instructions. +// It provides the implementations of the Block and setBlock methods. +type anInstruction struct { + block *BasicBlock // the basic block of this instruction +} + +// CallCommon is contained by Go, Defer and Call to hold the +// common parts of a function or method call. +// +// Each CallCommon exists in one of two modes, function call and +// interface method invocation, or "call" and "invoke" for short. +// +// 1. "call" mode: when Method is nil (!IsInvoke), a CallCommon +// represents an ordinary function call of the value in Value, +// which may be a *Builtin, a *Function or any other value of kind +// 'func'. +// +// Value may be one of: +// +// (a) a *Function, indicating a statically dispatched call +// to a package-level function, an anonymous function, or +// a method of a named type. +// (b) a *MakeClosure, indicating an immediately applied +// function literal with free variables. +// (c) a *Builtin, indicating a statically dispatched call +// to a built-in function. +// (d) any other value, indicating a dynamically dispatched +// function call. +// +// StaticCallee returns the identity of the callee in cases +// (a) and (b), nil otherwise. +// +// Args contains the arguments to the call. If Value is a method, +// Args[0] contains the receiver parameter. +// +// Example printed form: +// +// t2 = println(t0, t1) +// go t3() +// defer t5(...t6) +// +// 2. "invoke" mode: when Method is non-nil (IsInvoke), a CallCommon +// represents a dynamically dispatched call to an interface method. +// In this mode, Value is the interface value and Method is the +// interface's abstract method. The interface value may be a type +// parameter. Note: an interface method may be shared by multiple +// interfaces due to embedding; Value.Type() provides the specific +// interface used for this call. +// +// Value is implicitly supplied to the concrete method implementation +// as the receiver parameter; in other words, Args[0] holds not the +// receiver but the first true argument. +// +// Example printed form: +// +// t1 = invoke t0.String() +// go invoke t3.Run(t2) +// defer invoke t4.Handle(...t5) +// +// For all calls to variadic functions (Signature().Variadic()), +// the last element of Args is a slice. +type CallCommon struct { + Value Value // receiver (invoke mode) or func value (call mode) + Method *types.Func // interface method (invoke mode) + Args []Value // actual parameters (in static method call, includes receiver) + pos token.Pos // position of CallExpr.Lparen, iff explicit in source +} + +// IsInvoke returns true if this call has "invoke" (not "call") mode. +func (c *CallCommon) IsInvoke() bool { + return c.Method != nil +} + +func (c *CallCommon) Pos() token.Pos { return c.pos } + +// Signature returns the signature of the called function. +// +// For an "invoke"-mode call, the signature of the interface method is +// returned. +// +// In either "call" or "invoke" mode, if the callee is a method, its +// receiver is represented by sig.Recv, not sig.Params().At(0). +func (c *CallCommon) Signature() *types.Signature { + if c.Method != nil { + return c.Method.Type().(*types.Signature) + } + return typeparams.CoreType(c.Value.Type()).(*types.Signature) +} + +// StaticCallee returns the callee if this is a trivially static +// "call"-mode call to a function. +func (c *CallCommon) StaticCallee() *Function { + switch fn := c.Value.(type) { + case *Function: + return fn + case *MakeClosure: + return fn.Fn.(*Function) + } + return nil +} + +// Description returns a description of the mode of this call suitable +// for a user interface, e.g., "static method call". +func (c *CallCommon) Description() string { + switch fn := c.Value.(type) { + case *Builtin: + return "built-in function call" + case *MakeClosure: + return "static function closure call" + case *Function: + if fn.Signature.Recv() != nil { + return "static method call" + } + return "static function call" + } + if c.IsInvoke() { + return "dynamic method call" // ("invoke" mode) + } + return "dynamic function call" +} + +// The CallInstruction interface, implemented by *Go, *Defer and *Call, +// exposes the common parts of function-calling instructions, +// yet provides a way back to the Value defined by *Call alone. +type CallInstruction interface { + Instruction + Common() *CallCommon // returns the common parts of the call + Value() *Call // returns the result value of the call (*Call) or nil (*Go, *Defer) +} + +func (s *Call) Common() *CallCommon { return &s.Call } +func (s *Defer) Common() *CallCommon { return &s.Call } +func (s *Go) Common() *CallCommon { return &s.Call } + +func (s *Call) Value() *Call { return s } +func (s *Defer) Value() *Call { return nil } +func (s *Go) Value() *Call { return nil } + +func (v *Builtin) Type() types.Type { return v.sig } +func (v *Builtin) Name() string { return v.name } +func (*Builtin) Referrers() *[]Instruction { return nil } +func (v *Builtin) Pos() token.Pos { return token.NoPos } +func (v *Builtin) Object() types.Object { return types.Universe.Lookup(v.name) } +func (v *Builtin) Parent() *Function { return nil } + +func (v *FreeVar) Type() types.Type { return v.typ } +func (v *FreeVar) Name() string { return v.name } +func (v *FreeVar) Referrers() *[]Instruction { return &v.referrers } +func (v *FreeVar) Pos() token.Pos { return v.pos } +func (v *FreeVar) Parent() *Function { return v.parent } + +func (v *Global) Type() types.Type { return v.typ } +func (v *Global) Name() string { return v.name } +func (v *Global) Parent() *Function { return nil } +func (v *Global) Pos() token.Pos { return v.pos } +func (v *Global) Referrers() *[]Instruction { return nil } +func (v *Global) Token() token.Token { return token.VAR } +func (v *Global) Object() types.Object { return v.object } +func (v *Global) String() string { return v.RelString(nil) } +func (v *Global) Package() *Package { return v.Pkg } +func (v *Global) RelString(from *types.Package) string { return relString(v, from) } + +func (v *Function) Name() string { return v.name } +func (v *Function) Type() types.Type { return v.Signature } +func (v *Function) Pos() token.Pos { return v.pos } +func (v *Function) Token() token.Token { return token.FUNC } +func (v *Function) Object() types.Object { + if v.object != nil { + return types.Object(v.object) + } + return nil +} +func (v *Function) String() string { return v.RelString(nil) } +func (v *Function) Package() *Package { return v.Pkg } +func (v *Function) Parent() *Function { return v.parent } +func (v *Function) Referrers() *[]Instruction { + if v.parent != nil { + return &v.referrers + } + return nil +} + +// TypeParams are the function's type parameters if generic or the +// type parameters that were instantiated if fn is an instantiation. +// +// Specifically, the resulting list behaves like: +// +// func f // [] +// func f[P] // [P] +// func (T) m // [] +// func (T) m[P] // [P] +// func (T[P]) m // [P] +// func (T[P]) m[Q] // [P (index=0), Q (index=0)] +// +// Note that receiver type parameters precede other type parameters. +// Also, type parameters may have the same index if they come from +// different source type parameter lists. +func (fn *Function) TypeParams() *types.TypeParamList { + return consTypeParamLists(fn.recvtypeparams, fn.typeparams) +} + +func consTypeParamLists(l, r *types.TypeParamList) *types.TypeParamList { + if l.Len() == 0 { + return r + } + if r.Len() == 0 { + return l + } + + tpars := make([]*types.TypeParam, l.Len()+r.Len()) + for i := range l.Len() { + tpars[i] = l.At(i) + } + for i := range r.Len() { + tpars[i+l.Len()] = r.At(i) + } + // This logic unsafely assumes (and asserts) that the layout of the + // TypeParamList is identical to that of a slice of TypeParams. This + // is a hack while we work on getting a constructor for TypeParamList + // approved (see go.dev/issue/79603). + t := reflect.TypeFor[types.TypeParamList]() + if t.NumField() != 1 { + panic("TypeParamList has unexpected fields") + } + if f := t.Field(0); f.Offset != 0 || f.Type != reflect.TypeFor[[]*types.TypeParam]() { + panic("TypeParamList field is not []*TypeParam") + } + return (*types.TypeParamList)(unsafe.Pointer(&tpars)) +} + +// TypeArgs are the types that TypeParams() were instantiated by to create fn +// from fn.Origin(). +// +// Specifically, the resulting slice behaves like: +// +// f // [] +// f[int] // [int] +// T.m // [] +// T.m[int] // [int] +// T[int].m // [int] +// T[int].m[uint] // [int, uint] +// +// Note that receiver type arguments precede other type arguments. +func (fn *Function) TypeArgs() []types.Type { + return slices.Concat(fn.recvtypeargs, fn.typeargs) +} + +// Origin returns the generic function from which fn was instantiated, +// or nil if fn is not an instantiation. +func (fn *Function) Origin() *Function { + if fn.parent != nil && fn.parent.hasTypeArgs() { + // Nested functions are BUILT at a different time than their instances. + // Build declared package if not yet BUILT. This is not an expected use + // case, but is simple and robust. + fn.declaredPackage().Build() + } + return origin(fn) +} + +// hasTypeParams returns whether fn has any type parameters +func (fn *Function) hasTypeParams() bool { + return fn.recvtypeparams.Len()+fn.typeparams.Len() > 0 +} + +// hasTypeArgs returns whether fn has any type arguments +func (fn *Function) hasTypeArgs() bool { + return len(fn.recvtypeargs)+len(fn.typeargs) > 0 +} + +// subrtargs returns fn's receiver type parameters substituted with receiver type arguments +func (fn *Function) subrtargs(m *types.Func) []types.Type { + return fn.subst.types(receiverTypeArgs(m)) +} + +// subtargs returns fn's type parameters substituted with (possibly implied) type arguments +func (fn *Function) subtargs(id *ast.Ident) []types.Type { + return fn.subst.types(instanceArgs(fn.info, id)) +} + +// targstr returns a comma-separated string of the types in targs +func targstr(targs []types.Type) string { + var sb strings.Builder + if len(targs) > 0 { + sb.WriteString("[") + for i := range targs { + if i > 0 { + sb.WriteString(", ") + } + sb.WriteString(targs[i].String()) + } + sb.WriteString("]") + } + return sb.String() +} + +// origin is the function that fn is an instantiation of. Returns nil if fn is +// not an instantiation. +// +// Precondition: fn and the origin function are done building. +func origin(fn *Function) *Function { + if fn.parent != nil && fn.parent.hasTypeArgs() { + return origin(fn.parent).AnonFuncs[fn.anonIdx] + } + return fn.topLevelOrigin +} + +func (v *Parameter) Type() types.Type { return v.typ } +func (v *Parameter) Name() string { return v.name } +func (v *Parameter) Object() types.Object { return v.object } +func (v *Parameter) Referrers() *[]Instruction { return &v.referrers } +func (v *Parameter) Pos() token.Pos { return v.object.Pos() } +func (v *Parameter) Parent() *Function { return v.parent } + +func (v *Alloc) Type() types.Type { return v.typ } +func (v *Alloc) Referrers() *[]Instruction { return &v.referrers } +func (v *Alloc) Pos() token.Pos { return v.pos } + +func (v *register) Type() types.Type { return v.typ } +func (v *register) setType(typ types.Type) { v.typ = typ } +func (v *register) Name() string { return fmt.Sprintf("t%d", v.num) } +func (v *register) setNum(num int) { v.num = num } +func (v *register) Referrers() *[]Instruction { return &v.referrers } +func (v *register) Pos() token.Pos { return v.pos } +func (v *register) setPos(pos token.Pos) { v.pos = pos } + +func (v *anInstruction) Parent() *Function { return v.block.parent } +func (v *anInstruction) Block() *BasicBlock { return v.block } +func (v *anInstruction) setBlock(block *BasicBlock) { v.block = block } +func (v *anInstruction) Referrers() *[]Instruction { return nil } + +func (t *Type) Name() string { return t.object.Name() } +func (t *Type) Pos() token.Pos { return t.object.Pos() } +func (t *Type) Type() types.Type { return t.object.Type() } +func (t *Type) Token() token.Token { return token.TYPE } +func (t *Type) Object() types.Object { return t.object } +func (t *Type) String() string { return t.RelString(nil) } +func (t *Type) Package() *Package { return t.pkg } +func (t *Type) RelString(from *types.Package) string { return relString(t, from) } + +func (c *NamedConst) Name() string { return c.object.Name() } +func (c *NamedConst) Pos() token.Pos { return c.object.Pos() } +func (c *NamedConst) String() string { return c.RelString(nil) } +func (c *NamedConst) Type() types.Type { return c.object.Type() } +func (c *NamedConst) Token() token.Token { return token.CONST } +func (c *NamedConst) Object() types.Object { return c.object } +func (c *NamedConst) Package() *Package { return c.pkg } +func (c *NamedConst) RelString(from *types.Package) string { return relString(c, from) } + +func (d *DebugRef) Object() types.Object { return d.object } + +// Func returns the package-level function of the specified name, +// or nil if not found. +func (p *Package) Func(name string) (f *Function) { + f, _ = p.Members[name].(*Function) + return +} + +// Var returns the package-level variable of the specified name, +// or nil if not found. +func (p *Package) Var(name string) (g *Global) { + g, _ = p.Members[name].(*Global) + return +} + +// Const returns the package-level constant of the specified name, +// or nil if not found. +func (p *Package) Const(name string) (c *NamedConst) { + c, _ = p.Members[name].(*NamedConst) + return +} + +// Type returns the package-level type of the specified name, +// or nil if not found. +func (p *Package) Type(name string) (t *Type) { + t, _ = p.Members[name].(*Type) + return +} + +func (v *Call) Pos() token.Pos { return v.Call.pos } +func (s *Defer) Pos() token.Pos { return s.pos } +func (s *Go) Pos() token.Pos { return s.pos } +func (s *MapUpdate) Pos() token.Pos { return s.pos } +func (s *Panic) Pos() token.Pos { return s.pos } +func (s *Return) Pos() token.Pos { return s.pos } +func (s *Send) Pos() token.Pos { return s.pos } +func (s *Store) Pos() token.Pos { return s.pos } +func (s *If) Pos() token.Pos { return token.NoPos } +func (s *Jump) Pos() token.Pos { return token.NoPos } +func (s *RunDefers) Pos() token.Pos { return token.NoPos } +func (s *DebugRef) Pos() token.Pos { return s.Expr.Pos() } + +// Operands. + +func (v *Alloc) Operands(rands []*Value) []*Value { + return rands +} + +func (v *BinOp) Operands(rands []*Value) []*Value { + return append(rands, &v.X, &v.Y) +} + +func (c *CallCommon) Operands(rands []*Value) []*Value { + rands = append(rands, &c.Value) + for i := range c.Args { + rands = append(rands, &c.Args[i]) + } + return rands +} + +func (s *Go) Operands(rands []*Value) []*Value { + return s.Call.Operands(rands) +} + +func (s *Call) Operands(rands []*Value) []*Value { + return s.Call.Operands(rands) +} + +func (s *Defer) Operands(rands []*Value) []*Value { + return append(s.Call.Operands(rands), &s.DeferStack) +} + +func (v *ChangeInterface) Operands(rands []*Value) []*Value { + return append(rands, &v.X) +} + +func (v *ChangeType) Operands(rands []*Value) []*Value { + return append(rands, &v.X) +} + +func (v *Convert) Operands(rands []*Value) []*Value { + return append(rands, &v.X) +} + +func (v *MultiConvert) Operands(rands []*Value) []*Value { + return append(rands, &v.X) +} + +func (v *SliceToArrayPointer) Operands(rands []*Value) []*Value { + return append(rands, &v.X) +} + +func (s *DebugRef) Operands(rands []*Value) []*Value { + return append(rands, &s.X) +} + +func (v *Extract) Operands(rands []*Value) []*Value { + return append(rands, &v.Tuple) +} + +func (v *Field) Operands(rands []*Value) []*Value { + return append(rands, &v.X) +} + +func (v *FieldAddr) Operands(rands []*Value) []*Value { + return append(rands, &v.X) +} + +func (s *If) Operands(rands []*Value) []*Value { + return append(rands, &s.Cond) +} + +func (v *Index) Operands(rands []*Value) []*Value { + return append(rands, &v.X, &v.Index) +} + +func (v *IndexAddr) Operands(rands []*Value) []*Value { + return append(rands, &v.X, &v.Index) +} + +func (*Jump) Operands(rands []*Value) []*Value { + return rands +} + +func (v *Lookup) Operands(rands []*Value) []*Value { + return append(rands, &v.X, &v.Index) +} + +func (v *MakeChan) Operands(rands []*Value) []*Value { + return append(rands, &v.Size) +} + +func (v *MakeClosure) Operands(rands []*Value) []*Value { + rands = append(rands, &v.Fn) + for i := range v.Bindings { + rands = append(rands, &v.Bindings[i]) + } + return rands +} + +func (v *MakeInterface) Operands(rands []*Value) []*Value { + return append(rands, &v.X) +} + +func (v *MakeMap) Operands(rands []*Value) []*Value { + return append(rands, &v.Reserve) +} + +func (v *MakeSlice) Operands(rands []*Value) []*Value { + return append(rands, &v.Len, &v.Cap) +} + +func (v *MapUpdate) Operands(rands []*Value) []*Value { + return append(rands, &v.Map, &v.Key, &v.Value) +} + +func (v *Next) Operands(rands []*Value) []*Value { + return append(rands, &v.Iter) +} + +func (s *Panic) Operands(rands []*Value) []*Value { + return append(rands, &s.X) +} + +func (v *Phi) Operands(rands []*Value) []*Value { + for i := range v.Edges { + rands = append(rands, &v.Edges[i]) + } + return rands +} + +func (v *Range) Operands(rands []*Value) []*Value { + return append(rands, &v.X) +} + +func (s *Return) Operands(rands []*Value) []*Value { + for i := range s.Results { + rands = append(rands, &s.Results[i]) + } + return rands +} + +func (*RunDefers) Operands(rands []*Value) []*Value { + return rands +} + +func (v *Select) Operands(rands []*Value) []*Value { + for i := range v.States { + rands = append(rands, &v.States[i].Chan, &v.States[i].Send) + } + return rands +} + +func (s *Send) Operands(rands []*Value) []*Value { + return append(rands, &s.Chan, &s.X) +} + +func (v *Slice) Operands(rands []*Value) []*Value { + return append(rands, &v.X, &v.Low, &v.High, &v.Max) +} + +func (s *Store) Operands(rands []*Value) []*Value { + return append(rands, &s.Addr, &s.Val) +} + +func (v *TypeAssert) Operands(rands []*Value) []*Value { + return append(rands, &v.X) +} + +func (v *UnOp) Operands(rands []*Value) []*Value { + return append(rands, &v.X) +} + +// Non-Instruction Values: +func (v *Builtin) Operands(rands []*Value) []*Value { return rands } +func (v *FreeVar) Operands(rands []*Value) []*Value { return rands } +func (v *Const) Operands(rands []*Value) []*Value { return rands } +func (v *Function) Operands(rands []*Value) []*Value { return rands } +func (v *Global) Operands(rands []*Value) []*Value { return rands } +func (v *Parameter) Operands(rands []*Value) []*Value { return rands } diff --git a/vendor/golang.org/x/tools/go/ssa/ssautil/deprecated.go b/vendor/golang.org/x/tools/go/ssa/ssautil/deprecated.go new file mode 100644 index 0000000..4feff71 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/ssautil/deprecated.go @@ -0,0 +1,36 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssautil + +// This file contains deprecated public APIs. +// We discourage their use. + +import ( + "golang.org/x/tools/go/loader" + "golang.org/x/tools/go/ssa" +) + +// CreateProgram returns a new program in SSA form, given a program +// loaded from source. An SSA package is created for each transitively +// error-free package of lprog. +// +// Code for bodies of functions is not built until Build is called +// on the result. +// +// The mode parameter controls diagnostics and checking during SSA construction. +// +// Deprecated: Use [golang.org/x/tools/go/packages] and the [Packages] +// function instead; see ssa.Example_loadPackages. +func CreateProgram(lprog *loader.Program, mode ssa.BuilderMode) *ssa.Program { + prog := ssa.NewProgram(lprog.Fset, mode) + + for _, info := range lprog.AllPackages { + if info.TransitivelyErrorFree { + prog.CreatePackage(info.Pkg, info.Files, &info.Info, info.Importable) + } + } + + return prog +} diff --git a/vendor/golang.org/x/tools/go/ssa/ssautil/load.go b/vendor/golang.org/x/tools/go/ssa/ssautil/load.go new file mode 100644 index 0000000..c64b03f --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/ssautil/load.go @@ -0,0 +1,189 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssautil + +// This file defines utility functions for constructing programs in SSA form. + +import ( + "go/ast" + "go/token" + "go/types" + + "golang.org/x/tools/go/packages" + "golang.org/x/tools/go/ssa" +) + +// Packages creates an SSA program for a set of packages. +// +// The packages must have been loaded from source syntax using the +// [packages.Load] function in [packages.LoadSyntax] or +// [packages.LoadAllSyntax] mode. +// +// Packages creates an SSA package for each well-typed package in the +// initial list, plus all their dependencies. The resulting list of +// packages corresponds to the list of initial packages, and may contain +// a nil if SSA code could not be constructed for the corresponding initial +// package due to type errors. +// +// Code for bodies of functions is not built until [Program.Build] is +// called on the resulting Program. SSA code is constructed only for +// the initial packages with well-typed syntax trees. +// +// The mode parameter controls diagnostics and checking during SSA construction. +func Packages(initial []*packages.Package, mode ssa.BuilderMode) (*ssa.Program, []*ssa.Package) { + // TODO(adonovan): opt: this calls CreatePackage far more than + // necessary: for all dependencies, not just the (non-initial) + // direct dependencies of the initial packages. + // + // But can it reasonably be changed without breaking the + // spirit and/or letter of the law above? Clients may notice + // if we call CreatePackage less, as methods like + // Program.FuncValue will return nil. Or must we provide a new + // function (and perhaps deprecate this one)? Is it worth it? + // + // Tim King makes the interesting point that it would be + // possible to entirely alleviate the client from the burden + // of calling CreatePackage for non-syntax packages, if we + // were to treat vars and funcs lazily in the same way we now + // treat methods. (In essence, try to move away from the + // notion of ssa.Packages, and make the Program answer + // all reasonable questions about any types.Object.) + + return doPackages(initial, mode, false) +} + +// AllPackages creates an SSA program for a set of packages plus all +// their dependencies. +// +// The packages must have been loaded from source syntax using the +// [packages.Load] function in [packages.LoadAllSyntax] mode. +// +// AllPackages creates an SSA package for each well-typed package in the +// initial list, plus all their dependencies. The resulting list of +// packages corresponds to the list of initial packages, and may contain +// a nil if SSA code could not be constructed for the corresponding +// initial package due to type errors. +// +// Code for bodies of functions is not built until Build is called on +// the resulting Program. SSA code is constructed for all packages with +// well-typed syntax trees. +// +// The mode parameter controls diagnostics and checking during SSA construction. +func AllPackages(initial []*packages.Package, mode ssa.BuilderMode) (*ssa.Program, []*ssa.Package) { + return doPackages(initial, mode, true) +} + +func doPackages(initial []*packages.Package, mode ssa.BuilderMode, deps bool) (*ssa.Program, []*ssa.Package) { + + var fset *token.FileSet + if len(initial) > 0 { + fset = initial[0].Fset + } + + prog := ssa.NewProgram(fset, mode) + + isInitial := make(map[*packages.Package]bool, len(initial)) + for _, p := range initial { + isInitial[p] = true + } + + ssamap := make(map[*packages.Package]*ssa.Package) + packages.Visit(initial, nil, func(p *packages.Package) { + if p.Types != nil && !p.IllTyped { + var files []*ast.File + var info *types.Info + if deps || isInitial[p] { + files = p.Syntax + info = p.TypesInfo + } + ssamap[p] = prog.CreatePackage(p.Types, files, info, true) + } + }) + + var ssapkgs []*ssa.Package + for _, p := range initial { + ssapkgs = append(ssapkgs, ssamap[p]) // may be nil + } + return prog, ssapkgs +} + +// BuildPackage builds an SSA program with SSA intermediate +// representation (IR) for all functions of a single package. +// +// It populates pkg by type-checking the specified file syntax trees. All +// dependencies are loaded using the importer specified by tc, which +// typically loads compiler export data; SSA code cannot be built for +// those packages. BuildPackage then constructs an [ssa.Program] with all +// dependency packages created, and builds and returns the SSA package +// corresponding to pkg. +// +// The caller must have set pkg.Path to the import path. +// +// The operation fails if there were any type-checking or import errors. +// +// See ../example_test.go for an example. +func BuildPackage(tc *types.Config, fset *token.FileSet, pkg *types.Package, files []*ast.File, mode ssa.BuilderMode) (*ssa.Package, *types.Info, error) { + if fset == nil { + panic("no token.FileSet") + } + if pkg.Path() == "" { + panic("package has no import path") + } + + info := &types.Info{ + Types: make(map[ast.Expr]types.TypeAndValue), + Defs: make(map[*ast.Ident]types.Object), + Uses: make(map[*ast.Ident]types.Object), + Implicits: make(map[ast.Node]types.Object), + Instances: make(map[*ast.Ident]types.Instance), + Scopes: make(map[ast.Node]*types.Scope), + Selections: make(map[*ast.SelectorExpr]*types.Selection), + FileVersions: make(map[*ast.File]string), + } + if err := types.NewChecker(tc, fset, pkg, info).Files(files); err != nil { + return nil, nil, err + } + + prog := ssa.NewProgram(fset, mode) + + // Create SSA packages for all imports. + // Order is not significant. + created := make(map[*types.Package]bool) + var createAll func(pkgs []*types.Package) + createAll = func(pkgs []*types.Package) { + for _, p := range pkgs { + if !created[p] { + created[p] = true + prog.CreatePackage(p, nil, nil, true) + createAll(p.Imports()) + } + } + } + createAll(pkg.Imports()) + + // TODO(adonovan): we could replace createAll with just: + // + // // Create SSA packages for all imports. + // for _, p := range pkg.Imports() { + // prog.CreatePackage(p, nil, nil, true) + // } + // + // (with minor changes to changes to ../builder_test.go as + // shown in CL 511715 PS 10.) But this would strictly violate + // the letter of the doc comment above, which says "all + // dependencies created". + // + // Tim makes the good point with some extra work we could + // remove the need for any CreatePackage calls except the + // ones with syntax (i.e. primary packages). Of course + // You wouldn't have ssa.Packages and Members for as + // many things but no-one really uses that anyway. + // I wish I had done this from the outset. + + // Create and build the primary package. + ssapkg := prog.CreatePackage(pkg, files, info, false) + ssapkg.Build() + return ssapkg, info, nil +} diff --git a/vendor/golang.org/x/tools/go/ssa/ssautil/switch.go b/vendor/golang.org/x/tools/go/ssa/ssautil/switch.go new file mode 100644 index 0000000..dd4b04e --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/ssautil/switch.go @@ -0,0 +1,230 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssautil + +// This file implements discovery of switch and type-switch constructs +// from low-level control flow. +// +// Many techniques exist for compiling a high-level switch with +// constant cases to efficient machine code. The optimal choice will +// depend on the data type, the specific case values, the code in the +// body of each case, and the hardware. +// Some examples: +// - a lookup table (for a switch that maps constants to constants) +// - a computed goto +// - a binary tree +// - a perfect hash +// - a two-level switch (to partition constant strings by their first byte). + +import ( + "bytes" + "fmt" + "go/token" + "go/types" + + "golang.org/x/tools/go/ssa" +) + +// A ConstCase represents a single constant comparison. +// It is part of a Switch. +type ConstCase struct { + Block *ssa.BasicBlock // block performing the comparison + Body *ssa.BasicBlock // body of the case + Value *ssa.Const // case comparand +} + +// A TypeCase represents a single type assertion. +// It is part of a Switch. +type TypeCase struct { + Block *ssa.BasicBlock // block performing the type assert + Body *ssa.BasicBlock // body of the case + Type types.Type // case type + Binding ssa.Value // value bound by this case +} + +// A Switch is a logical high-level control flow operation +// (a multiway branch) discovered by analysis of a CFG containing +// only if/else chains. It is not part of the ssa.Instruction set. +// +// One of ConstCases and TypeCases has length >= 2; +// the other is nil. +// +// In a value switch, the list of cases may contain duplicate constants. +// A type switch may contain duplicate types, or types assignable +// to an interface type also in the list. +// TODO(adonovan): eliminate such duplicates. +type Switch struct { + Start *ssa.BasicBlock // block containing start of if/else chain + X ssa.Value // the switch operand + ConstCases []ConstCase // ordered list of constant comparisons + TypeCases []TypeCase // ordered list of type assertions + Default *ssa.BasicBlock // successor if all comparisons fail +} + +func (sw *Switch) String() string { + // We represent each block by the String() of its + // first Instruction, e.g. "print(42:int)". + var buf bytes.Buffer + if sw.ConstCases != nil { + fmt.Fprintf(&buf, "switch %s {\n", sw.X.Name()) + for _, c := range sw.ConstCases { + fmt.Fprintf(&buf, "case %s: %s\n", c.Value, c.Body.Instrs[0]) + } + } else { + fmt.Fprintf(&buf, "switch %s.(type) {\n", sw.X.Name()) + for _, c := range sw.TypeCases { + fmt.Fprintf(&buf, "case %s %s: %s\n", + c.Binding.Name(), c.Type, c.Body.Instrs[0]) + } + } + if sw.Default != nil { + fmt.Fprintf(&buf, "default: %s\n", sw.Default.Instrs[0]) + } + fmt.Fprintf(&buf, "}") + return buf.String() +} + +// Switches examines the control-flow graph of fn and returns the +// set of inferred value and type switches. A value switch tests an +// ssa.Value for equality against two or more compile-time constant +// values. Switches involving link-time constants (addresses) are +// ignored. A type switch type-asserts an ssa.Value against two or +// more types. +// +// The switches are returned in dominance order. +// +// The resulting switches do not necessarily correspond to uses of the +// 'switch' keyword in the source: for example, a single source-level +// switch statement with non-constant cases may result in zero, one or +// many Switches, one per plural sequence of constant cases. +// Switches may even be inferred from if/else- or goto-based control flow. +// (In general, the control flow constructs of the source program +// cannot be faithfully reproduced from the SSA representation.) +func Switches(fn *ssa.Function) []Switch { + // Traverse the CFG in dominance order, so we don't + // enter an if/else-chain in the middle. + var switches []Switch + seen := make(map[*ssa.BasicBlock]bool) // TODO(adonovan): opt: use ssa.blockSet + for _, b := range fn.DomPreorder() { + if x, k := isComparisonBlock(b); x != nil { + // Block b starts a switch. + sw := Switch{Start: b, X: x} + valueSwitch(&sw, k, seen) + if len(sw.ConstCases) > 1 { + switches = append(switches, sw) + } + } + + if y, x, T := isTypeAssertBlock(b); y != nil { + // Block b starts a type switch. + sw := Switch{Start: b, X: x} + typeSwitch(&sw, y, T, seen) + if len(sw.TypeCases) > 1 { + switches = append(switches, sw) + } + } + } + return switches +} + +func valueSwitch(sw *Switch, k *ssa.Const, seen map[*ssa.BasicBlock]bool) { + b := sw.Start + x := sw.X + for x == sw.X { + if seen[b] { + break + } + seen[b] = true + + sw.ConstCases = append(sw.ConstCases, ConstCase{ + Block: b, + Body: b.Succs[0], + Value: k, + }) + b = b.Succs[1] + if len(b.Instrs) > 2 { + // Block b contains not just 'if x == k', + // so it may have side effects that + // make it unsafe to elide. + break + } + if len(b.Preds) != 1 { + // Block b has multiple predecessors, + // so it cannot be treated as a case. + break + } + x, k = isComparisonBlock(b) + } + sw.Default = b +} + +func typeSwitch(sw *Switch, y ssa.Value, T types.Type, seen map[*ssa.BasicBlock]bool) { + b := sw.Start + x := sw.X + for x == sw.X { + if seen[b] { + break + } + seen[b] = true + + sw.TypeCases = append(sw.TypeCases, TypeCase{ + Block: b, + Body: b.Succs[0], + Type: T, + Binding: y, + }) + b = b.Succs[1] + if len(b.Instrs) > 4 { + // Block b contains not just + // {TypeAssert; Extract #0; Extract #1; If} + // so it may have side effects that + // make it unsafe to elide. + break + } + if len(b.Preds) != 1 { + // Block b has multiple predecessors, + // so it cannot be treated as a case. + break + } + y, x, T = isTypeAssertBlock(b) + } + sw.Default = b +} + +// isComparisonBlock returns the operands (v, k) if a block ends with +// a comparison v==k, where k is a compile-time constant. +func isComparisonBlock(b *ssa.BasicBlock) (v ssa.Value, k *ssa.Const) { + if n := len(b.Instrs); n >= 2 { + if i, ok := b.Instrs[n-1].(*ssa.If); ok { + if binop, ok := i.Cond.(*ssa.BinOp); ok && binop.Block() == b && binop.Op == token.EQL { + if k, ok := binop.Y.(*ssa.Const); ok { + return binop.X, k + } + if k, ok := binop.X.(*ssa.Const); ok { + return binop.Y, k + } + } + } + } + return +} + +// isTypeAssertBlock returns the operands (y, x, T) if a block ends with +// a type assertion "if y, ok := x.(T); ok {". +func isTypeAssertBlock(b *ssa.BasicBlock) (y, x ssa.Value, T types.Type) { + if n := len(b.Instrs); n >= 4 { + if i, ok := b.Instrs[n-1].(*ssa.If); ok { + if ext1, ok := i.Cond.(*ssa.Extract); ok && ext1.Block() == b && ext1.Index == 1 { + if ta, ok := ext1.Tuple.(*ssa.TypeAssert); ok && ta.Block() == b { + // hack: relies upon instruction ordering. + if ext0, ok := b.Instrs[n-3].(*ssa.Extract); ok { + return ext0, ta.X, ta.AssertedType + } + } + } + } + } + return +} diff --git a/vendor/golang.org/x/tools/go/ssa/ssautil/visit.go b/vendor/golang.org/x/tools/go/ssa/ssautil/visit.go new file mode 100644 index 0000000..3cfc2ba --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/ssautil/visit.go @@ -0,0 +1,166 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssautil // import "golang.org/x/tools/go/ssa/ssautil" + +import ( + "go/ast" + "go/types" + + "golang.org/x/tools/go/ssa" + + _ "unsafe" // for linkname hack +) + +// This file defines utilities for visiting the SSA representation of +// a Program. +// +// TODO(adonovan): test coverage. + +// AllFunctions finds and returns the set of functions potentially +// needed by program prog, as determined by a simple linker-style +// reachability algorithm starting from the members and method-sets of +// each package. The result may include anonymous functions and +// synthetic wrappers. +// +// Precondition: all packages are built. +// +// TODO(adonovan): this function is underspecified. It doesn't +// actually work like a linker, which computes reachability from main +// using something like go/callgraph/cha (without materializing the +// call graph). In fact, it treats all public functions and all +// methods of public non-parameterized types as roots, even though +// they may be unreachable--but only in packages created from syntax. +// +// I think we should deprecate AllFunctions function in favor of two +// clearly defined ones: +// +// 1. The first would efficiently compute CHA reachability from a set +// of main packages, making it suitable for a whole-program +// analysis context with InstantiateGenerics, in conjunction with +// Program.Build. +// +// 2. The second would return only the set of functions corresponding +// to source Func{Decl,Lit} syntax, like SrcFunctions in +// go/analysis/passes/buildssa; this is suitable for +// package-at-a-time (or handful of packages) context. +// ssa.Package could easily expose it as a field. +// +// We could add them unexported for now and use them via the linkname hack. +func AllFunctions(prog *ssa.Program) map[*ssa.Function]bool { + seen := make(map[*ssa.Function]bool) + + var function func(fn *ssa.Function) + function = func(fn *ssa.Function) { + if !seen[fn] { + seen[fn] = true + var buf [10]*ssa.Value // avoid alloc in common case + for _, b := range fn.Blocks { + for _, instr := range b.Instrs { + for _, op := range instr.Operands(buf[:0]) { + if fn, ok := (*op).(*ssa.Function); ok { + function(fn) + } + } + } + } + } + } + + // TODO(adonovan): opt: provide a way to share a builder + // across a sequence of MethodValue calls. + + methodsOf := func(T types.Type) { + if !types.IsInterface(T) { + mset := prog.MethodSets.MethodSet(T) + for sel := range mset.Methods() { + // Skip generic methods. + if sel.Obj().(*types.Func).Signature().TypeParams() == nil { + function(prog.MethodValue(sel)) + } + } + } + } + + // Historically, Program.RuntimeTypes used to include the type + // of any exported member of a package loaded from syntax that + // has a non-parameterized type, plus all types + // reachable from that type using reflection, even though + // these runtime types may not be required for them. + // + // Rather than break existing programs that rely on + // AllFunctions visiting extra methods that are unreferenced + // by IR and unreachable via reflection, we moved the logic + // here, unprincipled though it is. + // (See doc comment for better ideas.) + // + // Nonetheless, after the move, we no longer visit every + // method of any type recursively reachable from T, only the + // methods of T and *T themselves, and we only apply this to + // named types T, and not to the type of every exported + // package member. + exportedTypeHack := func(t *ssa.Type) { + if isSyntactic(t.Package()) && + ast.IsExported(t.Name()) && + !types.IsInterface(t.Type()) { + // Consider only named types. + // (Ignore aliases and unsafe.Pointer.) + if named, ok := t.Type().(*types.Named); ok { + // Skip generic types. + if named.TypeParams() == nil { + methodsOf(named) // T + methodsOf(types.NewPointer(named)) // *T + } + } + } + } + + for _, pkg := range prog.AllPackages() { + for _, mem := range pkg.Members { + switch mem := mem.(type) { + case *ssa.Function: + // Visit all package-level declared functions. + // + // (This may include generic functions, which is + // inconsistent with the treatment of methods: + // we skip both generic methods, + // and methods of generic types.) + function(mem) + + case *ssa.Type: + exportedTypeHack(mem) + } + } + } + + // Visit all methods of types for which runtime types were + // materialized, as they are reachable through reflection. + for _, T := range prog.RuntimeTypes() { + methodsOf(T) + } + + return seen +} + +// MainPackages returns the subset of the specified packages +// named "main" that define a main function. +// The result may include synthetic "testmain" packages. +func MainPackages(pkgs []*ssa.Package) []*ssa.Package { + var mains []*ssa.Package + for _, pkg := range pkgs { + if pkg.Pkg.Name() == "main" && pkg.Func("main") != nil { + mains = append(mains, pkg) + } + } + return mains +} + +// TODO(adonovan): propose a principled API for this. One possibility +// is a new field, Package.SrcFunctions []*Function, which would +// contain the list of SrcFunctions described in point 2 of the +// AllFunctions doc comment, or nil if the package is not from syntax. +// But perhaps overloading nil vs empty slice is too subtle. +// +//go:linkname isSyntactic golang.org/x/tools/go/ssa.isSyntactic +func isSyntactic(pkg *ssa.Package) bool diff --git a/vendor/golang.org/x/tools/go/ssa/subst.go b/vendor/golang.org/x/tools/go/ssa/subst.go new file mode 100644 index 0000000..f33caca --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/subst.go @@ -0,0 +1,567 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +import ( + "fmt" + "go/types" + + "golang.org/x/tools/go/types/typeutil" +) + +// subster defines a type substitution operation of a set of type parameters +// to type parameter free replacement types. Substitution is done within +// the context of a package-level function instantiation. *Named types +// declared in the function are unique to the instantiation. +// +// For example, given a parameterized function F +// +// func F[S, T any]() any { +// type X struct{ s S; next *X } +// var p *X +// return p +// } +// +// calling the instantiation F[string, int]() returns an interface +// value (*X[string,int], nil) where the underlying value of +// X[string,int] is a struct{s string; next *X[string,int]}. +// +// A nil *subster is a valid, empty substitution map. It always acts as +// the identity function. This allows for treating parameterized and +// non-parameterized functions identically while compiling to ssa. +// +// Not concurrency-safe. +// +// Note: Some may find it helpful to think through some of the most +// complex substitution cases using lambda calculus inspired notation. +// subst.typ() solves evaluating a type expression E +// within the body of a function Fn[m] with the type parameters m +// once we have applied the type arguments N. +// We can succinctly write this as a function application: +// +// ((λm. E) N) +// +// go/types does not provide this interface directly. +// So what subster provides is a type substitution operation +// +// E[m:=N] +type subster struct { + replacements map[*types.TypeParam]types.Type // values should contain no type params + cache map[types.Type]types.Type // cache of subst results + origin *types.Func // types.Objects declared within this origin function are unique within this context + ctxt *types.Context // speeds up repeated instantiations + uniqueness typeutil.Map // determines the uniqueness of the instantiations within the function + // TODO(taking): consider adding Pos +} + +// Returns a subster that replaces rtparams[i] with rtargs[i] and tparams[i] with targs[i]. +// Uses ctxt as a cache. rtargs and targs should not contain any types in rtparams or tparams. +// fn is the generic function for which we are substituting. +func makeSubster(ctxt *types.Context, fn *types.Func, rtparams *types.TypeParamList, rtargs []types.Type, tparams *types.TypeParamList, targs []types.Type) *subster { + got := len(rtargs) + len(targs) + want := rtparams.Len() + tparams.Len() + if got != want { + panic(fmt.Sprintf("makeSubster argument count must match: got %d; want %d", got, want)) + } + + subst := &subster{ + replacements: make(map[*types.TypeParam]types.Type, want), + cache: make(map[types.Type]types.Type), + origin: fn.Origin(), + ctxt: ctxt, + } + for i := 0; i < rtparams.Len(); i++ { + subst.replacements[rtparams.At(i)] = rtargs[i] + } + for i := 0; i < tparams.Len(); i++ { + subst.replacements[tparams.At(i)] = targs[i] + } + return subst +} + +// typ returns the type of t with the type parameter tparams[i] substituted +// for the type targs[i] where subst was created using tparams and targs. +func (subst *subster) typ(t types.Type) (res types.Type) { + if subst == nil { + return t // A nil subst is type preserving. + } + if r, ok := subst.cache[t]; ok { + return r + } + defer func() { + subst.cache[t] = res + }() + + switch t := t.(type) { + case *types.TypeParam: + if r := subst.replacements[t]; r != nil { + return r + } + return t + + case *types.Basic: + return t + + case *types.Array: + if r := subst.typ(t.Elem()); r != t.Elem() { + return types.NewArray(r, t.Len()) + } + return t + + case *types.Slice: + if r := subst.typ(t.Elem()); r != t.Elem() { + return types.NewSlice(r) + } + return t + + case *types.Pointer: + if r := subst.typ(t.Elem()); r != t.Elem() { + return types.NewPointer(r) + } + return t + + case *types.Tuple: + return subst.tuple(t) + + case *types.Struct: + return subst.struct_(t) + + case *types.Map: + key := subst.typ(t.Key()) + elem := subst.typ(t.Elem()) + if key != t.Key() || elem != t.Elem() { + return types.NewMap(key, elem) + } + return t + + case *types.Chan: + if elem := subst.typ(t.Elem()); elem != t.Elem() { + return types.NewChan(t.Dir(), elem) + } + return t + + case *types.Signature: + return subst.signature(t) + + case *types.Union: + return subst.union(t) + + case *types.Interface: + return subst.interface_(t) + + case *types.Alias: + return subst.alias(t) + + case *types.Named: + return subst.named(t) + + default: + panic("unreachable") + } +} + +// types returns the result of {subst.typ(ts[i])}. +func (subst *subster) types(ts []types.Type) []types.Type { + res := make([]types.Type, len(ts)) + for i := range ts { + res[i] = subst.typ(ts[i]) + } + return res +} + +func (subst *subster) tuple(t *types.Tuple) *types.Tuple { + if t != nil { + if vars := subst.varlist(t); vars != nil { + return types.NewTuple(vars...) + } + } + return t +} + +type varlist interface { + At(i int) *types.Var + Len() int +} + +// fieldlist is an adapter for structs for the varlist interface. +type fieldlist struct { + str *types.Struct +} + +func (fl fieldlist) At(i int) *types.Var { return fl.str.Field(i) } +func (fl fieldlist) Len() int { return fl.str.NumFields() } + +func (subst *subster) struct_(t *types.Struct) *types.Struct { + if t != nil { + if fields := subst.varlist(fieldlist{t}); fields != nil { + tags := make([]string, t.NumFields()) + for i, n := 0, t.NumFields(); i < n; i++ { + tags[i] = t.Tag(i) + } + return types.NewStruct(fields, tags) + } + } + return t +} + +// varlist returns subst(in[i]) or return nils if subst(v[i]) == v[i] for all i. +func (subst *subster) varlist(in varlist) []*types.Var { + var out []*types.Var // nil => no updates + for i, n := 0, in.Len(); i < n; i++ { + v := in.At(i) + w := subst.var_(v) + if v != w && out == nil { + out = make([]*types.Var, n) + for j := 0; j < i; j++ { + out[j] = in.At(j) + } + } + if out != nil { + out[i] = w + } + } + return out +} + +func (subst *subster) var_(v *types.Var) *types.Var { + if v != nil { + if typ := subst.typ(v.Type()); typ != v.Type() { + if v.IsField() { + return types.NewField(v.Pos(), v.Pkg(), v.Name(), typ, v.Embedded()) + } + return types.NewParam(v.Pos(), v.Pkg(), v.Name(), typ) + } + } + return v +} + +func (subst *subster) union(u *types.Union) *types.Union { + var out []*types.Term // nil => no updates + + for i, n := 0, u.Len(); i < n; i++ { + t := u.Term(i) + r := subst.typ(t.Type()) + if r != t.Type() && out == nil { + out = make([]*types.Term, n) + for j := 0; j < i; j++ { + out[j] = u.Term(j) + } + } + if out != nil { + out[i] = types.NewTerm(t.Tilde(), r) + } + } + + if out != nil { + return types.NewUnion(out) + } + return u +} + +func (subst *subster) interface_(iface *types.Interface) *types.Interface { + if iface == nil { + return nil + } + + // methods for the interface. Initially nil if there is no known change needed. + // Signatures for the method where recv is nil. NewInterfaceType fills in the receivers. + var methods []*types.Func + initMethods := func(n int) { // copy first n explicit methods + methods = make([]*types.Func, iface.NumExplicitMethods()) + for i := range n { + f := iface.ExplicitMethod(i) + norecv := changeRecv(f.Type().(*types.Signature), nil) + methods[i] = types.NewFunc(f.Pos(), f.Pkg(), f.Name(), norecv) + } + } + for i := 0; i < iface.NumExplicitMethods(); i++ { + f := iface.ExplicitMethod(i) + // On interfaces, we need to cycle break on anonymous interface types + // being in a cycle with their signatures being in cycles with their receivers + // that do not go through a Named. + norecv := changeRecv(f.Type().(*types.Signature), nil) + sig := subst.typ(norecv) + if sig != norecv && methods == nil { + initMethods(i) + } + if methods != nil { + methods[i] = types.NewFunc(f.Pos(), f.Pkg(), f.Name(), sig.(*types.Signature)) + } + } + + var embeds []types.Type + initEmbeds := func(n int) { // copy first n embedded types + embeds = make([]types.Type, iface.NumEmbeddeds()) + for i := range n { + embeds[i] = iface.EmbeddedType(i) + } + } + for i := 0; i < iface.NumEmbeddeds(); i++ { + e := iface.EmbeddedType(i) + r := subst.typ(e) + if e != r && embeds == nil { + initEmbeds(i) + } + if embeds != nil { + embeds[i] = r + } + } + + if methods == nil && embeds == nil { + return iface + } + if methods == nil { + initMethods(iface.NumExplicitMethods()) + } + if embeds == nil { + initEmbeds(iface.NumEmbeddeds()) + } + return types.NewInterfaceType(methods, embeds).Complete() +} + +func (subst *subster) alias(t *types.Alias) types.Type { + // See subster.named. This follows the same strategy. + tparams := t.TypeParams() + targs := t.TypeArgs() + tname := t.Obj() + torigin := t.Origin() + + if !declaredWithin(tname, subst.origin) { + // t is declared outside of the function origin. So t is a package level type alias. + if targs.Len() == 0 { + // No type arguments so no instantiation needed. + return t + } + + // Instantiate with the substituted type arguments. + newTArgs := subst.typelist(targs) + return subst.instantiate(torigin, newTArgs) + } + + if targs.Len() == 0 { + // t is declared within the function origin and has no type arguments. + // + // Example: This corresponds to A or B in F, but not A[int]: + // + // func F[T any]() { + // type A[S any] = struct{t T, s S} + // type B = T + // var x A[int] + // ... + // } + // + // This is somewhat different than *Named as *Alias cannot be created recursively. + + // Copy and substitute type params. + var newTParams []*types.TypeParam + for cur := range tparams.TypeParams() { + cobj := cur.Obj() + cname := types.NewTypeName(cobj.Pos(), cobj.Pkg(), cobj.Name(), nil) + ntp := types.NewTypeParam(cname, nil) + subst.cache[cur] = ntp // See the comment "Note: Subtle" in subster.named. + newTParams = append(newTParams, ntp) + } + + // Substitute rhs. + rhs := subst.typ(t.Rhs()) + + // Create the fresh alias. + tname := types.NewTypeName(tname.Pos(), tname.Pkg(), tname.Name(), nil) + types.NewAlias(tname, rhs).SetTypeParams(newTParams) + + // Substitute into all of the constraints after they are created. + for i, ntp := range newTParams { + bound := tparams.At(i).Constraint() + ntp.SetConstraint(subst.typ(bound)) + } + return tname.Type() + } + + // t is declared within the function origin and has type arguments. + // + // Example: This corresponds to A[int] in F. Cases A and B are handled above. + // func F[T any]() { + // type A[S any] = struct{t T, s S} + // type B = T + // var x A[int] + // ... + // } + subOrigin := subst.typ(torigin) + subTArgs := subst.typelist(targs) + return subst.instantiate(subOrigin, subTArgs) +} + +func (subst *subster) named(t *types.Named) types.Type { + // A Named type is a user defined type. + // Ignoring generics, Named types are canonical: they are identical if + // and only if they have the same defining symbol. + // Generics complicate things, both if the type definition itself is + // parameterized, and if the type is defined within the scope of a + // parameterized function. In this case, two named types are identical if + // and only if their identifying symbols are identical, and all type + // arguments bindings in scope of the named type definition (including the + // type parameters of the definition itself) are equivalent. + // + // Notably: + // 1. For type definition type T[P1 any] struct{}, T[A] and T[B] are identical + // only if A and B are identical. + // 2. Inside the generic func Fn[m any]() any { type T struct{}; return T{} }, + // the result of Fn[A] and Fn[B] have identical type if and only if A and + // B are identical. + // 3. Both 1 and 2 could apply, such as in + // func F[m any]() any { type T[x any] struct{}; return T{} } + // + // A subster replaces type parameters within a function scope, and therefore must + // also replace free type parameters in the definitions of local types. + // + // Note: There are some detailed notes sprinkled throughout that borrow from + // lambda calculus notation. These contain some over simplifying math. + // + // LC: One way to think about subster is that it is a way of evaluating + // ((λm. E) N) as E[m:=N]. + // Each Named type t has an object *TypeName within a scope S that binds an + // underlying type expression U. U can refer to symbols within S (+ S's ancestors). + // Let x = t.TypeParams() and A = t.TypeArgs(). + // Each Named type t is then either: + // U where len(x) == 0 && len(A) == 0 + // λx. U where len(x) != 0 && len(A) == 0 + // ((λx. U) A) where len(x) == len(A) + // In each case, we will evaluate t[m:=N]. + tparams := t.TypeParams() // x + targs := t.TypeArgs() // A + + if !declaredWithin(t.Obj(), subst.origin) { + // t is declared outside of Fn[m]. + // + // In this case, we can skip substituting t.Underlying(). + // The underlying type cannot refer to the type parameters. + // + // LC: Let free(E) be the set of free type parameters in an expression E. + // Then whenever m ∉ free(E), then E = E[m:=N]. + // t ∉ Scope(fn) so therefore m ∉ free(U) and m ∩ x = ∅. + if targs.Len() == 0 { + // t has no type arguments. So it does not need to be instantiated. + // + // This is the normal case in real Go code, where t is not parameterized, + // declared at some package scope, and m is a TypeParam from a parameterized + // function F[m] or method. + // + // LC: m ∉ free(A) lets us conclude m ∉ free(t). So t=t[m:=N]. + return t + } + + // t is declared outside of Fn[m] and has type arguments. + // The type arguments may contain type parameters m so + // substitute the type arguments, and instantiate the substituted + // type arguments. + // + // LC: Evaluate this as ((λx. U) A') where A' = A[m := N]. + newTArgs := subst.typelist(targs) + return subst.instantiate(t.Origin(), newTArgs) + } + + // t is declared within Fn[m]. + + if targs.Len() == 0 { // no type arguments? + assert(t == t.Origin(), "local parameterized type abstraction must be an origin type") + + // t has no type arguments. + // The underlying type of t may contain the function's type parameters, + // replace these, and create a new type. + // + // Subtle: We short circuit substitution and use a newly created type in + // subst, i.e. cache[t]=fresh, to preemptively replace t with fresh + // in recursive types during traversal. This both breaks infinite cycles + // and allows for constructing types with the replacement applied in + // subst.typ(U). + // + // A new copy of the Named and Typename (and constraints) per function + // instantiation matches the semantics of Go, which treats all function + // instantiations F[N] as having distinct local types. + // + // LC: x.Len()=0 can be thought of as a special case of λx. U. + // LC: Evaluate (λx. U)[m:=N] as (λx'. U') where U'=U[x:=x',m:=N]. + tname := t.Obj() + obj := types.NewTypeName(tname.Pos(), tname.Pkg(), tname.Name(), nil) + fresh := types.NewNamed(obj, nil, nil) + var newTParams []*types.TypeParam + for cur := range tparams.TypeParams() { + cobj := cur.Obj() + cname := types.NewTypeName(cobj.Pos(), cobj.Pkg(), cobj.Name(), nil) + ntp := types.NewTypeParam(cname, nil) + subst.cache[cur] = ntp + newTParams = append(newTParams, ntp) + } + fresh.SetTypeParams(newTParams) + subst.cache[t] = fresh + subst.cache[fresh] = fresh + fresh.SetUnderlying(subst.typ(t.Underlying())) + // Substitute into all of the constraints after they are created. + for i, ntp := range newTParams { + bound := tparams.At(i).Constraint() + ntp.SetConstraint(subst.typ(bound)) + } + return fresh + } + + // t is defined within Fn[m] and t has type arguments (an instantiation). + // We reduce this to the two cases above: + // (1) substitute the function's type parameters into t.Origin(). + // (2) substitute t's type arguments A and instantiate the updated t.Origin() with these. + // + // LC: Evaluate ((λx. U) A)[m:=N] as (t' A') where t' = (λx. U)[m:=N] and A'=A [m:=N] + subOrigin := subst.typ(t.Origin()) + subTArgs := subst.typelist(targs) + return subst.instantiate(subOrigin, subTArgs) +} + +func (subst *subster) instantiate(orig types.Type, targs []types.Type) types.Type { + i, err := types.Instantiate(subst.ctxt, orig, targs, false) + assert(err == nil, "failed to Instantiate named (Named or Alias) type") + if c, _ := subst.uniqueness.At(i).(types.Type); c != nil { + return c.(types.Type) + } + subst.uniqueness.Set(i, i) + return i +} + +func (subst *subster) typelist(l *types.TypeList) []types.Type { + res := make([]types.Type, l.Len()) + for i := 0; i < l.Len(); i++ { + res[i] = subst.typ(l.At(i)) + } + return res +} + +func (subst *subster) signature(t *types.Signature) types.Type { + tparams := t.TypeParams() + + // We are choosing not to support tparams.Len() > 0 until a need has been observed in practice. + // + // There are some known usages for types.Types coming from types.{Eval,CheckExpr}. + // To support tparams.Len() > 0, we just need to do the following [pseudocode]: + // targs := {subst.replacements[tparams[i]]]}; Instantiate(ctxt, t, targs, false) + + assert(tparams.Len() == 0, "Substituting types.Signatures with generic functions are currently unsupported.") + + // Either: + // (1)non-generic function. + // no type params to substitute + // (2)generic method and recv needs to be substituted. + + // Receivers can be either: + // named + // pointer to named + // interface + // nil + // interface is the problematic case. We need to cycle break there! + recv := subst.var_(t.Recv()) + params := subst.tuple(t.Params()) + results := subst.tuple(t.Results()) + if recv != t.Recv() || params != t.Params() || results != t.Results() { + return types.NewSignatureType(recv, nil, nil, params, results, t.Variadic()) + } + return t +} diff --git a/vendor/golang.org/x/tools/go/ssa/task.go b/vendor/golang.org/x/tools/go/ssa/task.go new file mode 100644 index 0000000..e090070 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/task.go @@ -0,0 +1,103 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +import ( + "sync/atomic" +) + +// Each task has two states: it is initially "active", +// and transitions to "done". +// +// tasks form a directed graph. An edge from x to y (with y in x.edges) +// indicates that the task x waits on the task y to be done. +// Cycles are permitted. +// +// Calling x.wait() blocks the calling goroutine until task x, +// and all the tasks transitively reachable from x are done. +// +// The nil *task is always considered done. +type task struct { + done chan unit // close when the task is done. + edges map[*task]unit // set of predecessors of this task. + transitive atomic.Bool // true once it is known all predecessors are done. +} + +func (x *task) isTransitivelyDone() bool { return x == nil || x.transitive.Load() } + +// addEdge creates an edge from x to y, indicating that +// x.wait() will not return before y is done. +// All calls to x.addEdge(...) should happen before x.markDone(). +func (x *task) addEdge(y *task) { + if x == y || y.isTransitivelyDone() { + return // no work remaining + } + + // heuristic done check + select { + case <-x.done: + panic("cannot add an edge to a done task") + default: + } + + if x.edges == nil { + x.edges = make(map[*task]unit) + } + x.edges[y] = unit{} +} + +// markDone changes the task's state to markDone. +func (x *task) markDone() { + if x != nil { + close(x.done) + } +} + +// wait blocks until x and all the tasks it can reach through edges are done. +func (x *task) wait() { + if x.isTransitivelyDone() { + return // already known to be done. Skip allocations. + } + + // Use BFS to wait on u.done to be closed, for all u transitively + // reachable from x via edges. + // + // This work can be repeated by multiple workers doing wait(). + // + // Note: Tarjan's SCC algorithm is able to mark SCCs as transitively done + // as soon as the SCC has been visited. This is theoretically faster, but is + // a more complex algorithm. Until we have evidence, we need the more complex + // algorithm, the simpler algorithm BFS is implemented. + // + // In Go 1.23, ssa/TestStdlib reaches <=3 *tasks per wait() in most schedules + // On some schedules, there is a cycle building net/http and internal/trace/testtrace + // due to slices functions. + work := []*task{x} + enqueued := map[*task]unit{x: {}} + for i := 0; i < len(work); i++ { + u := work[i] + if u.isTransitivelyDone() { // already transitively done + work[i] = nil + continue + } + <-u.done // wait for u to be marked done. + + for v := range u.edges { + if _, ok := enqueued[v]; !ok { + enqueued[v] = unit{} + work = append(work, v) + } + } + } + + // work is transitively closed over dependencies. + // u in work is done (or transitively done and skipped). + // u is transitively done. + for _, u := range work { + if u != nil { + u.transitive.Store(true) + } + } +} diff --git a/vendor/golang.org/x/tools/go/ssa/typeset.go b/vendor/golang.org/x/tools/go/ssa/typeset.go new file mode 100644 index 0000000..d0106dc --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/typeset.go @@ -0,0 +1,179 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +import ( + "go/types" + + "golang.org/x/tools/internal/typeparams" +) + +// Utilities for dealing with type sets. + +const debug = false + +// typeset is an iterator over the (type/underlying type) pairs of the +// specific type terms of the type set implied by t. +// If t is a type parameter, the implied type set is the type set of t's constraint. +// In that case, if there are no specific terms, typeset calls yield with (nil, nil). +// If t is not a type parameter, the implied type set consists of just t. +// In any case, typeset is guaranteed to call yield at least once. +func typeset(typ types.Type, yield func(t, u types.Type) bool) { + switch typ := types.Unalias(typ).(type) { + case *types.TypeParam, *types.Interface: + terms := termListOf(typ) + if len(terms) == 0 { + yield(nil, nil) + return + } + for _, term := range terms { + u := types.Unalias(term.Type()) + if !term.Tilde() { + u = u.Underlying() + } + if debug { + assert(types.Identical(u, u.Underlying()), "Unalias(x) == under(x) for ~x terms") + } + if !yield(term.Type(), u) { + break + } + } + return + default: + yield(typ, typ.Underlying()) + } +} + +// termListOf returns the type set of typ as a normalized term set. Returns an empty set on an error. +func termListOf(typ types.Type) []*types.Term { + terms, err := typeparams.NormalTerms(typ) + if err != nil { + return nil + } + return terms +} + +// typeSetIsEmpty returns true if a typeset is empty. +func typeSetIsEmpty(typ types.Type) bool { + var empty bool + typeset(typ, func(t, _ types.Type) bool { + empty = t == nil + return false + }) + return empty +} + +// isBytestring returns true if T has the same terms as interface{[]byte | string}. +// These act like a core type for some operations: slice expressions, append and copy. +// +// See https://go.dev/ref/spec#Core_types for the details on bytestring. +func isBytestring(T types.Type) bool { + U := T.Underlying() + if _, ok := U.(*types.Interface); !ok { + return false + } + + hasBytes, hasString := false, false + ok := underIs(U, func(t types.Type) bool { + switch { + case isString(t): + hasString = true + return true + case isByteSlice(t): + hasBytes = true + return true + default: + return false + } + }) + return ok && hasBytes && hasString +} + +// underIs calls f with the underlying types of the type terms +// of the type set of typ and reports whether all calls to f returned true. +// If there are no specific terms, underIs returns the result of f(nil). +func underIs(typ types.Type, f func(types.Type) bool) bool { + var ok bool + typeset(typ, func(t, u types.Type) bool { + ok = f(u) + return ok + }) + return ok +} + +// indexType returns the element type and index mode of a IndexExpr over a type. +// It returns an invalid mode if the type is not indexable; this should never occur in a well-typed program. +func indexType(typ types.Type) (types.Type, indexMode) { + switch U := typ.Underlying().(type) { + case *types.Array: + return U.Elem(), ixArrVar + case *types.Pointer: + if arr, ok := U.Elem().Underlying().(*types.Array); ok { + return arr.Elem(), ixVar + } + case *types.Slice: + return U.Elem(), ixVar + case *types.Map: + return U.Elem(), ixMap + case *types.Basic: + return tByte, ixValue // must be a string + case *types.Interface: + var elem types.Type + mode := ixInvalid + typeset(typ, func(t, _ types.Type) bool { + if t == nil { + return false // empty set + } + e, m := indexType(t) + if elem == nil { + elem, mode = e, m + } + if debug && !types.Identical(elem, e) { // if type checked, just a sanity check + mode = ixInvalid + return false + } + // Update the mode to the most constrained address type. + mode = mode.meet(m) + return mode != ixInvalid + }) + return elem, mode + } + return nil, ixInvalid +} + +// An indexMode specifies the (addressing) mode of an index operand. +// +// Addressing mode of an index operation is based on the set of +// underlying types. +// Hasse diagram of the indexMode meet semi-lattice: +// +// ixVar ixMap +// | | +// ixArrVar | +// | | +// ixValue | +// \ / +// ixInvalid +type indexMode byte + +const ( + ixInvalid indexMode = iota // index is invalid + ixValue // index is a computed value (not addressable) + ixArrVar // like ixVar, but index operand contains an array + ixVar // index is an addressable variable + ixMap // index is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment) +) + +// meet is the address type that is constrained by both x and y. +func (x indexMode) meet(y indexMode) indexMode { + if (x == ixMap || y == ixMap) && x != y { + return ixInvalid + } + // Use int representation and return min. + if x < y { + return y + } + return x +} diff --git a/vendor/golang.org/x/tools/go/ssa/util.go b/vendor/golang.org/x/tools/go/ssa/util.go new file mode 100644 index 0000000..399aaa3 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/util.go @@ -0,0 +1,413 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file defines a number of miscellaneous utility functions. + +import ( + "fmt" + "go/ast" + "go/token" + "go/types" + "io" + "os" + "sync" + _ "unsafe" // for go:linkname hack + + "golang.org/x/tools/go/types/typeutil" + "golang.org/x/tools/internal/typeparams" + "golang.org/x/tools/internal/typesinternal" +) + +type unit struct{} + +//// Sanity checking utilities + +// assert panics with the message msg if p is false. +// Avoid combining with expensive string formatting. +func assert(p bool, msg string) { + if !p { + panic(msg) + } +} + +//// AST utilities + +// isBlankIdent returns true iff e is an Ident with name "_". +// They have no associated types.Object, and thus no type. +func isBlankIdent(e ast.Expr) bool { + id, ok := e.(*ast.Ident) + return ok && id.Name == "_" +} + +//// Type utilities. Some of these belong in go/types. + +// isNonTypeParamInterface reports whether t is an interface type but not a type parameter. +func isNonTypeParamInterface(t types.Type) bool { + return !typeparams.IsTypeParam(t) && types.IsInterface(t) +} + +// isBasic reports whether t is a basic type. +// t is assumed to be an Underlying type (not Named or Alias). +func isBasic(t types.Type) bool { + _, ok := t.(*types.Basic) + return ok +} + +// isString reports whether t is exactly a string type. +// t is assumed to be an Underlying type (not Named or Alias). +func isString(t types.Type) bool { + basic, ok := t.(*types.Basic) + return ok && basic.Info()&types.IsString != 0 +} + +// isByteSlice reports whether t is of the form []~bytes. +// t is assumed to be an Underlying type (not Named or Alias). +func isByteSlice(t types.Type) bool { + if b, ok := t.(*types.Slice); ok { + e, _ := b.Elem().Underlying().(*types.Basic) + return e != nil && e.Kind() == types.Byte + } + return false +} + +// isRuneSlice reports whether t is of the form []~runes. +// t is assumed to be an Underlying type (not Named or Alias). +func isRuneSlice(t types.Type) bool { + if b, ok := t.(*types.Slice); ok { + e, _ := b.Elem().Underlying().(*types.Basic) + return e != nil && e.Kind() == types.Rune + } + return false +} + +// isBasicConvTypes returns true when the type set of a type +// can be one side of a Convert operation. This is when: +// - All are basic, []byte, or []rune. +// - At least 1 is basic. +// - At most 1 is []byte or []rune. +func isBasicConvTypes(typ types.Type) bool { + basics, cnt := 0, 0 + ok := underIs(typ, func(t types.Type) bool { + cnt++ + if isBasic(t) { + basics++ + return true + } + return isByteSlice(t) || isRuneSlice(t) + }) + return ok && basics >= 1 && cnt-basics <= 1 +} + +// isPointer reports whether t's underlying type is a pointer. +func isPointer(t types.Type) bool { + return is[*types.Pointer](t.Underlying()) +} + +// isPointerCore reports whether t's core type is a pointer. +// +// (Most pointer manipulation is related to receivers, in which case +// isPointer is appropriate. tecallers can use isPointer(t). +func isPointerCore(t types.Type) bool { + return is[*types.Pointer](typeparams.CoreType(t)) +} + +func is[T any](x any) bool { + _, ok := x.(T) + return ok +} + +// recvType returns the receiver type of method obj. +func recvType(obj *types.Func) types.Type { + return obj.Signature().Recv().Type() +} + +// fieldOf returns the index'th field of the (core type of) a struct type; +// otherwise returns nil. +func fieldOf(typ types.Type, index int) *types.Var { + if st, ok := typeparams.CoreType(typ).(*types.Struct); ok { + if 0 <= index && index < st.NumFields() { + return st.Field(index) + } + } + return nil +} + +// isUntyped reports whether typ is the type of an untyped constant. +func isUntyped(typ types.Type) bool { + // No Underlying/Unalias: untyped constant types cannot be Named or Alias. + b, ok := typ.(*types.Basic) + return ok && b.Info()&types.IsUntyped != 0 +} + +// declaredWithin reports whether an object is declared within a function. +// +// obj must not be a method or a field. +func declaredWithin(obj types.Object, fn *types.Func) bool { + if obj.Pos() != token.NoPos { + return fn.Scope().Contains(obj.Pos()) // trust the positions if they exist. + } + if fn.Pkg() != obj.Pkg() { + return false // fast path for different packages + } + + // Traverse Parent() scopes for fn.Scope(). + for p := obj.Parent(); p != nil; p = p.Parent() { + if p == fn.Scope() { + return true + } + } + return false +} + +// logStack prints the formatted "start" message to stderr and +// returns a closure that prints the corresponding "end" message. +// Call using 'defer logStack(...)()' to show builder stack on panic. +// Don't forget trailing parens! +func logStack(format string, args ...any) func() { + msg := fmt.Sprintf(format, args...) + io.WriteString(os.Stderr, msg) + io.WriteString(os.Stderr, "\n") + return func() { + io.WriteString(os.Stderr, msg) + io.WriteString(os.Stderr, " end\n") + } +} + +// newVar creates a 'var' for use in a types.Tuple. +func newVar(name string, typ types.Type) *types.Var { + return types.NewParam(token.NoPos, nil, name, typ) +} + +var lenResults = typesinternal.TupleOf(tInt) + +// makeLen returns the len builtin specialized to type func(T)int. +func makeLen(T types.Type) *Builtin { + return &Builtin{ + name: "len", + sig: types.NewSignatureType(nil, nil, nil, typesinternal.TupleOf(T), lenResults, false), + } +} + +// receiverTypeArgs returns the type arguments to a method's receiver. +// Returns an empty list if the receiver does not have type arguments. +func receiverTypeArgs(method *types.Func) []types.Type { + _, named := typesinternal.RecvBase(method) + if named == nil { + return nil // recv is anonymous struct/interface + } + ts := named.TypeArgs() + if ts.Len() == 0 { + return nil + } + targs := make([]types.Type, ts.Len()) + for i := 0; i < ts.Len(); i++ { + targs[i] = ts.At(i) + } + return targs +} + +// recvAsFirstArg takes a method signature and returns a function +// signature with receiver as the first parameter. +func recvAsFirstArg(sig *types.Signature) *types.Signature { + params := make([]*types.Var, 0, 1+sig.Params().Len()) + params = append(params, sig.Recv()) + for v := range sig.Params().Variables() { + params = append(params, v) + } + return types.NewSignatureType(nil, nil, nil, types.NewTuple(params...), sig.Results(), sig.Variadic()) +} + +// instance returns whether an expression is a simple or qualified identifier +// that is a generic instantiation. +func instance(info *types.Info, expr ast.Expr) bool { + // Compare the logic here against go/types.instantiatedIdent, + // which also handles *IndexExpr and *IndexListExpr. + var id *ast.Ident + switch x := expr.(type) { + case *ast.Ident: + id = x + case *ast.SelectorExpr: + id = x.Sel + default: + return false + } + _, ok := info.Instances[id] + return ok +} + +// instanceArgs returns the Instance[id].TypeArgs as a slice. +func instanceArgs(info *types.Info, id *ast.Ident) []types.Type { + targList := info.Instances[id].TypeArgs + if targList == nil { + return nil + } + + targs := make([]types.Type, targList.Len()) + for i, n := 0, targList.Len(); i < n; i++ { + targs[i] = targList.At(i) + } + return targs +} + +// Mapping of a type T to a canonical instance C s.t. types.Identical(T, C). +// Thread-safe. +type canonizer struct { + mu sync.Mutex + types typeutil.Map // map from type to a canonical instance + lists typeListMap // map from a list of types to a canonical instance +} + +func newCanonizer() *canonizer { + c := &canonizer{} + h := typeutil.MakeHasher() + c.types.SetHasher(h) + c.lists.hasher = h + return c +} + +// List returns a canonical representative of a list of types. +// Representative of the empty list is nil. +func (c *canonizer) List(ts []types.Type) *typeList { + if len(ts) == 0 { + return nil + } + + unaliasAll := func(ts []types.Type) []types.Type { + // Is there some top level alias? + var found bool + for _, t := range ts { + if _, ok := t.(*types.Alias); ok { + found = true + break + } + } + if !found { + return ts // no top level alias + } + + cp := make([]types.Type, len(ts)) // copy with top level aliases removed. + for i, t := range ts { + cp[i] = types.Unalias(t) + } + return cp + } + l := unaliasAll(ts) + + c.mu.Lock() + defer c.mu.Unlock() + return c.lists.rep(l) +} + +// Type returns a canonical representative of type T. +// Removes top-level aliases. +// +// For performance, reasons the canonical instance is order-dependent, +// and may contain deeply nested aliases. +func (c *canonizer) Type(T types.Type) types.Type { + T = types.Unalias(T) // remove the top level alias. + + // A Signature's receiver is not part of its type identity, so a method + // signature must not stand in for an identical function signature, nor + // for a method signature with a different receiver (go.dev/issue/81602). + if sig, ok := T.(*types.Signature); ok && sig.Recv() != nil { + return T + } + + c.mu.Lock() + defer c.mu.Unlock() + + if r := c.types.At(T); r != nil { + return r.(types.Type) + } + c.types.Set(T, T) + return T +} + +// A type for representing a canonized list of types. +type typeList []types.Type + +func (l *typeList) identical(ts []types.Type) bool { + if l == nil { + return len(ts) == 0 + } + n := len(*l) + if len(ts) != n { + return false + } + for i, left := range *l { + right := ts[i] + if !types.Identical(left, right) { + return false + } + } + return true +} + +type typeListMap struct { + hasher typeutil.Hasher + buckets map[uint32][]*typeList +} + +// rep returns a canonical representative of a slice of types. +func (m *typeListMap) rep(ts []types.Type) *typeList { + if m == nil || len(ts) == 0 { + return nil + } + + if m.buckets == nil { + m.buckets = make(map[uint32][]*typeList) + } + + h := m.hash(ts) + bucket := m.buckets[h] + for _, l := range bucket { + if l.identical(ts) { + return l + } + } + + // not present. create a representative. + cp := make(typeList, len(ts)) + copy(cp, ts) + rep := &cp + + m.buckets[h] = append(bucket, rep) + return rep +} + +func (m *typeListMap) hash(ts []types.Type) uint32 { + if m == nil { + return 0 + } + // Some smallish prime far away from typeutil.Hash. + n := len(ts) + h := uint32(13619) + 2*uint32(n) + for i := range n { + h += 3 * m.hasher.Hash(ts[i]) + } + return h +} + +// instantiateMethod instantiates m with targs and returns a canonical representative for this method. +func (canon *canonizer) instantiateMethod(m *types.Func, targs []types.Type, ctxt *types.Context) *types.Func { + recv := recvType(m) + if p, ok := types.Unalias(recv).(*types.Pointer); ok { + recv = p.Elem() + } + named := types.Unalias(recv).(*types.Named) + inst, err := types.Instantiate(ctxt, named.Origin(), targs, false) + if err != nil { + panic(err) + } + rep := canon.Type(inst) + obj, _, _ := types.LookupFieldOrMethod(rep, true, m.Pkg(), m.Name()) + return obj.(*types.Func) +} + +// Exposed to ssautil using the linkname hack. +// +//go:linkname isSyntactic golang.org/x/tools/go/ssa.isSyntactic +func isSyntactic(pkg *Package) bool { return pkg.syntax } diff --git a/vendor/golang.org/x/tools/go/ssa/wrappers.go b/vendor/golang.org/x/tools/go/ssa/wrappers.go new file mode 100644 index 0000000..fbb0674 --- /dev/null +++ b/vendor/golang.org/x/tools/go/ssa/wrappers.go @@ -0,0 +1,367 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// This file defines synthesis of Functions that delegate to declared +// methods; they come in three kinds: +// +// (1) wrappers: methods that wrap declared methods, performing +// implicit pointer indirections and embedded field selections. +// +// (2) thunks: funcs that wrap declared methods. Like wrappers, +// thunks perform indirections and field selections. The thunk's +// first parameter is used as the receiver for the method call. +// +// (3) bounds: funcs that wrap declared methods. The bound's sole +// free variable, supplied by a closure, is used as the receiver +// for the method call. No indirections or field selections are +// performed since they can be done before the call. + +import ( + "fmt" + + "go/token" + "go/types" + + "golang.org/x/tools/internal/typeparams" + "golang.org/x/tools/internal/typesinternal" +) + +// -- wrappers ----------------------------------------------------------- + +// createWrapper returns a synthetic method that delegates to the +// declared method denoted by meth.Obj(), first performing any +// necessary pointer indirections or field selections implied by meth. +// +// The resulting method's receiver type is meth.Recv(). +// +// This function is versatile but quite subtle! Consider the +// following axes of variation when making changes: +// - optional receiver indirection +// - optional implicit field selections +// - optional method type arguments +// - meth.Obj() may denote a concrete or an interface method +// - the result may be a thunk or a wrapper. +func createWrapper(prog *Program, sel *selection, targs []types.Type) *Function { + obj := sel.obj.(*types.Func) // the declared function + name, sig := maybeInstance(prog, obj.Name(), sel.typ.(*types.Signature), targs) + + var recv *types.Var // wrapper's receiver or thunk's params[0] + var description string + if sel.kind == types.MethodExpr { + name += "$thunk" + description = "thunk" + recv = sig.Params().At(0) + } else { + description = "wrapper" + recv = sig.Recv() + } + + description = fmt.Sprintf("%s for %s", description, obj) + if prog.mode&LogSource != 0 { + defer logStack("create %s to (%s)", description, recv.Type())() + } + /* method wrapper */ + return &Function{ + name: name, + method: sel, + object: obj, + Signature: sig, + Synthetic: description, + Prog: prog, + pos: obj.Pos(), + typeargs: targs, + // wrappers have no syntax + build: (*builder).buildWrapper, + syntax: nil, + info: nil, + goversion: "", + } +} + +// maybeInstance returns name and sig instantiated to reflect any type arguments in targs. +func maybeInstance(prog *Program, name string, sig *types.Signature, targs []types.Type) (string, *types.Signature) { + if len(targs) > 0 { + name = fmt.Sprintf("%s%s", name, targstr(targs)) + instSig, err := types.Instantiate(prog.ctxt, sig, targs, false) + if err != nil { + // validate was false, we should never get an error + panic(err) + } + sig = prog.canon.Type(instSig).(*types.Signature) + } + return name, sig +} + +// buildWrapper builds fn.Body for a method wrapper. +func (b *builder) buildWrapper(fn *Function) { + var recv *types.Var // wrapper's receiver or thunk's params[0] + var start int // first regular param + if fn.method.kind == types.MethodExpr { + recv = fn.Signature.Params().At(0) + start = 1 + } else { + recv = fn.Signature.Recv() + } + + fn.startBody() + fn.addSpilledParam(recv) + createParams(fn, start) + + indices := fn.method.index + + var v Value = fn.Locals[0] // spilled receiver + if isPointer(fn.method.recv) { + v = emitLoad(fn, v) + + // For simple indirection wrappers, perform an informative nil-check: + // "value method (T).f called using nil *T pointer" + if len(indices) == 1 && !isPointer(recvType(fn.object)) { + params := typesinternal.TupleOf(fn.method.recv, tString, tString) + results := typesinternal.TupleOf(fn.method.recv) + var c Call + c.Call.Value = &Builtin{ + name: "ssa:wrapnilchk", + sig: types.NewSignatureType(nil, nil, nil, params, results, false), + } + c.Call.Args = []Value{ + v, + stringConst(typeparams.MustDeref(fn.method.recv).String()), + stringConst(fn.method.obj.Name()), + } + c.setType(v.Type()) + v = fn.emit(&c) + } + } + + // Invariant: v is a pointer, either + // value of *A receiver param, or + // address of A spilled receiver. + + // We use pointer arithmetic (FieldAddr possibly followed by + // Load) in preference to value extraction (Field possibly + // preceded by Load). + + v = emitImplicitSelections(fn, v, indices[:len(indices)-1], token.NoPos) + + // Invariant: v is a pointer, either + // value of implicit *C field, or + // address of implicit C field. + + var c Call + if r := recvType(fn.object); !types.IsInterface(r) { // concrete method + if !isPointer(r) { + v = emitLoad(fn, v) + } + c.Call.Value = fn.Prog.objectMethod(fn.object, fn.typeargs, b) + c.Call.Args = append(c.Call.Args, v) + } else { + c.Call.Method = fn.object + c.Call.Value = emitLoad(fn, v) // interface (possibly a typeparam) + } + for _, arg := range fn.Params[1:] { + c.Call.Args = append(c.Call.Args, arg) + } + emitTailCall(fn, &c) + fn.finishBody() +} + +// createParams creates parameters for wrapper method fn based on its +// Signature.Params, which do not include the receiver. +// start is the index of the first regular parameter to use. +func createParams(fn *Function, start int) { + tparams := fn.Signature.Params() + for i, n := start, tparams.Len(); i < n; i++ { + fn.addParamVar(tparams.At(i)) + } +} + +// -- bounds ----------------------------------------------------------- + +// createBound returns a bound method wrapper (or "bound"), a synthetic +// function that delegates to a concrete or interface method denoted +// by obj. The resulting function has no receiver, but has one free +// variable which will be used as the method's receiver in the +// tail-call. +// +// Use MakeClosure with such a wrapper to construct a bound method +// closure. e.g.: +// +// type T int or: type T interface { meth() } +// func (t T) meth() +// var t T +// f := t.meth +// f() // calls t.meth() +// +// f is a closure of a synthetic wrapper defined as if by: +// +// f := func() { return t.meth() } +// +// Unlike createWrapper, createBound need perform no indirection or field +// selections because that can be done before the closure is +// constructed. +func createBound(prog *Program, obj *types.Func, targs []types.Type) *Function { + description := fmt.Sprintf("bound method wrapper for %s", obj) + if prog.mode&LogSource != 0 { + defer logStack("%s", description)() + } + name, sig := maybeInstance(prog, obj.Name(), obj.Type().(*types.Signature), targs) + + /* bound method wrapper */ + fn := &Function{ + name: name + "$bound", + object: obj, + Signature: changeRecv(sig, nil), // drop receiver + Synthetic: description, + Prog: prog, + pos: obj.Pos(), + typeargs: targs, + // wrappers have no syntax + build: (*builder).buildBound, + syntax: nil, + info: nil, + goversion: "", + } + fn.FreeVars = []*FreeVar{{name: "recv", typ: recvType(obj), parent: fn}} // (cyclic) + return fn +} + +// buildBound builds fn.Body for a bound method closure. +func (b *builder) buildBound(fn *Function) { + fn.startBody() + createParams(fn, 0) + var c Call + + recv := fn.FreeVars[0] + if !types.IsInterface(recvType(fn.object)) { // concrete + c.Call.Value = fn.Prog.objectMethod(fn.object, fn.typeargs, b) + c.Call.Args = []Value{recv} + } else { + c.Call.Method = fn.object + c.Call.Value = recv // interface (possibly a typeparam) + } + for _, arg := range fn.Params { + c.Call.Args = append(c.Call.Args, arg) + } + emitTailCall(fn, &c) + fn.finishBody() +} + +// -- thunks ----------------------------------------------------------- + +// createThunk returns a thunk, a synthetic function that delegates to a +// concrete or interface method denoted by sel.obj. The resulting +// function has no receiver, but has an additional (first) regular +// parameter. +// +// Precondition: sel.kind == types.MethodExpr. +// +// type T int or: type T interface { meth() } +// func (t T) meth() +// f := T.meth +// var t T +// f(t) // calls t.meth() +// +// f is a synthetic wrapper defined as if by: +// +// f := func(t T) { return t.meth() } +func createThunk(prog *Program, sel *selection, targs []types.Type) *Function { + if sel.kind != types.MethodExpr { + panic(sel) + } + + fn := createWrapper(prog, sel, targs) + if fn.Signature.Recv() != nil { + panic(fn) // unexpected receiver + } + + return fn +} + +func changeRecv(s *types.Signature, recv *types.Var) *types.Signature { + return types.NewSignatureType(recv, nil, nil, s.Params(), s.Results(), s.Variadic()) +} + +// A local version of *types.Selection. +// Needed for some additional control, such as creating a MethodExpr for an instantiation. +type selection struct { + kind types.SelectionKind + recv types.Type + typ types.Type + obj types.Object + index []int + indirect bool +} + +func toSelection(sel *types.Selection) *selection { + return &selection{ + kind: sel.Kind(), + recv: sel.Recv(), + typ: sel.Type(), + obj: sel.Obj(), + index: sel.Index(), + indirect: sel.Indirect(), + } +} + +// -- instantiations -------------------------------------------------- + +// buildInstantiationWrapper builds the body of an instantiation +// wrapper fn. The body calls the original generic function, +// bracketed by ChangeType conversions on its arguments and results. +func (b *builder) buildInstantiationWrapper(fn *Function) { + orig := fn.topLevelOrigin + sig := fn.Signature + + fn.startBody() + if sig.Recv() != nil { + fn.addParamVar(sig.Recv()) + } + createParams(fn, 0) + + // Create body. Add a call to origin generic function + // and make type changes between argument and parameters, + // as well as return values. + var c Call + c.Call.Value = orig + if res := orig.Signature.Results(); res.Len() == 1 { + c.typ = res.At(0).Type() + } else { + c.typ = res + } + + // parameter of instance becomes an argument to the call + // to the original generic function. + argOffset := 0 + for i, arg := range fn.Params { + var typ types.Type + if i == 0 && sig.Recv() != nil { + typ = orig.Signature.Recv().Type() + argOffset = 1 + } else { + typ = orig.Signature.Params().At(i - argOffset).Type() + } + c.Call.Args = append(c.Call.Args, emitTypeCoercion(fn, arg, typ)) + } + + results := fn.emit(&c) + var ret Return + switch res := sig.Results(); res.Len() { + case 0: + // no results, do nothing. + case 1: + ret.Results = []Value{emitTypeCoercion(fn, results, res.At(0).Type())} + default: + for i := 0; i < sig.Results().Len(); i++ { + v := emitExtract(fn, results, i) + ret.Results = append(ret.Results, emitTypeCoercion(fn, v, res.At(i).Type())) + } + } + + fn.emit(&ret) + fn.currentBlock = nil + + fn.finishBody() +} diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go new file mode 100644 index 0000000..91add84 --- /dev/null +++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go @@ -0,0 +1,956 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package objectpath defines a naming scheme for types.Objects +// (that is, named entities in Go programs) relative to their enclosing +// package. +// +// Type-checker objects are canonical, so they are usually identified by +// their address in memory (a pointer), but a pointer has meaning only +// within one address space. By contrast, objectpath names allow the +// identity of an object to be sent from one program to another, +// establishing a correspondence between types.Object variables that are +// distinct but logically equivalent. +// +// A single object may have multiple paths. In this example, +// +// type A struct{ X int } +// type B A +// +// the field X has two paths due to its membership of both A and B. +// The For(obj) function always returns one of these paths, arbitrarily +// but consistently. +package objectpath + +import ( + "encoding/binary" + "fmt" + "go/types" + "slices" + "strconv" + "strings" + "sync" + // This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps. +) + +// TODO(adonovan): think about generic aliases. + +// A Path is an opaque name that identifies a types.Object +// relative to its package. Conceptually, the name consists of a +// sequence of destructuring operations applied to the package scope +// to obtain the original object. +// The name does not include the package itself. +type Path string + +// Encoding +// +// An object path is a textual and (with training) human-readable encoding +// of a sequence of destructuring operators, starting from a types.Package. +// The sequences represent a path through the package/object/type graph. +// We classify these operators by their type: +// +// PO package->object Package.Scope.Lookup +// OT object->type Object.Type +// TT type->type Type.{Elem,Key,{,{,Recv}Type}Params,Results,Underlying,Rhs} [EKPRUTrCa] +// TO type->object Type.{At,Field,Method,Obj} [AFMO] +// +// All valid paths start with a package and end at an object +// and thus may be defined by the regular language: +// +// objectpath = PO (OT TT* TO)* +// +// The concrete encoding follows directly: +// - The only PO operator is Package.Scope.Lookup, which requires an identifier. +// - The only OT operator is Object.Type, +// which we encode as '.' because dot cannot appear in an identifier. +// - The TT operators are encoded as [EKPRUTrCa]; +// two of these ({,Recv}TypeParams) require an integer operand, +// which is encoded as a string of decimal digits. +// - The TO operators are encoded as [AFMO]; +// three of these (At,Field,Method) require an integer operand, +// which is encoded as a string of decimal digits. +// These indices are stable across different representations +// of the same package, even source and export data. +// The indices used are implementation specific and may not correspond to +// the argument to the go/types function. +// +// In the example below, +// +// package p +// +// type T interface { +// f() (a string, b struct{ X int }) +// } +// +// field X has the path "T.UM0.RA1.F0", +// representing the following sequence of operations: +// +// p.Lookup("T") T +// .Type().Underlying().Method(0). f +// .Type().Results().At(1) b +// .Type().Field(0) X +// +// The encoding is not maximally compact---every R or P is +// followed by an A, for example---but this simplifies the +// encoder and decoder. +const ( + // object->type operators + opType = '.' // .Type() (Object) + + // type->type operators + opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map) + opKey = 'K' // .Key() (Map) + opParams = 'P' // .Params() (Signature) + opResults = 'R' // .Results() (Signature) + opUnderlying = 'U' // .Underlying() (Named) + opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature) + opRecvTypeParam = 'r' // .RecvTypeParams.At(i) (Signature) + opConstraint = 'C' // .Constraint() (TypeParam) + opRhs = 'a' // .Rhs() (Alias) + + // type->object operators + opAt = 'A' // .At(i) (Tuple) + opField = 'F' // .Field(i) (Struct) + opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored) + opObj = 'O' // .Obj() (Named, TypeParam) +) + +// For is equivalent to new(Encoder).For(obj). +// +// It may be more efficient to reuse a single Encoder across several calls. +func For(obj types.Object) (Path, error) { + return new(Encoder).For(obj) +} + +// An Encoder amortizes the cost of encoding the paths of multiple objects. +// The zero value of an Encoder is ready to use. +type Encoder struct { + pkgIndexMu sync.Mutex + pkgIndex map[*types.Package]*pkgIndex +} + +// A traversal encapsulates the state of a single traversal of the object/type graph. +type traversal struct { + pkg *types.Package + ix *pkgIndex // non-nil if we are building the index + + target types.Object // the sought symbol (if ix == nil) + found Path // the found path (if ix == nil) + + // These maps are used to short circuit cycles through + // interface methods, such as occur in the following example: + // + // type I interface { f() interface{I} } + // + // See golang/go#68046 for details. + seenTParamNames map[*types.TypeName]bool // global cycle breaking through type parameters + seenMethods map[*types.Func]bool // global cycle breaking through recursive interfaces +} + +// A pkgIndex holds a compressed index of objectpaths of all symbols +// (fields, methods, params) requiring search for an entire package. +// +// The first time a search for a given package is requested, we simply +// traverse the type graph for the target object, maintaining the +// current object path as a stack. If we find the target object, we +// save the path and terminate the main loop (but it's not worth +// breaking out of the current recursion). +// +// On the second search (a pkgIndex exists but its data is nil), we +// build an index of the traversal, which we use for all subsequent +// searches. +// +// The traversal index is encoded in the data field as a list of records, +// one per node, in preorder. Records are of two types: +// +// - A record for a package-level object consists of a pair +// (parent, nameIndex uvarint), where parent is zero and +// nameIndex is the index of the object's name in the sorted +// pkg.Scope().Names() slice. +// +// - A record for a nested node (a segment of an object path) +// consists of (parent uvarint, op byte, index uvarint), where +// parent is the index of the record for the parent node, +// op is the destructuring operator, and index (if op = [AFMTr]) +// is its integer operand. +// +// Since data[0] = 0 all nodes have positive offsets. In effect the +// encoding is a trie in which each node stores one path segment +// and points to the node for its prefix. +// +// TODO(adonovan): opt: evaluate an only 2-level tree with nodes for +// package-level objects and the-rest-of-the-path. One calculation +// suggested that it might be similar speed but 30% more compact. +type pkgIndex struct { + pkg *types.Package + data []byte // encoding of traversal; nil if not yet constructed + scopeNames []string // memo of pkg.Scope().Names() to avoid O(n) alloc/sort at lookup + offsets map[types.Object]uint32 // each object's node offset within encoded traversal data +} + +// For returns the path to an object relative to its package, +// or an error if the object is not accessible from the package's Scope. +// +// For is safe for concurrent use. +// +// The For function guarantees to return a path only for the following objects: +// - package-level types +// - exported package-level non-types +// - methods +// - parameter and result variables +// - struct fields +// These objects are sufficient to define the API of their package. +// The objects described by a package's export data are drawn from this set. +// +// The set of objects accessible from a package's Scope depends on +// whether the package was produced by type-checking syntax, or +// reading export data; the latter may have a smaller Scope since +// export data trims objects that are not reachable from an exported +// declaration. For example, the For function will return a path for +// an exported method of an unexported type that is not reachable +// from any public declaration; this path will cause the Object +// function to fail if called on a package loaded from export data. +// TODO(adonovan): is this a bug or feature? Should this package +// compute accessibility in the same way? +// +// For does not return a path for predeclared names, imported package +// names, local names, and unexported package-level names (except +// types). +// +// Example: given this definition, +// +// package p +// +// type T interface { +// f() (a string, b struct{ X int }) +// } +// +// For(X) would return a path that denotes the following sequence of operations: +// +// p.Scope().Lookup("T") (TypeName T) +// .Type().Underlying().Method(0). (method Func f) +// .Type().Results().At(1) (field Var b) +// .Type().Field(0) (field Var X) +// +// where p is the package (*types.Package) to which X belongs. +func (enc *Encoder) For(obj types.Object) (Path, error) { + pkg := obj.Pkg() + + // This table lists the cases of interest. + // + // Object Action + // ------ ------ + // nil reject + // builtin reject + // pkgname reject + // label reject + // var + // package-level accept + // func param/result accept + // local reject + // struct field accept + // const + // package-level accept + // local reject + // func + // package-level accept + // init functions reject + // concrete method accept + // interface method accept + // type + // package-level accept + // local reject + // + // The only accessible package-level objects are members of pkg itself. + // + // The cases are handled in four steps: + // + // 1. reject nil and builtin + // 2. accept package-level objects + // 3. reject obviously invalid objects + // 4. search the API for the path to the param/result/field/method. + + // 1. reference to nil or builtin? + if pkg == nil { + return "", fmt.Errorf("predeclared %s has no path", obj) + } + + // 2. package-level object? + if pkg.Scope().Lookup(obj.Name()) == obj { + // Only exported objects (and non-exported types) have a path. + // Non-exported types may be referenced by other objects. + if _, ok := obj.(*types.TypeName); !ok && !obj.Exported() { + return "", fmt.Errorf("no path for non-exported %v", obj) + } + return Path(obj.Name()), nil + } + + // 3. Not a package-level object. + // Reject obviously non-viable cases. + switch obj := obj.(type) { + case *types.TypeName: + if _, ok := types.Unalias(obj.Type()).(*types.TypeParam); !ok { + // With the exception of type parameters, only package-level type names + // have a path. + return "", fmt.Errorf("no path for %v", obj) + } + + case *types.Const, // Only package-level constants have a path. + *types.Label, // Labels are function-local. + *types.PkgName: // PkgNames are file-local. + return "", fmt.Errorf("no path for %v", obj) + + case *types.Var: + // A var, if not package-level, must be a + // parameter (incl. receiver) or result, or a struct field. + if obj.Kind() == types.LocalVar { + return "", fmt.Errorf("no path for local %v", obj) + } + + case *types.Func: + // A func, if not package-level, must be a method. + if recv := obj.Signature().Recv(); recv == nil { + return "", fmt.Errorf("func is not a method: %v", obj) + } + + if path, ok := enc.concreteMethod(obj); ok { + // Fast path for concrete methods that avoids looping over scope. + return path, nil + } + + default: + panic(obj) + } + + enc.pkgIndexMu.Lock() + defer enc.pkgIndexMu.Unlock() + + // 4. Search the object/type graph for the path to + // the var (field/param/result) or method. + ix, ok := enc.pkgIndex[pkg] + if !ok { + // First search: don't build an index, just traverse. + // This avoids allocation in [For], whose Encoder + // lives for a single call. + ix = &pkgIndex{pkg: pkg} + + if enc.pkgIndex == nil { + enc.pkgIndex = make(map[*types.Package]*pkgIndex) + } + enc.pkgIndex[pkg] = ix // build the index next time + + f := traversal{pkg: pkg, target: obj} + f.traverse() + + if f.found != "" { + return f.found, nil + } + } else { + // Second search: build an index while traversing. + if ix.data == nil { + ix.offsets = make(map[types.Object]uint32) + ix.data = []byte{0} // offset 0 is sentinel + (&traversal{pkg: pkg, ix: ix}).traverse() + } + + // Second and later searches: consult the index. + if offset, ok := ix.offsets[obj]; ok { + return ix.path(offset), nil + } + } + + return "", fmt.Errorf("can't find path for %v in %s", obj, pkg.Path()) +} + +// traverse performs a complete traversal of all symbols reachable from the package. +func (tr *traversal) traverse() { + scope := tr.pkg.Scope() + names := scope.Names() + if tr.ix != nil { + tr.ix.scopeNames = names + } + + empty := make([]byte, 0, 48) // initial space for stack (ix == nil) + + // First inspect package-level type names. + // In the presence of path aliases, these give + // the best paths because non-types may + // refer to types, but not the reverse. + for i, name := range names { + if tr.found != "" { + return // found (ix == nil) + } + + obj := scope.Lookup(name) + if _, ok := obj.(*types.TypeName); !ok { + continue // handle non-types in second pass + } + + // emit (name, opType) + var path []byte + var offset uint32 + if tr.ix == nil { + path = append(empty, name...) + path = append(path, opType) + } else { + offset = tr.ix.emitPackageLevel(i) + tr.ix.offsets[obj] = offset + offset = tr.ix.emitPathSegment(offset, opType, -1) + } + + // A TypeName (for Named or Alias) may have type parameters. + switch t := obj.Type().(type) { + case *types.Alias: + tr.tparams(t.TypeParams(), path, offset, opTypeParam) + tr.typ(path, offset, opRhs, -1, t.Rhs()) + case *types.Named: + tr.tparams(t.TypeParams(), path, offset, opTypeParam) + tr.typ(path, offset, opUnderlying, -1, t.Underlying()) + } + } + + // Then inspect everything else: + // exported non-types, and declared methods of defined types. + for i, name := range names { + if tr.found != "" { + return // found (ix == nil) + } + + obj := scope.Lookup(name) + + if tname, ok := obj.(*types.TypeName); !ok { + if obj.Exported() { + // exported non-type (const, var, func) + var path []byte + var offset uint32 + if tr.ix == nil { + path = append(empty, name...) + } else { + offset = tr.ix.emitPackageLevel(i) + tr.ix.offsets[obj] = offset + } + tr.typ(path, offset, opType, -1, obj.Type()) + } + + } else if T, ok := types.Unalias(tname.Type()).(*types.Named); ok { + // defined type + var path []byte + var offset uint32 + if tr.ix == nil { + path = append(empty, name...) + path = append(path, opType) + } else { + // Inv: map entry for obj was populated in first pass. + offset = tr.ix.emitPathSegment(tr.ix.offsets[obj], opType, -1) + } + + // Inspect declared methods of defined types. + // + // The method index here is always with respect + // to the underlying go/types data structures, + // which ultimately derives from source order + // and must be preserved by export data. + for i := 0; i < T.NumMethods(); i++ { + m := T.Method(i) + tr.object(path, offset, opMethod, i, m) + } + } + } +} + +func (tr *traversal) visitType(path []byte, offset uint32, T types.Type) { + switch T := T.(type) { + case *types.Alias: + tr.typ(path, offset, opRhs, -1, T.Rhs()) + + case *types.Basic, *types.Named: + // Named types belonging to pkg were handled already, + // so T must belong to another package. No path. + return + + case *types.Pointer, *types.Slice, *types.Array, *types.Chan: + type hasElem interface{ Elem() types.Type } // note: includes Map + tr.typ(path, offset, opElem, -1, T.(hasElem).Elem()) + + case *types.Map: + tr.typ(path, offset, opKey, -1, T.Key()) + tr.typ(path, offset, opElem, -1, T.Elem()) + + case *types.Signature: + tr.tparams(T.RecvTypeParams(), path, offset, opRecvTypeParam) + tr.tparams(T.TypeParams(), path, offset, opTypeParam) + tr.typ(path, offset, opParams, -1, T.Params()) + tr.typ(path, offset, opResults, -1, T.Results()) + + case *types.Struct: + for i := 0; i < T.NumFields(); i++ { + tr.object(path, offset, opField, i, T.Field(i)) + } + + case *types.Tuple: + for i := 0; i < T.Len(); i++ { + tr.object(path, offset, opAt, i, T.At(i)) + } + + case *types.Interface: + for i := 0; i < T.NumMethods(); i++ { + m := T.Method(i) + if m.Pkg() != nil && m.Pkg() != tr.pkg { + continue // embedded method from another package + } + if !tr.seenMethods[m] { + if tr.seenMethods == nil { + tr.seenMethods = make(map[*types.Func]bool) + } + tr.seenMethods[m] = true + tr.object(path, offset, opMethod, i, m) + } + } + + case *types.TypeParam: + tname := T.Obj() + if tname.Pkg() != nil && tname.Pkg() != tr.pkg { + return // type parameter from another package + } + if !tr.seenTParamNames[tname] { + if tr.seenTParamNames == nil { + tr.seenTParamNames = make(map[*types.TypeName]bool) + } + tr.seenTParamNames[tname] = true + tr.object(path, offset, opObj, -1, tname) + tr.typ(path, offset, opConstraint, -1, T.Constraint()) + } + } +} + +func (tr *traversal) tparams(list *types.TypeParamList, path []byte, offset uint32, op byte) { + for i := 0; i < list.Len(); i++ { + tr.typ(path, offset, op, i, list.At(i)) + } +} + +// typ descends the type graph edge (op, index), then proceeds to traverse type t. +func (tr *traversal) typ(path []byte, offset uint32, op byte, index int, t types.Type) { + if tr.ix == nil { + path = appendOpArg(path, op, index) + } else { + offset = tr.ix.emitPathSegment(offset, op, index) + } + tr.visitType(path, offset, t) +} + +// object descends the type graph edge (op, index), records object +// obj, then proceeds to traverse its type. +func (tr *traversal) object(path []byte, offset uint32, op byte, index int, obj types.Object) { + if tr.ix == nil { + path = appendOpArg(path, op, index) + if obj == tr.target && tr.found == "" { + tr.found = Path(path) + } + path = append(path, opType) + } else { + offset = tr.ix.emitPathSegment(offset, op, index) + if _, ok := tr.ix.offsets[obj]; !ok { + tr.ix.offsets[obj] = offset + } + offset = tr.ix.emitPathSegment(offset, opType, -1) + } + tr.visitType(path, offset, obj.Type()) +} + +// emitPackageLevel encodes a record for a package-level symbol, +// identified by its index in ix.scopeNames. +func (p *pkgIndex) emitPackageLevel(index int) uint32 { + off := uint32(len(p.data)) + p.data = append(p.data, 0) // zero varint => no parent + p.data = binary.AppendUvarint(p.data, uint64(index)) + return off +} + +// emitPathSegment emits a record for a non-initial object path segment. +func (p *pkgIndex) emitPathSegment(parent uint32, op byte, index int) uint32 { + off := uint32(len(p.data)) + p.data = binary.AppendUvarint(p.data, uint64(parent)) + p.data = append(p.data, op) + switch op { + case opAt, opField, opMethod, opTypeParam, opRecvTypeParam: + p.data = binary.AppendUvarint(p.data, uint64(index)) + } + return off +} + +// path returns the Path for the encoded node at the specified offset. +func (p *pkgIndex) path(offset uint32) Path { + var elems []string // path elements in reverse + for { + // Read parent index. + parent, n := binary.Uvarint(p.data[offset:]) + offset += uint32(n) + + if parent == 0 { + break // root (end of path) + } + + op := p.data[offset] + offset++ + + // The [AFMTr] operators have a numeric operand. + switch op { + case opAt, opField, opMethod, opTypeParam, opRecvTypeParam: + val, n := binary.Uvarint(p.data[offset:]) + offset += uint32(n) + elems = append(elems, strconv.Itoa(int(val))) + } + + elems = append(elems, string([]byte{op})) + + offset = uint32(parent) + } + idx, _ := binary.Uvarint(p.data[offset:]) + + // Convert index to Path string. + name := p.scopeNames[idx] + sz := len(name) + for _, elem := range elems { + sz += len(elem) + } + var buf strings.Builder + buf.Grow(sz) + buf.WriteString(name) + for _, elem := range slices.Backward(elems) { + buf.WriteString(elem) + } + return Path(buf.String()) +} + +// appendOpArg appends (op, index) to the object path. +// A negative index is ignored. +func appendOpArg(path []byte, op byte, index int) []byte { + path = append(path, op) + if index >= 0 { + path = strconv.AppendInt(path, int64(index), 10) + } + return path +} + +// concreteMethod returns the path for meth, which must have a non-nil receiver. +// The second return value indicates success and may be false if the method is +// an interface method or if it is an instantiated method. +// +// This function is just an optimization that avoids the general scope walking +// approach. You are expected to fall back to the general approach if this +// function fails. +func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) { + // Concrete methods can only be declared on package-scoped named types. For + // that reason we can skip the expensive walk over the package scope: the + // path will always be package -> named type -> method. We can trivially get + // the type name from the receiver, and only have to look over the type's + // methods to find the method index. + // + // Methods on generic types require special consideration, however. Consider + // the following package: + // + // L1: type S[T any] struct{} + // L2: func (recv S[A]) Foo() { recv.Bar() } + // L3: func (recv S[B]) Bar() { } + // L4: type Alias = S[int] + // L5: func _[T any]() { var s S[int]; s.Foo() } + // + // The receivers of methods on generic types are instantiations. L2 and L3 + // instantiate S with the type-parameters A and B, which are scoped to the + // respective methods. L4 and L5 each instantiate S with int. Each of these + // instantiations has its own method set, full of methods (and thus objects) + // with receivers whose types are the respective instantiations. In other + // words, we have + // + // S[A].Foo, S[A].Bar + // S[B].Foo, S[B].Bar + // S[int].Foo, S[int].Bar + // + // We may thus be trying to produce object paths for any of these objects. + // + // S[A].Foo and S[B].Bar are the origin methods, and their paths are S.Foo + // and S.Bar, which are the paths that this function naturally produces. + // + // S[A].Bar, S[B].Foo, and both methods on S[int] are instantiations that + // don't correspond to the origin methods. For S[int], this is significant. + // The most precise object path for S[int].Foo, for example, is Alias.Foo, + // not S.Foo. Our function, however, would produce S.Foo, which would + // resolve to a different object. + // + // For S[A].Bar and S[B].Foo it could be argued that S.Bar and S.Foo are + // still the correct paths, since only the origin methods have meaningful + // paths. But this is likely only true for trivial cases and has edge cases. + // Since this function is only an optimization, we err on the side of giving + // up, deferring to the slower but definitely correct algorithm. Most users + // of objectpath will only be giving us origin methods, anyway, as referring + // to instantiated methods is usually not useful. + + if meth.Origin() != meth { + return "", false + } + + // Avoid dependency on typesinternal.RecvBase here. + t := meth.Signature().Recv().Type() + if ptr, ok := types.Unalias(t).(*types.Pointer); ok { + t = ptr.Elem() + } + named, ok := types.Unalias(t).(*types.Named) + if !ok { + return "", false + } + + if types.IsInterface(named) { + // Named interfaces don't have to be package-scoped + // + // TODO(dominikh): opt: if scope.Lookup(name) == named, then we can apply this optimization to interface + // methods, too, I think. + return "", false + } + + // Preallocate space for the name, opType, opMethod, and some digits. + name := named.Obj().Name() + path := make([]byte, 0, len(name)+8) + path = append(path, name...) + path = append(path, opType) + + // Method indices are w.r.t. the go/types data structures, + // ultimately deriving from source order, + // which is preserved by export data. + for i := 0; i < named.NumMethods(); i++ { + if named.Method(i) == meth { + path = appendOpArg(path, opMethod, i) + return Path(path), true + } + } + + // Due to golang/go#59944, go/types fails to associate the receiver with + // certain methods on cgo types. + // + // TODO(rfindley): replace this panic once golang/go#59944 is fixed in all Go + // versions gopls supports. + return "", false + // panic(fmt.Sprintf("couldn't find method %s on type %s; methods: %#v", meth, named, enc.namedMethods(named))) +} + +// Object returns the object denoted by path p within the package pkg. +func Object(pkg *types.Package, p Path) (types.Object, error) { + pathstr := string(p) + if pathstr == "" { + return nil, fmt.Errorf("empty path") + } + + var pkgobj, suffix string + if dot := strings.IndexByte(pathstr, opType); dot < 0 { + pkgobj = pathstr + } else { + pkgobj = pathstr[:dot] + suffix = pathstr[dot:] // suffix starts with "." + } + + obj := pkg.Scope().Lookup(pkgobj) + if obj == nil { + return nil, fmt.Errorf("package %s does not contain %q", pkg.Path(), pkgobj) + } + + // abstraction of *types.{Pointer,Slice,Array,Chan,Map} + type hasElem interface { + Elem() types.Type + } + // abstraction of *types.{Named,Signature} + type hasTypeParams interface { + TypeParams() *types.TypeParamList + } + // abstraction of *types.{Alias,Named,TypeParam} + type hasObj interface { + Obj() *types.TypeName + } + + // The loop state is the pair (t, obj), + // exactly one of which is non-nil, initially obj. + // All suffixes start with '.' (the only object->type operation), + // followed by optional type->type operations, + // then a type->object operation. + // The cycle then repeats. + var t types.Type + for suffix != "" { + code := suffix[0] + suffix = suffix[1:] + + // Codes [AFMTr] have an integer operand. + var index int + switch code { + case opAt, opField, opMethod, opTypeParam, opRecvTypeParam: + rest := strings.TrimLeft(suffix, "0123456789") + numerals := suffix[:len(suffix)-len(rest)] + suffix = rest + i, err := strconv.Atoi(numerals) + if err != nil { + return nil, fmt.Errorf("invalid path: bad numeric operand %q for code %q", numerals, code) + } + index = int(i) + case opObj: + // no operand + default: + // The suffix must end with a type->object operation. + if suffix == "" { + return nil, fmt.Errorf("invalid path: ends with %q, want [AFMO]", code) + } + } + + if code == opType { + if t != nil { + return nil, fmt.Errorf("invalid path: unexpected %q in type context", opType) + } + t = obj.Type() + obj = nil + continue + } + + if t == nil { + return nil, fmt.Errorf("invalid path: code %q in object context", code) + } + + // Inv: t != nil, obj == nil + + t = types.Unalias(t) + switch code { + case opElem: + hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want pointer, slice, array, chan or map)", code, t, t) + } + t = hasElem.Elem() + + case opKey: + mapType, ok := t.(*types.Map) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want map)", code, t, t) + } + t = mapType.Key() + + case opParams: + sig, ok := t.(*types.Signature) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) + } + t = sig.Params() + + case opResults: + sig, ok := t.(*types.Signature) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) + } + t = sig.Results() + + case opUnderlying: + named, ok := t.(*types.Named) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named)", code, t, t) + } + t = named.Underlying() + + case opRhs: + if alias, ok := t.(*types.Alias); ok { + t = alias.Rhs() + } else if false { + // Now that go1.24 is assured, we should be able to + // replace this with "if true {", but it causes objectpath + // tests to fail. TODO(adonovan): investigate. + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want alias)", code, t, t) + } + + case opTypeParam: + hasTypeParams, ok := t.(hasTypeParams) // Named, Signature + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or signature)", code, t, t) + } + tparams := hasTypeParams.TypeParams() + if n := tparams.Len(); index >= n { + return nil, fmt.Errorf("type parameter index %d out of range [0-%d)", index, n) + } + t = tparams.At(index) + + case opRecvTypeParam: + sig, ok := t.(*types.Signature) // Signature + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) + } + rtparams := sig.RecvTypeParams() + if n := rtparams.Len(); index >= n { + return nil, fmt.Errorf("receiver type parameter index %d out of range [0-%d)", index, n) + } + t = rtparams.At(index) + + case opConstraint: + tparam, ok := t.(*types.TypeParam) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t) + } + t = tparam.Constraint() + + case opAt: + tuple, ok := t.(*types.Tuple) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want tuple)", code, t, t) + } + if n := tuple.Len(); index >= n { + return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) + } + obj = tuple.At(index) + t = nil + + case opField: + structType, ok := t.(*types.Struct) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want struct)", code, t, t) + } + if n := structType.NumFields(); index >= n { + return nil, fmt.Errorf("field index %d out of range [0-%d)", index, n) + } + obj = structType.Field(index) + t = nil + + case opMethod: + switch t := t.(type) { + case *types.Interface: + if index >= t.NumMethods() { + return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods()) + } + obj = t.Method(index) // Id-ordered + + case *types.Named: + if index >= t.NumMethods() { + return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods()) + } + obj = t.Method(index) + + default: + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t) + } + t = nil + + case opObj: + hasObj, ok := t.(hasObj) + if !ok { + return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or type param)", code, t, t) + } + obj = hasObj.Obj() + t = nil + + default: + return nil, fmt.Errorf("invalid path: unknown code %q", code) + } + } + + if obj == nil { + panic(p) // path does not end in an object-valued operator + } + + if obj.Pkg() != pkg { + return nil, fmt.Errorf("path denotes %s, which belongs to a different package", obj) + } + + return obj, nil // success +} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/callee.go b/vendor/golang.org/x/tools/go/types/typeutil/callee.go new file mode 100644 index 0000000..b64a8f4 --- /dev/null +++ b/vendor/golang.org/x/tools/go/types/typeutil/callee.go @@ -0,0 +1,33 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typeutil + +import ( + "go/ast" + "go/types" + + "golang.org/x/tools/internal/typesinternal" +) + +// Callee returns the named target of a function call, if any: +// a function, method, builtin, or variable. +// It returns nil for a T(x) conversion. +// +// Functions and methods may potentially have type parameters. +// +// Note: for calls of instantiated functions and methods, Callee returns +// the corresponding generic function or method on the generic type. +func Callee(info *types.Info, call *ast.CallExpr) types.Object { + return typesinternal.Callee(info, call) +} + +// StaticCallee returns the target (function or method) of a static function +// call, if any. It returns nil for calls to builtins. +// +// Note: for calls of instantiated functions and methods, StaticCallee returns +// the corresponding generic function or method on the generic type. +func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func { + return typesinternal.StaticCallee(info, call) +} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/imports.go b/vendor/golang.org/x/tools/go/types/typeutil/imports.go new file mode 100644 index 0000000..b81ce0c --- /dev/null +++ b/vendor/golang.org/x/tools/go/types/typeutil/imports.go @@ -0,0 +1,30 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typeutil + +import "go/types" + +// Dependencies returns all dependencies of the specified packages. +// +// Dependent packages appear in topological order: if package P imports +// package Q, Q appears earlier than P in the result. +// The algorithm follows import statements in the order they +// appear in the source code, so the result is a total order. +func Dependencies(pkgs ...*types.Package) []*types.Package { + var result []*types.Package + seen := make(map[*types.Package]bool) + var visit func(pkgs []*types.Package) + visit = func(pkgs []*types.Package) { + for _, p := range pkgs { + if !seen[p] { + seen[p] = true + visit(p.Imports()) + result = append(result, p) + } + } + } + visit(pkgs) + return result +} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/map.go b/vendor/golang.org/x/tools/go/types/typeutil/map.go new file mode 100644 index 0000000..3662457 --- /dev/null +++ b/vendor/golang.org/x/tools/go/types/typeutil/map.go @@ -0,0 +1,459 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package typeutil defines various utilities for types, such as [Map], +// a hash table that maps [types.Type] to any value. +package typeutil + +import ( + "bytes" + "fmt" + "go/types" + "hash/maphash" + + "golang.org/x/tools/internal/typeparams" +) + +// Map is a hash-table-based mapping from types (types.Type) to +// arbitrary values. The concrete types that implement +// the Type interface are pointers. Since they are not canonicalized, +// == cannot be used to check for equivalence, and thus we cannot +// simply use a Go map. +// +// Just as with map[K]V, a nil *Map is a valid empty map. +// +// Read-only map operations ([Map.At], [Map.Len], and so on) may +// safely be called concurrently. +// +// TODO(adonovan): deprecate in favor of https://go.dev/issues/69420 +// and 69559, if the latter proposals for a generic hash-map type and +// a types.Hash function are accepted. +type Map struct { + table map[uint32][]entry // maps hash to bucket; entry.key==nil means unused + length int // number of map entries +} + +// entry is an entry (key/value association) in a hash bucket. +type entry struct { + key types.Type + value any +} + +// SetHasher has no effect. +// +// It is a relic of an optimization that is no longer profitable. Do +// not use [Hasher], [MakeHasher], or [SetHasher] in new code. +func (m *Map) SetHasher(Hasher) {} + +// Delete removes the entry with the given key, if any. +// It returns true if the entry was found. +func (m *Map) Delete(key types.Type) bool { + if m != nil && m.table != nil { + hash := hash(key) + bucket := m.table[hash] + for i, e := range bucket { + if e.key != nil && types.Identical(key, e.key) { + // We can't compact the bucket as it + // would disturb iterators. + bucket[i] = entry{} + m.length-- + return true + } + } + } + return false +} + +// At returns the map entry for the given key. +// The result is nil if the entry is not present. +func (m *Map) At(key types.Type) any { + if m != nil && m.table != nil { + for _, e := range m.table[hash(key)] { + if e.key != nil && types.Identical(key, e.key) { + return e.value + } + } + } + return nil +} + +// Set sets the map entry for key to val, +// and returns the previous entry, if any. +func (m *Map) Set(key types.Type, value any) (prev any) { + if m.table != nil { + hash := hash(key) + bucket := m.table[hash] + var hole *entry + for i, e := range bucket { + if e.key == nil { + hole = &bucket[i] + } else if types.Identical(key, e.key) { + prev = e.value + bucket[i].value = value + return + } + } + + if hole != nil { + *hole = entry{key, value} // overwrite deleted entry + } else { + m.table[hash] = append(bucket, entry{key, value}) + } + } else { + hash := hash(key) + m.table = map[uint32][]entry{hash: {entry{key, value}}} + } + + m.length++ + return +} + +// Len returns the number of map entries. +func (m *Map) Len() int { + if m != nil { + return m.length + } + return 0 +} + +// Iterate calls function f on each entry in the map in unspecified order. +// +// If f should mutate the map, Iterate provides the same guarantees as +// Go maps: if f deletes a map entry that Iterate has not yet reached, +// f will not be invoked for it, but if f inserts a map entry that +// Iterate has not yet reached, whether or not f will be invoked for +// it is unspecified. +func (m *Map) Iterate(f func(key types.Type, value any)) { + if m != nil { + for _, bucket := range m.table { + for _, e := range bucket { + if e.key != nil { + f(e.key, e.value) + } + } + } + } +} + +// Keys returns a new slice containing the set of map keys. +// The order is unspecified. +func (m *Map) Keys() []types.Type { + keys := make([]types.Type, 0, m.Len()) + m.Iterate(func(key types.Type, _ any) { + keys = append(keys, key) + }) + return keys +} + +func (m *Map) toString(values bool) string { + if m == nil { + return "{}" + } + var buf bytes.Buffer + fmt.Fprint(&buf, "{") + sep := "" + m.Iterate(func(key types.Type, value any) { + fmt.Fprint(&buf, sep) + sep = ", " + fmt.Fprint(&buf, key) + if values { + fmt.Fprintf(&buf, ": %q", value) + } + }) + fmt.Fprint(&buf, "}") + return buf.String() +} + +// String returns a string representation of the map's entries. +// Values are printed using fmt.Sprintf("%v", v). +// Order is unspecified. +func (m *Map) String() string { + return m.toString(true) +} + +// KeysString returns a string representation of the map's key set. +// Order is unspecified. +func (m *Map) KeysString() string { + return m.toString(false) +} + +// -- Hasher -- + +// hash returns the hash of type t. +// TODO(adonovan): replace by types.Hash when Go proposal #69420 is accepted. +func hash(t types.Type) uint32 { + return theHasher.Hash(t) +} + +// A Hasher provides a [Hasher.Hash] method to map a type to its hash value. +// Hashers are stateless, and all are equivalent. +type Hasher struct{} + +var theHasher Hasher + +// MakeHasher returns Hasher{}. +// Hashers are stateless; all are equivalent. +func MakeHasher() Hasher { return theHasher } + +// Hash computes a hash value for the given type t such that +// Identical(t, t') => Hash(t) == Hash(t'). +func (h Hasher) Hash(t types.Type) uint32 { + return hasher{inGenericSig: false}.hash(t) +} + +// hasher holds the state of a single Hash traversal: whether we are +// inside the signature of a generic function; this is used to +// optimize [hasher.hashTypeParam]. +type hasher struct{ inGenericSig bool } + +// hashString computes the Fowler–Noll–Vo hash of s. +func hashString(s string) uint32 { + var h uint32 + for i := 0; i < len(s); i++ { + h ^= uint32(s[i]) + h *= 16777619 + } + return h +} + +// hash computes the hash of t. +func (h hasher) hash(t types.Type) uint32 { + // See Identical for rationale. + switch t := t.(type) { + case *types.Basic: + return uint32(t.Kind()) + + case *types.Alias: + return h.hash(types.Unalias(t)) + + case *types.Array: + return 9043 + 2*uint32(t.Len()) + 3*h.hash(t.Elem()) + + case *types.Slice: + return 9049 + 2*h.hash(t.Elem()) + + case *types.Struct: + var hash uint32 = 9059 + for i, n := 0, t.NumFields(); i < n; i++ { + f := t.Field(i) + if f.Anonymous() { + hash += 8861 + } + hash += hashString(t.Tag(i)) + hash += hashString(f.Name()) // (ignore f.Pkg) + hash += h.hash(f.Type()) + } + return hash + + case *types.Pointer: + return 9067 + 2*h.hash(t.Elem()) + + case *types.Signature: + var hash uint32 = 9091 + if t.Variadic() { + hash *= 8863 + } + + tparams := t.TypeParams() + if n := tparams.Len(); n > 0 { + h.inGenericSig = true // affects constraints, params, and results + + for i := range n { + tparam := tparams.At(i) + hash += 7 * h.hash(tparam.Constraint()) + } + } + + return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results()) + + case *types.Union: + return h.hashUnion(t) + + case *types.Interface: + // Interfaces are identical if they have the same set of methods, with + // identical names and types, and they have the same set of type + // restrictions. See go/types.identical for more details. + var hash uint32 = 9103 + + // Hash methods. + for i, n := 0, t.NumMethods(); i < n; i++ { + // Method order is not significant. + // Ignore m.Pkg(). + m := t.Method(i) + // Use shallow hash on method signature to + // avoid anonymous interface cycles. + hash += 3*hashString(m.Name()) + 5*h.shallowHash(m.Type()) + } + + // Hash type restrictions. + terms, err := typeparams.InterfaceTermSet(t) + // if err != nil t has invalid type restrictions. + if err == nil { + hash += h.hashTermSet(terms) + } + + return hash + + case *types.Map: + return 9109 + 2*h.hash(t.Key()) + 3*h.hash(t.Elem()) + + case *types.Chan: + return 9127 + 2*uint32(t.Dir()) + 3*h.hash(t.Elem()) + + case *types.Named: + hash := h.hashTypeName(t.Obj()) + targs := t.TypeArgs() + for targ := range targs.Types() { + hash += 2 * h.hash(targ) + } + return hash + + case *types.TypeParam: + return h.hashTypeParam(t) + + case *types.Tuple: + return h.hashTuple(t) + } + + panic(fmt.Sprintf("%T: %v", t, t)) +} + +func (h hasher) hashTuple(tuple *types.Tuple) uint32 { + // See go/types.identicalTypes for rationale. + n := tuple.Len() + hash := 9137 + 2*uint32(n) + for i := range n { + hash += 3 * h.hash(tuple.At(i).Type()) + } + return hash +} + +func (h hasher) hashUnion(t *types.Union) uint32 { + // Hash type restrictions. + terms, err := typeparams.UnionTermSet(t) + // if err != nil t has invalid type restrictions. Fall back on a non-zero + // hash. + if err != nil { + return 9151 + } + return h.hashTermSet(terms) +} + +func (h hasher) hashTermSet(terms []*types.Term) uint32 { + hash := 9157 + 2*uint32(len(terms)) + for _, term := range terms { + // term order is not significant. + termHash := h.hash(term.Type()) + if term.Tilde() { + termHash *= 9161 + } + hash += 3 * termHash + } + return hash +} + +// hashTypeParam returns the hash of a type parameter. +func (h hasher) hashTypeParam(t *types.TypeParam) uint32 { + // Within the signature of a generic function, TypeParams are + // identical if they have the same index and constraint, so we + // hash them based on index. + // + // When we are outside a generic function, free TypeParams are + // identical iff they are the same object, so we can use a + // more discriminating hash consistent with object identity. + // This optimization saves [Map] about 4% when hashing all the + // types.Info.Types in the forward closure of net/http. + if !h.inGenericSig { + // Optimization: outside a generic function signature, + // use a more discrimating hash consistent with object identity. + return h.hashTypeName(t.Obj()) + } + return 9173 + 3*uint32(t.Index()) +} + +var theSeed = maphash.MakeSeed() + +// hashTypeName hashes the pointer of tname. +func (hasher) hashTypeName(tname *types.TypeName) uint32 { + // Since types.Identical uses == to compare TypeNames, + // the Hash function uses maphash.Comparable. + hash := maphash.Comparable(theSeed, tname) + return uint32(hash ^ (hash >> 32)) +} + +// shallowHash computes a hash of t without looking at any of its +// element Types, to avoid potential anonymous cycles in the types of +// interface methods. +// +// When an unnamed non-empty interface type appears anywhere among the +// arguments or results of an interface method, there is a potential +// for endless recursion. Consider: +// +// type X interface { m() []*interface { X } } +// +// The problem is that the Methods of the interface in m's result type +// include m itself; there is no mention of the named type X that +// might help us break the cycle. +// (See comment in go/types.identical, case *Interface, for more.) +func (h hasher) shallowHash(t types.Type) uint32 { + // t is the type of an interface method (Signature), + // its params or results (Tuples), or their immediate + // elements (mostly Slice, Pointer, Basic, Named), + // so there's no need to optimize anything else. + switch t := t.(type) { + case *types.Alias: + return h.shallowHash(types.Unalias(t)) + + case *types.Signature: + var hash uint32 = 604171 + if t.Variadic() { + hash *= 971767 + } + // The Signature/Tuple recursion is always finite + // and invariably shallow. + return hash + 1062599*h.shallowHash(t.Params()) + 1282529*h.shallowHash(t.Results()) + + case *types.Tuple: + n := t.Len() + hash := 9137 + 2*uint32(n) + for i := range n { + hash += 53471161 * h.shallowHash(t.At(i).Type()) + } + return hash + + case *types.Basic: + return 45212177 * uint32(t.Kind()) + + case *types.Array: + return 1524181 + 2*uint32(t.Len()) + + case *types.Slice: + return 2690201 + + case *types.Struct: + return 3326489 + + case *types.Pointer: + return 4393139 + + case *types.Union: + return 562448657 + + case *types.Interface: + return 2124679 // no recursion here + + case *types.Map: + return 9109 + + case *types.Chan: + return 9127 + + case *types.Named: + return h.hashTypeName(t.Obj()) + + case *types.TypeParam: + return h.hashTypeParam(t) + } + panic(fmt.Sprintf("shallowHash: %T: %v", t, t)) +} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go b/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go new file mode 100644 index 0000000..f766602 --- /dev/null +++ b/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go @@ -0,0 +1,71 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements a cache of method sets. + +package typeutil + +import ( + "go/types" + "sync" +) + +// A MethodSetCache records the method set of each type T for which +// MethodSet(T) is called so that repeat queries are fast. +// The zero value is a ready-to-use cache instance. +type MethodSetCache struct { + mu sync.Mutex + named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N + others map[types.Type]*types.MethodSet // all other types +} + +// MethodSet returns the method set of type T. It is thread-safe. +// +// If cache is nil, this function is equivalent to types.NewMethodSet(T). +// Utility functions can thus expose an optional *MethodSetCache +// parameter to clients that care about performance. +func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet { + if cache == nil { + return types.NewMethodSet(T) + } + cache.mu.Lock() + defer cache.mu.Unlock() + + switch T := types.Unalias(T).(type) { + case *types.Named: + return cache.lookupNamed(T).value + + case *types.Pointer: + if N, ok := types.Unalias(T.Elem()).(*types.Named); ok { + return cache.lookupNamed(N).pointer + } + } + + // all other types + // (The map uses pointer equivalence, not type identity.) + mset := cache.others[T] + if mset == nil { + mset = types.NewMethodSet(T) + if cache.others == nil { + cache.others = make(map[types.Type]*types.MethodSet) + } + cache.others[T] = mset + } + return mset +} + +func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } { + if cache.named == nil { + cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet }) + } + // Avoid recomputing mset(*T) for each distinct Pointer + // instance whose underlying type is a named type. + msets, ok := cache.named[named] + if !ok { + msets.value = types.NewMethodSet(named) + msets.pointer = types.NewMethodSet(types.NewPointer(named)) + cache.named[named] = msets + } + return msets +} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/ui.go b/vendor/golang.org/x/tools/go/types/typeutil/ui.go new file mode 100644 index 0000000..9dda6a2 --- /dev/null +++ b/vendor/golang.org/x/tools/go/types/typeutil/ui.go @@ -0,0 +1,53 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typeutil + +// This file defines utilities for user interfaces that display types. + +import ( + "go/types" +) + +// IntuitiveMethodSet returns the intuitive method set of a type T, +// which is the set of methods you can call on an addressable value of +// that type. +// +// The result always contains MethodSet(T), and is exactly MethodSet(T) +// for interface types and for pointer-to-concrete types. +// For all other concrete types T, the result additionally +// contains each method belonging to *T if there is no identically +// named method on T itself. +// +// This corresponds to user intuition about method sets; +// this function is intended only for user interfaces. +// +// The order of the result is as for types.MethodSet(T). +func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { + isPointerToConcrete := func(T types.Type) bool { + ptr, ok := types.Unalias(T).(*types.Pointer) + return ok && !types.IsInterface(ptr.Elem()) + } + + var result []*types.Selection + mset := msets.MethodSet(T) + if types.IsInterface(T) || isPointerToConcrete(T) { + for i, n := 0, mset.Len(); i < n; i++ { + result = append(result, mset.At(i)) + } + } else { + // T is some other concrete type. + // Report methods of T and *T, preferring those of T. + pmset := msets.MethodSet(types.NewPointer(T)) + for i, n := 0, pmset.Len(); i < n; i++ { + meth := pmset.At(i) + if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil { + meth = m + } + result = append(result, meth) + } + + } + return result +} diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go new file mode 100644 index 0000000..42c2188 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/core/event.go @@ -0,0 +1,95 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package core provides support for event based telemetry. +package core + +import ( + "fmt" + "iter" + "time" + + "golang.org/x/tools/internal/event/label" +) + +// Event holds the information about an event of note that occurred. +type Event struct { + at time.Time + + // As events are often on the stack, storing the first few labels directly + // in the event can avoid an allocation at all for the very common cases of + // simple events. + // The length needs to be large enough to cope with the majority of events + // but no so large as to cause undue stack pressure. + // A log message with two values will use 3 labels (one for each value and + // one for the message itself). + + static [3]label.Label // inline storage for the first few labels + dynamic []label.Label // dynamically sized storage for remaining labels +} + +func (ev Event) At() time.Time { return ev.at } + +func (ev Event) Format(f fmt.State, r rune) { + if !ev.at.IsZero() { + fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 ")) + } + for l := range ev.Labels() { + fmt.Fprintf(f, "\n\t%v", l) + } +} + +func (ev Event) Valid(index int) bool { + return index >= 0 && index < len(ev.static)+len(ev.dynamic) +} + +func (ev Event) Label(index int) label.Label { + if index < len(ev.static) { + return ev.static[index] + } + return ev.dynamic[index-len(ev.static)] +} + +// Labels returns an iterator over the event's valid labels. +func (ev Event) Labels() iter.Seq[label.Label] { + return func(yield func(label.Label) bool) { + for _, l := range ev.static { + if l.Valid() && !yield(l) { + return + } + } + for _, l := range ev.dynamic { + if l.Valid() && !yield(l) { + return + } + } + } +} + +func (ev Event) Find(key label.Key) label.Label { + for _, l := range ev.static { + if l.Key() == key { + return l + } + } + for _, l := range ev.dynamic { + if l.Key() == key { + return l + } + } + return label.Label{} +} + +func MakeEvent(static [3]label.Label, labels []label.Label) Event { + return Event{ + static: static, + dynamic: labels, + } +} + +// CloneEvent event returns a copy of the event with the time adjusted to at. +func CloneEvent(ev Event, at time.Time) Event { + ev.at = at + return ev +} diff --git a/vendor/golang.org/x/tools/internal/event/core/export.go b/vendor/golang.org/x/tools/internal/event/core/export.go new file mode 100644 index 0000000..16ae6bb --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/core/export.go @@ -0,0 +1,67 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package core + +import ( + "context" + "sync/atomic" + "time" + + "golang.org/x/tools/internal/event/label" +) + +// Exporter is a function that handles events. +// It may return a modified context and event. +type Exporter func(context.Context, Event, label.Map) context.Context + +var exporter atomic.Pointer[Exporter] + +// SetExporter sets the global exporter function that handles all events. +// The exporter is called synchronously from the event call site, so it should +// return quickly so as not to hold up user code. +func SetExporter(e Exporter) { + if e == nil { + // &e is always valid, and so p is always valid, but for the early abort + // of ProcessEvent to be efficient it needs to make the nil check on the + // pointer without having to dereference it, so we make the nil function + // also a nil pointer + exporter.Store(nil) + } else { + exporter.Store(&e) + } +} + +// deliver is called to deliver an event to the supplied exporter. +// it will fill in the time. +func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context { + // add the current time to the event + ev.at = time.Now() + // hand the event off to the current exporter + return exporter(ctx, ev, ev) +} + +// Export is called to deliver an event to the global exporter if set. +func Export(ctx context.Context, ev Event) context.Context { + // get the global exporter and abort early if there is not one + exporterPtr := exporter.Load() + if exporterPtr == nil { + return ctx + } + return deliver(ctx, *exporterPtr, ev) +} + +// ExportPair is called to deliver a start event to the supplied exporter. +// It also returns a function that will deliver the end event to the same +// exporter. +// It will fill in the time. +func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) { + // get the global exporter and abort early if there is not one + exporterPtr := exporter.Load() + if exporterPtr == nil { + return ctx, func() {} + } + ctx = deliver(ctx, *exporterPtr, begin) + return ctx, func() { deliver(ctx, *exporterPtr, end) } +} diff --git a/vendor/golang.org/x/tools/internal/event/core/fast.go b/vendor/golang.org/x/tools/internal/event/core/fast.go new file mode 100644 index 0000000..06c1d46 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/core/fast.go @@ -0,0 +1,77 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package core + +import ( + "context" + + "golang.org/x/tools/internal/event/keys" + "golang.org/x/tools/internal/event/label" +) + +// Log1 takes a message and one label delivers a log event to the exporter. +// It is a customized version of Print that is faster and does no allocation. +func Log1(ctx context.Context, message string, t1 label.Label) { + Export(ctx, MakeEvent([3]label.Label{ + keys.Msg.Of(message), + t1, + }, nil)) +} + +// Log2 takes a message and two labels and delivers a log event to the exporter. +// It is a customized version of Print that is faster and does no allocation. +func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) { + Export(ctx, MakeEvent([3]label.Label{ + keys.Msg.Of(message), + t1, + t2, + }, nil)) +} + +// Metric1 sends a label event to the exporter with the supplied labels. +func Metric1(ctx context.Context, t1 label.Label) context.Context { + return Export(ctx, MakeEvent([3]label.Label{ + keys.Metric.New(), + t1, + }, nil)) +} + +// Metric2 sends a label event to the exporter with the supplied labels. +func Metric2(ctx context.Context, t1, t2 label.Label) context.Context { + return Export(ctx, MakeEvent([3]label.Label{ + keys.Metric.New(), + t1, + t2, + }, nil)) +} + +// Start1 sends a span start event with the supplied label list to the exporter. +// It also returns a function that will end the span, which should normally be +// deferred. +func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) { + return ExportPair(ctx, + MakeEvent([3]label.Label{ + keys.Start.Of(name), + t1, + }, nil), + MakeEvent([3]label.Label{ + keys.End.New(), + }, nil)) +} + +// Start2 sends a span start event with the supplied label list to the exporter. +// It also returns a function that will end the span, which should normally be +// deferred. +func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) { + return ExportPair(ctx, + MakeEvent([3]label.Label{ + keys.Start.Of(name), + t1, + t2, + }, nil), + MakeEvent([3]label.Label{ + keys.End.New(), + }, nil)) +} diff --git a/vendor/golang.org/x/tools/internal/event/doc.go b/vendor/golang.org/x/tools/internal/event/doc.go new file mode 100644 index 0000000..5dc6e6b --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/doc.go @@ -0,0 +1,7 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package event provides a set of packages that cover the main +// concepts of telemetry in an implementation agnostic way. +package event diff --git a/vendor/golang.org/x/tools/internal/event/event.go b/vendor/golang.org/x/tools/internal/event/event.go new file mode 100644 index 0000000..4d55e57 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/event.go @@ -0,0 +1,127 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package event + +import ( + "context" + + "golang.org/x/tools/internal/event/core" + "golang.org/x/tools/internal/event/keys" + "golang.org/x/tools/internal/event/label" +) + +// Exporter is a function that handles events. +// It may return a modified context and event. +type Exporter func(context.Context, core.Event, label.Map) context.Context + +// SetExporter sets the global exporter function that handles all events. +// The exporter is called synchronously from the event call site, so it should +// return quickly so as not to hold up user code. +func SetExporter(e Exporter) { + core.SetExporter(core.Exporter(e)) +} + +// Log takes a message and a label list and combines them into a single event +// before delivering them to the exporter. +func Log(ctx context.Context, message string, labels ...label.Label) { + core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Msg.Of(message), + }, labels)) +} + +// IsLog returns true if the event was built by the Log function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsLog(ev core.Event) bool { + return ev.Label(0).Key() == keys.Msg +} + +// Error takes a message and a label list and combines them into a single event +// before delivering them to the exporter. It captures the error in the +// delivered event. +func Error(ctx context.Context, message string, err error, labels ...label.Label) { + core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Msg.Of(message), + keys.Err.Of(err), + }, labels)) +} + +// IsError returns true if the event was built by the Error function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsError(ev core.Event) bool { + return ev.Label(0).Key() == keys.Msg && + ev.Label(1).Key() == keys.Err +} + +// Metric sends a label event to the exporter with the supplied labels. +func Metric(ctx context.Context, labels ...label.Label) { + core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Metric.New(), + }, labels)) +} + +// IsMetric returns true if the event was built by the Metric function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsMetric(ev core.Event) bool { + return ev.Label(0).Key() == keys.Metric +} + +// Label sends a label event to the exporter with the supplied labels. +func Label(ctx context.Context, labels ...label.Label) context.Context { + return core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Label.New(), + }, labels)) +} + +// IsLabel returns true if the event was built by the Label function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsLabel(ev core.Event) bool { + return ev.Label(0).Key() == keys.Label +} + +// Start sends a span start event with the supplied label list to the exporter. +// It also returns a function that will end the span, which should normally be +// deferred. +func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) { + return core.ExportPair(ctx, + core.MakeEvent([3]label.Label{ + keys.Start.Of(name), + }, labels), + core.MakeEvent([3]label.Label{ + keys.End.New(), + }, nil)) +} + +// IsStart returns true if the event was built by the Start function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsStart(ev core.Event) bool { + return ev.Label(0).Key() == keys.Start +} + +// IsEnd returns true if the event was built by the End function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsEnd(ev core.Event) bool { + return ev.Label(0).Key() == keys.End +} + +// Detach returns a context without an associated span. +// This allows the creation of spans that are not children of the current span. +func Detach(ctx context.Context) context.Context { + return core.Export(ctx, core.MakeEvent([3]label.Label{ + keys.Detach.New(), + }, nil)) +} + +// IsDetach returns true if the event was built by the Detach function. +// It is intended to be used in exporters to identify the semantics of the +// event when deciding what to do with it. +func IsDetach(ev core.Event) bool { + return ev.Label(0).Key() == keys.Detach +} diff --git a/vendor/golang.org/x/tools/internal/event/keys/keys.go b/vendor/golang.org/x/tools/internal/event/keys/keys.go new file mode 100644 index 0000000..ac78bc3 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/keys/keys.go @@ -0,0 +1,237 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package keys + +import ( + "fmt" + "math" + "strconv" + + "golang.org/x/tools/internal/event/label" +) + +// Value is a [label.Key] for untyped values. +type Value struct { + name string + description string +} + +// New creates a new Key for untyped values. +func New(name, description string) *Value { + return &Value{name: name, description: description} +} + +func (k *Value) Name() string { return k.name } +func (k *Value) Description() string { return k.description } + +func (k *Value) Append(buf []byte, l label.Label) []byte { + return fmt.Append(buf, k.From(l)) +} + +// Get returns the label for the key of a label.Map. +func (k *Value) Get(lm label.Map) any { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return nil +} + +// From returns the value of a Label. +func (k *Value) From(t label.Label) any { return t.UnpackValue() } + +// Of creates a new Label with this key and the supplied value. +func (k *Value) Of(value any) label.Label { return label.OfValue(k, value) } + +// Tag represents a key for tagging labels that have no value. +// These are used when the existence of the label is the entire information it +// carries, such as marking events to be of a specific kind, or from a specific +// package. +type Tag struct { + name string + description string +} + +// NewTag creates a new [label.Key] for tagging labels. +func NewTag(name, description string) *Tag { + return &Tag{name: name, description: description} +} + +func (k *Tag) Name() string { return k.name } +func (k *Tag) Description() string { return k.description } + +func (k *Tag) Append(buf []byte, l label.Label) []byte { return buf } + +// New creates a new Label with this key. +func (k *Tag) New() label.Label { return label.OfValue(k, nil) } + +// Int is a [label.Key] for signed integers. +type Int struct { + name string + description string +} + +// NewInt returns a new [label.Key] for int64 values. +func NewInt(name, description string) *Int { + return &Int{name: name, description: description} +} + +func (k *Int) Name() string { return k.name } +func (k *Int) Description() string { return k.description } + +func (k *Int) Append(buf []byte, l label.Label) []byte { + return strconv.AppendInt(buf, k.From(l), 10) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Int) Of(v int) label.Label { return k.Of64(int64(v)) } + +// Of64 creates a new Label with this key and the supplied value. +func (k *Int) Of64(v int64) label.Label { return label.Of64(k, uint64(v)) } + +// Get returns the label for the key of a label.Map. +func (k *Int) Get(lm label.Map) int64 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From returns the value of a Label. +func (k *Int) From(t label.Label) int64 { return int64(t.Unpack64()) } + +// Uint is a [label.Key] for unsigned integers. +type Uint struct { + name string + description string +} + +// NewUint creates a new [label.Key] for unsigned values. +func NewUint(name, description string) *Uint { + return &Uint{name: name, description: description} +} + +func (k *Uint) Name() string { return k.name } +func (k *Uint) Description() string { return k.description } + +func (k *Uint) Append(buf []byte, l label.Label) []byte { + return strconv.AppendUint(buf, k.From(l), 10) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Uint) Of(v uint64) label.Label { return label.Of64(k, v) } + +// Get returns the label for the key of a label.Map. +func (k *Uint) Get(lm label.Map) uint64 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From returns the value of a Label. +func (k *Uint) From(t label.Label) uint64 { return t.Unpack64() } + +// Float is a label.Key for floating-point values. +type Float struct { + name string + description string +} + +// NewFloat creates a new [label.Key] for floating-point values. +func NewFloat(name, description string) *Float { + return &Float{name: name, description: description} +} + +func (k *Float) Name() string { return k.name } +func (k *Float) Description() string { return k.description } + +func (k *Float) Append(buf []byte, l label.Label) []byte { + return strconv.AppendFloat(buf, k.From(l), 'E', -1, 64) +} + +// Of creates a new Label with this key and the supplied value. +func (k *Float) Of(v float64) label.Label { + return label.Of64(k, math.Float64bits(v)) +} + +// Get returns the label for the key of a label.Map. +func (k *Float) Get(lm label.Map) float64 { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return 0 +} + +// From returns the value of a Label. +func (k *Float) From(t label.Label) float64 { + return math.Float64frombits(t.Unpack64()) +} + +// String represents a key +type String struct { + name string + description string +} + +// NewString creates a new Key for int64 values. +func NewString(name, description string) *String { + return &String{name: name, description: description} +} + +func (k *String) Name() string { return k.name } +func (k *String) Description() string { return k.description } + +func (k *String) Append(buf []byte, l label.Label) []byte { + return strconv.AppendQuote(buf, k.From(l)) +} + +// Of creates a new Label with this key and the supplied value. +func (k *String) Of(v string) label.Label { return label.OfString(k, v) } + +// Get returns the label for the key of a label.Map. +func (k *String) Get(lm label.Map) string { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return "" +} + +// From returns the value of a Label. +func (k *String) From(t label.Label) string { return t.UnpackString() } + +// Error represents a key +type Error struct { + name string + description string +} + +// NewError returns a new [label.Key] for error values. +func NewError(name, description string) *Error { + return &Error{name: name, description: description} +} + +func (k *Error) Name() string { return k.name } +func (k *Error) Description() string { return k.description } + +func (k *Error) Append(buf []byte, l label.Label) []byte { + return append(buf, k.From(l).Error()...) +} + +// Of returns a new Label with this key and the supplied value. +func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) } + +// Get returns the label for the key of a label.Map. +func (k *Error) Get(lm label.Map) error { + if t := lm.Find(k); t.Valid() { + return k.From(t) + } + return nil +} + +// From returns the value of a Label. +func (k *Error) From(t label.Label) error { + err, _ := t.UnpackValue().(error) + return err +} diff --git a/vendor/golang.org/x/tools/internal/event/keys/standard.go b/vendor/golang.org/x/tools/internal/event/keys/standard.go new file mode 100644 index 0000000..7e95866 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/keys/standard.go @@ -0,0 +1,22 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package keys + +var ( + // Msg is a key used to add message strings to label lists. + Msg = NewString("message", "a readable message") + // Label is a key used to indicate an event adds labels to the context. + Label = NewTag("label", "a label context marker") + // Start is used for things like traces that have a name. + Start = NewString("start", "span start") + // Metric is a key used to indicate an event records metrics. + End = NewTag("end", "a span end marker") + // Metric is a key used to indicate an event records metrics. + Detach = NewTag("detach", "a span detach marker") + // Err is a key used to add error values to label lists. + Err = NewError("error", "an error that occurred") + // Metric is a key used to indicate an event records metrics. + Metric = NewTag("metric", "a metric event marker") +) diff --git a/vendor/golang.org/x/tools/internal/event/keys/util.go b/vendor/golang.org/x/tools/internal/event/keys/util.go new file mode 100644 index 0000000..c0e8e73 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/keys/util.go @@ -0,0 +1,21 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package keys + +import ( + "sort" + "strings" +) + +// Join returns a canonical join of the keys in S: +// a sorted comma-separated string list. +func Join[S ~[]T, T ~string](s S) string { + strs := make([]string, 0, len(s)) + for _, v := range s { + strs = append(strs, string(v)) + } + sort.Strings(strs) + return strings.Join(strs, ",") +} diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go new file mode 100644 index 0000000..e84226f --- /dev/null +++ b/vendor/golang.org/x/tools/internal/event/label/label.go @@ -0,0 +1,203 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package label + +import ( + "fmt" + "io" + "slices" + "unsafe" +) + +// Key is used as the identity of a Label. +// Keys are intended to be compared by pointer only, the name should be unique +// for communicating with external systems, but it is not required or enforced. +type Key interface { + // Name returns the key name. + Name() string + // Description returns a string that can be used to describe the value. + Description() string + // Append appends the formatted value of the label to the supplied buffer. + Append(buf []byte, l Label) []byte +} + +// Label holds a key and value pair. +// It is normally used when passing around lists of labels. +type Label struct { + key Key + packed uint64 + untyped any +} + +// Map is the interface to a collection of Labels indexed by key. +type Map interface { + // Find returns the label that matches the supplied key. + Find(key Key) Label +} + +// List is the interface to something that provides an iterable +// list of labels. +// Iteration should start from 0 and continue until Valid returns false. +type List interface { + // Valid returns true if the index is within range for the list. + // It does not imply the label at that index will itself be valid. + Valid(index int) bool + // Label returns the label at the given index. + Label(index int) Label +} + +// list implements LabelList for a list of Labels. +type list struct { + labels []Label +} + +// filter wraps a LabelList filtering out specific labels. +type filter struct { + keys []Key + underlying List +} + +// listMap implements LabelMap for a simple list of labels. +type listMap struct { + labels []Label +} + +// mapChain implements LabelMap for a list of underlying LabelMap. +type mapChain struct { + maps []Map +} + +// OfValue creates a new label from the key and value. +// This method is for implementing new key types, label creation should +// normally be done with the Of method of the key. +func OfValue(k Key, value any) Label { return Label{key: k, untyped: value} } + +// UnpackValue assumes the label was built using LabelOfValue and returns the value +// that was passed to that constructor. +// This method is for implementing new key types, for type safety normal +// access should be done with the From method of the key. +func (t Label) UnpackValue() any { return t.untyped } + +// Of64 creates a new label from a key and a uint64. This is often +// used for non uint64 values that can be packed into a uint64. +// This method is for implementing new key types, label creation should +// normally be done with the Of method of the key. +func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} } + +// Unpack64 assumes the label was built using LabelOf64 and returns the value that +// was passed to that constructor. +// This method is for implementing new key types, for type safety normal +// access should be done with the From method of the key. +func (t Label) Unpack64() uint64 { return t.packed } + +type stringptr unsafe.Pointer + +// OfString creates a new label from a key and a string. +// This method is for implementing new key types, label creation should +// normally be done with the Of method of the key. +func OfString(k Key, v string) Label { + return Label{ + key: k, + packed: uint64(len(v)), + untyped: stringptr(unsafe.StringData(v)), + } +} + +// UnpackString assumes the label was built using LabelOfString and returns the +// value that was passed to that constructor. +// This method is for implementing new key types, for type safety normal +// access should be done with the From method of the key. +func (t Label) UnpackString() string { + return unsafe.String((*byte)(t.untyped.(stringptr)), int(t.packed)) +} + +// Valid returns true if the Label is a valid one (it has a key). +func (t Label) Valid() bool { return t.key != nil } + +// Key returns the key of this Label. +func (t Label) Key() Key { return t.key } + +// Format is used for debug printing of labels. +func (t Label) Format(f fmt.State, r rune) { + if !t.Valid() { + io.WriteString(f, `nil`) + return + } + io.WriteString(f, t.Key().Name()) + io.WriteString(f, "=") + f.Write(t.Key().Append(nil, t)) // ignore error +} + +func (l *list) Valid(index int) bool { + return index >= 0 && index < len(l.labels) +} + +func (l *list) Label(index int) Label { + return l.labels[index] +} + +func (f *filter) Valid(index int) bool { + return f.underlying.Valid(index) +} + +func (f *filter) Label(index int) Label { + l := f.underlying.Label(index) + if slices.Contains(f.keys, l.Key()) { + return Label{} + } + return l +} + +func (lm listMap) Find(key Key) Label { + for _, l := range lm.labels { + if l.Key() == key { + return l + } + } + return Label{} +} + +func (c mapChain) Find(key Key) Label { + for _, src := range c.maps { + l := src.Find(key) + if l.Valid() { + return l + } + } + return Label{} +} + +var emptyList = &list{} + +func NewList(labels ...Label) List { + if len(labels) == 0 { + return emptyList + } + return &list{labels: labels} +} + +func Filter(l List, keys ...Key) List { + if len(keys) == 0 { + return l + } + return &filter{keys: keys, underlying: l} +} + +func NewMap(labels ...Label) Map { + return listMap{labels: labels} +} + +func MergeMaps(srcs ...Map) Map { + var nonNil []Map + for _, src := range srcs { + if src != nil { + nonNil = append(nonNil, src) + } + } + if len(nonNil) == 1 { + return nonNil[0] + } + return mapChain{maps: nonNil} +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/internal/gcimporter/bimport.go new file mode 100644 index 0000000..3fca56c --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/bimport.go @@ -0,0 +1,90 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file contains the remaining vestiges of +// $GOROOT/src/go/internal/gcimporter/bimport.go. + +package gcimporter + +import ( + "fmt" + "go/token" + "go/types" + "sync" + // This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps. +) + +func errorf(format string, args ...any) { + panic(fmt.Sprintf(format, args...)) +} + +const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go + +// Synthesize a token.Pos +type fakeFileSet struct { + fset *token.FileSet + files map[string]*fileInfo +} + +type fileInfo struct { + file *token.File + lastline int +} + +const maxlines = 64 * 1024 + +func (s *fakeFileSet) pos(file string, line, column int) token.Pos { + _ = column // TODO(mdempsky): Make use of column. + + // Since we don't know the set of needed file positions, we reserve maxlines + // positions per file. We delay calling token.File.SetLines until all + // positions have been calculated (by way of fakeFileSet.setLines), so that + // we can avoid setting unnecessary lines. See also golang/go#46586. + f := s.files[file] + if f == nil { + f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)} + s.files[file] = f + } + if line > maxlines { + line = 1 + } + if line > f.lastline { + f.lastline = line + } + + // Return a fake position assuming that f.file consists only of newlines. + return token.Pos(f.file.Base() + line - 1) +} + +func (s *fakeFileSet) setLines() { + fakeLinesOnce.Do(func() { + fakeLines = make([]int, maxlines) + for i := range fakeLines { + fakeLines[i] = i + } + }) + for _, f := range s.files { + f.file.SetLines(fakeLines[:f.lastline]) + } +} + +var ( + fakeLines []int + fakeLinesOnce sync.Once +) + +func chanDir(d int) types.ChanDir { + // tag values must match the constants in cmd/compile/internal/gc/go.go + switch d { + case 1 /* Crecv */ : + return types.RecvOnly + case 2 /* Csend */ : + return types.SendOnly + case 3 /* Cboth */ : + return types.SendRecv + default: + errorf("unexpected channel dir %d", d) + return 0 + } +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go new file mode 100644 index 0000000..885369d --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go @@ -0,0 +1,422 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file should be kept in sync with $GOROOT/src/internal/exportdata/exportdata.go. +// This file also additionally implements FindExportData for gcexportdata.NewReader. + +package gcimporter + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "go/build" + "io" + "os" + "os/exec" + "path/filepath" + "strings" + "sync" + // This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps. +) + +// FindExportData positions the reader r at the beginning of the +// export data section of an underlying cmd/compile created archive +// file by reading from it. The reader must be positioned at the +// start of the file before calling this function. +// This returns the length of the export data in bytes. +// +// This function is needed by [gcexportdata.Read], which must +// accept inputs produced by the last two releases of cmd/compile, +// plus tip. +func FindExportData(r *bufio.Reader) (size int64, err error) { + arsize, err := FindPackageDefinition(r) + if err != nil { + return + } + size = int64(arsize) + + objapi, headers, err := ReadObjectHeaders(r) + if err != nil { + return + } + size -= int64(len(objapi)) + for _, h := range headers { + size -= int64(len(h)) + } + + // Check for the binary export data section header "$$B\n". + // TODO(taking): Unify with ReadExportDataHeader so that it stops at the 'u' instead of reading + line, err := r.ReadSlice('\n') + if err != nil { + return + } + hdr := string(line) + if hdr != "$$B\n" { + err = fmt.Errorf("unknown export data header: %q", hdr) + return + } + size -= int64(len(hdr)) + + // For files with a binary export data header "$$B\n", + // these are always terminated by an end-of-section marker "\n$$\n". + // So the last bytes must always be this constant. + // + // The end-of-section marker is not a part of the export data itself. + // Do not include these in size. + // + // It would be nice to have sanity check that the final bytes after + // the export data are indeed the end-of-section marker. The split + // of gcexportdata.NewReader and gcexportdata.Read make checking this + // ugly so gcimporter gives up enforcing this. The compiler and go/types + // importer do enforce this, which seems good enough. + const endofsection = "\n$$\n" + size -= int64(len(endofsection)) + + if size < 0 { + err = fmt.Errorf("invalid size (%d) in the archive file: %d bytes remain without section headers (recompile package)", arsize, size) + return + } + + return +} + +// ReadUnified reads the contents of the unified export data from a reader r +// that contains the contents of a GC-created archive file. +// +// On success, the reader will be positioned after the end-of-section marker "\n$$\n". +// +// Supported GC-created archive files have 4 layers of nesting: +// - An archive file containing a package definition file. +// - The package definition file contains headers followed by a data section. +// Headers are lines (≤ 4kb) that do not start with "$$". +// - The data section starts with "$$B\n" followed by export data followed +// by an end of section marker "\n$$\n". (The section start "$$\n" is no +// longer supported.) +// - The export data starts with a format byte ('u') followed by the in +// the given format. (See ReadExportDataHeader for older formats.) +// +// Putting this together, the bytes in a GC-created archive files are expected +// to look like the following. +// See cmd/internal/archive for more details on ar file headers. +// +// | \n | ar file signature +// | __.PKGDEF...size...\n | ar header for __.PKGDEF including size. +// | go object <...>\n | objabi header +// | \n | other headers such as build id +// | $$B\n | binary format marker +// | u\n | unified export +// | $$\n | end-of-section marker +// | [optional padding] | padding byte (0x0A) if size is odd +// | [ar file header] | other ar files +// | [ar file data] | +func ReadUnified(r *bufio.Reader) (data []byte, err error) { + // We historically guaranteed headers at the default buffer size (4096) work. + // This ensures we can use ReadSlice throughout. + const minBufferSize = 4096 + r = bufio.NewReaderSize(r, minBufferSize) + + size, err := FindPackageDefinition(r) + if err != nil { + return + } + n := size + + objapi, headers, err := ReadObjectHeaders(r) + if err != nil { + return + } + n -= len(objapi) + for _, h := range headers { + n -= len(h) + } + + hdrlen, err := ReadExportDataHeader(r) + if err != nil { + return + } + n -= hdrlen + + // size also includes the end of section marker. Remove that many bytes from the end. + const marker = "\n$$\n" + n -= len(marker) + + if n < 0 { + err = fmt.Errorf("invalid size (%d) in the archive file: %d bytes remain without section headers (recompile package)", size, n) + return + } + + // Read n bytes from buf. + data = make([]byte, n) + _, err = io.ReadFull(r, data) + if err != nil { + return + } + + // Check for marker at the end. + var suffix [len(marker)]byte + _, err = io.ReadFull(r, suffix[:]) + if err != nil { + return + } + if s := string(suffix[:]); s != marker { + err = fmt.Errorf("read %q instead of end-of-section marker (%q)", s, marker) + return + } + + return +} + +// FindPackageDefinition positions the reader r at the beginning of a package +// definition file ("__.PKGDEF") within a GC-created archive by reading +// from it, and returns the size of the package definition file in the archive. +// +// The reader must be positioned at the start of the archive file before calling +// this function, and "__.PKGDEF" is assumed to be the first file in the archive. +// +// See cmd/internal/archive for details on the archive format. +func FindPackageDefinition(r *bufio.Reader) (size int, err error) { + // Uses ReadSlice to limit risk of malformed inputs. + + // Read first line to make sure this is an object file. + line, err := r.ReadSlice('\n') + if err != nil { + err = fmt.Errorf("can't find export data (%v)", err) + return + } + + // Is the first line an archive file signature? + if string(line) != "!\n" { + err = fmt.Errorf("not the start of an archive file (%q)", line) + return + } + + // package export block should be first + size = readArchiveHeader(r, "__.PKGDEF") + if size <= 0 { + err = fmt.Errorf("not a package file") + return + } + + return +} + +// ReadObjectHeaders reads object headers from the reader. Object headers are +// lines that do not start with an end-of-section marker "$$". The first header +// is the objabi header. On success, the reader will be positioned at the beginning +// of the end-of-section marker. +// +// It returns an error if any header does not fit in r.Size() bytes. +func ReadObjectHeaders(r *bufio.Reader) (objapi string, headers []string, err error) { + // line is a temporary buffer for headers. + // Use bounded reads (ReadSlice, Peek) to limit risk of malformed inputs. + var line []byte + + // objapi header should be the first line + if line, err = r.ReadSlice('\n'); err != nil { + err = fmt.Errorf("can't find export data (%v)", err) + return + } + objapi = string(line) + + // objapi header begins with "go object ". + if !strings.HasPrefix(objapi, "go object ") { + err = fmt.Errorf("not a go object file: %s", objapi) + return + } + + // process remaining object header lines + for { + // check for an end of section marker "$$" + line, err = r.Peek(2) + if err != nil { + return + } + if string(line) == "$$" { + return // stop + } + + // read next header + line, err = r.ReadSlice('\n') + if err != nil { + return + } + headers = append(headers, string(line)) + } +} + +// ReadExportDataHeader reads the export data header and format from r. +// It returns the number of bytes read, or an error if the format is no longer +// supported or it failed to read. +// +// The only currently supported format is binary export data in the +// unified export format. +func ReadExportDataHeader(r *bufio.Reader) (n int, err error) { + // Read export data header. + line, err := r.ReadSlice('\n') + if err != nil { + return + } + + hdr := string(line) + switch hdr { + case "$$\n": + err = fmt.Errorf("old textual export format no longer supported (recompile package)") + return + + case "$$B\n": + var format byte + format, err = r.ReadByte() + if err != nil { + return + } + // The unified export format starts with a 'u'. + switch format { + case 'u': + default: + // Older no longer supported export formats include: + // indexed export format which started with an 'i'; and + // the older binary export format which started with a 'c', + // 'd', or 'v' (from "version"). + err = fmt.Errorf("binary export format %q is no longer supported (recompile package)", format) + return + } + + default: + err = fmt.Errorf("unknown export data header: %q", hdr) + return + } + + n = len(hdr) + 1 // + 1 is for 'u' + return +} + +// FindPkg returns the filename and unique package id for an import +// path based on package information provided by build.Import (using +// the build.Default build.Context). A relative srcDir is interpreted +// relative to the current working directory. +// +// FindPkg is only used in tests within x/tools. +func FindPkg(path, srcDir string) (filename, id string, err error) { + // TODO(taking): Move internal/exportdata.FindPkg into its own file, + // and then this copy into a _test package. + if path == "" { + return "", "", errors.New("path is empty") + } + + var noext string + switch { + default: + // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" + // Don't require the source files to be present. + if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282 + srcDir = abs + } + var bp *build.Package + bp, err = build.Import(path, srcDir, build.FindOnly|build.AllowBinary) + if bp.PkgObj == "" { + if bp.Goroot && bp.Dir != "" { + filename, err = lookupGorootExport(bp.Dir) + if err == nil { + _, err = os.Stat(filename) + } + if err == nil { + return filename, bp.ImportPath, nil + } + } + goto notfound + } else { + noext = strings.TrimSuffix(bp.PkgObj, ".a") + } + id = bp.ImportPath + + case build.IsLocalImport(path): + // "./x" -> "/this/directory/x.ext", "/this/directory/x" + noext = filepath.Join(srcDir, path) + id = noext + + case filepath.IsAbs(path): + // for completeness only - go/build.Import + // does not support absolute imports + // "/x" -> "/x.ext", "/x" + noext = path + id = path + } + + if false { // for debugging + if path != id { + fmt.Printf("%s -> %s\n", path, id) + } + } + + // try extensions + for _, ext := range pkgExts { + filename = noext + ext + f, statErr := os.Stat(filename) + if statErr == nil && !f.IsDir() { + return filename, id, nil + } + if err == nil { + err = statErr + } + } + +notfound: + if err == nil { + return "", path, fmt.Errorf("can't find import: %q", path) + } + return "", path, fmt.Errorf("can't find import: %q: %w", path, err) +} + +var pkgExts = [...]string{".a", ".o"} // a file from the build cache will have no extension + +var exportMap sync.Map // package dir → func() (string, error) + +// lookupGorootExport returns the location of the export data +// (normally found in the build cache, but located in GOROOT/pkg +// in prior Go releases) for the package located in pkgDir. +// +// (We use the package's directory instead of its import path +// mainly to simplify handling of the packages in src/vendor +// and cmd/vendor.) +// +// lookupGorootExport is only used in tests within x/tools. +func lookupGorootExport(pkgDir string) (string, error) { + f, ok := exportMap.Load(pkgDir) + if !ok { + var ( + listOnce sync.Once + exportPath string + err error + ) + f, _ = exportMap.LoadOrStore(pkgDir, func() (string, error) { + listOnce.Do(func() { + cmd := exec.Command(filepath.Join(build.Default.GOROOT, "bin", "go"), "list", "-export", "-f", "{{.Export}}", pkgDir) + cmd.Dir = build.Default.GOROOT + cmd.Env = append(os.Environ(), "PWD="+cmd.Dir, "GOROOT="+build.Default.GOROOT) + var output []byte + output, err = cmd.Output() + if err != nil { + if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 { + err = errors.New(string(ee.Stderr)) + } + return + } + + exports := strings.Split(string(bytes.TrimSpace(output)), "\n") + if len(exports) != 1 { + err = fmt.Errorf("go list reported %d exports; expected 1", len(exports)) + return + } + + exportPath = exports[0] + }) + + return exportPath, err + }) + } + + return f.(func() (string, error))() +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go new file mode 100644 index 0000000..8c56f5d --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go @@ -0,0 +1,122 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file is a reduced copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go. + +// Package gcimporter provides various functions for reading +// gc-generated object files that can be used to implement the +// Importer interface defined by the Go 1.5 standard library package. +// +// The encoding is deterministic: if the encoder is applied twice to +// the same types.Package data structure, both encodings are equal. +// This property may be important to avoid spurious changes in +// applications such as build systems. +// +// However, the encoder is not necessarily idempotent. Importing an +// exported package may yield a types.Package that, while it +// represents the same set of Go types as the original, may differ in +// the details of its internal representation. Because of these +// differences, re-encoding the imported package may yield a +// different, but equally valid, encoding of the package. +package gcimporter // import "golang.org/x/tools/internal/gcimporter" + +import ( + "bufio" + "fmt" + "go/token" + "go/types" + "io" + "os" + // This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps. +) + +const ( + // Enable debug during development: it adds some additional checks, and + // prevents errors from being recovered. + debug = false + + // If trace is set, debugging output is printed to std out. + trace = false +) + +// Import imports a gc-generated package given its import path and srcDir, adds +// the corresponding package object to the packages map, and returns the object. +// The packages map must contain all packages already imported. +// +// Import is only used in tests. +func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) { + var rc io.ReadCloser + var id string + if lookup != nil { + // With custom lookup specified, assume that caller has + // converted path to a canonical import path for use in the map. + if path == "unsafe" { + return types.Unsafe, nil + } + id = path + + // No need to re-import if the package was imported completely before. + if pkg = packages[id]; pkg != nil && pkg.Complete() { + return + } + f, err := lookup(path) + if err != nil { + return nil, err + } + rc = f + } else { + var filename string + filename, id, err = FindPkg(path, srcDir) + if filename == "" { + if path == "unsafe" { + return types.Unsafe, nil + } + return nil, err + } + + // no need to re-import if the package was imported completely before + if pkg = packages[id]; pkg != nil && pkg.Complete() { + return + } + + // open file + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer func() { + if err != nil { + // add file name to error + err = fmt.Errorf("%s: %v", filename, err) + } + }() + rc = f + } + defer rc.Close() + + buf := bufio.NewReader(rc) + peek, err := buf.Peek(1) + if err != nil { + return + } + if peek[0] == 'i' { + var data []byte // avoid redeclaring err + data, err = io.ReadAll(buf) + if err != nil { + return + } + pkg, err = IImportData(fset, packages, data[1:], path) + return + } + data, err := ReadUnified(buf) + if err != nil { + err = fmt.Errorf("import %q: %v", path, err) + return + } + + // unified: emitted by cmd/compile since go1.20. + _, pkg, err = UImportData(fset, packages, data, id) + + return +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go new file mode 100644 index 0000000..c9468fc --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go @@ -0,0 +1,1576 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Indexed package export. +// +// The indexed export data format is an evolution of the previous +// binary export data format. Its chief contribution is introducing an +// index table, which allows efficient random access of individual +// declarations and inline function bodies. In turn, this allows +// avoiding unnecessary work for compilation units that import large +// packages. +// +// +// The top-level data format is structured as: +// +// Header struct { +// Tag byte // 'i' +// Version uvarint +// StringSize uvarint +// DataSize uvarint +// } +// +// Strings [StringSize]byte +// Data [DataSize]byte +// +// MainIndex []struct{ +// PkgPath stringOff +// PkgName stringOff +// PkgHeight uvarint +// +// Decls []struct{ +// Name stringOff +// Offset declOff +// } +// } +// +// Fingerprint [8]byte +// +// uvarint means a uint64 written out using uvarint encoding. +// +// []T means a uvarint followed by that many T objects. In other +// words: +// +// Len uvarint +// Elems [Len]T +// +// stringOff means a uvarint that indicates an offset within the +// Strings section. At that offset is another uvarint, followed by +// that many bytes, which form the string value. +// +// declOff means a uvarint that indicates an offset within the Data +// section where the associated declaration can be found. +// +// +// There are five kinds of declarations, distinguished by their first +// byte: +// +// type Var struct { +// Tag byte // 'V' +// Pos Pos +// Type typeOff +// } +// +// type Func struct { +// Tag byte // 'F' or 'G' +// Pos Pos +// TypeParams []typeOff // only present if Tag == 'G' +// Signature Signature +// } +// +// type Const struct { +// Tag byte // 'C' +// Pos Pos +// Value Value +// } +// +// type Type struct { +// Tag byte // 'T' or 'U' +// Pos Pos +// TypeParams []typeOff // only present if Tag == 'U' +// Underlying typeOff +// +// Methods []struct{ // omitted if Underlying is an interface type +// Pos Pos +// Name stringOff +// Recv Param +// Signature Signature +// } +// } +// +// type Alias struct { +// Tag byte // 'A' or 'B' +// Pos Pos +// TypeParams []typeOff // only present if Tag == 'B' +// Type typeOff +// } +// +// // "Automatic" declaration of each typeparam +// type TypeParam struct { +// Tag byte // 'P' +// Pos Pos +// Implicit bool +// Constraint typeOff +// } +// +// typeOff means a uvarint that either indicates a predeclared type, +// or an offset into the Data section. If the uvarint is less than +// predeclReserved, then it indicates the index into the predeclared +// types list (see predeclared in bexport.go for order). Otherwise, +// subtracting predeclReserved yields the offset of a type descriptor. +// +// Value means a type, kind, and type-specific value. See +// (*exportWriter).value for details. +// +// +// There are twelve kinds of type descriptors, distinguished by an itag: +// +// type DefinedType struct { +// Tag itag // definedType +// Name stringOff +// PkgPath stringOff +// } +// +// type PointerType struct { +// Tag itag // pointerType +// Elem typeOff +// } +// +// type SliceType struct { +// Tag itag // sliceType +// Elem typeOff +// } +// +// type ArrayType struct { +// Tag itag // arrayType +// Len uint64 +// Elem typeOff +// } +// +// type ChanType struct { +// Tag itag // chanType +// Dir uint64 // 1 RecvOnly; 2 SendOnly; 3 SendRecv +// Elem typeOff +// } +// +// type MapType struct { +// Tag itag // mapType +// Key typeOff +// Elem typeOff +// } +// +// type FuncType struct { +// Tag itag // signatureType +// PkgPath stringOff +// Signature Signature +// } +// +// type StructType struct { +// Tag itag // structType +// PkgPath stringOff +// Fields []struct { +// Pos Pos +// Name stringOff +// Type typeOff +// Embedded bool +// Note stringOff +// } +// } +// +// type InterfaceType struct { +// Tag itag // interfaceType +// PkgPath stringOff +// Embeddeds []struct { +// Pos Pos +// Type typeOff +// } +// Methods []struct { +// Pos Pos +// Name stringOff +// Signature Signature +// } +// } +// +// // Reference to a type param declaration +// type TypeParamType struct { +// Tag itag // typeParamType +// Name stringOff +// PkgPath stringOff +// } +// +// // Instantiation of a generic type (like List[T2] or List[int]) +// type InstanceType struct { +// Tag itag // instanceType +// Pos pos +// TypeArgs []typeOff +// BaseType typeOff +// } +// +// type UnionType struct { +// Tag itag // interfaceType +// Terms []struct { +// tilde bool +// Type typeOff +// } +// } +// +// +// +// type Signature struct { +// Params []Param +// Results []Param +// Variadic bool // omitted if Results is empty +// } +// +// type Param struct { +// Pos Pos +// Name stringOff +// Type typOff +// } +// +// +// Pos encodes a file:line:column triple, incorporating a simple delta +// encoding scheme within a data object. See exportWriter.pos for +// details. + +package gcimporter + +import ( + "bytes" + "encoding/binary" + "fmt" + "go/constant" + "go/token" + "go/types" + "io" + "math/big" + "reflect" + "slices" + "sort" + "strconv" + "strings" + + "golang.org/x/tools/go/types/objectpath" + // This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps. +) + +// IExportShallow encodes "shallow" export data for the specified package. +// +// For types, we use "shallow" export data. Historically, the Go +// compiler always produced a summary of the types for a given package +// that included types from other packages that it indirectly +// referenced: "deep" export data. This had the advantage that the +// compiler (and analogous tools such as gopls) need only load one +// file per direct import. However, it meant that the files tended to +// get larger based on the level of the package in the import +// graph. For example, higher-level packages in the kubernetes module +// have over 1MB of "deep" export data, even when they have almost no +// content of their own, merely because they mention a major type that +// references many others. In pathological cases the export data was +// 300x larger than the source for a package due to this quadratic +// growth. +// +// "Shallow" export data means that the serialized types describe only +// a single package. If those types mention types from other packages, +// the type checker may need to request additional packages beyond +// just the direct imports. Type information for the entire transitive +// closure of imports is provided (lazily) by the DAG. +// +// No promises are made about the encoding other than that it can be decoded by +// the same version of IIExportShallow. If you plan to save export data in the +// file system, be sure to include a cryptographic digest of the executable in +// the key to avoid version skew. +// +// If the provided reportf func is non-nil, it is used for reporting +// bugs (e.g. recovered panics) encountered during export, enabling us +// to obtain via telemetry the stack that would otherwise be lost by +// merely returning an error. +func IExportShallow(fset *token.FileSet, pkg *types.Package, reportf ReportFunc) ([]byte, error) { + // In principle this operation can only fail if out.Write fails, + // but that's impossible for bytes.Buffer---and as a matter of + // fact iexportCommon doesn't even check for I/O errors. + // TODO(adonovan): handle I/O errors properly. + // TODO(adonovan): use byte slices throughout, avoiding copying. + const shallow = true + var out bytes.Buffer + err := iexportCommon(&out, fset, shallow, iexportVersion, []*types.Package{pkg}, reportf) + return out.Bytes(), err +} + +// IImportShallow decodes "shallow" types.Package data encoded by +// [IExportShallow] in the same executable. This function cannot import data +// from cmd/compile or gcexportdata.Write. +// +// The importer calls getPackages to obtain package symbols for all +// packages mentioned in the export data, including the one being +// decoded. +// +// If the provided reportf func is non-nil, it will be used for reporting bugs +// encountered during import. +// TODO(rfindley): remove reportf when we are confident enough in the new +// objectpath encoding. +func IImportShallow(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, path string, reportf ReportFunc) (*types.Package, error) { + const shallow = true + pkgs, err := iimportCommon(fset, getPackages, data, path, shallow, reportf) + if err != nil { + return nil, err + } + return pkgs[0], nil +} + +// ReportFunc is the type of a function used to report formatted bugs. +type ReportFunc = func(string, ...any) + +// IExportData writes indexed export data for pkg to out. +// +// If no file set is provided, position info will be missing. +// The package path of the top-level package will not be recorded, +// so that calls to IImportData can override with a provided package path. +func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error { + const shallow = false + return iexportCommon(out, fset, shallow, iexportVersion, []*types.Package{pkg}, nil) +} + +func iexportCommon(out io.Writer, fset *token.FileSet, shallow bool, version int, pkgs []*types.Package, reportf ReportFunc) (err error) { + if !debug { + defer func() { + if e := recover(); e != nil { + // Report the stack via telemetry (see #71067). + if reportf != nil { + reportf("panic in exporter") + } + if ierr, ok := e.(internalError); ok { + // internalError usually means we exported a + // bad go/types data structure: a violation + // of an implicit precondition of Export. + err = ierr + return + } + // Not an internal error; panic again. + panic(e) + } + }() + } + + p := iexporter{ + fset: fset, + version: version, + shallow: shallow, + allPkgs: map[*types.Package]bool{}, + stringIndex: map[string]uint64{}, + declIndex: map[types.Object]uint64{}, + tparamNames: map[types.Object]string{}, + typIndex: map[types.Type]uint64{}, + localpkg: pkgs[0], + } + + for i, pt := range predeclared() { + p.typIndex[pt] = uint64(i) + } + if len(p.typIndex) > predeclReserved { + panic(internalErrorf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)) + } + + // Initialize work queue with exported declarations. + for _, pkg := range pkgs { + scope := pkg.Scope() + for _, name := range scope.Names() { + if token.IsExported(name) { + p.pushDecl(scope.Lookup(name)) + } + } + } + + // Loop until no more work. + for !p.declTodo.empty() { + p.doDecl(p.declTodo.popHead()) + } + + // Produce index of offset of each file record in files. + var files intWriter + var fileOffset []uint64 // fileOffset[i] is offset in files of file encoded as i + if p.shallow { + fileOffset = make([]uint64, len(p.fileInfos)) + for i, info := range p.fileInfos { + fileOffset[i] = uint64(files.Len()) + p.encodeFile(&files, info.file, info.needed) + } + } + + // Append indices to data0 section. + dataLen := uint64(p.data0.Len()) + w := p.newWriter() + w.writeIndex(p.declIndex) + w.flush() + + // Assemble header. + var hdr intWriter + hdr.uint64(uint64(p.version)) + hdr.uint64(uint64(p.strings.Len())) + if p.shallow { + hdr.uint64(uint64(files.Len())) + hdr.uint64(uint64(len(fileOffset))) + for _, offset := range fileOffset { + hdr.uint64(offset) + } + } + hdr.uint64(dataLen) + + // Flush output. + io.Copy(out, &hdr) + io.Copy(out, &p.strings) + if p.shallow { + io.Copy(out, &files) + } + io.Copy(out, &p.data0) + + return nil +} + +// encodeFile writes to w a representation of the file sufficient to +// faithfully restore position information about all needed offsets. +// Mutates the needed array. +func (p *iexporter) encodeFile(w *intWriter, file *token.File, needed []uint64) { + _ = needed[0] // precondition: needed is non-empty + + w.uint64(p.stringOff(file.Name())) + + size := uint64(file.Size()) + w.uint64(size) + + // Sort the set of needed offsets. Duplicates are harmless. + slices.Sort(needed) + + lines := file.Lines() // byte offset of each line start + w.uint64(uint64(len(lines))) + + // Rather than record the entire array of line start offsets, + // we save only a sparse list of (index, offset) pairs for + // the start of each line that contains a needed position. + var sparse [][2]int // (index, offset) pairs +outer: + for i, lineStart := range lines { + lineEnd := size + if i < len(lines)-1 { + lineEnd = uint64(lines[i+1]) + } + // Does this line contains a needed offset? + if needed[0] < lineEnd { + sparse = append(sparse, [2]int{i, lineStart}) + for needed[0] < lineEnd { + needed = needed[1:] + if len(needed) == 0 { + break outer + } + } + } + } + + // Delta-encode the columns. + w.uint64(uint64(len(sparse))) + var prev [2]int + for _, pair := range sparse { + w.uint64(uint64(pair[0] - prev[0])) + w.uint64(uint64(pair[1] - prev[1])) + prev = pair + } +} + +// writeIndex writes out an object index. mainIndex indicates whether +// we're writing out the main index, which is also read by +// non-compiler tools and includes a complete package description +// (i.e., name and height). +func (w *exportWriter) writeIndex(index map[types.Object]uint64) { + type pkgObj struct { + obj types.Object + name string // qualified name; differs from obj.Name for type params + } + // Build a map from packages to objects from that package. + pkgObjs := map[*types.Package][]pkgObj{} + + // For the main index, make sure to include every package that + // we reference, even if we're not exporting (or reexporting) + // any symbols from it. + if w.p.localpkg != nil { + pkgObjs[w.p.localpkg] = nil + } + for pkg := range w.p.allPkgs { + pkgObjs[pkg] = nil + } + + for obj := range index { + name := w.p.exportName(obj) + pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name}) + } + + var pkgs []*types.Package + for pkg, objs := range pkgObjs { + pkgs = append(pkgs, pkg) + + sort.Slice(objs, func(i, j int) bool { + return objs[i].name < objs[j].name + }) + } + + sort.Slice(pkgs, func(i, j int) bool { + return w.exportPath(pkgs[i]) < w.exportPath(pkgs[j]) + }) + + w.uint64(uint64(len(pkgs))) + for _, pkg := range pkgs { + w.string(w.exportPath(pkg)) + w.string(pkg.Name()) + w.uint64(uint64(0)) // package height is not needed for go/types + + objs := pkgObjs[pkg] + w.uint64(uint64(len(objs))) + for _, obj := range objs { + w.string(obj.name) + w.uint64(index[obj.obj]) + } + } +} + +// exportName returns the 'exported' name of an object. It differs from +// obj.Name() only for type parameters (see tparamExportName for details). +func (p *iexporter) exportName(obj types.Object) (res string) { + if name := p.tparamNames[obj]; name != "" { + return name + } + return obj.Name() +} + +type iexporter struct { + fset *token.FileSet + version int + + shallow bool // don't put types from other packages in the index + objEncoder *objectpath.Encoder // encodes objects from other packages in shallow mode; lazily allocated + localpkg *types.Package + + // allPkgs tracks all packages that have been referenced by + // the export data, so we can ensure to include them in the + // main index. + allPkgs map[*types.Package]bool + + declTodo objQueue + + strings intWriter + stringIndex map[string]uint64 + + // In shallow mode, object positions are encoded as (file, offset). + // Each file is recorded as a line-number table. + // Only the lines of needed positions are saved faithfully. + fileInfo map[*token.File]uint64 // value is index in fileInfos + fileInfos []*filePositions + + data0 intWriter + declIndex map[types.Object]uint64 + tparamNames map[types.Object]string // typeparam->exported name + typIndex map[types.Type]uint64 + + indent int // for tracing support +} + +type filePositions struct { + file *token.File + needed []uint64 // unordered list of needed file offsets +} + +func (p *iexporter) trace(format string, args ...any) { + if !trace { + // Call sites should also be guarded, but having this check here allows + // easily enabling/disabling debug trace statements. + return + } + fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) +} + +// objectpathEncoder returns the lazily allocated objectpath.Encoder to use +// when encoding objects in other packages during shallow export. +// +// Using a shared Encoder amortizes some of cost of objectpath search. +func (p *iexporter) objectpathEncoder() *objectpath.Encoder { + if p.objEncoder == nil { + p.objEncoder = new(objectpath.Encoder) + } + return p.objEncoder +} + +// stringOff returns the offset of s within the string section. +// If not already present, it's added to the end. +func (p *iexporter) stringOff(s string) uint64 { + off, ok := p.stringIndex[s] + if !ok { + off = uint64(p.strings.Len()) + p.stringIndex[s] = off + + p.strings.uint64(uint64(len(s))) + p.strings.WriteString(s) + } + return off +} + +// fileIndexAndOffset returns the index of the token.File and the byte offset of pos within it. +func (p *iexporter) fileIndexAndOffset(file *token.File, pos token.Pos) (uint64, uint64) { + index, ok := p.fileInfo[file] + if !ok { + index = uint64(len(p.fileInfo)) + p.fileInfos = append(p.fileInfos, &filePositions{file: file}) + if p.fileInfo == nil { + p.fileInfo = make(map[*token.File]uint64) + } + p.fileInfo[file] = index + } + // Record each needed offset. + info := p.fileInfos[index] + offset := uint64(file.Offset(pos)) + info.needed = append(info.needed, offset) + + return index, offset +} + +// pushDecl adds n to the declaration work queue, if not already present. +func (p *iexporter) pushDecl(obj types.Object) { + // Package unsafe is known to the compiler and predeclared. + // Caller should not ask us to do export it. + if obj.Pkg() == types.Unsafe { + panic("cannot export package unsafe") + } + + // Shallow export data: don't index decls from other packages. + if p.shallow && obj.Pkg() != p.localpkg { + return + } + + if _, ok := p.declIndex[obj]; ok { + return + } + + p.declIndex[obj] = ^uint64(0) // mark obj present in work queue + p.declTodo.pushTail(obj) +} + +// exportWriter handles writing out individual data section chunks. +type exportWriter struct { + p *iexporter + + data intWriter + prevFile string + prevLine int64 + prevColumn int64 +} + +func (w *exportWriter) exportPath(pkg *types.Package) string { + if pkg == w.p.localpkg { + return "" + } + return pkg.Path() +} + +func (p *iexporter) doDecl(obj types.Object) { + if trace { + p.trace("exporting decl %v (%T)", obj, obj) + p.indent++ + defer func() { + p.indent-- + p.trace("=> %s", obj) + }() + } + w := p.newWriter() + + switch obj := obj.(type) { + case *types.Var: + w.tag(varTag) + w.pos(obj.Pos()) + w.typ(obj.Type(), obj.Pkg()) + + case *types.Func: + sig := obj.Type().(*types.Signature) + if sig.Recv() != nil { + // We shouldn't see methods in the package scope, + // but the type checker may repair "func () F() {}" + // to "func (Invalid) F()" and then treat it like "func F()", + // so allow that. See golang/go#57729. + if sig.Recv().Type() != types.Typ[types.Invalid] { + panic(internalErrorf("unexpected method: %v", sig)) + } + } + + // Function. + if sig.TypeParams().Len() == 0 { + w.tag(funcTag) + } else { + w.tag(genericFuncTag) + } + w.pos(obj.Pos()) + // The tparam list of the function type is the declaration of the type + // params. So, write out the type params right now. Then those type params + // will be referenced via their type offset (via typOff) in all other + // places in the signature and function where they are used. + // + // While importing the type parameters, tparamList computes and records + // their export name, so that it can be later used when writing the index. + if tparams := sig.TypeParams(); tparams.Len() > 0 { + w.tparamList(obj.Name(), tparams, obj.Pkg()) + } + w.signature(sig) + + case *types.Const: + w.tag(constTag) + w.pos(obj.Pos()) + w.value(obj.Type(), obj.Val(), obj.Pkg()) + + case *types.TypeName: + t := obj.Type() + + if tparam, ok := types.Unalias(t).(*types.TypeParam); ok { + w.tag(typeParamTag) + w.pos(obj.Pos()) + constraint := tparam.Constraint() + if p.version >= iexportVersionGo1_18 { + implicit := false + if iface, _ := types.Unalias(constraint).(*types.Interface); iface != nil { + implicit = iface.IsImplicit() + } + w.bool(implicit) + } + w.typ(constraint, obj.Pkg()) + break + } + + if obj.IsAlias() { + alias, materialized := t.(*types.Alias) // perhaps false for certain built-ins? + + var tparams *types.TypeParamList + if materialized { + tparams = alias.TypeParams() + } + if tparams.Len() == 0 { + w.tag(aliasTag) + } else { + w.tag(genericAliasTag) + } + w.pos(obj.Pos()) + if tparams.Len() > 0 { + w.tparamList(obj.Name(), tparams, obj.Pkg()) + } + if materialized { + // Preserve materialized aliases, + // even of non-exported types. + t = alias.Rhs() + } + w.typ(t, obj.Pkg()) + break + } + + // Defined type. + named, ok := t.(*types.Named) + if !ok { + panic(internalErrorf("%s is not a defined type", t)) + } + + if named.TypeParams().Len() == 0 { + w.tag(typeTag) + } else { + w.tag(genericTypeTag) + } + w.pos(obj.Pos()) + + if named.TypeParams().Len() > 0 { + // While importing the type parameters, tparamList computes and records + // their export name, so that it can be later used when writing the index. + w.tparamList(obj.Name(), named.TypeParams(), obj.Pkg()) + } + + underlying := named.Underlying() + w.typ(underlying, obj.Pkg()) + + if types.IsInterface(t) { + break + } + + n := named.NumMethods() + w.uint64(uint64(n)) + for i := range n { + m := named.Method(i) + w.pos(m.Pos()) + w.string(m.Name()) + sig := m.Type().(*types.Signature) + if w.p.version >= iexportVersionGenericMethods && w.bool(sig.TypeParams().Len() > 0) { + w.tparamList(obj.Name()+"."+m.Name(), sig.TypeParams(), obj.Pkg()) + } + + // Receiver type parameters are type arguments of the receiver type, so + // their name must be qualified before exporting recv. + if rparams := sig.RecvTypeParams(); rparams.Len() > 0 { + prefix := obj.Name() + "." + m.Name() + for rparam := range rparams.TypeParams() { + name := tparamExportName(prefix, rparam) + w.p.tparamNames[rparam.Obj()] = name + } + } + w.param(sig.Recv()) + w.signature(sig) + } + + default: + panic(internalErrorf("unexpected object: %v", obj)) + } + + p.declIndex[obj] = w.flush() +} + +func (w *exportWriter) tag(tag byte) { + w.data.WriteByte(tag) +} + +func (w *exportWriter) pos(pos token.Pos) { + if w.p.shallow { + w.posV2(pos) + } else if w.p.version >= iexportVersionPosCol { + w.posV1(pos) + } else { + w.posV0(pos) + } +} + +// posV2 encoding (used only in shallow mode) records positions as +// (file, offset), where file is the index in the token.File table +// (which records the file name and newline offsets) and offset is a +// byte offset. It effectively ignores //line directives. +func (w *exportWriter) posV2(pos token.Pos) { + if pos == token.NoPos { + w.uint64(0) + return + } + file := w.p.fset.File(pos) // fset must be non-nil + index, offset := w.p.fileIndexAndOffset(file, pos) + w.uint64(1 + index) + w.uint64(offset) +} + +func (w *exportWriter) posV1(pos token.Pos) { + if w.p.fset == nil { + w.int64(0) + return + } + + p := w.p.fset.Position(pos) + file := p.Filename + line := int64(p.Line) + column := int64(p.Column) + + deltaColumn := (column - w.prevColumn) << 1 + deltaLine := (line - w.prevLine) << 1 + + if file != w.prevFile { + deltaLine |= 1 + } + if deltaLine != 0 { + deltaColumn |= 1 + } + + w.int64(deltaColumn) + if deltaColumn&1 != 0 { + w.int64(deltaLine) + if deltaLine&1 != 0 { + w.string(file) + } + } + + w.prevFile = file + w.prevLine = line + w.prevColumn = column +} + +func (w *exportWriter) posV0(pos token.Pos) { + if w.p.fset == nil { + w.int64(0) + return + } + + p := w.p.fset.Position(pos) + file := p.Filename + line := int64(p.Line) + + // When file is the same as the last position (common case), + // we can save a few bytes by delta encoding just the line + // number. + // + // Note: Because data objects may be read out of order (or not + // at all), we can only apply delta encoding within a single + // object. This is handled implicitly by tracking prevFile and + // prevLine as fields of exportWriter. + + if file == w.prevFile { + delta := line - w.prevLine + w.int64(delta) + if delta == deltaNewFile { + w.int64(-1) + } + } else { + w.int64(deltaNewFile) + w.int64(line) // line >= 0 + w.string(file) + w.prevFile = file + } + w.prevLine = line +} + +func (w *exportWriter) pkg(pkg *types.Package) { + if pkg == nil { + // [exportWriter.typ] accepts a nil pkg only for types + // of constants, which cannot contain named objects + // such as fields or methods and thus should never + // reach this method (#76222). + panic("nil package") + } + // Ensure any referenced packages are declared in the main index. + w.p.allPkgs[pkg] = true + + w.string(w.exportPath(pkg)) +} + +func (w *exportWriter) qualifiedType(obj *types.TypeName) { + name := w.p.exportName(obj) + + // Ensure any referenced declarations are written out too. + w.p.pushDecl(obj) + w.string(name) + w.pkg(obj.Pkg()) +} + +// typ emits the specified type. +// +// Objects within the type (struct fields and interface methods) are +// qualified by pkg. +func (w *exportWriter) typ(t types.Type, pkg *types.Package) { + if pkg == nil { + pkg = w.p.localpkg + } + w.data.uint64(w.p.typOff(t, pkg)) +} + +func (p *iexporter) newWriter() *exportWriter { + return &exportWriter{p: p} +} + +func (w *exportWriter) flush() uint64 { + off := uint64(w.p.data0.Len()) + io.Copy(&w.p.data0, &w.data) + return off +} + +func (p *iexporter) typOff(t types.Type, pkg *types.Package) uint64 { + off, ok := p.typIndex[t] + if !ok { + w := p.newWriter() + w.doTyp(t, pkg) + off = predeclReserved + w.flush() + p.typIndex[t] = off + } + return off +} + +func (w *exportWriter) startType(k itag) { + w.data.uint64(uint64(k)) +} + +// doTyp is the implementation of [exportWriter.typ]. +func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { + if trace { + w.p.trace("exporting type %s (%T)", t, t) + w.p.indent++ + defer func() { + w.p.indent-- + w.p.trace("=> %s", t) + }() + } + switch t := t.(type) { + case *types.Alias: + if targs := t.TypeArgs(); targs.Len() > 0 { + w.startType(instanceType) + w.pos(t.Obj().Pos()) + w.typeList(targs, pkg) + w.typ(t.Origin(), pkg) + return + } + w.startType(aliasType) + w.qualifiedType(t.Obj()) + + case *types.Named: + if targs := t.TypeArgs(); targs.Len() > 0 { + w.startType(instanceType) + // TODO(rfindley): investigate if this position is correct, and if it + // matters. + w.pos(t.Obj().Pos()) + w.typeList(targs, pkg) + w.typ(t.Origin(), pkg) + return + } + w.startType(definedType) + w.qualifiedType(t.Obj()) + + case *types.TypeParam: + w.startType(typeParamType) + w.qualifiedType(t.Obj()) + + case *types.Pointer: + w.startType(pointerType) + w.typ(t.Elem(), pkg) + + case *types.Slice: + w.startType(sliceType) + w.typ(t.Elem(), pkg) + + case *types.Array: + w.startType(arrayType) + w.uint64(uint64(t.Len())) + w.typ(t.Elem(), pkg) + + case *types.Chan: + w.startType(chanType) + // 1 RecvOnly; 2 SendOnly; 3 SendRecv + var dir uint64 + switch t.Dir() { + case types.RecvOnly: + dir = 1 + case types.SendOnly: + dir = 2 + case types.SendRecv: + dir = 3 + } + w.uint64(dir) + w.typ(t.Elem(), pkg) + + case *types.Map: + w.startType(mapType) + w.typ(t.Key(), pkg) + w.typ(t.Elem(), pkg) + + case *types.Signature: + w.startType(signatureType) + w.pkg(pkg) // qualifies param/result vars + w.signature(t) + + case *types.Struct: + w.startType(structType) + n := t.NumFields() + // Even for struct{} we must emit some qualifying package, because that's + // what the compiler does, and thus that's what the importer expects. + fieldPkg := pkg + if n > 0 { + fieldPkg = t.Field(0).Pkg() + } + if fieldPkg == nil { + // TODO(rfindley): improve this very hacky logic. + // + // The importer expects a package to be set for all struct types, even + // those with no fields. A better encoding might be to set NumFields + // before pkg. setPkg panics with a nil package, which may be possible + // to reach with invalid packages (and perhaps valid packages, too?), so + // (arbitrarily) set the localpkg if available. + // + // Alternatively, we may be able to simply guarantee that pkg != nil, by + // reconsidering the encoding of constant values. + if w.p.shallow { + fieldPkg = w.p.localpkg + } else { + panic(internalErrorf("no package to set for empty struct")) + } + } + w.pkg(fieldPkg) + w.uint64(uint64(n)) + + for i := range n { + f := t.Field(i) + if w.p.shallow { + w.objectPath(f) + } + w.pos(f.Pos()) + w.string(f.Name()) // unexported fields implicitly qualified by prior setPkg + w.typ(f.Type(), fieldPkg) + w.bool(f.Anonymous()) + w.string(t.Tag(i)) // note (or tag) + } + + case *types.Interface: + w.startType(interfaceType) + w.pkg(pkg) // qualifies unexported method funcs + + n := t.NumEmbeddeds() + w.uint64(uint64(n)) + for i := 0; i < n; i++ { + ft := t.EmbeddedType(i) + if named, _ := types.Unalias(ft).(*types.Named); named != nil { + w.pos(named.Obj().Pos()) + } else { + // e.g. ~int + w.pos(token.NoPos) + } + w.typ(ft, pkg) + } + + // See comment for struct fields. In shallow mode we change the encoding + // for interface methods that are promoted from other packages. + + n = t.NumExplicitMethods() + w.uint64(uint64(n)) + for i := 0; i < n; i++ { + m := t.ExplicitMethod(i) + if w.p.shallow { + w.objectPath(m) + } + w.pos(m.Pos()) + w.string(m.Name()) + sig := m.Type().(*types.Signature) + w.signature(sig) + } + + case *types.Union: + w.startType(unionType) + nt := t.Len() + w.uint64(uint64(nt)) + for i := range nt { + term := t.Term(i) + w.bool(term.Tilde()) + w.typ(term.Type(), pkg) + } + + default: + panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t))) + } +} + +// objectPath writes the package and objectPath to use to look up obj in a +// different package, when encoding in "shallow" mode. +// +// When doing a shallow import, the importer creates only the local package, +// and requests package symbols for dependencies from the client. +// However, certain types defined in the local package may hold objects defined +// (perhaps deeply) within another package. +// +// For example, consider the following: +// +// package a +// func F() chan * map[string] struct { X int } +// +// package b +// import "a" +// var B = a.F() +// +// In this example, the type of b.B holds fields defined in package a. +// In order to have the correct canonical objects for the field defined in the +// type of B, they are encoded as objectPaths and later looked up in the +// importer. The same problem applies to interface methods. +func (w *exportWriter) objectPath(obj types.Object) { + if obj.Pkg() == nil || obj.Pkg() == w.p.localpkg { + // obj.Pkg() may be nil for the builtin error.Error. + // In this case, or if obj is declared in the local package, no need to + // encode. + w.string("") + return + } + objectPath, err := w.p.objectpathEncoder().For(obj) + if err != nil { + // Fall back to the empty string, which will cause the importer to create a + // new object, which matches earlier behavior. Creating a new object is + // sufficient for many purposes (such as type checking), but causes certain + // references algorithms to fail (golang/go#60819). However, we didn't + // notice this problem during months of gopls@v0.12.0 testing. + // + // TODO(golang/go#61674): this workaround is insufficient, as in the case + // where the field forwarded from an instantiated type that may not appear + // in the export data of the original package: + // + // // package a + // type A[P any] struct{ F P } + // + // // package b + // type B a.A[int] + // + // We need to update references algorithms not to depend on this + // de-duplication, at which point we may want to simply remove the + // workaround here. + w.string("") + return + } + w.string(string(objectPath)) + w.pkg(obj.Pkg()) +} + +func (w *exportWriter) signature(sig *types.Signature) { + w.paramList(sig.Params()) + w.paramList(sig.Results()) + if sig.Params().Len() > 0 { + w.bool(sig.Variadic()) + } +} + +func (w *exportWriter) typeList(ts *types.TypeList, pkg *types.Package) { + w.uint64(uint64(ts.Len())) + for t := range ts.Types() { + w.typ(t, pkg) + } +} + +func (w *exportWriter) tparamList(prefix string, list *types.TypeParamList, pkg *types.Package) { + ll := uint64(list.Len()) + w.uint64(ll) + for tparam := range list.TypeParams() { + // Set the type parameter exportName before exporting its type. + exportName := tparamExportName(prefix, tparam) + w.p.tparamNames[tparam.Obj()] = exportName + w.typ(tparam, pkg) + } +} + +const blankMarker = "$" + +// tparamExportName returns the 'exported' name of a type parameter, which +// differs from its actual object name: it is prefixed with a qualifier, and +// blank type parameter names are disambiguated by their index in the type +// parameter list. +func tparamExportName(prefix string, tparam *types.TypeParam) string { + assert(prefix != "") + name := tparam.Obj().Name() + if name == "_" { + name = blankMarker + strconv.Itoa(tparam.Index()) + } + return prefix + "." + name +} + +// tparamName returns the real name of a type parameter, after stripping its +// qualifying prefix and reverting blank-name encoding. See tparamExportName +// for details. +func tparamName(exportName string) string { + // Remove the "path" from the type param name that makes it unique. + ix := strings.LastIndex(exportName, ".") + if ix < 0 { + errorf("malformed type parameter export name %s: missing prefix", exportName) + } + name := exportName[ix+1:] + if strings.HasPrefix(name, blankMarker) { + return "_" + } + return name +} + +func (w *exportWriter) paramList(tup *types.Tuple) { + n := tup.Len() + w.uint64(uint64(n)) + for i := range n { + w.param(tup.At(i)) + } +} + +func (w *exportWriter) param(obj types.Object) { + w.pos(obj.Pos()) + w.localIdent(obj) + w.typ(obj.Type(), obj.Pkg()) +} + +// only called for constants +func (w *exportWriter) value(typ types.Type, v constant.Value, pkg *types.Package) { + if pkg == nil { + pkg = w.p.localpkg + } + w.typ(typ, pkg) + if w.p.version >= iexportVersionGo1_18 { + w.int64(int64(v.Kind())) + } + + if v.Kind() == constant.Unknown { + // golang/go#60605: treat unknown constant values as if they have invalid type + // + // This loses some fidelity over the package type-checked from source, but that + // is acceptable. + // + // TODO(rfindley): we should switch on the recorded constant kind rather + // than the constant type + return + } + + switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { + case types.IsBoolean: + w.bool(constant.BoolVal(v)) + case types.IsInteger: + var i big.Int + if i64, exact := constant.Int64Val(v); exact { + i.SetInt64(i64) + } else if ui64, exact := constant.Uint64Val(v); exact { + i.SetUint64(ui64) + } else { + i.SetString(v.ExactString(), 10) + } + w.mpint(&i, typ) + case types.IsFloat: + f := constantToFloat(v) + w.mpfloat(f, typ) + case types.IsComplex: + w.mpfloat(constantToFloat(constant.Real(v)), typ) + w.mpfloat(constantToFloat(constant.Imag(v)), typ) + case types.IsString: + w.string(constant.StringVal(v)) + default: + if b.Kind() == types.Invalid { + // package contains type errors + break + } + panic(internalErrorf("unexpected type %v (%v)", typ, typ.Underlying())) + } +} + +// constantToFloat converts a constant.Value with kind constant.Float to a +// big.Float. +func constantToFloat(x constant.Value) *big.Float { + x = constant.ToFloat(x) + // Use the same floating-point precision (512) as cmd/compile + // (see Mpprec in cmd/compile/internal/gc/mpfloat.go). + const mpprec = 512 + var f big.Float + f.SetPrec(mpprec) + if v, exact := constant.Float64Val(x); exact { + // float64 + f.SetFloat64(v) + } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int { + // TODO(gri): add big.Rat accessor to constant.Value. + n := valueToRat(num) + d := valueToRat(denom) + f.SetRat(n.Quo(n, d)) + } else { + // Value too large to represent as a fraction => inaccessible. + // TODO(gri): add big.Float accessor to constant.Value. + _, ok := f.SetString(x.ExactString()) + assert(ok) + } + return &f +} + +func valueToRat(x constant.Value) *big.Rat { + // Convert little-endian to big-endian. + // I can't believe this is necessary. + bytes := constant.Bytes(x) + for i := 0; i < len(bytes)/2; i++ { + bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i] + } + return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes)) +} + +// mpint exports a multi-precision integer. +// +// For unsigned types, small values are written out as a single +// byte. Larger values are written out as a length-prefixed big-endian +// byte string, where the length prefix is encoded as its complement. +// For example, bytes 0, 1, and 2 directly represent the integer +// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-, +// 2-, and 3-byte big-endian string follow. +// +// Encoding for signed types use the same general approach as for +// unsigned types, except small values use zig-zag encoding and the +// bottom bit of length prefix byte for large values is reserved as a +// sign bit. +// +// The exact boundary between small and large encodings varies +// according to the maximum number of bytes needed to encode a value +// of type typ. As a special case, 8-bit types are always encoded as a +// single byte. +// +// TODO(mdempsky): Is this level of complexity really worthwhile? +func (w *exportWriter) mpint(x *big.Int, typ types.Type) { + basic, ok := typ.Underlying().(*types.Basic) + if !ok { + panic(internalErrorf("unexpected type %v (%T)", typ.Underlying(), typ.Underlying())) + } + + signed, maxBytes := intSize(basic) + + negative := x.Sign() < 0 + if !signed && negative { + panic(internalErrorf("negative unsigned integer; type %v, value %v", typ, x)) + } + + b := x.Bytes() + if len(b) > 0 && b[0] == 0 { + panic(internalErrorf("leading zeros")) + } + if uint(len(b)) > maxBytes { + panic(internalErrorf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)) + } + + maxSmall := 256 - maxBytes + if signed { + maxSmall = 256 - 2*maxBytes + } + if maxBytes == 1 { + maxSmall = 256 + } + + // Check if x can use small value encoding. + if len(b) <= 1 { + var ux uint + if len(b) == 1 { + ux = uint(b[0]) + } + if signed { + ux <<= 1 + if negative { + ux-- + } + } + if ux < maxSmall { + w.data.WriteByte(byte(ux)) + return + } + } + + n := 256 - uint(len(b)) + if signed { + n = 256 - 2*uint(len(b)) + if negative { + n |= 1 + } + } + if n < maxSmall || n >= 256 { + panic(internalErrorf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)) + } + + w.data.WriteByte(byte(n)) + w.data.Write(b) +} + +// mpfloat exports a multi-precision floating point number. +// +// The number's value is decomposed into mantissa × 2**exponent, where +// mantissa is an integer. The value is written out as mantissa (as a +// multi-precision integer) and then the exponent, except exponent is +// omitted if mantissa is zero. +func (w *exportWriter) mpfloat(f *big.Float, typ types.Type) { + if f.IsInf() { + panic("infinite constant") + } + + // Break into f = mant × 2**exp, with 0.5 <= mant < 1. + var mant big.Float + exp := int64(f.MantExp(&mant)) + + // Scale so that mant is an integer. + prec := mant.MinPrec() + mant.SetMantExp(&mant, int(prec)) + exp -= int64(prec) + + manti, acc := mant.Int(nil) + if acc != big.Exact { + panic(internalErrorf("mantissa scaling failed for %f (%s)", f, acc)) + } + w.mpint(manti, typ) + if manti.Sign() != 0 { + w.int64(exp) + } +} + +func (w *exportWriter) bool(b bool) bool { + var x uint64 + if b { + x = 1 + } + w.uint64(x) + return b +} + +func (w *exportWriter) int64(x int64) { w.data.int64(x) } +func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) } +func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) } + +func (w *exportWriter) localIdent(obj types.Object) { + // Anonymous parameters. + if obj == nil { + w.string("") + return + } + + name := obj.Name() + if name == "_" { + w.string("_") + return + } + + w.string(name) +} + +type intWriter struct { + bytes.Buffer +} + +func (w *intWriter) int64(x int64) { + var buf [binary.MaxVarintLen64]byte + n := binary.PutVarint(buf[:], x) + w.Write(buf[:n]) +} + +func (w *intWriter) uint64(x uint64) { + var buf [binary.MaxVarintLen64]byte + n := binary.PutUvarint(buf[:], x) + w.Write(buf[:n]) +} + +func assert(cond bool) { + if !cond { + panic("internal error: assertion failed") + } +} + +// The below is copied from go/src/cmd/compile/internal/gc/syntax.go. + +// objQueue is a FIFO queue of types.Object. The zero value of objQueue is +// a ready-to-use empty queue. +type objQueue struct { + ring []types.Object + head, tail int +} + +// empty returns true if q contains no Nodes. +func (q *objQueue) empty() bool { + return q.head == q.tail +} + +// pushTail appends n to the tail of the queue. +func (q *objQueue) pushTail(obj types.Object) { + if len(q.ring) == 0 { + q.ring = make([]types.Object, 16) + } else if q.head+len(q.ring) == q.tail { + // Grow the ring. + nring := make([]types.Object, len(q.ring)*2) + // Copy the old elements. + part := q.ring[q.head%len(q.ring):] + if q.tail-q.head <= len(part) { + part = part[:q.tail-q.head] + copy(nring, part) + } else { + pos := copy(nring, part) + copy(nring[pos:], q.ring[:q.tail%len(q.ring)]) + } + q.ring, q.head, q.tail = nring, 0, q.tail-q.head + } + + q.ring[q.tail%len(q.ring)] = obj + q.tail++ +} + +// popHead pops a node from the head of the queue. It panics if q is empty. +func (q *objQueue) popHead() types.Object { + if q.empty() { + panic("dequeue empty") + } + obj := q.ring[q.head%len(q.ring)] + q.head++ + return obj +} + +// internalError represents an error generated inside this package. +type internalError string + +func (e internalError) Error() string { return "gcimporter: " + string(e) } + +// TODO(adonovan): make this call panic, so that it's symmetric with errorf. +// Otherwise it's easy to forget to do anything with the error. +// +// TODO(adonovan): also, consider switching the names "errorf" and +// "internalErrorf" as the former is used for bugs, whose cause is +// internal inconsistency, whereas the latter is used for ordinary +// situations like bad input, whose cause is external. +func internalErrorf(format string, args ...any) error { + return internalError(fmt.Sprintf(format, args...)) +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go new file mode 100644 index 0000000..5999072 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go @@ -0,0 +1,1092 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Indexed package import. +// See iexport.go for the export data format. + +package gcimporter + +import ( + "bytes" + "encoding/binary" + "fmt" + "go/constant" + "go/token" + "go/types" + "io" + "math/big" + "slices" + "sort" + "strings" + + "golang.org/x/tools/go/types/objectpath" + // This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps. +) + +type intReader struct { + *bytes.Reader + path string +} + +func (r *intReader) uint64() uint64 { + i, err := binary.ReadUvarint(r.Reader) + if err != nil { + errorf("import %q: read varint error: %v", r.path, err) + } + return i +} + +// Keep this in sync with constants in iexport.go. +const ( + iexportVersionGo1_11 = 0 + iexportVersionPosCol = 1 + iexportVersionGo1_18 = 2 + iexportVersionGenerics = 2 + iexportVersionGenericMethods = 3 + iexportVersion = iexportVersionGenericMethods + + iexportVersionCurrent = 3 +) + +type ident struct { + pkg *types.Package + name string +} + +const predeclReserved = 32 + +type itag uint64 + +const ( + // Types + definedType itag = iota + pointerType + sliceType + arrayType + chanType + mapType + signatureType + structType + interfaceType + typeParamType + instanceType + unionType + aliasType +) + +// Object tags +const ( + varTag = 'V' + funcTag = 'F' + genericFuncTag = 'G' + constTag = 'C' + aliasTag = 'A' + genericAliasTag = 'B' + typeParamTag = 'P' + typeTag = 'T' + genericTypeTag = 'U' +) + +// IImportData imports a package from the serialized package data +// and returns 0 and a reference to the package. +// If the export data version is not recognized or the format is otherwise +// compromised, an error is returned. +func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (*types.Package, error) { + pkgs, err := iimportCommon(fset, GetPackagesFromMap(imports), data, path, false, nil) + if err != nil { + return nil, err + } + return pkgs[0], nil +} + +// A GetPackagesFunc function obtains the non-nil symbols for a set of +// packages, creating and recursively importing them as needed. An +// implementation should store each package symbol is in the Pkg +// field of the items array. +// +// Any error causes importing to fail. This can be used to quickly read +// the import manifest of an export data file without fully decoding it. +type GetPackagesFunc = func(items []GetPackagesItem) error + +// A GetPackagesItem is a request from the importer for the package +// symbol of the specified name and path. +type GetPackagesItem struct { + Name, Path string + Pkg *types.Package // to be filled in by GetPackagesFunc call + + // private importer state + pathOffset uint64 + nameIndex map[string]uint64 +} + +// GetPackagesFromMap returns a GetPackagesFunc that retrieves +// packages from the given map of package path to package. +// +// The returned function may mutate m: each requested package that is not +// found is created with types.NewPackage and inserted into m. +func GetPackagesFromMap(m map[string]*types.Package) GetPackagesFunc { + return func(items []GetPackagesItem) error { + for i, item := range items { + pkg, ok := m[item.Path] + if !ok { + pkg = types.NewPackage(item.Path, item.Name) + m[item.Path] = pkg + } + items[i].Pkg = pkg + } + return nil + } +} + +func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, path string, shallow bool, reportf ReportFunc) (pkgs []*types.Package, err error) { + const currentVersion = iexportVersionCurrent + version := int64(-1) + if !debug { + defer func() { + if e := recover(); e != nil { + if version > currentVersion { + err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) + } else { + err = fmt.Errorf("internal error while importing %q (%v); please report an issue", path, e) + } + } + }() + } + + r := &intReader{bytes.NewReader(data), path} + + version = int64(r.uint64()) + switch version { + case iexportVersionGenericMethods, iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11: + default: + if version > iexportVersionGenericMethods { + errorf("unstable iexport format version %d, just rebuild compiler and std library", version) + } else { + errorf("unknown iexport format version %d", version) + } + } + + sLen := int64(r.uint64()) + var fLen int64 + var fileOffset []uint64 + if shallow { + // Shallow mode uses a different position encoding. + fLen = int64(r.uint64()) + fileOffset = make([]uint64, r.uint64()) + for i := range fileOffset { + fileOffset[i] = r.uint64() + } + } + dLen := int64(r.uint64()) + + whence, _ := r.Seek(0, io.SeekCurrent) + stringData := data[whence : whence+sLen] + fileData := data[whence+sLen : whence+sLen+fLen] + declData := data[whence+sLen+fLen : whence+sLen+fLen+dLen] + r.Seek(sLen+fLen+dLen, io.SeekCurrent) + + p := iimporter{ + version: int(version), + ipath: path, + shallow: shallow, + reportf: reportf, + + stringData: stringData, + stringCache: make(map[uint64]string), + fileOffset: fileOffset, + fileData: fileData, + fileCache: make([]*token.File, len(fileOffset)), + pkgCache: make(map[uint64]*types.Package), + + declData: declData, + pkgIndex: make(map[*types.Package]map[string]uint64), + typCache: make(map[uint64]types.Type), + // Separate map for typeparams, keyed by their package and unique + // name. + tparamIndex: make(map[ident]types.Type), + + fake: fakeFileSet{ + fset: fset, + files: make(map[string]*fileInfo), + }, + } + defer p.fake.setLines() // set lines for files in fset + + for i, pt := range predeclared() { + p.typCache[uint64(i)] = pt + } + + // Gather the relevant packages from the manifest. + items := make([]GetPackagesItem, r.uint64()) + uniquePkgPaths := make(map[string]bool) + for i := range items { + pkgPathOff := r.uint64() + pkgPath := p.stringAt(pkgPathOff) + pkgName := p.stringAt(r.uint64()) + _ = r.uint64() // package height; unused by go/types + + if pkgPath == "" { + pkgPath = path + } + items[i].Name = pkgName + items[i].Path = pkgPath + items[i].pathOffset = pkgPathOff + + // Read index for package. + nameIndex := make(map[string]uint64) + nSyms := r.uint64() + // In shallow mode, only the current package (i=0) has an index. + assert(!(shallow && i > 0 && nSyms != 0)) + for ; nSyms > 0; nSyms-- { + name := p.stringAt(r.uint64()) + nameIndex[name] = r.uint64() + } + + items[i].nameIndex = nameIndex + + uniquePkgPaths[pkgPath] = true + } + // Debugging #63822; hypothesis: there are duplicate PkgPaths. + if len(uniquePkgPaths) != len(items) { + reportf("found duplicate PkgPaths while reading export data manifest: %v", items) + } + + // Request packages all at once from the client, + // enabling a parallel implementation. + if err := getPackages(items); err != nil { + return nil, err // don't wrap this error + } + + // Check the results and complete the index. + pkgList := make([]*types.Package, len(items)) + for i, item := range items { + pkg := item.Pkg + if pkg == nil { + errorf("internal error: getPackages returned nil package for %q", item.Path) + } else if pkg.Path() != item.Path { + errorf("internal error: getPackages returned wrong path %q, want %q", pkg.Path(), item.Path) + } else if pkg.Name() != item.Name { + errorf("internal error: getPackages returned wrong name %s for package %q, want %s", pkg.Name(), item.Path, item.Name) + } + p.pkgCache[item.pathOffset] = pkg + p.pkgIndex[pkg] = item.nameIndex + pkgList[i] = pkg + } + + if len(pkgList) == 0 { + errorf("no packages found for %s", path) + panic("unreachable") + } + pkgs = pkgList[:1] + + // record all referenced packages as imports + list := slices.Clone(pkgList[1:]) + sort.Sort(byPath(list)) + pkgs[0].SetImports(list) + + for _, pkg := range pkgs { + if pkg.Complete() { + continue + } + + names := make([]string, 0, len(p.pkgIndex[pkg])) + for name := range p.pkgIndex[pkg] { + names = append(names, name) + } + sort.Strings(names) + for _, name := range names { + p.doDecl(pkg, name) + } + + // package was imported completely and without errors + pkg.MarkComplete() + } + + // SetConstraint can't be called if the constraint type is not yet complete. + // When type params are created in the typeParamTag case of (*importReader).obj(), + // the associated constraint type may not be complete due to recursion. + // Therefore, we defer calling SetConstraint there, and call it here instead + // after all types are complete. + for _, d := range p.later { + d.t.SetConstraint(d.constraint) + } + + for _, typ := range p.interfaceList { + typ.Complete() + } + + // Workaround for golang/go#61561. See the doc for instanceList for details. + for _, typ := range p.instanceList { + if iface, _ := typ.Underlying().(*types.Interface); iface != nil { + iface.Complete() + } + } + + return pkgs, nil +} + +type setConstraintArgs struct { + t *types.TypeParam + constraint types.Type +} + +type iimporter struct { + version int + ipath string + + shallow bool + reportf ReportFunc // if non-nil, used to report bugs + + stringData []byte + stringCache map[uint64]string + fileOffset []uint64 // fileOffset[i] is offset in fileData for info about file encoded as i + fileData []byte + fileCache []*token.File // memoized decoding of file encoded as i + pkgCache map[uint64]*types.Package + + declData []byte + pkgIndex map[*types.Package]map[string]uint64 + typCache map[uint64]types.Type + tparamIndex map[ident]types.Type + + fake fakeFileSet + interfaceList []*types.Interface + + // Workaround for the go/types bug golang/go#61561: instances produced during + // instantiation may contain incomplete interfaces. Here we only complete the + // underlying type of the instance, which is the most common case but doesn't + // handle parameterized interface literals defined deeper in the type. + instanceList []types.Type // instances for later completion (see golang/go#61561) + + // Arguments for calls to SetConstraint that are deferred due to recursive types + later []setConstraintArgs + + indent int // for tracing support +} + +func (p *iimporter) trace(format string, args ...any) { + if !trace { + // Call sites should also be guarded, but having this check here allows + // easily enabling/disabling debug trace statements. + return + } + fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) +} + +func (p *iimporter) doDecl(pkg *types.Package, name string) { + if debug { + p.trace("import decl %s", name) + p.indent++ + defer func() { + p.indent-- + p.trace("=> %s", name) + }() + } + // See if we've already imported this declaration. + if obj := pkg.Scope().Lookup(name); obj != nil { + return + } + + off, ok := p.pkgIndex[pkg][name] + if !ok { + // In deep mode, the index should be complete. In shallow + // mode, we should have already recursively loaded necessary + // dependencies so the above Lookup succeeds. + errorf("%v.%v not in index", pkg, name) + } + + r := &importReader{p: p} + r.declReader.Reset(p.declData[off:]) + + r.obj(pkg, name) +} + +func (p *iimporter) stringAt(off uint64) string { + if s, ok := p.stringCache[off]; ok { + return s + } + + slen, n := binary.Uvarint(p.stringData[off:]) + if n <= 0 { + errorf("varint failed") + } + spos := off + uint64(n) + s := string(p.stringData[spos : spos+slen]) + p.stringCache[off] = s + return s +} + +func (p *iimporter) fileAt(index uint64) *token.File { + file := p.fileCache[index] + if file == nil { + off := p.fileOffset[index] + file = p.decodeFile(intReader{bytes.NewReader(p.fileData[off:]), p.ipath}) + p.fileCache[index] = file + } + return file +} + +func (p *iimporter) decodeFile(rd intReader) *token.File { + filename := p.stringAt(rd.uint64()) + size := int(rd.uint64()) + file := p.fake.fset.AddFile(filename, -1, size) + + // SetLines requires a nondecreasing sequence. + // Because it is common for clients to derive the interval + // [start, start+len(name)] from a start position, and we + // want to ensure that the end offset is on the same line, + // we fill in the gaps of the sparse encoding with values + // that strictly increase by the largest possible amount. + // This allows us to avoid having to record the actual end + // offset of each needed line. + + lines := make([]int, int(rd.uint64())) + var index, offset int + for i, n := 0, int(rd.uint64()); i < n; i++ { + index += int(rd.uint64()) + offset += int(rd.uint64()) + lines[index] = offset + + // Ensure monotonicity between points. + for j := index - 1; j > 0 && lines[j] == 0; j-- { + lines[j] = lines[j+1] - 1 + } + } + + // Ensure monotonicity after last point. + for j := len(lines) - 1; j > 0 && lines[j] == 0; j-- { + size-- + lines[j] = size + } + + if !file.SetLines(lines) { + errorf("SetLines failed: %d", lines) // can't happen + } + return file +} + +func (p *iimporter) pkgAt(off uint64) *types.Package { + if pkg, ok := p.pkgCache[off]; ok { + return pkg + } + path := p.stringAt(off) + errorf("missing package %q in %q", path, p.ipath) + return nil +} + +func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { + if t, ok := p.typCache[off]; ok && canReuse(base, t) { + return t + } + + if off < predeclReserved { + errorf("predeclared type missing from cache: %v", off) + } + + r := &importReader{p: p} + r.declReader.Reset(p.declData[off-predeclReserved:]) + t := r.doType(base) + + if canReuse(base, t) { + p.typCache[off] = t + } + return t +} + +// canReuse reports whether the type rhs on the RHS of the declaration for def +// may be re-used. +// +// Specifically, if def is non-nil and rhs is an interface type with methods, it +// may not be re-used because we have a convention of setting the receiver type +// for interface methods to def. +func canReuse(def *types.Named, rhs types.Type) bool { + if def == nil { + return true + } + iface, _ := types.Unalias(rhs).(*types.Interface) + if iface == nil { + return true + } + // Don't use iface.Empty() here as iface may not be complete. + return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0 +} + +type importReader struct { + p *iimporter + declReader bytes.Reader + prevFile string + prevLine int64 + prevColumn int64 +} + +// markBlack is redefined in iimport_go123.go, to work around golang/go#69912. +// +// If TypeNames are not marked black (in the sense of go/types cycle +// detection), they may be mutated when dot-imported. Fix this by punching a +// hole through the type, when compiling with Go 1.23. (The bug has been fixed +// for 1.24, but the fix was not worth back-porting). +var markBlack = func(name *types.TypeName) {} + +// obj decodes and declares the package-level object denoted by (pkg, name). +func (r *importReader) obj(pkg *types.Package, name string) { + tag := r.byte() + pos := r.pos() + + switch tag { + case aliasTag, genericAliasTag: + var tparams []*types.TypeParam + if tag == genericAliasTag { + tparams = r.tparamList() + } + obj := types.NewTypeName(pos, pkg, name, nil) + types.NewAlias(obj, r.typ()).SetTypeParams(tparams) + markBlack(obj) // workaround for golang/go#69912 + r.declare(obj) + + case constTag: + typ, val := r.value() + + r.declare(types.NewConst(pos, pkg, name, typ, val)) + + case funcTag, genericFuncTag: + var tparams []*types.TypeParam + if tag == genericFuncTag { + tparams = r.tparamList() + } + sig := r.signature(pkg, nil, nil, tparams) + r.declare(types.NewFunc(pos, pkg, name, sig)) + + case typeTag, genericTypeTag: + // Types can be recursive. We need to setup a stub + // declaration before recursing. + obj := types.NewTypeName(pos, pkg, name, nil) + named := types.NewNamed(obj, nil, nil) + + markBlack(obj) // workaround for golang/go#69912 + + // Declare obj before calling r.tparamList, so the new type name is recognized + // if used in the constraint of one of its own typeparams (see #48280). + r.declare(obj) + if tag == genericTypeTag { + tparams := r.tparamList() + named.SetTypeParams(tparams) + } + + underlying := r.p.typAt(r.uint64(), named).Underlying() + named.SetUnderlying(underlying) + + if !isInterface(underlying) { + for n := r.uint64(); n > 0; n-- { + mpos := r.pos() + mname := r.ident() + var tpars []*types.TypeParam + if r.p.version >= iexportVersionGenericMethods && r.bool() { + tpars = r.tparamList() + } + recv := r.param(pkg) + + // If the receiver has any targs, set those as the + // rparams of the method (since those are the + // typeparams being used in the method sig/body). + // + // Avoid dependency on typesinternal.RecvBase here. + t := recv.Type() + if ptr, ok := types.Unalias(t).(*types.Pointer); ok { + t = ptr.Elem() + } + targs := types.Unalias(t).(*types.Named).TypeArgs() + var rparams []*types.TypeParam + if targs.Len() > 0 { + rparams = make([]*types.TypeParam, targs.Len()) + for i := range rparams { + rparams[i] = types.Unalias(targs.At(i)).(*types.TypeParam) + } + } + msig := r.signature(pkg, recv, rparams, tpars) + named.AddMethod(types.NewFunc(mpos, pkg, mname, msig)) + } + } + + case typeParamTag: + // We need to "declare" a typeparam in order to have a name that + // can be referenced recursively (if needed) in the type param's + // bound. + if r.p.version < iexportVersionGenerics { + errorf("unexpected type param type") + } + name0 := tparamName(name) + tn := types.NewTypeName(pos, pkg, name0, nil) + t := types.NewTypeParam(tn, nil) + + // To handle recursive references to the typeparam within its + // bound, save the partial type in tparamIndex before reading the bounds. + id := ident{pkg, name} + r.p.tparamIndex[id] = t + var implicit bool + if r.p.version >= iexportVersionGo1_18 { + implicit = r.bool() + } + constraint := r.typ() + if implicit { + iface, _ := types.Unalias(constraint).(*types.Interface) + if iface == nil { + errorf("non-interface constraint marked implicit") + } + iface.MarkImplicit() + } + // The constraint type may not be complete, if we + // are in the middle of a type recursion involving type + // constraints. So, we defer SetConstraint until we have + // completely set up all types in ImportData. + r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint}) + + case varTag: + typ := r.typ() + + v := types.NewVar(pos, pkg, name, typ) + v.SetKind(types.PackageVar) + r.declare(v) + + default: + errorf("unexpected tag: %v", tag) + } +} + +func (r *importReader) declare(obj types.Object) { + obj.Pkg().Scope().Insert(obj) +} + +func (r *importReader) value() (typ types.Type, val constant.Value) { + typ = r.typ() + if r.p.version >= iexportVersionGo1_18 { + // TODO: add support for using the kind. + _ = constant.Kind(r.int64()) + } + + switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { + case types.IsBoolean: + val = constant.MakeBool(r.bool()) + + case types.IsString: + val = constant.MakeString(r.string()) + + case types.IsInteger: + var x big.Int + r.mpint(&x, b) + val = constant.Make(&x) + + case types.IsFloat: + val = r.mpfloat(b) + + case types.IsComplex: + re := r.mpfloat(b) + im := r.mpfloat(b) + val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) + + default: + if b.Kind() == types.Invalid { + val = constant.MakeUnknown() + return + } + errorf("unexpected type %v", typ) // panics + panic("unreachable") + } + + return +} + +func intSize(b *types.Basic) (signed bool, maxBytes uint) { + if (b.Info() & types.IsUntyped) != 0 { + return true, 64 + } + + switch b.Kind() { + case types.Float32, types.Complex64: + return true, 3 + case types.Float64, types.Complex128: + return true, 7 + } + + signed = (b.Info() & types.IsUnsigned) == 0 + switch b.Kind() { + case types.Int8, types.Uint8: + maxBytes = 1 + case types.Int16, types.Uint16: + maxBytes = 2 + case types.Int32, types.Uint32: + maxBytes = 4 + default: + maxBytes = 8 + } + + return +} + +func (r *importReader) mpint(x *big.Int, typ *types.Basic) { + signed, maxBytes := intSize(typ) + + maxSmall := 256 - maxBytes + if signed { + maxSmall = 256 - 2*maxBytes + } + if maxBytes == 1 { + maxSmall = 256 + } + + n, _ := r.declReader.ReadByte() + if uint(n) < maxSmall { + v := int64(n) + if signed { + v >>= 1 + if n&1 != 0 { + v = ^v + } + } + x.SetInt64(v) + return + } + + v := -n + if signed { + v = -(n &^ 1) >> 1 + } + if v < 1 || uint(v) > maxBytes { + errorf("weird decoding: %v, %v => %v", n, signed, v) + } + b := make([]byte, v) + io.ReadFull(&r.declReader, b) + x.SetBytes(b) + if signed && n&1 != 0 { + x.Neg(x) + } +} + +func (r *importReader) mpfloat(typ *types.Basic) constant.Value { + var mant big.Int + r.mpint(&mant, typ) + var f big.Float + f.SetInt(&mant) + if f.Sign() != 0 { + f.SetMantExp(&f, int(r.int64())) + } + return constant.Make(&f) +} + +func (r *importReader) ident() string { + return r.string() +} + +func (r *importReader) qualifiedIdent() (*types.Package, string) { + name := r.string() + pkg := r.pkg() + return pkg, name +} + +func (r *importReader) pos() token.Pos { + if r.p.shallow { + // precise offsets are encoded only in shallow mode + return r.posv2() + } + if r.p.version >= iexportVersionPosCol { + r.posv1() + } else { + r.posv0() + } + + if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 { + return token.NoPos + } + return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn)) +} + +func (r *importReader) posv0() { + delta := r.int64() + if delta != deltaNewFile { + r.prevLine += delta + } else if l := r.int64(); l == -1 { + r.prevLine += deltaNewFile + } else { + r.prevFile = r.string() + r.prevLine = l + } +} + +func (r *importReader) posv1() { + delta := r.int64() + r.prevColumn += delta >> 1 + if delta&1 != 0 { + delta = r.int64() + r.prevLine += delta >> 1 + if delta&1 != 0 { + r.prevFile = r.string() + } + } +} + +func (r *importReader) posv2() token.Pos { + file := r.uint64() + if file == 0 { + return token.NoPos + } + tf := r.p.fileAt(file - 1) + return tf.Pos(int(r.uint64())) +} + +func (r *importReader) typ() types.Type { + return r.p.typAt(r.uint64(), nil) +} + +func isInterface(t types.Type) bool { + _, ok := types.Unalias(t).(*types.Interface) + return ok +} + +func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } +func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } + +func (r *importReader) doType(base *types.Named) (res types.Type) { + k := r.kind() + if debug { + r.p.trace("importing type %d (base: %v)", k, base) + r.p.indent++ + defer func() { + r.p.indent-- + r.p.trace("=> %s", res) + }() + } + switch k { + default: + errorf("unexpected kind tag in %q: %v", r.p.ipath, k) + return nil + + case aliasType, definedType: + pkg, name := r.qualifiedIdent() + r.p.doDecl(pkg, name) + return pkg.Scope().Lookup(name).(*types.TypeName).Type() + case pointerType: + return types.NewPointer(r.typ()) + case sliceType: + return types.NewSlice(r.typ()) + case arrayType: + n := r.uint64() + return types.NewArray(r.typ(), int64(n)) + case chanType: + dir := chanDir(int(r.uint64())) + return types.NewChan(dir, r.typ()) + case mapType: + return types.NewMap(r.typ(), r.typ()) + case signatureType: + paramPkg := r.pkg() + return r.signature(paramPkg, nil, nil, nil) + + case structType: + fieldPkg := r.pkg() + + fields := make([]*types.Var, r.uint64()) + tags := make([]string, len(fields)) + for i := range fields { + var field *types.Var + if r.p.shallow { + field, _ = r.objectPathObject().(*types.Var) + } + + fpos := r.pos() + fname := r.ident() + ftyp := r.typ() + emb := r.bool() + tag := r.string() + + // Either this is not a shallow import, the field is local, or the + // encoded objectPath failed to produce an object (a bug). + // + // Even in this last, buggy case, fall back on creating a new field. As + // discussed in iexport.go, this is not correct, but mostly works and is + // preferable to failing (for now at least). + if field == nil { + field = types.NewField(fpos, fieldPkg, fname, ftyp, emb) + } + + fields[i] = field + tags[i] = tag + } + return types.NewStruct(fields, tags) + + case interfaceType: + methodPkg := r.pkg() // qualifies methods and their param/result vars + + embeddeds := make([]types.Type, r.uint64()) + for i := range embeddeds { + _ = r.pos() + embeddeds[i] = r.typ() + } + + methods := make([]*types.Func, r.uint64()) + for i := range methods { + var method *types.Func + if r.p.shallow { + method, _ = r.objectPathObject().(*types.Func) + } + + mpos := r.pos() + mname := r.ident() + + // TODO(mdempsky): Matches bimport.go, but I + // don't agree with this. + var recv *types.Var + if base != nil { + recv = types.NewVar(token.NoPos, methodPkg, "", base) + } + msig := r.signature(methodPkg, recv, nil, nil) + + if method == nil { + method = types.NewFunc(mpos, methodPkg, mname, msig) + } + methods[i] = method + } + + typ := types.NewInterfaceType(methods, embeddeds) + r.p.interfaceList = append(r.p.interfaceList, typ) + return typ + + case typeParamType: + if r.p.version < iexportVersionGenerics { + errorf("unexpected type param type") + } + pkg, name := r.qualifiedIdent() + id := ident{pkg, name} + if t, ok := r.p.tparamIndex[id]; ok { + // We're already in the process of importing this typeparam. + return t + } + // Otherwise, import the definition of the typeparam now. + r.p.doDecl(pkg, name) + return r.p.tparamIndex[id] + + case instanceType: + if r.p.version < iexportVersionGenerics { + errorf("unexpected instantiation type") + } + // pos does not matter for instances: they are positioned on the original + // type. + _ = r.pos() + len := r.uint64() + targs := make([]types.Type, len) + for i := range targs { + targs[i] = r.typ() + } + baseType := r.typ() + // The imported instantiated type doesn't include any methods, so + // we must always use the methods of the base (orig) type. + // TODO provide a non-nil *Environment + t, _ := types.Instantiate(nil, baseType, targs, false) + + // Workaround for golang/go#61561. See the doc for instanceList for details. + r.p.instanceList = append(r.p.instanceList, t) + return t + + case unionType: + if r.p.version < iexportVersionGenerics { + errorf("unexpected instantiation type") + } + terms := make([]*types.Term, r.uint64()) + for i := range terms { + terms[i] = types.NewTerm(r.bool(), r.typ()) + } + return types.NewUnion(terms) + } +} + +func (r *importReader) kind() itag { + return itag(r.uint64()) +} + +// objectPathObject is the inverse of exportWriter.objectPath. +// +// In shallow mode, certain fields and methods may need to be looked up in an +// imported package. See the doc for exportWriter.objectPath for a full +// explanation. +func (r *importReader) objectPathObject() types.Object { + objPath := objectpath.Path(r.string()) + if objPath == "" { + return nil + } + pkg := r.pkg() + obj, err := objectpath.Object(pkg, objPath) + if err != nil { + if r.p.reportf != nil { + r.p.reportf("failed to find object for objectPath %q: %v", objPath, err) + } + } + return obj +} + +func (r *importReader) signature(paramPkg *types.Package, recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature { + params := r.paramList(paramPkg) + results := r.paramList(paramPkg) + variadic := params.Len() > 0 && r.bool() + return types.NewSignatureType(recv, rparams, tparams, params, results, variadic) +} + +func (r *importReader) tparamList() []*types.TypeParam { + n := r.uint64() + if n == 0 { + return nil + } + xs := make([]*types.TypeParam, n) + for i := range xs { + // Note: the standard library importer is tolerant of nil types here, + // though would panic in SetTypeParams. + xs[i] = types.Unalias(r.typ()).(*types.TypeParam) + } + return xs +} + +func (r *importReader) paramList(pkg *types.Package) *types.Tuple { + xs := make([]*types.Var, r.uint64()) + for i := range xs { + xs[i] = r.param(pkg) + } + return types.NewTuple(xs...) +} + +func (r *importReader) param(pkg *types.Package) *types.Var { + pos := r.pos() + name := r.ident() + typ := r.typ() + return types.NewParam(pos, pkg, name, typ) +} + +func (r *importReader) bool() bool { + return r.uint64() != 0 +} + +func (r *importReader) int64() int64 { + n, err := binary.ReadVarint(&r.declReader) + if err != nil { + errorf("readVarint: %v", err) + } + return n +} + +func (r *importReader) uint64() uint64 { + n, err := binary.ReadUvarint(&r.declReader) + if err != nil { + errorf("readUvarint: %v", err) + } + return n +} + +func (r *importReader) byte() byte { + x, err := r.declReader.ReadByte() + if err != nil { + errorf("declReader.ReadByte: %v", err) + } + return x +} + +type byPath []*types.Package + +func (a byPath) Len() int { return len(a) } +func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() } diff --git a/vendor/golang.org/x/tools/internal/gcimporter/predeclared.go b/vendor/golang.org/x/tools/internal/gcimporter/predeclared.go new file mode 100644 index 0000000..a8bfa87 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/predeclared.go @@ -0,0 +1,92 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gcimporter + +import ( + "go/types" + "sync" + // This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps. +) + +// predecl is a cache for the predeclared types in types.Universe. +// +// Cache a distinct result based on the runtime value of any. +// The pointer value of the any type varies based on GODEBUG settings. +var predeclMu sync.Mutex +var predecl map[types.Type][]types.Type + +func predeclared() []types.Type { + anyt := types.Universe.Lookup("any").Type() + + predeclMu.Lock() + defer predeclMu.Unlock() + + if pre, ok := predecl[anyt]; ok { + return pre + } + + if predecl == nil { + predecl = make(map[types.Type][]types.Type) + } + + decls := []types.Type{ // basic types + types.Typ[types.Bool], + types.Typ[types.Int], + types.Typ[types.Int8], + types.Typ[types.Int16], + types.Typ[types.Int32], + types.Typ[types.Int64], + types.Typ[types.Uint], + types.Typ[types.Uint8], + types.Typ[types.Uint16], + types.Typ[types.Uint32], + types.Typ[types.Uint64], + types.Typ[types.Uintptr], + types.Typ[types.Float32], + types.Typ[types.Float64], + types.Typ[types.Complex64], + types.Typ[types.Complex128], + types.Typ[types.String], + + // basic type aliases + types.Universe.Lookup("byte").Type(), + types.Universe.Lookup("rune").Type(), + + // error + types.Universe.Lookup("error").Type(), + + // untyped types + types.Typ[types.UntypedBool], + types.Typ[types.UntypedInt], + types.Typ[types.UntypedRune], + types.Typ[types.UntypedFloat], + types.Typ[types.UntypedComplex], + types.Typ[types.UntypedString], + types.Typ[types.UntypedNil], + + // package unsafe + types.Typ[types.UnsafePointer], + + // invalid type + types.Typ[types.Invalid], // only appears in packages with errors + + // used internally by gc; never used by this package or in .a files + anyType{}, + + // comparable + types.Universe.Lookup("comparable").Type(), + + // any + anyt, + } + + predecl[anyt] = decls + return decls +} + +type anyType struct{} + +func (t anyType) Underlying() types.Type { return t } +func (t anyType) String() string { return "any" } diff --git a/vendor/golang.org/x/tools/internal/gcimporter/support.go b/vendor/golang.org/x/tools/internal/gcimporter/support.go new file mode 100644 index 0000000..28b1769 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/support.go @@ -0,0 +1,31 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gcimporter + +import ( + "bufio" + "io" + "strconv" + "strings" + // This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps. +) + +// Copy of $GOROOT/src/cmd/internal/archive.ReadHeader. +func readArchiveHeader(b *bufio.Reader, name string) int { + // architecture-independent object file output + const HeaderSize = 60 + + var buf [HeaderSize]byte + if _, err := io.ReadFull(b, buf[:]); err != nil { + return -1 + } + aname := strings.Trim(string(buf[0:16]), " ") + if !strings.HasPrefix(aname, name) { + return -1 + } + asize := strings.Trim(string(buf[48:58]), " ") + i, _ := strconv.Atoi(asize) + return i +} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader.go new file mode 100644 index 0000000..09e833c --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gcimporter/ureader.go @@ -0,0 +1,853 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Derived from go/internal/gcimporter/ureader.go + +package gcimporter + +import ( + "fmt" + "go/token" + "go/types" + "sort" + "strings" + + "golang.org/x/tools/internal/pkgbits" + // This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps. +) + +// A pkgReader holds the shared state for reading a unified IR package +// description. +type pkgReader struct { + pkgbits.PkgDecoder + + fake fakeFileSet + + ctxt *types.Context + imports map[string]*types.Package // previously imported packages, indexed by path + + // lazily initialized arrays corresponding to the unified IR + // PosBase, Pkg, and Type sections, respectively. + posBases []string // position bases (i.e., file names) + pkgs []*types.Package + typs []types.Type + + // laterFns holds functions that need to be invoked at the end of + // import reading. + // + // TODO(mdempsky): Is it safe to have a single "later" slice or do + // we need to have multiple passes? See comments on CL 386002 and + // go.dev/issue/52104. + laterFns []func() + // laterFors is used in case of 'type A B' to ensure that B is processed before A. + laterFors map[types.Type]int + + // ifaces holds a list of constructed Interfaces, which need to have + // Complete called after importing is done. + ifaces []*types.Interface +} + +// later adds a function to be invoked at the end of import reading. +func (pr *pkgReader) later(fn func()) { + pr.laterFns = append(pr.laterFns, fn) +} + +// See cmd/compile/internal/noder.derivedInfo. +type derivedInfo struct { + idx pkgbits.Index +} + +// See cmd/compile/internal/noder.typeInfo. +type typeInfo struct { + idx pkgbits.Index + derived bool +} + +func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + if !debug { + defer func() { + if x := recover(); x != nil { + err = fmt.Errorf("internal error in importing %q (%v); please report an issue", path, x) + } + }() + } + + s := string(data) + input := pkgbits.NewPkgDecoder(path, s) + pkg = readUnifiedPackage(fset, nil, imports, input) + return +} + +// laterFor adds a function to be invoked at the end of import reading, and records the type that function is finishing. +func (pr *pkgReader) laterFor(t types.Type, fn func()) { + if pr.laterFors == nil { + pr.laterFors = make(map[types.Type]int) + } + pr.laterFors[t] = len(pr.laterFns) + pr.laterFns = append(pr.laterFns, fn) +} + +// readUnifiedPackage reads a package description from the given +// unified IR export data decoder. +func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package { + pr := pkgReader{ + PkgDecoder: input, + + fake: fakeFileSet{ + fset: fset, + files: make(map[string]*fileInfo), + }, + + ctxt: ctxt, + imports: imports, + + posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)), + pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)), + typs: make([]types.Type, input.NumElems(pkgbits.RelocType)), + } + defer pr.fake.setLines() + + r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) + pkg := r.pkg() + if r.Version().Has(pkgbits.HasInit) { + r.Bool() + } + + for i, n := 0, r.Len(); i < n; i++ { + // As if r.obj(), but avoiding the Scope.Lookup call, + // to avoid eager loading of imports. + r.Sync(pkgbits.SyncObject) + if r.Version().Has(pkgbits.DerivedFuncInstance) { + assert(!r.Bool()) + } + r.p.objIdx(r.Reloc(pkgbits.RelocObj)) + assert(r.Len() == 0) + } + + r.Sync(pkgbits.SyncEOF) + + for _, fn := range pr.laterFns { + fn() + } + + for _, iface := range pr.ifaces { + iface.Complete() + } + + // Imports() of pkg are all of the transitive packages that were loaded. + var imps []*types.Package + for _, imp := range pr.pkgs { + if imp != nil && imp != pkg { + imps = append(imps, imp) + } + } + sort.Sort(byPath(imps)) + pkg.SetImports(imps) + + pkg.MarkComplete() + return pkg +} + +// A reader holds the state for reading a single unified IR element +// within a package. +type reader struct { + pkgbits.Decoder + + p *pkgReader + + dict *readerDict +} + +// A readerDict holds the state for type parameters that parameterize +// the current unified IR element. +type readerDict struct { + rtbounds []typeInfo // contains constraint types for each parameter in rtparams + rtparams []*types.TypeParam // contains receiver type parameters for an element + + tbounds []typeInfo // contains constraint types for each parameter in tparams + tparams []*types.TypeParam // contains type parameters for an element + + // derived is a slice of types derived from tparams, which may be + // instantiated while reading the current element. + derived []derivedInfo + derivedTypes []types.Type // lazily instantiated from derived +} + +func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { + return &reader{ + Decoder: pr.NewDecoder(k, idx, marker), + p: pr, + } +} + +func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { + return &reader{ + Decoder: pr.TempDecoder(k, idx, marker), + p: pr, + } +} + +func (pr *pkgReader) retireReader(r *reader) { + pr.RetireDecoder(&r.Decoder) +} + +// @@@ Positions + +func (r *reader) pos() token.Pos { + r.Sync(pkgbits.SyncPos) + if !r.Bool() { + return token.NoPos + } + + // TODO(mdempsky): Delta encoding. + posBase := r.posBase() + line := r.Uint() + col := r.Uint() + return r.p.fake.pos(posBase, int(line), int(col)) +} + +func (r *reader) posBase() string { + return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)) +} + +func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string { + if b := pr.posBases[idx]; b != "" { + return b + } + + var filename string + { + r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase) + + // Within types2, position bases have a lot more details (e.g., + // keeping track of where //line directives appeared exactly). + // + // For go/types, we just track the file name. + + filename = r.String() + + if r.Bool() { // file base + // Was: "b = token.NewTrimmedFileBase(filename, true)" + } else { // line base + pos := r.pos() + line := r.Uint() + col := r.Uint() + + // Was: "b = token.NewLineBase(pos, filename, true, line, col)" + _, _, _ = pos, line, col + } + pr.retireReader(r) + } + b := filename + pr.posBases[idx] = b + return b +} + +// @@@ Packages + +func (r *reader) pkg() *types.Package { + r.Sync(pkgbits.SyncPkg) + return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg)) +} + +func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package { + // TODO(mdempsky): Consider using some non-nil pointer to indicate + // the universe scope, so we don't need to keep re-reading it. + if pkg := pr.pkgs[idx]; pkg != nil { + return pkg + } + + pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg() + pr.pkgs[idx] = pkg + return pkg +} + +func (r *reader) doPkg() *types.Package { + path := r.String() + switch path { + // cmd/compile emits path="main" for main packages because + // that's the linker symbol prefix it used; but we need + // the package's path as it would be reported by go list, + // hence "main" below. + // See test at go/packages.TestMainPackagePathInModeTypes. + case "", "main": + path = r.p.PkgPath() + case "builtin": + return nil // universe + case "unsafe": + return types.Unsafe + } + + if pkg := r.p.imports[path]; pkg != nil { + return pkg + } + + name := r.String() + + pkg := types.NewPackage(path, name) + r.p.imports[path] = pkg + + return pkg +} + +// @@@ Types + +func (r *reader) typ() types.Type { + return r.p.typIdx(r.typInfo(), r.dict) +} + +func (r *reader) typInfo() typeInfo { + r.Sync(pkgbits.SyncType) + if r.Bool() { + return typeInfo{idx: pkgbits.Index(r.Len()), derived: true} + } + return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false} +} + +func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type { + idx := info.idx + var where *types.Type + if info.derived { + where = &dict.derivedTypes[idx] + idx = dict.derived[idx].idx + } else { + where = &pr.typs[idx] + } + + if typ := *where; typ != nil { + return typ + } + + var typ types.Type + { + r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx) + r.dict = dict + + typ = r.doTyp() + assert(typ != nil) + pr.retireReader(r) + } + // See comment in pkgReader.typIdx explaining how this happens. + if prev := *where; prev != nil { + return prev + } + + *where = typ + return typ +} + +func (r *reader) doTyp() (res types.Type) { + switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag { + default: + errorf("unhandled type tag: %v", tag) + panic("unreachable") + + case pkgbits.TypeBasic: + return types.Typ[r.Len()] + + case pkgbits.TypeNamed: + obj, targs := r.obj() + name := obj.(*types.TypeName) + if len(targs) != 0 { + t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false) + return t + } + return name.Type() + + case pkgbits.TypeTypeParam: + n := r.Len() + if n < len(r.dict.rtbounds) { + return r.dict.rtparams[n] + } + return r.dict.tparams[n-len(r.dict.rtbounds)] + + case pkgbits.TypeArray: + len := int64(r.Uint64()) + return types.NewArray(r.typ(), len) + case pkgbits.TypeChan: + dir := types.ChanDir(r.Len()) + return types.NewChan(dir, r.typ()) + case pkgbits.TypeMap: + return types.NewMap(r.typ(), r.typ()) + case pkgbits.TypePointer: + return types.NewPointer(r.typ()) + case pkgbits.TypeSignature: + return r.signature(nil, nil, nil) + case pkgbits.TypeSlice: + return types.NewSlice(r.typ()) + case pkgbits.TypeStruct: + return r.structType() + case pkgbits.TypeInterface: + return r.interfaceType() + case pkgbits.TypeUnion: + return r.unionType() + } +} + +func (r *reader) structType() *types.Struct { + fields := make([]*types.Var, r.Len()) + var tags []string + for i := range fields { + pos := r.pos() + pkg, name := r.selector() + ftyp := r.typ() + tag := r.String() + embedded := r.Bool() + + fields[i] = types.NewField(pos, pkg, name, ftyp, embedded) + if tag != "" { + for len(tags) < i { + tags = append(tags, "") + } + tags = append(tags, tag) + } + } + return types.NewStruct(fields, tags) +} + +func (r *reader) unionType() *types.Union { + terms := make([]*types.Term, r.Len()) + for i := range terms { + terms[i] = types.NewTerm(r.Bool(), r.typ()) + } + return types.NewUnion(terms) +} + +func (r *reader) interfaceType() *types.Interface { + methods := make([]*types.Func, r.Len()) + embeddeds := make([]types.Type, r.Len()) + implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool() + + for i := range methods { + pos := r.pos() + pkg, name := r.selector() + mtyp := r.signature(nil, nil, nil) + methods[i] = types.NewFunc(pos, pkg, name, mtyp) + } + + for i := range embeddeds { + embeddeds[i] = r.typ() + } + + iface := types.NewInterfaceType(methods, embeddeds) + if implicit { + iface.MarkImplicit() + } + + // We need to call iface.Complete(), but if there are any embedded + // defined types, then we may not have set their underlying + // interface type yet. So we need to defer calling Complete until + // after we've called SetUnderlying everywhere. + // + // TODO(mdempsky): After CL 424876 lands, it should be safe to call + // iface.Complete() immediately. + r.p.ifaces = append(r.p.ifaces, iface) + + return iface +} + +func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature { + r.Sync(pkgbits.SyncSignature) + + params := r.params() + results := r.params() + variadic := r.Bool() + + return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic) +} + +func (r *reader) params() *types.Tuple { + r.Sync(pkgbits.SyncParams) + + params := make([]*types.Var, r.Len()) + for i := range params { + params[i] = r.param() + } + + return types.NewTuple(params...) +} + +func (r *reader) param() *types.Var { + r.Sync(pkgbits.SyncParam) + + pos := r.pos() + pkg, name := r.localIdent() + typ := r.typ() + + return types.NewParam(pos, pkg, name, typ) +} + +// @@@ Objects + +func (r *reader) obj() (types.Object, []types.Type) { + r.Sync(pkgbits.SyncObject) + + if r.Version().Has(pkgbits.DerivedFuncInstance) { + assert(!r.Bool()) + } + + pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj)) + obj := pkgScope(pkg).Lookup(name) + + targs := make([]types.Type, r.Len()) + for i := range targs { + targs[i] = r.typ() + } + + return obj, targs +} + +func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { + + var objPkg *types.Package + var objName string + var tag pkgbits.CodeObj + { + rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1) + + objPkg, objName = rname.qualifiedIdent() + assert(objName != "") + + tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj)) + pr.retireReader(rname) + } + + if tag == pkgbits.ObjStub { + assert(objPkg == nil || objPkg == types.Unsafe) + return objPkg, objName + } + + // Ignore local types promoted to global scope (#55110). + if _, suffix := splitVargenSuffix(objName); suffix != "" { + return objPkg, objName + } + + // TODO(mark): This, like the above splitVargenSuffix, is not ideal. + // Ignore generic methods promoted to global scope. + if strings.Contains(objName, ".") { + return objPkg, objName + } + + if objPkg.Scope().Lookup(objName) == nil { + dict := pr.objDictIdx(idx) + + r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1) + r.dict = dict + + declare := func(obj types.Object) { + objPkg.Scope().Insert(obj) + } + + switch tag { + default: + panic("weird") + + case pkgbits.ObjAlias: + pos := r.pos() + var tparams []*types.TypeParam + if r.Version().Has(pkgbits.AliasTypeParamNames) { + tparams = r.typeParamNames(false) + } + typ := r.typ() + tname := types.NewTypeName(pos, objPkg, objName, nil) + types.NewAlias(tname, typ).SetTypeParams(tparams) + declare(tname) + + case pkgbits.ObjConst: + pos := r.pos() + typ := r.typ() + val := r.Value() + declare(types.NewConst(pos, objPkg, objName, typ, val)) + + case pkgbits.ObjFunc: + pos := r.pos() + if r.Version().Has(pkgbits.GenericMethods) { + assert(!r.Bool()) // generic methods are read in their defining type + } + tparams := r.typeParamNames(false) + sig := r.signature(nil, nil, tparams) + declare(types.NewFunc(pos, objPkg, objName, sig)) + + case pkgbits.ObjType: + pos := r.pos() + + obj := types.NewTypeName(pos, objPkg, objName, nil) + named := types.NewNamed(obj, nil, nil) + declare(obj) + + named.SetTypeParams(r.typeParamNames(false)) + + setUnderlying := func(underlying types.Type) { + // If the underlying type is an interface, we need to + // duplicate its methods so we can replace the receiver + // parameter's type (#49906). + if iface, ok := types.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 { + methods := make([]*types.Func, iface.NumExplicitMethods()) + for i := range methods { + fn := iface.ExplicitMethod(i) + sig := fn.Type().(*types.Signature) + + recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named) + recv.SetKind(types.RecvVar) + methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignatureType(recv, nil, nil, sig.Params(), sig.Results(), sig.Variadic())) + } + + embeds := make([]types.Type, iface.NumEmbeddeds()) + for i := range embeds { + embeds[i] = iface.EmbeddedType(i) + } + + newIface := types.NewInterfaceType(methods, embeds) + r.p.ifaces = append(r.p.ifaces, newIface) + underlying = newIface + } + + named.SetUnderlying(underlying) + } + + // Since go.dev/cl/455279, we can assume rhs.Underlying() will + // always be non-nil. However, to temporarily support users of + // older snapshot releases, we continue to fallback to the old + // behavior for now. + // + // TODO(mdempsky): Remove fallback code and simplify after + // allowing time for snapshot users to upgrade. + rhs := r.typ() + if underlying := rhs.Underlying(); underlying != nil { + setUnderlying(underlying) + } else { + pk := r.p + pk.laterFor(named, func() { + // First be sure that the rhs is initialized, if it needs to be initialized. + delete(pk.laterFors, named) // prevent cycles + if i, ok := pk.laterFors[rhs]; ok { + f := pk.laterFns[i] + pk.laterFns[i] = func() {} // function is running now, so replace it with a no-op + f() // initialize RHS + } + setUnderlying(rhs.Underlying()) + }) + } + + if r.Version().Has(pkgbits.GenericMethods) { + // V4 (go1.27.0) emitted all non-generic methods + // before all generic ones, discarding source + // order: a bug (go.dev/issue/81188). + // V5 (go1.27.x) fixes it by emitting an explicit + // index along with each method. + type indexedMethod struct { + index int // (or -1 in V4) + fn *types.Func + } + + var methods []indexedMethod + + // ordinary methods + for range r.Len() { + idx, m := r.method() + methods = append(methods, indexedMethod{idx, m}) + } + + // generic methods + for range r.Len() { + // Careful: objIdx is used to read in package-scoped declarations, which + // methods are not. Instead, decode it here. This makes it easier to + // associate it with the type and avoids the main objIdx loop. + idx := r.Reloc(pkgbits.RelocObj) + + r := pr.tempReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1) + r.dict = pr.objDictIdx(idx) + + pos := r.pos() + assert(r.Bool()) // generic method + pkg, name := r.selector() + rtparams := r.typeParamNames(true) + recv := r.param() + methodIdx := -1 + if r.Version().Has(pkgbits.PreserveMethodOrder) { + methodIdx = r.Len() + } + tparams := r.typeParamNames(false) + sig := r.signature(recv, rtparams, tparams) + + pr.retireReader(r) + methods = append(methods, indexedMethod{methodIdx, types.NewFunc(pos, pkg, name, sig)}) + } + + if r.Version().Has(pkgbits.PreserveMethodOrder) { + sort.Slice(methods, func(i, j int) bool { + return methods[i].index < methods[j].index + }) + } + + for _, m := range methods { + named.AddMethod(m.fn) + } + + } else { + for range r.Len() { + _, m := r.method() + named.AddMethod(m) + } + } + + case pkgbits.ObjVar: + pos := r.pos() + typ := r.typ() + v := types.NewVar(pos, objPkg, objName, typ) + v.SetKind(types.PackageVar) + declare(v) + } + } + + return objPkg, objName +} + +func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { + + var dict readerDict + + { + r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1) + if implicits := r.Len(); implicits != 0 { + errorf("unexpected object with %v implicit type parameter(s)", implicits) + } + + nreceivers := 0 + if r.Version().Has(pkgbits.GenericMethods) { + nreceivers = r.Len() + } + nexplicits := r.Len() + + dict.rtbounds = make([]typeInfo, nreceivers) + for i := range dict.rtbounds { + dict.rtbounds[i] = r.typInfo() + } + + dict.tbounds = make([]typeInfo, nexplicits) + for i := range dict.tbounds { + dict.tbounds[i] = r.typInfo() + } + + dict.derived = make([]derivedInfo, r.Len()) + dict.derivedTypes = make([]types.Type, len(dict.derived)) + for i := range dict.derived { + dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.RelocType)} + if r.Version().Has(pkgbits.DerivedInfoNeeded) { + assert(!r.Bool()) + } + } + + pr.retireReader(r) + } + // function references follow, but reader doesn't need those + + return &dict +} + +func (r *reader) typeParamNames(isGenMeth bool) []*types.TypeParam { + r.Sync(pkgbits.SyncTypeParamNames) + + // Note: This code assumes there are no implicit type parameters. + // This is fine since it only reads exported declarations, which + // never have implicits. + + var in []typeInfo + var out *[]*types.TypeParam + if isGenMeth { + in = r.dict.rtbounds + out = &r.dict.rtparams + } else { + in = r.dict.tbounds + out = &r.dict.tparams + } + + if len(in) == 0 { + return nil + } + + // Careful: Type parameter lists may have cycles. To allow for this, + // we construct the type parameter list in two passes: first we + // create all the TypeNames and TypeParams, then we construct and + // set the bound type. + + // We have to save tparams outside of the closure, because typeParamNames + // can be called multiple times with the same dictionary instance. + tparams := make([]*types.TypeParam, len(in)) + *out = tparams + + for i := range in { + pos := r.pos() + pkg, name := r.localIdent() + + tname := types.NewTypeName(pos, pkg, name, nil) + tparams[i] = types.NewTypeParam(tname, nil) + } + + // The reader dictionary will continue mutating before we have time + // to call delayed functions; make a local copy of the constraints. + types := make([]types.Type, len(in)) + for i, info := range in { + types[i] = r.p.typIdx(info, r.dict) + } + + // This needs to happen later to make sure SetUnderlying has been called. + r.p.later(func() { + for i, typ := range types { + tparams[i].SetConstraint(typ) + } + }) + + return tparams +} + +func (r *reader) method() (int, *types.Func) { + r.Sync(pkgbits.SyncMethod) + idx := -1 + if r.Version().Has(pkgbits.PreserveMethodOrder) { + idx = r.Len() + } + pos := r.pos() + pkg, name := r.selector() + + rparams := r.typeParamNames(false) + sig := r.signature(r.param(), rparams, nil) + + _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go. + return idx, types.NewFunc(pos, pkg, name, sig) +} + +func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) } +func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) } +func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) } + +func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) { + r.Sync(marker) + return r.pkg(), r.String() +} + +// pkgScope returns pkg.Scope(). +// If pkg is nil, it returns types.Universe instead. +// +// TODO(mdempsky): Remove after x/tools can depend on Go 1.19. +func pkgScope(pkg *types.Package) *types.Scope { + if pkg != nil { + return pkg.Scope() + } + return types.Universe +} + +// See cmd/compile/internal/types.SplitVargenSuffix. +func splitVargenSuffix(name string) (base, suffix string) { + i := len(name) + for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' { + i-- + } + const dot = "·" + if i >= len(dot) && name[i-len(dot):i] == dot { + i -= len(dot) + return name[:i], name[i:] + } + return name, "" +} diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go new file mode 100644 index 0000000..ec4e713 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go @@ -0,0 +1,569 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package gocommand is a helper for calling the go command. +package gocommand + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "runtime" + "strconv" + "strings" + "sync" + "time" + + "golang.org/x/tools/internal/event" + "golang.org/x/tools/internal/event/keys" + "golang.org/x/tools/internal/event/label" +) + +// A Runner will run go command invocations and serialize +// them if it sees a concurrency error. +type Runner struct { + // once guards the runner initialization. + once sync.Once + + // inFlight tracks available workers. + inFlight chan struct{} + + // serialized guards the ability to run a go command serially, + // to avoid deadlocks when claiming workers. + serialized chan struct{} +} + +const maxInFlight = 10 + +func (runner *Runner) initialize() { + runner.once.Do(func() { + runner.inFlight = make(chan struct{}, maxInFlight) + runner.serialized = make(chan struct{}, 1) + }) +} + +// 1.13: go: updates to go.mod needed, but contents have changed +// 1.14: go: updating go.mod: existing contents have changed since last read +var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`) + +// event keys for go command invocations +var ( + verb = keys.NewString("verb", "go command verb") + directory = keys.NewString("directory", "") +) + +func invLabels(inv Invocation) []label.Label { + return []label.Label{verb.Of(inv.Verb), directory.Of(inv.WorkingDir)} +} + +// Run is a convenience wrapper around RunRaw. +// It returns only stdout and a "friendly" error. +func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) { + ctx, done := event.Start(ctx, "gocommand.Runner.Run", invLabels(inv)...) + defer done() + + stdout, _, friendly, _ := runner.RunRaw(ctx, inv) + return stdout, friendly +} + +// RunPiped runs the invocation serially, always waiting for any concurrent +// invocations to complete first. +func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) error { + ctx, done := event.Start(ctx, "gocommand.Runner.RunPiped", invLabels(inv)...) + defer done() + + _, err := runner.runPiped(ctx, inv, stdout, stderr) + return err +} + +// RunRaw runs the invocation, serializing requests only if they fight over +// go.mod changes. +// Postcondition: both error results have same nilness. +func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { + ctx, done := event.Start(ctx, "gocommand.Runner.RunRaw", invLabels(inv)...) + defer done() + // Make sure the runner is always initialized. + runner.initialize() + + // First, try to run the go command concurrently. + stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv) + + // If we encounter a load concurrency error, we need to retry serially. + if friendlyErr != nil && modConcurrencyError.MatchString(friendlyErr.Error()) { + event.Error(ctx, "Load concurrency error, will retry serially", err) + + // Run serially by calling runPiped. + stdout.Reset() + stderr.Reset() + friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr) + } + + return stdout, stderr, friendlyErr, err +} + +// Postcondition: both error results have same nilness. +func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { + // Wait for 1 worker to become available. + select { + case <-ctx.Done(): + return nil, nil, ctx.Err(), ctx.Err() + case runner.inFlight <- struct{}{}: + defer func() { <-runner.inFlight }() + } + + stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{} + friendlyErr, err := inv.runWithFriendlyError(ctx, stdout, stderr) + return stdout, stderr, friendlyErr, err +} + +// Postcondition: both error results have same nilness. +func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) { + // Make sure the runner is always initialized. + runner.initialize() + + // Acquire the serialization lock. This avoids deadlocks between two + // runPiped commands. + select { + case <-ctx.Done(): + return ctx.Err(), ctx.Err() + case runner.serialized <- struct{}{}: + defer func() { <-runner.serialized }() + } + + // Wait for all in-progress go commands to return before proceeding, + // to avoid load concurrency errors. + for range maxInFlight { + select { + case <-ctx.Done(): + return ctx.Err(), ctx.Err() + case runner.inFlight <- struct{}{}: + // Make sure we always "return" any workers we took. + defer func() { <-runner.inFlight }() + } + } + + return inv.runWithFriendlyError(ctx, stdout, stderr) +} + +// An Invocation represents a call to the go command. +type Invocation struct { + Verb string + Args []string + BuildFlags []string + + // If ModFlag is set, the go command is invoked with -mod=ModFlag. + // TODO(rfindley): remove, in favor of Args. + ModFlag string + + // If ModFile is set, the go command is invoked with -modfile=ModFile. + // TODO(rfindley): remove, in favor of Args. + ModFile string + + // Overlay is the name of the JSON overlay file that describes + // unsaved editor buffers; see [WriteOverlays]. + // If set, the go command is invoked with -overlay=Overlay. + // TODO(rfindley): remove, in favor of Args. + Overlay string + + // If CleanEnv is set, the invocation will run only with the environment + // in Env, not starting with os.Environ. + CleanEnv bool + Env []string + WorkingDir string + Logf func(format string, args ...any) +} + +// Postcondition: both error results have same nilness. +func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) { + rawError = i.run(ctx, stdout, stderr) + if rawError != nil { + friendlyError = rawError + // Check for 'go' executable not being found. + if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound { + friendlyError = fmt.Errorf("go command required, not found: %v", ee) + } + if ctx.Err() != nil { + friendlyError = ctx.Err() + } + friendlyError = fmt.Errorf("err: %v: stderr: %s", friendlyError, stderr) + } + return +} + +// logf logs if i.Logf is non-nil. +func (i *Invocation) logf(format string, args ...any) { + if i.Logf != nil { + i.Logf(format, args...) + } +} + +func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { + goArgs := []string{i.Verb} + + appendModFile := func() { + if i.ModFile != "" { + goArgs = append(goArgs, "-modfile="+i.ModFile) + } + } + appendModFlag := func() { + if i.ModFlag != "" { + goArgs = append(goArgs, "-mod="+i.ModFlag) + } + } + appendOverlayFlag := func() { + if i.Overlay != "" { + goArgs = append(goArgs, "-overlay="+i.Overlay) + } + } + + switch i.Verb { + case "env", "version": + goArgs = append(goArgs, i.Args...) + case "mod": + // mod needs the sub-verb before flags. + goArgs = append(goArgs, i.Args[0]) + appendModFile() + appendOverlayFlag() // all 'go mod' subcommands accept -overlay + goArgs = append(goArgs, i.Args[1:]...) + case "get": + goArgs = append(goArgs, i.BuildFlags...) + appendModFile() + goArgs = append(goArgs, i.Args...) + + default: // notably list and build. + goArgs = append(goArgs, i.BuildFlags...) + appendModFile() + appendModFlag() + appendOverlayFlag() + goArgs = append(goArgs, i.Args...) + } + cmd := exec.Command("go", goArgs...) + setProcessGroup(cmd) + cmd.Stdout = stdout + cmd.Stderr = stderr + + // https://go.dev/issue/59541: don't wait forever copying stderr + // after the command has exited. + // After CL 484741 we copy stdout manually, so we we'll stop reading that as + // soon as ctx is done. However, we also don't want to wait around forever + // for stderr. Give a much-longer-than-reasonable delay and then assume that + // something has wedged in the kernel or runtime. + cmd.WaitDelay = 30 * time.Second + + // The cwd gets resolved to the real path. On Darwin, where + // /tmp is a symlink, this breaks anything that expects the + // working directory to keep the original path, including the + // go command when dealing with modules. + // + // os.Getwd has a special feature where if the cwd and the PWD + // are the same node then it trusts the PWD, so by setting it + // in the env for the child process we fix up all the paths + // returned by the go command. + if !i.CleanEnv { + cmd.Env = os.Environ() + } + cmd.Env = append(cmd.Env, i.Env...) + if i.WorkingDir != "" { + cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir) + cmd.Dir = i.WorkingDir + } + + debugStr := cmdDebugStr(cmd) + i.logf("starting %v", debugStr) + start := time.Now() + defer func() { + i.logf("%s for %v", time.Since(start), debugStr) + }() + + return runCmdContext(ctx, cmd) +} + +// DebugHangingGoCommands may be set by tests to enable additional +// instrumentation (including panics) for debugging hanging Go commands. +// +// See golang/go#54461 for details. +var DebugHangingGoCommands = false + +// runCmdContext is like exec.CommandContext except it sends os.Interrupt +// before os.Kill. +func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) { + // If cmd.Stdout is not an *os.File, the exec package will create a pipe and + // copy it to the Writer in a goroutine until the process has finished and + // either the pipe reaches EOF or command's WaitDelay expires. + // + // However, the output from 'go list' can be quite large, and we don't want to + // keep reading (and allocating buffers) if we've already decided we don't + // care about the output. We don't want to wait for the process to finish, and + // we don't wait to wait for the WaitDelay to expire either. + // + // Instead, if cmd.Stdout requires a copying goroutine we explicitly replace + // it with a pipe (which is an *os.File), which we can close in order to stop + // copying output as soon as we realize we don't care about it. + var stdoutW *os.File + if cmd.Stdout != nil { + if _, ok := cmd.Stdout.(*os.File); !ok { + var stdoutR *os.File + stdoutR, stdoutW, err = os.Pipe() + if err != nil { + return err + } + prevStdout := cmd.Stdout + cmd.Stdout = stdoutW + + stdoutErr := make(chan error, 1) + go func() { + _, err := io.Copy(prevStdout, stdoutR) + if err != nil { + err = fmt.Errorf("copying stdout: %w", err) + } + stdoutErr <- err + }() + defer func() { + // We started a goroutine to copy a stdout pipe. + // Wait for it to finish, or terminate it if need be. + var err2 error + select { + case err2 = <-stdoutErr: + stdoutR.Close() + case <-ctx.Done(): + stdoutR.Close() + // Per https://pkg.go.dev/os#File.Close, the call to stdoutR.Close + // should cause the Read call in io.Copy to unblock and return + // immediately, but we still need to receive from stdoutErr to confirm + // that it has happened. + <-stdoutErr + err2 = ctx.Err() + } + if err == nil { + err = err2 + } + }() + + // Per https://pkg.go.dev/os/exec#Cmd, “If Stdout and Stderr are the + // same writer, and have a type that can be compared with ==, at most + // one goroutine at a time will call Write.” + // + // Since we're starting a goroutine that writes to cmd.Stdout, we must + // also update cmd.Stderr so that it still holds. + func() { + defer func() { recover() }() + if cmd.Stderr == prevStdout { + cmd.Stderr = cmd.Stdout + } + }() + } + } + + startTime := time.Now() + err = cmd.Start() + if stdoutW != nil { + // The child process has inherited the pipe file, + // so close the copy held in this process. + stdoutW.Close() + stdoutW = nil + } + if err != nil { + return err + } + + resChan := make(chan error, 1) + go func() { + resChan <- cmd.Wait() + }() + + // If we're interested in debugging hanging Go commands, stop waiting after a + // minute and panic with interesting information. + debug := DebugHangingGoCommands + if debug { + timer := time.NewTimer(1 * time.Minute) + defer timer.Stop() + select { + case err := <-resChan: + return err + case <-timer.C: + // HandleHangingGoCommand terminates this process. + // Pass off resChan in case we can collect the command error. + handleHangingGoCommand(startTime, cmd, resChan) + case <-ctx.Done(): + } + } else { + select { + case err := <-resChan: + return err + case <-ctx.Done(): + } + } + + // Cancelled. Interrupt and see if it ends voluntarily. + if err := interruptProcess(cmd); err == nil { + // (We used to wait only 1s but this proved + // fragile on loaded builder machines.) + timer := time.NewTimer(5 * time.Second) + defer timer.Stop() + select { + case err := <-resChan: + return err + case <-timer.C: + } + } + + // Didn't shut down in response to interrupt. Kill it hard. + if err := killProcess(cmd); err != nil && !errors.Is(err, os.ErrProcessDone) && debug { + log.Printf("error killing the Go command: %v", err) + } + + return <-resChan +} + +// handleHangingGoCommand outputs debugging information to help diagnose the +// cause of a hanging Go command, and then exits with log.Fatalf. +func handleHangingGoCommand(start time.Time, cmd *exec.Cmd, resChan chan error) { + switch runtime.GOOS { + case "linux", "darwin", "freebsd", "netbsd", "openbsd": + fmt.Fprintln(os.Stderr, `DETECTED A HANGING GO COMMAND + + The gopls test runner has detected a hanging go command. In order to debug + this, the output of ps and lsof/fstat is printed below. + + See golang/go#54461 for more details.`) + + fmt.Fprintln(os.Stderr, "\nps axo ppid,pid,command:") + fmt.Fprintln(os.Stderr, "-------------------------") + psCmd := exec.Command("ps", "axo", "ppid,pid,command") + psCmd.Stdout = os.Stderr + psCmd.Stderr = os.Stderr + if err := psCmd.Run(); err != nil { + log.Printf("Handling hanging Go command: running ps: %v", err) + } + + listFiles := "lsof" + if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" { + listFiles = "fstat" + } + + fmt.Fprintln(os.Stderr, "\n"+listFiles+":") + fmt.Fprintln(os.Stderr, "-----") + listFilesCmd := exec.Command(listFiles) + listFilesCmd.Stdout = os.Stderr + listFilesCmd.Stderr = os.Stderr + if err := listFilesCmd.Run(); err != nil { + log.Printf("Handling hanging Go command: running %s: %v", listFiles, err) + } + // Try to extract information about the slow go process by issuing a SIGQUIT. + if err := cmd.Process.Signal(sigStuckProcess); err == nil { + select { + case err := <-resChan: + stderr := "not a bytes.Buffer" + if buf, _ := cmd.Stderr.(*bytes.Buffer); buf != nil { + stderr = buf.String() + } + log.Printf("Quit hanging go command:\n\terr:%v\n\tstderr:\n%v\n\n", err, stderr) + case <-time.After(5 * time.Second): + } + } else { + log.Printf("Sending signal %d to hanging go command: %v", sigStuckProcess, err) + } + } + log.Fatalf("detected hanging go command (golang/go#54461); waited %s\n\tcommand:%s\n\tpid:%d", time.Since(start), cmd, cmd.Process.Pid) +} + +func cmdDebugStr(cmd *exec.Cmd) string { + env := make(map[string]string) + for _, kv := range cmd.Env { + split := strings.SplitN(kv, "=", 2) + if len(split) == 2 { + k, v := split[0], split[1] + env[k] = v + } + } + + var args []string + for _, arg := range cmd.Args { + quoted := strconv.Quote(arg) + if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { + args = append(args, quoted) + } else { + args = append(args, arg) + } + } + return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) +} + +// WriteOverlays writes each value in the overlay (see the Overlay +// field of go/packages.Config) to a temporary file and returns the name +// of a JSON file describing the mapping that is suitable for the "go +// list -overlay" flag. +// +// On success, the caller must call the cleanup function exactly once +// when the files are no longer needed. +func WriteOverlays(overlay map[string][]byte) (filename string, cleanup func(), err error) { + // Do nothing if there are no overlays in the config. + if len(overlay) == 0 { + return "", func() {}, nil + } + + dir, err := os.MkdirTemp("", "gocommand-*") + if err != nil { + return "", nil, err + } + + // The caller must clean up this directory, + // unless this function returns an error. + // (The cleanup operand of each return + // statement below is ignored.) + defer func() { + cleanup = func() { + os.RemoveAll(dir) + } + if err != nil { + cleanup() + cleanup = nil + } + }() + + // Write each map entry to a temporary file. + overlays := make(map[string]string) + for k, v := range overlay { + // Use a unique basename for each file (001-foo.go), + // to avoid creating nested directories. + base := fmt.Sprintf("%d-%s", 1+len(overlays), filepath.Base(k)) + filename := filepath.Join(dir, base) + err := os.WriteFile(filename, v, 0666) + if err != nil { + return "", nil, err + } + overlays[k] = filename + } + + // Write the JSON overlay file that maps logical file names to temp files. + // + // OverlayJSON is the format overlay files are expected to be in. + // The Replace map maps from overlaid paths to replacement paths: + // the Go command will forward all reads trying to open + // each overlaid path to its replacement path, or consider the overlaid + // path not to exist if the replacement path is empty. + // + // From golang/go#39958. + type OverlayJSON struct { + Replace map[string]string `json:"replace,omitempty"` + } + b, err := json.Marshal(OverlayJSON{Replace: overlays}) + if err != nil { + return "", nil, err + } + filename = filepath.Join(dir, "overlay.json") + if err := os.WriteFile(filename, b, 0666); err != nil { + return "", nil, err + } + + return filename, nil, nil +} diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke_notunix.go b/vendor/golang.org/x/tools/internal/gocommand/invoke_notunix.go new file mode 100644 index 0000000..a156a8f --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gocommand/invoke_notunix.go @@ -0,0 +1,45 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !unix + +package gocommand + +import ( + "errors" + "os" + "os/exec" +) + +// sigStuckProcess is the signal to send to kill a hanging subprocess. +// On Unix we send SIGQUIT, but on non-Unix we only have os.Kill. +var sigStuckProcess = os.Kill + +// setProcessGroup is a no-op on non-Unix platforms. +// +// As a consequence of not using process groups (or Windows job objects), +// signals sent to cmd.Process will not propagate to descendant processes +// spawned by the Go command (such as cgo or C compilers). If the command +// is cancelled, those subprocesses may continue running in the background +// until they finish or fail due to broken pipes. +// TODO(pjw): consider adding Windows job objects. +func setProcessGroup(cmd *exec.Cmd) { +} + +// interruptProcess sends an interrupt signal to the process. On Windows, +// os.Interrupt is not supported and will return an error, causing the caller +// to fall back to killProcess immediately. +func interruptProcess(cmd *exec.Cmd) error { + return cmd.Process.Signal(os.Interrupt) +} + +// killProcess terminates the process directly. Subprocesses spawned by the +// Go command will not be killed directly. +func killProcess(cmd *exec.Cmd) error { + err := cmd.Process.Kill() + if errors.Is(err, os.ErrProcessDone) { + return nil + } + return err +} diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke_unix.go b/vendor/golang.org/x/tools/internal/gocommand/invoke_unix.go new file mode 100644 index 0000000..be60ebb --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gocommand/invoke_unix.go @@ -0,0 +1,53 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build unix + +package gocommand + +import ( + "errors" + "os/exec" + "syscall" +) + +// sigStuckProcess is the signal to send to kill a hanging subprocess. +// Send SIGQUIT to get a stack trace. +var sigStuckProcess = syscall.SIGQUIT + +// setProcessGroup sets Setpgid so that the child process runs as the leader of +// its own process group. Any subprocesses spawned by the Go command (such as +// cgo, compilers, or assemblers) will inherit this process group, allowing +// cancellation signals to reach all descendant processes rather than orphaning +// them (see golang/go#81408). +func setProcessGroup(cmd *exec.Cmd) { + if cmd.SysProcAttr == nil { + cmd.SysProcAttr = &syscall.SysProcAttr{} + } + cmd.SysProcAttr.Setpgid = true +} + +// interruptProcess sends SIGINT to the entire process group (-pid) so that both +// the Go command and any subprocesses (such as C compilers) get +// the interrupt signal and terminate promptly. +// +// Unlike cmd.Process.Signal, syscall.Kill(-pid, ...) does not synchronize with +// cmd.Process.Wait via os.Process's internal lock. PGID reuse is not a +// problem, as the kernel reserves the PGID as long as any member +// of the process group is alive, and runCmdContext only signals the +// process group while cmd.Wait is still blocked on the process or its open pipes. +func interruptProcess(cmd *exec.Cmd) error { + return syscall.Kill(-cmd.Process.Pid, syscall.SIGINT) +} + +// killProcess sends SIGKILL to the entire process group (-pid) to forcefully +// terminate any remaining descendant processes. It ignores ESRCH if the process +// group has already terminated. +func killProcess(cmd *exec.Cmd) error { + err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL) + if errors.Is(err, syscall.ESRCH) { + return nil + } + return err +} diff --git a/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/vendor/golang.org/x/tools/internal/gocommand/vendor.go new file mode 100644 index 0000000..e38d1fb --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gocommand/vendor.go @@ -0,0 +1,163 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gocommand + +import ( + "bytes" + "context" + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + "time" + + "golang.org/x/mod/semver" +) + +// ModuleJSON holds information about a module. +type ModuleJSON struct { + Path string // module path + Version string // module version + Versions []string // available module versions (with -versions) + Replace *ModuleJSON // replaced by this module + Time *time.Time // time version was created + Update *ModuleJSON // available update, if any (with -u) + Main bool // is this the main module? + Indirect bool // is this module only an indirect dependency of main module? + Dir string // directory holding files for this module, if any + GoMod string // path to go.mod file used when loading this module, if any + GoVersion string // go version used in module +} + +var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`) + +// VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands +// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, +// of which only Verb and Args are modified to run the appropriate Go command. +// Inspired by setDefaultBuildMod in modload/init.go +func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, *ModuleJSON, error) { + mainMod, go114, err := getMainModuleAnd114(ctx, inv, r) + if err != nil { + return false, nil, err + } + + // We check the GOFLAGS to see if there is anything overridden or not. + inv.Verb = "env" + inv.Args = []string{"GOFLAGS"} + stdout, err := r.Run(ctx, inv) + if err != nil { + return false, nil, err + } + goflags := string(bytes.TrimSpace(stdout.Bytes())) + matches := modFlagRegexp.FindStringSubmatch(goflags) + var modFlag string + if len(matches) != 0 { + modFlag = matches[1] + } + // Don't override an explicit '-mod=' argument. + if modFlag == "vendor" { + return true, mainMod, nil + } else if modFlag != "" { + return false, nil, nil + } + if mainMod == nil || !go114 { + return false, nil, nil + } + // Check 1.14's automatic vendor mode. + if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() { + if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 { + // The Go version is at least 1.14, and a vendor directory exists. + // Set -mod=vendor by default. + return true, mainMod, nil + } + } + return false, nil, nil +} + +// getMainModuleAnd114 gets one of the main modules' information and whether the +// go command in use is 1.14+. This is the information needed to figure out +// if vendoring should be enabled. +func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { + const format = `{{.Path}} +{{.Dir}} +{{.GoMod}} +{{.GoVersion}} +{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}} +` + inv.Verb = "list" + inv.Args = []string{"-m", "-f", format} + stdout, err := r.Run(ctx, inv) + if err != nil { + return nil, false, err + } + + lines := strings.Split(stdout.String(), "\n") + if len(lines) < 5 { + return nil, false, fmt.Errorf("unexpected stdout: %q", stdout.String()) + } + mod := &ModuleJSON{ + Path: lines[0], + Dir: lines[1], + GoMod: lines[2], + GoVersion: lines[3], + Main: true, + } + return mod, lines[4] == "go1.14", nil +} + +// WorkspaceVendorEnabled reports whether workspace vendoring is enabled. It takes a *Runner to execute Go commands +// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, +// of which only Verb and Args are modified to run the appropriate Go command. +// Inspired by setDefaultBuildMod in modload/init.go +func WorkspaceVendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, []*ModuleJSON, error) { + inv.Verb = "env" + inv.Args = []string{"GOWORK"} + stdout, err := r.Run(ctx, inv) + if err != nil { + return false, nil, err + } + goWork := string(bytes.TrimSpace(stdout.Bytes())) + if fi, err := os.Stat(filepath.Join(filepath.Dir(goWork), "vendor")); err == nil && fi.IsDir() { + mainMods, err := getWorkspaceMainModules(ctx, inv, r) + if err != nil { + return false, nil, err + } + return true, mainMods, nil + } + return false, nil, nil +} + +// getWorkspaceMainModules gets the main modules' information. +// This is the information needed to figure out if vendoring should be enabled. +func getWorkspaceMainModules(ctx context.Context, inv Invocation, r *Runner) ([]*ModuleJSON, error) { + const format = `{{.Path}} +{{.Dir}} +{{.GoMod}} +{{.GoVersion}} +` + inv.Verb = "list" + inv.Args = []string{"-m", "-f", format} + stdout, err := r.Run(ctx, inv) + if err != nil { + return nil, err + } + + lines := strings.Split(strings.TrimSuffix(stdout.String(), "\n"), "\n") + if len(lines) < 4 { + return nil, fmt.Errorf("unexpected stdout: %q", stdout.String()) + } + mods := make([]*ModuleJSON, 0, len(lines)/4) + for i := 0; i < len(lines); i += 4 { + mods = append(mods, &ModuleJSON{ + Path: lines[i], + Dir: lines[i+1], + GoMod: lines[i+2], + GoVersion: lines[i+3], + Main: true, + }) + } + return mods, nil +} diff --git a/vendor/golang.org/x/tools/internal/gocommand/version.go b/vendor/golang.org/x/tools/internal/gocommand/version.go new file mode 100644 index 0000000..d82f13a --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gocommand/version.go @@ -0,0 +1,75 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gocommand + +import ( + "context" + "fmt" + "regexp" + "slices" + "strings" +) + +// GoVersion reports the minor version number of the highest release +// tag built into the go command on the PATH. +// +// Note that this may be higher than the version of the go tool used +// to build this application, and thus the versions of the standard +// go/{scanner,parser,ast,types} packages that are linked into it. +// In that case, callers should either downgrade to the version of +// go used to build the application, or report an error that the +// application is too old to use the go command on the PATH. +func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) { + inv.Verb = "list" + inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`, `--`, `unsafe`} + inv.BuildFlags = nil // This is not a build command. + inv.ModFlag = "" + inv.ModFile = "" + // Set GO111MODULE=off so that we are immune to errors in go.{work,mod}. + // Unfortunately, this breaks the Go 1.21+ toolchain directive and + // may affect the set of ReleaseTags; see #68495. + inv.Env = append(inv.Env[:len(inv.Env):len(inv.Env)], "GO111MODULE=off") + + stdoutBytes, err := r.Run(ctx, inv) + if err != nil { + return 0, err + } + stdout := stdoutBytes.String() + if len(stdout) < 3 { + return 0, fmt.Errorf("bad ReleaseTags output: %q", stdout) + } + // Split up "[go1.1 go1.15]" and return highest go1.X value. + tags := strings.Fields(stdout[1 : len(stdout)-2]) + for _, tag := range slices.Backward(tags) { + var version int + if _, err := fmt.Sscanf(tag, "go1.%d", &version); err != nil { + continue + } + return version, nil + } + return 0, fmt.Errorf("no parseable ReleaseTags in %v", tags) +} + +// GoVersionOutput returns the complete output of the go version command. +func GoVersionOutput(ctx context.Context, inv Invocation, r *Runner) (string, error) { + inv.Verb = "version" + goVersion, err := r.Run(ctx, inv) + if err != nil { + return "", err + } + return goVersion.String(), nil +} + +// ParseGoVersionOutput extracts the Go version string +// from the output of the "go version" command. +// Given an unrecognized form, it returns an empty string. +func ParseGoVersionOutput(data string) string { + re := regexp.MustCompile(`^go version (go\S+|devel \S+)`) + m := re.FindStringSubmatch(data) + if len(m) != 2 { + return "" // unrecognized version + } + return m[1] +} diff --git a/vendor/golang.org/x/tools/internal/gopathwalk/walk.go b/vendor/golang.org/x/tools/internal/gopathwalk/walk.go new file mode 100644 index 0000000..5252144 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/gopathwalk/walk.go @@ -0,0 +1,336 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package gopathwalk is like filepath.Walk but specialized for finding Go +// packages, particularly in $GOPATH and $GOROOT. +package gopathwalk + +import ( + "bufio" + "bytes" + "io" + "io/fs" + "os" + "path/filepath" + "runtime" + "slices" + "strings" + "sync" + "time" +) + +// Options controls the behavior of a Walk call. +type Options struct { + // If Logf is non-nil, debug logging is enabled through this function. + Logf func(format string, args ...any) + + // Search module caches. Also disables legacy goimports ignore rules. + ModulesEnabled bool + + // Maximum number of concurrent calls to user-provided callbacks, + // or 0 for GOMAXPROCS. + Concurrency int +} + +// RootType indicates the type of a Root. +type RootType int + +const ( + RootUnknown RootType = iota + RootGOROOT + RootGOPATH + RootCurrentModule + RootModuleCache + RootOther +) + +// A Root is a starting point for a Walk. +type Root struct { + Path string + Type RootType +} + +// Walk concurrently walks Go source directories ($GOROOT, $GOPATH, etc) to find packages. +// +// For each package found, add will be called with the absolute +// paths of the containing source directory and the package directory. +// +// Unlike filepath.WalkDir, Walk follows symbolic links +// (while guarding against cycles). +func Walk(roots []Root, add func(root Root, dir string), opts Options) { + WalkSkip(roots, add, func(Root, string) bool { return false }, opts) +} + +// WalkSkip concurrently walks Go source directories ($GOROOT, $GOPATH, etc) to +// find packages. +// +// For each package found, add will be called with the absolute +// paths of the containing source directory and the package directory. +// For each directory that will be scanned, skip will be called +// with the absolute paths of the containing source directory and the directory. +// If skip returns false on a directory it will be processed. +// +// Unlike filepath.WalkDir, WalkSkip follows symbolic links +// (while guarding against cycles). +func WalkSkip(roots []Root, add func(root Root, dir string), skip func(root Root, dir string) bool, opts Options) { + for _, root := range roots { + walkDir(root, add, skip, opts) + } +} + +// walkDir creates a walker and starts fastwalk with this walker. +func walkDir(root Root, add func(Root, string), skip func(root Root, dir string) bool, opts Options) { + if opts.Logf == nil { + opts.Logf = func(format string, args ...any) {} + } + if _, err := os.Stat(root.Path); os.IsNotExist(err) { + opts.Logf("skipping nonexistent directory: %v", root.Path) + return + } + start := time.Now() + opts.Logf("scanning %s", root.Path) + + concurrency := opts.Concurrency + if concurrency == 0 { + // The walk be either CPU-bound or I/O-bound, depending on what the + // caller-supplied add function does and the details of the user's platform + // and machine. Rather than trying to fine-tune the concurrency level for a + // specific environment, we default to GOMAXPROCS: it is likely to be a good + // choice for a CPU-bound add function, and if it is instead I/O-bound, then + // dealing with I/O saturation is arguably the job of the kernel and/or + // runtime. (Oversaturating I/O seems unlikely to harm performance as badly + // as failing to saturate would.) + concurrency = runtime.GOMAXPROCS(0) + } + w := &walker{ + root: root, + add: add, + skip: skip, + opts: opts, + sem: make(chan struct{}, concurrency), + } + w.init() + + w.sem <- struct{}{} + path := root.Path + if path == "" { + path = "." + } + if fi, err := os.Lstat(path); err == nil { + w.walk(path, nil, fs.FileInfoToDirEntry(fi)) + } else { + w.opts.Logf("scanning directory %v: %v", root.Path, err) + } + <-w.sem + w.walking.Wait() + + opts.Logf("scanned %s in %v", root.Path, time.Since(start)) +} + +// walker is the callback for fastwalk.Walk. +type walker struct { + root Root // The source directory to scan. + add func(Root, string) // The callback that will be invoked for every possible Go package dir. + skip func(Root, string) bool // The callback that will be invoked for every dir. dir is skipped if it returns true. + opts Options // Options passed to Walk by the user. + + walking sync.WaitGroup + sem chan struct{} // Channel of semaphore tokens; send to acquire, receive to release. + ignoredDirs []string + + added sync.Map // map[string]bool +} + +// A symlinkList is a linked list of os.FileInfos for parent directories +// reached via symlinks. +type symlinkList struct { + info os.FileInfo + prev *symlinkList +} + +// init initializes the walker based on its Options +func (w *walker) init() { + var ignoredPaths []string + if w.root.Type == RootModuleCache { + ignoredPaths = []string{"cache"} + } + if !w.opts.ModulesEnabled && w.root.Type == RootGOPATH { + ignoredPaths = w.getIgnoredDirs(w.root.Path) + ignoredPaths = append(ignoredPaths, "v", "mod") + } + + for _, p := range ignoredPaths { + full := filepath.Join(w.root.Path, p) + w.ignoredDirs = append(w.ignoredDirs, full) + w.opts.Logf("Directory added to ignore list: %s", full) + } +} + +// getIgnoredDirs reads an optional config file at /.goimportsignore +// of relative directories to ignore when scanning for go files. +// The provided path is one of the $GOPATH entries with "src" appended. +func (w *walker) getIgnoredDirs(path string) []string { + file := filepath.Join(path, ".goimportsignore") + slurp, err := os.ReadFile(file) + if err != nil { + w.opts.Logf("%v", err) + } else { + w.opts.Logf("Read %s", file) + } + if err != nil { + return nil + } + + var ignoredDirs []string + bs := bufio.NewScanner(bytes.NewReader(slurp)) + for bs.Scan() { + line := strings.TrimSpace(bs.Text()) + if line == "" || strings.HasPrefix(line, "#") { + continue + } + ignoredDirs = append(ignoredDirs, line) + } + return ignoredDirs +} + +// shouldSkipDir reports whether the file should be skipped or not. +func (w *walker) shouldSkipDir(dir string) bool { + if slices.Contains(w.ignoredDirs, dir) { + return true + } + if w.skip != nil { + // Check with the user specified callback. + return w.skip(w.root, dir) + } + return false +} + +// walk walks through the given path. +// +// Errors are logged if w.opts.Logf is non-nil, but otherwise ignored. +func (w *walker) walk(path string, pathSymlinks *symlinkList, d fs.DirEntry) { + if d.Type()&os.ModeSymlink != 0 { + // Walk the symlink's target rather than the symlink itself. + // + // (Note that os.Stat, unlike the lower-lever os.Readlink, + // follows arbitrarily many layers of symlinks, so it will eventually + // reach either a non-symlink or a nonexistent target.) + // + // TODO(bcmills): 'go list all' itself ignores symlinks within GOROOT/src + // and GOPATH/src. Do we really need to traverse them here? If so, why? + + fi, err := os.Stat(path) + if err != nil { + w.opts.Logf("%v", err) + return + } + + // Avoid walking symlink cycles: if we have already followed a symlink to + // this directory as a parent of itself, don't follow it again. + // + // This doesn't catch the first time through a cycle, but it also minimizes + // the number of extra stat calls we make if we *don't* encounter a cycle. + // Since we don't actually expect to encounter symlink cycles in practice, + // this seems like the right tradeoff. + for parent := pathSymlinks; parent != nil; parent = parent.prev { + if os.SameFile(fi, parent.info) { + return + } + } + + pathSymlinks = &symlinkList{ + info: fi, + prev: pathSymlinks, + } + d = fs.FileInfoToDirEntry(fi) + } + + if d.Type().IsRegular() { + if !strings.HasSuffix(path, ".go") { + return + } + + dir := filepath.Dir(path) + if dir == w.root.Path && (w.root.Type == RootGOROOT || w.root.Type == RootGOPATH) { + // Doesn't make sense to have regular files + // directly in your $GOPATH/src or $GOROOT/src. + // + // TODO(bcmills): there are many levels of directory within + // RootModuleCache where this also wouldn't make sense, + // Can we generalize this to any directory without a corresponding + // import path? + return + } + + if _, dup := w.added.LoadOrStore(dir, true); !dup { + w.add(w.root, dir) + } + } + + if !d.IsDir() { + return + } + + base := filepath.Base(path) + if base == "" || base[0] == '.' || base[0] == '_' || + base == "testdata" || + (w.root.Type == RootGOROOT && w.opts.ModulesEnabled && base == "vendor") || + (!w.opts.ModulesEnabled && base == "node_modules") || + w.shouldSkipDir(path) { + return + } + + // Read the directory and walk its entries. + + f, err := os.Open(path) + if err != nil { + w.opts.Logf("%v", err) + return + } + defer f.Close() + + for { + // We impose an arbitrary limit on the number of ReadDir results per + // directory to limit the amount of memory consumed for stale or upcoming + // directory entries. The limit trades off CPU (number of syscalls to read + // the whole directory) against RAM (reachable directory entries other than + // the one currently being processed). + // + // Since we process the directories recursively, we will end up maintaining + // a slice of entries for each level of the directory tree. + // (Compare https://go.dev/issue/36197.) + ents, err := f.ReadDir(1024) + if err != nil { + if err != io.EOF { + w.opts.Logf("%v", err) + } + break + } + + for _, d := range ents { + nextPath := filepath.Join(path, d.Name()) + if d.IsDir() { + select { + case w.sem <- struct{}{}: + // Got a new semaphore token, so we can traverse the directory concurrently. + d := d + w.walking.Add(1) + go func() { + defer func() { + <-w.sem + w.walking.Done() + }() + w.walk(nextPath, pathSymlinks, d) + }() + continue + + default: + // No tokens available, so traverse serially. + } + } + + w.walk(nextPath, pathSymlinks, d) + } + } +} diff --git a/vendor/golang.org/x/tools/internal/imports/fix.go b/vendor/golang.org/x/tools/internal/imports/fix.go new file mode 100644 index 0000000..b4544aa --- /dev/null +++ b/vendor/golang.org/x/tools/internal/imports/fix.go @@ -0,0 +1,2028 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package imports + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "go/ast" + "go/build" + "go/parser" + "go/token" + "go/types" + "io/fs" + "io/ioutil" + "maps" + "os" + "path" + "path/filepath" + "reflect" + "sort" + "strconv" + "strings" + "sync" + "unicode" + "unicode/utf8" + + "golang.org/x/tools/go/ast/astutil" + "golang.org/x/tools/internal/event" + "golang.org/x/tools/internal/gocommand" + "golang.org/x/tools/internal/gopathwalk" + "golang.org/x/tools/internal/modindex" + "golang.org/x/tools/internal/stdlib" +) + +// importToGroup is a list of functions which map from an import path to +// a group number. +var importToGroup = []func(localPrefix, importPath string) (num int, ok bool){ + func(localPrefix, importPath string) (num int, ok bool) { + if localPrefix == "" { + return + } + for p := range strings.SplitSeq(localPrefix, ",") { + if strings.HasPrefix(importPath, p) || strings.TrimSuffix(p, "/") == importPath { + return 3, true + } + } + return + }, + func(_, importPath string) (num int, ok bool) { + if strings.HasPrefix(importPath, "appengine") { + return 2, true + } + return + }, + func(_, importPath string) (num int, ok bool) { + firstComponent := strings.Split(importPath, "/")[0] + if strings.Contains(firstComponent, ".") { + return 1, true + } + return + }, +} + +func importGroup(localPrefix, importPath string) int { + for _, fn := range importToGroup { + if n, ok := fn(localPrefix, importPath); ok { + return n + } + } + return 0 +} + +type ImportFixType int + +const ( + AddImport ImportFixType = iota + DeleteImport + SetImportName +) + +type ImportFix struct { + // StmtInfo represents the import statement this fix will add, remove, or change. + StmtInfo ImportInfo + // IdentName is the identifier that this fix will add or remove. + IdentName string + // FixType is the type of fix this is (AddImport, DeleteImport, SetImportName). + FixType ImportFixType + Relevance float64 // see pkg +} + +// parseOtherFiles parses all the Go files in srcDir except filename, including +// test files if filename looks like a test. +// +// It returns an error only if ctx is cancelled. Files with parse errors are +// ignored. +func parseOtherFiles(ctx context.Context, fset *token.FileSet, srcDir, filename string) ([]*ast.File, error) { + // This could use go/packages but it doesn't buy much, and it fails + // with https://golang.org/issue/26296 in LoadFiles mode in some cases. + considerTests := strings.HasSuffix(filename, "_test.go") + + fileBase := filepath.Base(filename) + packageFileInfos, err := os.ReadDir(srcDir) + if err != nil { + return nil, ctx.Err() + } + + var files []*ast.File + for _, fi := range packageFileInfos { + if ctx.Err() != nil { + return nil, ctx.Err() + } + if fi.Name() == fileBase || !strings.HasSuffix(fi.Name(), ".go") { + continue + } + if !considerTests && strings.HasSuffix(fi.Name(), "_test.go") { + continue + } + + f, err := parser.ParseFile(fset, filepath.Join(srcDir, fi.Name()), nil, parser.SkipObjectResolution) + if err != nil { + continue + } + + files = append(files, f) + } + + return files, ctx.Err() +} + +// addGlobals puts the names of package vars into the provided map. +func addGlobals(f *ast.File, globals map[string]bool) { + for _, decl := range f.Decls { + genDecl, ok := decl.(*ast.GenDecl) + if !ok { + continue + } + + for _, spec := range genDecl.Specs { + valueSpec, ok := spec.(*ast.ValueSpec) + if !ok { + continue + } + globals[valueSpec.Names[0].Name] = true + } + } +} + +// collectReferences builds a map of selector expressions, from +// left hand side (X) to a set of right hand sides (Sel). +func collectReferences(f *ast.File) References { + refs := References{} + + var visitor visitFn + visitor = func(node ast.Node) ast.Visitor { + if node == nil { + return visitor + } + switch v := node.(type) { + case *ast.SelectorExpr: + xident, ok := v.X.(*ast.Ident) + if !ok { + break + } + if xident.Obj != nil { + // If the parser can resolve it, it's not a package ref. + break + } + if !ast.IsExported(v.Sel.Name) { + // Whatever this is, it's not exported from a package. + break + } + pkgName := xident.Name + r := refs[pkgName] + if r == nil { + r = make(map[string]bool) + refs[pkgName] = r + } + r[v.Sel.Name] = true + } + return visitor + } + ast.Walk(visitor, f) + return refs +} + +// collectImports returns all the imports in f. +// Unnamed imports (., _) and "C" are ignored. +func collectImports(f *ast.File) []*ImportInfo { + var imports []*ImportInfo + for _, imp := range f.Imports { + var name string + if imp.Name != nil { + name = imp.Name.Name + } + if imp.Path.Value == `"C"` || name == "_" || name == "." { + continue + } + path := strings.Trim(imp.Path.Value, `"`) + imports = append(imports, &ImportInfo{ + Name: name, + ImportPath: path, + }) + } + return imports +} + +// findMissingImport searches pass's candidates for an import that provides +// pkg, containing all of syms. +func (p *pass) findMissingImport(pkg string, syms map[string]bool) *ImportInfo { + for _, candidate := range p.candidates { + pkgInfo, ok := p.knownPackages[candidate.ImportPath] + if !ok { + continue + } + if p.importIdentifier(candidate) != pkg { + continue + } + + allFound := true + for right := range syms { + if !pkgInfo.Exports[right] { + allFound = false + break + } + } + + if allFound { + return candidate + } + } + return nil +} + +// A pass contains all the inputs and state necessary to fix a file's imports. +// It can be modified in some ways during use; see comments below. +type pass struct { + // Inputs. These must be set before a call to load, and not modified after. + fset *token.FileSet // fset used to parse f and its siblings. + f *ast.File // the file being fixed. + srcDir string // the directory containing f. + logf func(string, ...any) + source Source // the environment to use for go commands, etc. + loadRealPackageNames bool // if true, load package names from disk rather than guessing them. + otherFiles []*ast.File // sibling files. + goroot string + + // Intermediate state, generated by load. + existingImports map[string][]*ImportInfo + allRefs References + missingRefs References + + // Inputs to fix. These can be augmented between successive fix calls. + lastTry bool // indicates that this is the last call and fix should clean up as best it can. + candidates []*ImportInfo // candidate imports in priority order. + knownPackages map[string]*PackageInfo // information about all known packages. +} + +// loadPackageNames saves the package names for everything referenced by imports. +func (p *pass) loadPackageNames(ctx context.Context, imports []*ImportInfo) error { + if p.logf != nil { + p.logf("loading package names for %v packages", len(imports)) + defer func() { + p.logf("done loading package names for %v packages", len(imports)) + }() + } + var unknown []string + for _, imp := range imports { + if _, ok := p.knownPackages[imp.ImportPath]; ok { + continue + } + unknown = append(unknown, imp.ImportPath) + } + names, err := p.source.LoadPackageNames(ctx, p.srcDir, unknown) + if err != nil { + return err + } + + // TODO(rfindley): revisit this. Why do we need to store known packages with + // no exports? The inconsistent data is confusing. + for path, name := range names { + p.knownPackages[path] = &PackageInfo{ + Name: name, + Exports: map[string]bool{}, + } + } + return nil +} + +// WithoutVersion removes a trailing major version, if there is one. +func WithoutVersion(nm string) string { + if v := path.Base(nm); len(v) > 0 && v[0] == 'v' { + if _, err := strconv.Atoi(v[1:]); err == nil { + // this is, for instance, called with rand/v2 and returns rand + if len(v) < len(nm) { + xnm := nm[:len(nm)-len(v)-1] + return path.Base(xnm) + } + } + } + return nm +} + +// importIdentifier returns the identifier that imp will introduce. It will +// guess if the package name has not been loaded, e.g. because the source +// is not available. +func (p *pass) importIdentifier(imp *ImportInfo) string { + if imp.Name != "" { + return imp.Name + } + known := p.knownPackages[imp.ImportPath] + if known != nil && known.Name != "" { + return WithoutVersion(known.Name) + } + return ImportPathToAssumedName(imp.ImportPath) +} + +// load reads in everything necessary to run a pass, and reports whether the +// file already has all the imports it needs. It fills in p.missingRefs with the +// file's missing symbols, if any, or removes unused imports if not. +// This is called 3(!) times: self, otherFiles, loadRealPackageNames +func (p *pass) load(ctx context.Context) ([]*ImportFix, bool) { + p.knownPackages = map[string]*PackageInfo{} + p.missingRefs = References{} + p.existingImports = map[string][]*ImportInfo{} + + // Load basic information about the file in question. + p.allRefs = collectReferences(p.f) + + // Load stuff from other files in the same package: + // global variables so we know they don't need resolving, and imports + // that we might want to mimic. + globals := map[string]bool{} + for _, otherFile := range p.otherFiles { + // Don't load globals from files that are in the same directory + // but a different package. Using them to suggest imports is OK. + if p.f.Name.Name == otherFile.Name.Name { + addGlobals(otherFile, globals) + } + p.candidates = append(p.candidates, collectImports(otherFile)...) + } + + // Resolve all the import paths we've seen to package names, and store + // f's imports by the identifier they introduce. + imports := collectImports(p.f) + if p.loadRealPackageNames { + err := p.loadPackageNames(ctx, append(imports, p.candidates...)) + if err != nil { + if p.logf != nil { + p.logf("loading package names: %v", err) + } + return nil, false + } + } + for _, imp := range imports { + p.existingImports[p.importIdentifier(imp)] = append(p.existingImports[p.importIdentifier(imp)], imp) + } + + // Find missing references. + for left, rights := range p.allRefs { + if globals[left] { + continue + } + _, ok := p.existingImports[left] + if !ok { + p.missingRefs[left] = rights + continue + } + } + if len(p.missingRefs) != 0 { + return nil, false + } + + return p.fix() +} + +// fix attempts to satisfy missing imports using p.candidates. If it finds +// everything, or if p.lastTry is true, it updates fixes to add the imports it found, +// delete anything unused, and update import names, and returns true. +func (p *pass) fix() ([]*ImportFix, bool) { + // Find missing imports. + var selected []*ImportInfo + for left, rights := range p.missingRefs { + if imp := p.findMissingImport(left, rights); imp != nil { + selected = append(selected, imp) + } + } + + if !p.lastTry && len(selected) != len(p.missingRefs) { + return nil, false + } + + // Found everything, or giving up. Add the new imports and remove any unused. + var fixes []*ImportFix + for _, identifierImports := range p.existingImports { + for _, imp := range identifierImports { + // We deliberately ignore globals here, because we can't be sure + // they're in the same package. People do things like put multiple + // main packages in the same directory, and we don't want to + // remove imports if they happen to have the same name as a var in + // a different package. + if _, ok := p.allRefs[p.importIdentifier(imp)]; !ok { + fixes = append(fixes, &ImportFix{ + StmtInfo: *imp, + IdentName: p.importIdentifier(imp), + FixType: DeleteImport, + }) + continue + } + + // An existing import may need to update its import name to be correct. + if name := p.importSpecName(imp); name != imp.Name { + fixes = append(fixes, &ImportFix{ + StmtInfo: ImportInfo{ + Name: name, + ImportPath: imp.ImportPath, + }, + IdentName: p.importIdentifier(imp), + FixType: SetImportName, + }) + } + } + } + // Collecting fixes involved map iteration, so sort for stability. See + // golang/go#59976. + sortFixes(fixes) + + // collect selected fixes in a separate slice, so that it can be sorted + // separately. Note that these fixes must occur after fixes to existing + // imports. TODO(rfindley): figure out why. + var selectedFixes []*ImportFix + for _, imp := range selected { + selectedFixes = append(selectedFixes, &ImportFix{ + StmtInfo: ImportInfo{ + Name: p.importSpecName(imp), + ImportPath: imp.ImportPath, + }, + IdentName: p.importIdentifier(imp), + FixType: AddImport, + }) + } + sortFixes(selectedFixes) + + return append(fixes, selectedFixes...), true +} + +func sortFixes(fixes []*ImportFix) { + sort.Slice(fixes, func(i, j int) bool { + fi, fj := fixes[i], fixes[j] + if fi.StmtInfo.ImportPath != fj.StmtInfo.ImportPath { + return fi.StmtInfo.ImportPath < fj.StmtInfo.ImportPath + } + if fi.StmtInfo.Name != fj.StmtInfo.Name { + return fi.StmtInfo.Name < fj.StmtInfo.Name + } + if fi.IdentName != fj.IdentName { + return fi.IdentName < fj.IdentName + } + return fi.FixType < fj.FixType + }) +} + +func hasDeleteFix(fixes []*ImportFix) bool { + for _, fix := range fixes { + if fix.FixType == DeleteImport { + return true + } + } + return false +} + +// importSpecName gets the import name of imp in the import spec. +// +// When the import identifier matches the assumed import name, the import name does +// not appear in the import spec. +func (p *pass) importSpecName(imp *ImportInfo) string { + // If we did not load the real package names, or the name is already set, + // we just return the existing name. + if !p.loadRealPackageNames || imp.Name != "" { + return imp.Name + } + + ident := p.importIdentifier(imp) + if ident == ImportPathToAssumedName(imp.ImportPath) { + return "" // ident not needed since the assumed and real names are the same. + } + return ident +} + +// apply will perform the fixes on f in order. +func apply(fset *token.FileSet, f *ast.File, fixes []*ImportFix) { + for _, fix := range fixes { + switch fix.FixType { + case DeleteImport: + astutil.DeleteNamedImport(fset, f, fix.StmtInfo.Name, fix.StmtInfo.ImportPath) + case AddImport: + astutil.AddNamedImport(fset, f, fix.StmtInfo.Name, fix.StmtInfo.ImportPath) + case SetImportName: + // Find the matching import path and change the name. + for _, spec := range f.Imports { + path := strings.Trim(spec.Path.Value, `"`) + if path == fix.StmtInfo.ImportPath { + spec.Name = &ast.Ident{ + Name: fix.StmtInfo.Name, + NamePos: spec.Pos(), + } + } + } + } + } +} + +// assumeSiblingImportsValid assumes that siblings' use of packages is valid, +// adding the exports they use. +func (p *pass) assumeSiblingImportsValid() { + for _, f := range p.otherFiles { + refs := collectReferences(f) + imports := collectImports(f) + importsByName := map[string]*ImportInfo{} + for _, imp := range imports { + importsByName[p.importIdentifier(imp)] = imp + } + for left, rights := range refs { + if imp, ok := importsByName[left]; ok { + if m, ok := stdlib.PackageSymbols[imp.ImportPath]; ok { + // We have the stdlib in memory; no need to guess. + rights = symbolNameSet(m) + } + // TODO(rfindley): we should set package name here, for consistency. + p.addCandidate(imp, &PackageInfo{ + // no name; we already know it. + Exports: rights, + }) + } + } + } +} + +// addCandidate adds a candidate import to p, and merges in the information +// in pkg. +func (p *pass) addCandidate(imp *ImportInfo, pkg *PackageInfo) { + p.candidates = append(p.candidates, imp) + if existing, ok := p.knownPackages[imp.ImportPath]; ok { + if existing.Name == "" { + existing.Name = pkg.Name + } + for export := range pkg.Exports { + existing.Exports[export] = true + } + } else { + p.knownPackages[imp.ImportPath] = pkg + } +} + +// fixImports adds and removes imports from f so that all its references are +// satisfied and there are no unused imports. +// +// This is declared as a variable rather than a function so goimports can +// easily be extended by adding a file with an init function. +// +// DO NOT REMOVE: used internally at Google. +var fixImports = fixImportsDefault + +func fixImportsDefault(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) error { + fixes, err := getFixes(context.Background(), fset, f, filename, env) + if err != nil { + return err + } + apply(fset, f, fixes) + return nil +} + +// getFixes gets the import fixes that need to be made to f in order to fix the imports. +// It does not modify the ast. +func getFixes(ctx context.Context, fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) ([]*ImportFix, error) { + source, err := NewProcessEnvSource(env, filename, f.Name.Name) + if err != nil { + return nil, err + } + goEnv, err := env.goEnv() + if err != nil { + return nil, err + } + return getFixesWithSource(ctx, fset, f, filename, goEnv["GOROOT"], env.logf, source) +} + +func getFixesWithSource(ctx context.Context, fset *token.FileSet, f *ast.File, filename string, goroot string, logf func(string, ...any), source Source) ([]*ImportFix, error) { + fixes, err := computeFixesWithSource(ctx, fset, f, filename, goroot, logf, source) + if err != nil { + return nil, err + } + return ensureEmbedImport(f, fixes), nil +} + +// ensureEmbedImport makes sure a file containing a //go:embed directive +// imports "embed" once fixes are applied. The compiler requires the import +// whenever a //go:embed directive is present, even when the embedded +// variable's type (string or []byte) means the package is never referenced by +// name. Any import of "embed" (renamed or blank) satisfies it. +func ensureEmbedImport(f *ast.File, fixes []*ImportFix) []*ImportFix { + if !hasEmbedDirective(f) { + return fixes + } + // Work out the state of the "embed" import once fixes are applied. It may + // already be imported (under any name), be added by normal resolution (as + // for an embed.FS variable), or be deleted as an unused import. + imported := importsEmbed(f) + deleteFix := -1 + for i, fix := range fixes { + if fix.StmtInfo.ImportPath != "embed" { + continue + } + switch fix.FixType { + case AddImport: + imported = true + case DeleteImport: + imported = false + deleteFix = i + } + } + if imported { + return fixes + } + blankEmbed := &ImportFix{ + StmtInfo: ImportInfo{ImportPath: "embed", Name: "_"}, + IdentName: "_", + Relevance: MaxRelevance, + } + if deleteFix >= 0 { + // The file imports "embed" but the import is about to be removed as + // unused. Keep it as a blank import instead of deleting it and adding + // a new one back. + blankEmbed.FixType = SetImportName + fixes[deleteFix] = blankEmbed + return fixes + } + blankEmbed.FixType = AddImport + return append(fixes, blankEmbed) +} + +// hasEmbedDirective reports whether f contains a //go:embed directive. +func hasEmbedDirective(f *ast.File) bool { + for _, cg := range f.Comments { + for _, c := range cg.List { + // A //go:embed directive is the text "//go:embed" followed by + // whitespace and the patterns (see go/build.parseGoEmbed). The + // whitespace is what distinguishes it from an ordinary comment + // such as "//go:embedded". + if rest, ok := strings.CutPrefix(c.Text, "//go:embed"); ok && + len(rest) > 0 && (rest[0] == ' ' || rest[0] == '\t') { + return true + } + } + } + return false +} + +// importsEmbed reports whether f imports the "embed" package under any name. +func importsEmbed(f *ast.File) bool { + for _, imp := range f.Imports { + if imp.Path.Value == `"embed"` { + return true + } + } + return false +} + +func computeFixesWithSource(ctx context.Context, fset *token.FileSet, f *ast.File, filename string, goroot string, logf func(string, ...any), source Source) ([]*ImportFix, error) { + // This logic is defensively duplicated from getFixes. + abs, err := filepath.Abs(filename) + if err != nil { + return nil, err + } + srcDir := filepath.Dir(abs) + + if logf != nil { + logf("fixImports(filename=%q), srcDir=%q ...", filename, srcDir) + } + + // First pass: looking only at f, and using the naive algorithm to + // derive package names from import paths, see if the file is already + // complete. We can't add any imports yet, because we don't know + // if missing references are actually package vars. + p := &pass{ + fset: fset, + f: f, + srcDir: srcDir, + logf: logf, + goroot: goroot, + source: source, + } + if fixes, done := p.load(ctx); done { + return fixes, nil + } + + otherFiles, err := parseOtherFiles(ctx, fset, srcDir, filename) + if err != nil { + return nil, err + } + + // Second pass: add information from other files in the same package, + // like their package vars and imports. + p.otherFiles = otherFiles + if fixes, done := p.load(ctx); done { + return fixes, nil + } + + // Now we can try adding imports from the stdlib. + p.assumeSiblingImportsValid() + addStdlibCandidates(p, p.missingRefs) + if fixes, done := p.fix(); done && !hasDeleteFix(fixes) { + return fixes, nil + } + + // Third pass: get real package names where we had previously used + // the naive algorithm. + p = &pass{ + fset: fset, + f: f, + srcDir: srcDir, + logf: logf, + goroot: goroot, + source: p.source, // safe to reuse, as it's just a wrapper around env + } + p.loadRealPackageNames = true + p.otherFiles = otherFiles + + // If there is an Index for the GOMODCACHE, remember that, and later make it so that the + // directory walk doesn't go into the module cache, since we already have all the information. + var ix *modindex.Index + if src, ok := source.(*ProcessEnvSource); ok { + var err error + if ix, err = modindex.Read(src.env.Env["GOMODCACHE"]); err != nil { + ix = nil // don't use it if there was an error + } + } + + if ix != nil { + src, ok := p.source.(*ProcessEnvSource) + if ok { + // For safety, clone the env so that we don't modify the caller's env. + env := *src.env + env.Env = maps.Clone(src.env.Env) + src.env = &env + // avoid looking in the module cache, as we have the index instead: + // This makes a later call to newModuleresolver (from + // LoadPackageNames) produce a resolver that will not look + // in the module cache + src.env.Env["GOMODCACHE"] = "" + } + } + if fixes, done := p.load(ctx); done { + return fixes, nil + } + + if err := addStdlibCandidates(p, p.missingRefs); err != nil { + return nil, err + } + p.assumeSiblingImportsValid() + if fixes, done := p.fix(); done { + return fixes, nil + } + + // Go look for candidates in $GOPATH, etc. We don't necessarily load + // the real exports of sibling imports, so keep assuming their contents. + if err := addExternalCandidates(ctx, p, p.missingRefs, filename, ix); err != nil { + return nil, err + } + + p.lastTry = true + fixes, _ := p.fix() + return fixes, nil +} + +// MaxRelevance is the highest relevance, used for the standard library. +// Chosen arbitrarily to match pre-existing gopls code. +const MaxRelevance = 7.0 + +// getCandidatePkgs works with the passed callback to find all acceptable packages. +// It deduplicates by import path, and uses a cached stdlib rather than reading +// from disk. +func getCandidatePkgs(ctx context.Context, wrappedCallback *scanCallback, filename, filePkg string, env *ProcessEnv) error { + notSelf := func(p *pkg) bool { + return p.packageName != filePkg || p.dir != filepath.Dir(filename) + } + goenv, err := env.goEnv() + if err != nil { + return err + } + + var mu sync.Mutex // to guard asynchronous access to dupCheck + dupCheck := map[string]struct{}{} + + // Start off with the standard library. + for importPath, symbols := range stdlib.PackageSymbols { + p := &pkg{ + dir: filepath.Join(goenv["GOROOT"], "src", importPath), + importPathShort: importPath, + packageName: path.Base(importPath), + relevance: MaxRelevance, + } + dupCheck[importPath] = struct{}{} + if notSelf(p) && wrappedCallback.dirFound(p) && wrappedCallback.packageNameLoaded(p) { + var exports []stdlib.Symbol + for _, sym := range symbols { + switch sym.Kind { + case stdlib.Func, stdlib.Type, stdlib.Var, stdlib.Const: + exports = append(exports, sym) + } + } + wrappedCallback.exportsLoaded(p, exports) + } + } + + scanFilter := &scanCallback{ + rootFound: func(root gopathwalk.Root) bool { + // Exclude goroot results -- getting them is relatively expensive, not cached, + // and generally redundant with the in-memory version. + return root.Type != gopathwalk.RootGOROOT && wrappedCallback.rootFound(root) + }, + dirFound: wrappedCallback.dirFound, + packageNameLoaded: func(pkg *pkg) bool { + mu.Lock() + defer mu.Unlock() + if _, ok := dupCheck[pkg.importPathShort]; ok { + return false + } + dupCheck[pkg.importPathShort] = struct{}{} + return notSelf(pkg) && wrappedCallback.packageNameLoaded(pkg) + }, + exportsLoaded: func(pkg *pkg, exports []stdlib.Symbol) { + // If we're an x_test, load the package under test's test variant. + if strings.HasSuffix(filePkg, "_test") && pkg.dir == filepath.Dir(filename) { + var err error + _, exports, err = loadExportsFromFiles(ctx, env, pkg.dir, true) + if err != nil { + return + } + } + wrappedCallback.exportsLoaded(pkg, exports) + }, + } + resolver, err := env.GetResolver() + if err != nil { + return err + } + return resolver.scan(ctx, scanFilter) +} + +func ScoreImportPaths(ctx context.Context, env *ProcessEnv, paths []string) (map[string]float64, error) { + result := make(map[string]float64) + resolver, err := env.GetResolver() + if err != nil { + return nil, err + } + for _, path := range paths { + result[path] = resolver.scoreImportPath(ctx, path) + } + return result, nil +} + +func PrimeCache(ctx context.Context, resolver Resolver) error { + // Fully scan the disk for directories, but don't actually read any Go files. + callback := &scanCallback{ + rootFound: func(root gopathwalk.Root) bool { + // See getCandidatePkgs: walking GOROOT is apparently expensive and + // unnecessary. + return root.Type != gopathwalk.RootGOROOT + }, + dirFound: func(pkg *pkg) bool { + return false + }, + // packageNameLoaded and exportsLoaded must never be called. + } + + return resolver.scan(ctx, callback) +} + +func candidateImportName(pkg *pkg) string { + if ImportPathToAssumedName(pkg.importPathShort) != pkg.packageName { + return pkg.packageName + } + return "" +} + +// GetAllCandidates calls wrapped for each package whose name starts with +// searchPrefix, and can be imported from filename with the package name filePkg. +// +// Beware that the wrapped function may be called multiple times concurrently. +// TODO(adonovan): encapsulate the concurrency. +func GetAllCandidates(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error { + callback := &scanCallback{ + rootFound: func(gopathwalk.Root) bool { + return true + }, + dirFound: func(pkg *pkg) bool { + if !CanUse(filename, pkg.dir) { + return false + } + // Try the assumed package name first, then a simpler path match + // in case of packages named vN, which are not uncommon. + return strings.HasPrefix(ImportPathToAssumedName(pkg.importPathShort), searchPrefix) || + strings.HasPrefix(path.Base(pkg.importPathShort), searchPrefix) + }, + packageNameLoaded: func(pkg *pkg) bool { + if !strings.HasPrefix(pkg.packageName, searchPrefix) { + return false + } + wrapped(ImportFix{ + StmtInfo: ImportInfo{ + ImportPath: pkg.importPathShort, + Name: candidateImportName(pkg), + }, + IdentName: pkg.packageName, + FixType: AddImport, + Relevance: pkg.relevance, + }) + return false + }, + } + return getCandidatePkgs(ctx, callback, filename, filePkg, env) +} + +// GetImportPaths calls wrapped for each package whose import path starts with +// searchPrefix, and can be imported from filename with the package name filePkg. +func GetImportPaths(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error { + callback := &scanCallback{ + rootFound: func(gopathwalk.Root) bool { + return true + }, + dirFound: func(pkg *pkg) bool { + if !CanUse(filename, pkg.dir) { + return false + } + return strings.HasPrefix(pkg.importPathShort, searchPrefix) + }, + packageNameLoaded: func(pkg *pkg) bool { + wrapped(ImportFix{ + StmtInfo: ImportInfo{ + ImportPath: pkg.importPathShort, + Name: candidateImportName(pkg), + }, + IdentName: pkg.packageName, + FixType: AddImport, + Relevance: pkg.relevance, + }) + return false + }, + } + return getCandidatePkgs(ctx, callback, filename, filePkg, env) +} + +// A PackageExport is a package and its exports. +type PackageExport struct { + Fix *ImportFix + Exports []stdlib.Symbol +} + +// GetPackageExports returns all known packages with name pkg and their exports. +func GetPackageExports(ctx context.Context, wrapped func(PackageExport), searchPkg, filename, filePkg string, env *ProcessEnv) error { + callback := &scanCallback{ + rootFound: func(gopathwalk.Root) bool { + return true + }, + dirFound: func(pkg *pkg) bool { + return pkgIsCandidate(filename, References{searchPkg: nil}, pkg) + }, + packageNameLoaded: func(pkg *pkg) bool { + return pkg.packageName == searchPkg + }, + exportsLoaded: func(pkg *pkg, exports []stdlib.Symbol) { + sortSymbols(exports) + wrapped(PackageExport{ + Fix: &ImportFix{ + StmtInfo: ImportInfo{ + ImportPath: pkg.importPathShort, + Name: candidateImportName(pkg), + }, + IdentName: pkg.packageName, + FixType: AddImport, + Relevance: pkg.relevance, + }, + Exports: exports, + }) + }, + } + return getCandidatePkgs(ctx, callback, filename, filePkg, env) +} + +// TODO(rfindley): we should depend on GOOS and GOARCH, to provide accurate +// imports when doing cross-platform development. +var requiredGoEnvVars = []string{ + "GO111MODULE", + "GOFLAGS", + "GOINSECURE", + "GOMOD", + "GOMODCACHE", + "GONOPROXY", + "GONOSUMDB", + "GOPATH", + "GOPROXY", + "GOROOT", + "GOSUMDB", + "GOWORK", +} + +// ProcessEnv contains environment variables and settings that affect the use of +// the go command, the go/build package, etc. +// +// ...a ProcessEnv *also* overwrites its Env along with derived state in the +// form of the resolver. And because it is lazily initialized, an env may just +// be broken and unusable, but there is no way for the caller to detect that: +// all queries will just fail. +// +// TODO(rfindley): refactor this package so that this type (perhaps renamed to +// just Env or Config) is an immutable configuration struct, to be exchanged +// for an initialized object via a constructor that returns an error. Perhaps +// the signature should be `func NewResolver(*Env) (*Resolver, error)`, where +// resolver is a concrete type used for resolving imports. Via this +// refactoring, we can avoid the need to call ProcessEnv.init and +// ProcessEnv.GoEnv everywhere, and implicitly fix all the places where this +// these are misused. Also, we'd delegate the caller the decision of how to +// handle a broken environment. +type ProcessEnv struct { + GocmdRunner *gocommand.Runner + + BuildFlags []string + ModFlag string + + // SkipPathInScan returns true if the path should be skipped from scans of + // the RootCurrentModule root type. The function argument is a clean, + // absolute path. + SkipPathInScan func(string) bool + + // Env overrides the OS environment, and can be used to specify + // GOPROXY, GO111MODULE, etc. PATH cannot be set here, because + // exec.Command will not honor it. + // Specifying all of requiredGoEnvVars avoids a call to `go env`. + Env map[string]string + + WorkingDir string + + // If Logf is non-nil, debug logging is enabled through this function. + Logf func(format string, args ...any) + + // If set, ModCache holds a shared cache of directory info to use across + // multiple ProcessEnvs. + ModCache *DirInfoCache + + initialized bool // see TODO above + + // resolver and resolverErr are lazily evaluated (see GetResolver). + // This is unclean, but see the big TODO in the docstring for ProcessEnv + // above: for now, we can't be sure that the ProcessEnv is fully initialized. + resolver Resolver + resolverErr error +} + +func (e *ProcessEnv) goEnv() (map[string]string, error) { + if err := e.init(); err != nil { + return nil, err + } + return e.Env, nil +} + +func (e *ProcessEnv) matchFile(dir, name string) (bool, error) { + bctx, err := e.buildContext() + if err != nil { + return false, err + } + return bctx.MatchFile(dir, name) +} + +// CopyConfig copies the env's configuration into a new env. +func (e *ProcessEnv) CopyConfig() *ProcessEnv { + copy := &ProcessEnv{ + GocmdRunner: e.GocmdRunner, + initialized: e.initialized, + BuildFlags: e.BuildFlags, + Logf: e.Logf, + WorkingDir: e.WorkingDir, + resolver: nil, + Env: map[string]string{}, + } + maps.Copy(copy.Env, e.Env) + return copy +} + +func (e *ProcessEnv) init() error { + if e.initialized { + return nil + } + + foundAllRequired := true + for _, k := range requiredGoEnvVars { + if _, ok := e.Env[k]; !ok { + foundAllRequired = false + break + } + } + if foundAllRequired { + e.initialized = true + return nil + } + + if e.Env == nil { + e.Env = map[string]string{} + } + + goEnv := map[string]string{} + stdout, err := e.invokeGo(context.TODO(), "env", append([]string{"-json"}, requiredGoEnvVars...)...) + if err != nil { + return err + } + if err := json.Unmarshal(stdout.Bytes(), &goEnv); err != nil { + return err + } + maps.Copy(e.Env, goEnv) + e.initialized = true + return nil +} + +func (e *ProcessEnv) env() []string { + var env []string // the gocommand package will prepend os.Environ. + for k, v := range e.Env { + env = append(env, k+"="+v) + } + return env +} + +func (e *ProcessEnv) GetResolver() (Resolver, error) { + if err := e.init(); err != nil { + return nil, err + } + + if e.resolver == nil && e.resolverErr == nil { + // TODO(rfindley): we should only use a gopathResolver here if the working + // directory is actually *in* GOPATH. (I seem to recall an open gopls issue + // for this behavior, but I can't find it). + // + // For gopls, we can optionally explicitly choose a resolver type, since we + // already know the view type. + if e.Env["GOMOD"] == "" && (e.Env["GOWORK"] == "" || e.Env["GOWORK"] == "off") { + e.resolver = newGopathResolver(e) + e.logf("created gopath resolver") + } else if r, err := newModuleResolver(e, e.ModCache); err != nil { + e.resolverErr = err + e.logf("failed to create module resolver: %v", err) + } else { + e.resolver = Resolver(r) + e.logf("created module resolver") + } + } + + return e.resolver, e.resolverErr +} + +// logf logs if e.Logf is non-nil. +func (e *ProcessEnv) logf(format string, args ...any) { + if e.Logf != nil { + e.Logf(format, args...) + } +} + +// buildContext returns the build.Context to use for matching files. +// +// TODO(rfindley): support dynamic GOOS, GOARCH here, when doing cross-platform +// development. +func (e *ProcessEnv) buildContext() (*build.Context, error) { + ctx := build.Default + goenv, err := e.goEnv() + if err != nil { + return nil, err + } + ctx.GOROOT = goenv["GOROOT"] + ctx.GOPATH = goenv["GOPATH"] + + // As of Go 1.14, build.Context has a Dir field + // (see golang.org/issue/34860). + // Populate it only if present. + rc := reflect.ValueOf(&ctx).Elem() + dir := rc.FieldByName("Dir") + if dir.IsValid() && dir.Kind() == reflect.String { + dir.SetString(e.WorkingDir) + } + + // Since Go 1.11, go/build.Context.Import may invoke 'go list' depending on + // the value in GO111MODULE in the process's environment. We always want to + // run in GOPATH mode when calling Import, so we need to prevent this from + // happening. In Go 1.16, GO111MODULE defaults to "on", so this problem comes + // up more frequently. + // + // HACK: setting any of the Context I/O hooks prevents Import from invoking + // 'go list', regardless of GO111MODULE. This is undocumented, but it's + // unlikely to change before GOPATH support is removed. + ctx.ReadDir = ioutil.ReadDir + + return &ctx, nil +} + +func (e *ProcessEnv) invokeGo(ctx context.Context, verb string, args ...string) (*bytes.Buffer, error) { + inv := gocommand.Invocation{ + Verb: verb, + Args: args, + BuildFlags: e.BuildFlags, + Env: e.env(), + Logf: e.Logf, + WorkingDir: e.WorkingDir, + } + return e.GocmdRunner.Run(ctx, inv) +} + +func addStdlibCandidates(pass *pass, refs References) error { + localbase := func(nm string) string { + ans := path.Base(nm) + if ans[0] == 'v' { + // this is called, for instance, with math/rand/v2 and returns rand/v2 + if _, err := strconv.Atoi(ans[1:]); err == nil { + ix := strings.LastIndex(nm, ans) + more := path.Base(nm[:ix]) + ans = path.Join(more, ans) + } + } + return ans + } + add := func(pkg string) { + // Prevent self-imports. + if path.Base(pkg) == pass.f.Name.Name && filepath.Join(pass.goroot, "src", pkg) == pass.srcDir { + return + } + exports := symbolNameSet(stdlib.PackageSymbols[pkg]) + pass.addCandidate( + &ImportInfo{ImportPath: pkg}, + &PackageInfo{Name: localbase(pkg), Exports: exports}) + } + for left := range refs { + if left == "rand" { + // Make sure we try crypto/rand before any version of math/rand as both have Int() + // and our policy is to recommend crypto + add("crypto/rand") + // if the user's no later than go1.21, this should be "math/rand" + // but we have no way of figuring out what the user is using + // TODO: investigate using the toolchain version to disambiguate in the stdlib + add("math/rand/v2") + // math/rand has an overlapping API + // TestIssue66407 fails without this + add("math/rand") + continue + } + for importPath := range stdlib.PackageSymbols { + if path.Base(importPath) == left { + add(importPath) + } + } + } + return nil +} + +// A Resolver does the build-system-specific parts of goimports. +type Resolver interface { + // loadPackageNames loads the package names in importPaths. + loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) + + // scan works with callback to search for packages. See scanCallback for details. + scan(ctx context.Context, callback *scanCallback) error + + // loadExports returns the package name and set of exported symbols in the + // package at dir. loadExports may be called concurrently. + loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []stdlib.Symbol, error) + + // scoreImportPath returns the relevance for an import path. + scoreImportPath(ctx context.Context, path string) float64 + + // ClearForNewScan returns a new Resolver based on the receiver that has + // cleared its internal caches of directory contents. + // + // The new resolver should be primed and then set via + // [ProcessEnv.UpdateResolver]. + ClearForNewScan() Resolver +} + +// A scanCallback controls a call to scan and receives its results. +// In general, minor errors will be silently discarded; a user should not +// expect to receive a full series of calls for everything. +type scanCallback struct { + // rootFound is called before scanning a new root dir. If it returns true, + // the root will be scanned. Returning false will not necessarily prevent + // directories from that root making it to dirFound. + rootFound func(gopathwalk.Root) bool + // dirFound is called when a directory is found that is possibly a Go package. + // pkg will be populated with everything except packageName. + // If it returns true, the package's name will be loaded. + dirFound func(pkg *pkg) bool + // packageNameLoaded is called when a package is found and its name is loaded. + // If it returns true, the package's exports will be loaded. + packageNameLoaded func(pkg *pkg) bool + // exportsLoaded is called when a package's exports have been loaded. + exportsLoaded func(pkg *pkg, exports []stdlib.Symbol) +} + +func addExternalCandidates(ctx context.Context, pass *pass, refs References, filename string, ix *modindex.Index) error { + ctx, done := event.Start(ctx, "imports.addExternalCandidates") + defer done() + + results, err := pass.source.ResolveReferences(ctx, filename, refs) + if err != nil { + return err + } + + // Add candidates from the module cache. + if ix != nil { + for k, v := range refs { + for n := range v { + cands := ix.Lookup(k, n, false) + for _, cand := range cands { + x := &Result{ + &ImportInfo{ImportPath: cand.ImportPath}, + &PackageInfo{Name: cand.PkgName, + Exports: map[string]bool{cand.Name: true}, + }, + } + results = append(results, x) + } + } + } + } + + for _, result := range results { + if result == nil { + continue + } + // Don't offer completions that would shadow predeclared + // names, such as github.com/coreos/etcd/error. + if types.Universe.Lookup(result.Package.Name) != nil { // predeclared + // Ideally we would skip this candidate only + // if the predeclared name is actually + // referenced by the file, but that's a lot + // trickier to compute and would still create + // an import that is likely to surprise the + // user before long. + continue + } + pass.addCandidate(result.Import, result.Package) + } + return nil +} + +// notIdentifier reports whether ch is an invalid identifier character. +func notIdentifier(ch rune) bool { + return !('a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || + '0' <= ch && ch <= '9' || + ch == '_' || + ch >= utf8.RuneSelf && (unicode.IsLetter(ch) || unicode.IsDigit(ch))) +} + +// ImportPathToAssumedName returns the assumed package name of an import path. +// It does this using only string parsing of the import path. +// It picks the last element of the path that does not look like a major +// version, and then picks the valid identifier off the start of that element. +// It is used to determine if a local rename should be added to an import for +// clarity. +// This function could be moved to a standard package and exported if we want +// for use in other tools. +func ImportPathToAssumedName(importPath string) string { + base := path.Base(importPath) + if strings.HasPrefix(base, "v") { + if _, err := strconv.Atoi(base[1:]); err == nil { + dir := path.Dir(importPath) + if dir != "." { + base = path.Base(dir) + } + } + } + base = strings.TrimPrefix(base, "go-") + if i := strings.IndexFunc(base, notIdentifier); i >= 0 { + base = base[:i] + } + return base +} + +// gopathResolver implements resolver for GOPATH workspaces. +type gopathResolver struct { + env *ProcessEnv + cache *DirInfoCache + scanSema chan struct{} // scanSema prevents concurrent scans. +} + +func newGopathResolver(env *ProcessEnv) *gopathResolver { + r := &gopathResolver{ + env: env, + cache: NewDirInfoCache(), + scanSema: make(chan struct{}, 1), + } + r.scanSema <- struct{}{} + return r +} + +func (r *gopathResolver) ClearForNewScan() Resolver { + return newGopathResolver(r.env) +} + +func (r *gopathResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) { + names := map[string]string{} + bctx, err := r.env.buildContext() + if err != nil { + return nil, err + } + for _, path := range importPaths { + names[path] = importPathToName(bctx, path, srcDir) + } + return names, nil +} + +// importPathToName finds out the actual package name, as declared in its .go files. +func importPathToName(bctx *build.Context, importPath, srcDir string) string { + // Fast path for standard library without going to disk. + if stdlib.HasPackage(importPath) { + return path.Base(importPath) // stdlib packages always match their paths. + } + + buildPkg, err := bctx.Import(importPath, srcDir, build.FindOnly) + if err != nil { + return "" + } + pkgName, err := packageDirToName(buildPkg.Dir) + if err != nil { + return "" + } + return pkgName +} + +// packageDirToName is a faster version of build.Import if +// the only thing desired is the package name. Given a directory, +// packageDirToName then only parses one file in the package, +// trusting that the files in the directory are consistent. +func packageDirToName(dir string) (packageName string, err error) { + d, err := os.Open(dir) + if err != nil { + return "", err + } + names, err := d.Readdirnames(-1) + d.Close() + if err != nil { + return "", err + } + sort.Strings(names) // to have predictable behavior + var lastErr error + var nfile int + for _, name := range names { + if !strings.HasSuffix(name, ".go") { + continue + } + if strings.HasSuffix(name, "_test.go") { + continue + } + nfile++ + fullFile := filepath.Join(dir, name) + + fset := token.NewFileSet() + f, err := parser.ParseFile(fset, fullFile, nil, parser.PackageClauseOnly) + if err != nil { + lastErr = err + continue + } + pkgName := f.Name.Name + if pkgName == "documentation" { + // Special case from go/build.ImportDir, not + // handled by ctx.MatchFile. + continue + } + if pkgName == "main" { + // Also skip package main, assuming it's a +build ignore generator or example. + // Since you can't import a package main anyway, there's no harm here. + continue + } + return pkgName, nil + } + if lastErr != nil { + return "", lastErr + } + return "", fmt.Errorf("no importable package found in %d Go files", nfile) +} + +type pkg struct { + dir string // absolute file path to pkg directory ("/usr/lib/go/src/net/http") + importPathShort string // vendorless import path ("net/http", "a/b") + packageName string // package name loaded from source if requested + relevance float64 // a weakly-defined score of how relevant a package is. 0 is most relevant. +} + +type pkgDistance struct { + pkg *pkg + distance int // relative distance to target +} + +// byDistanceOrImportPathShortLength sorts by relative distance breaking ties +// on the short import path length and then the import string itself. +type byDistanceOrImportPathShortLength []pkgDistance + +func (s byDistanceOrImportPathShortLength) Len() int { return len(s) } +func (s byDistanceOrImportPathShortLength) Less(i, j int) bool { + di, dj := s[i].distance, s[j].distance + if di == -1 { + return false + } + if dj == -1 { + return true + } + if di != dj { + return di < dj + } + + vi, vj := s[i].pkg.importPathShort, s[j].pkg.importPathShort + if len(vi) != len(vj) { + return len(vi) < len(vj) + } + return vi < vj +} +func (s byDistanceOrImportPathShortLength) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +func distance(basepath, targetpath string) int { + p, err := filepath.Rel(basepath, targetpath) + if err != nil { + return -1 + } + if p == "." { + return 0 + } + return strings.Count(p, string(filepath.Separator)) + 1 +} + +func (r *gopathResolver) scan(ctx context.Context, callback *scanCallback) error { + add := func(root gopathwalk.Root, dir string) { + // We assume cached directories have not changed. We can skip them and their + // children. + if _, ok := r.cache.Load(dir); ok { + return + } + + importpath := filepath.ToSlash(dir[len(root.Path)+len("/"):]) + info := directoryPackageInfo{ + status: directoryScanned, + dir: dir, + rootType: root.Type, + nonCanonicalImportPath: VendorlessPath(importpath), + } + r.cache.Store(dir, info) + } + processDir := func(info directoryPackageInfo) { + // Skip this directory if we were not able to get the package information successfully. + if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil { + return + } + + p := &pkg{ + importPathShort: info.nonCanonicalImportPath, + dir: info.dir, + relevance: MaxRelevance - 1, + } + if info.rootType == gopathwalk.RootGOROOT { + p.relevance = MaxRelevance + } + + if !callback.dirFound(p) { + return + } + var err error + p.packageName, err = r.cache.CachePackageName(info) + if err != nil { + return + } + + if !callback.packageNameLoaded(p) { + return + } + if _, exports, err := r.loadExports(ctx, p, false); err == nil { + callback.exportsLoaded(p, exports) + } + } + stop := r.cache.ScanAndListen(ctx, processDir) + defer stop() + + goenv, err := r.env.goEnv() + if err != nil { + return err + } + var roots []gopathwalk.Root + roots = append(roots, gopathwalk.Root{Path: filepath.Join(goenv["GOROOT"], "src"), Type: gopathwalk.RootGOROOT}) + for _, p := range filepath.SplitList(goenv["GOPATH"]) { + roots = append(roots, gopathwalk.Root{Path: filepath.Join(p, "src"), Type: gopathwalk.RootGOPATH}) + } + // The callback is not necessarily safe to use in the goroutine below. Process roots eagerly. + roots = filterRoots(roots, callback.rootFound) + // We can't cancel walks, because we need them to finish to have a usable + // cache. Instead, run them in a separate goroutine and detach. + scanDone := make(chan struct{}) + go func() { + select { + case <-ctx.Done(): + return + case <-r.scanSema: + } + defer func() { r.scanSema <- struct{}{} }() + gopathwalk.Walk(roots, add, gopathwalk.Options{Logf: r.env.Logf, ModulesEnabled: false}) + close(scanDone) + }() + select { + case <-ctx.Done(): + case <-scanDone: + } + return nil +} + +func (r *gopathResolver) scoreImportPath(ctx context.Context, path string) float64 { + if stdlib.HasPackage(path) { + return MaxRelevance + } + return MaxRelevance - 1 +} + +func filterRoots(roots []gopathwalk.Root, include func(gopathwalk.Root) bool) []gopathwalk.Root { + var result []gopathwalk.Root + for _, root := range roots { + if !include(root) { + continue + } + result = append(result, root) + } + return result +} + +func (r *gopathResolver) loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []stdlib.Symbol, error) { + if info, ok := r.cache.Load(pkg.dir); ok && !includeTest { + return r.cache.CacheExports(ctx, r.env, info) + } + return loadExportsFromFiles(ctx, r.env, pkg.dir, includeTest) +} + +// VendorlessPath returns the devendorized version of the import path ipath. +// For example, VendorlessPath("foo/bar/vendor/a/b") returns "a/b". +func VendorlessPath(ipath string) string { + // Devendorize for use in import statement. + if i := strings.LastIndex(ipath, "/vendor/"); i >= 0 { + return ipath[i+len("/vendor/"):] + } + if strings.HasPrefix(ipath, "vendor/") { + return ipath[len("vendor/"):] + } + return ipath +} + +func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string, includeTest bool) (string, []stdlib.Symbol, error) { + // Look for non-test, buildable .go files which could provide exports. + all, err := os.ReadDir(dir) + if err != nil { + return "", nil, err + } + var files []fs.DirEntry + for _, fi := range all { + name := fi.Name() + if !strings.HasSuffix(name, ".go") || (!includeTest && strings.HasSuffix(name, "_test.go")) { + continue + } + match, err := env.matchFile(dir, fi.Name()) + if err != nil || !match { + continue + } + files = append(files, fi) + } + + if len(files) == 0 { + return "", nil, fmt.Errorf("dir %v contains no buildable, non-test .go files", dir) + } + + var pkgName string + var exports []stdlib.Symbol + fset := token.NewFileSet() + for _, fi := range files { + select { + case <-ctx.Done(): + return "", nil, ctx.Err() + default: + } + + fullFile := filepath.Join(dir, fi.Name()) + // Legacy ast.Object resolution is needed here. + f, err := parser.ParseFile(fset, fullFile, nil, 0) + if err != nil { + env.logf("error parsing %v: %v", fullFile, err) + continue + } + if f.Name.Name == "documentation" { + // Special case from go/build.ImportDir, not + // handled by MatchFile above. + continue + } + if includeTest && strings.HasSuffix(f.Name.Name, "_test") { + // x_test package. We want internal test files only. + continue + } + pkgName = f.Name.Name + for name, obj := range f.Scope.Objects { + if ast.IsExported(name) { + var kind stdlib.Kind + switch obj.Kind { + case ast.Con: + kind = stdlib.Const + case ast.Typ: + kind = stdlib.Type + case ast.Var: + kind = stdlib.Var + case ast.Fun: + kind = stdlib.Func + } + exports = append(exports, stdlib.Symbol{ + Name: name, + Kind: kind, + Version: 0, // unknown; be permissive + }) + } + } + } + sortSymbols(exports) + + env.logf("loaded exports in dir %v (package %v): %v", dir, pkgName, exports) + return pkgName, exports, nil +} + +func sortSymbols(syms []stdlib.Symbol) { + sort.Slice(syms, func(i, j int) bool { + return syms[i].Name < syms[j].Name + }) +} + +// A symbolSearcher searches for a package with a set of symbols, among a set +// of candidates. See [symbolSearcher.search]. +// +// The search occurs within the scope of a single file, with context captured +// in srcDir and xtest. +type symbolSearcher struct { + logf func(string, ...any) + srcDir string // directory containing the file + xtest bool // if set, the file containing is an x_test file + loadExports func(ctx context.Context, pkg *pkg, includeTest bool) (string, []stdlib.Symbol, error) +} + +// search searches the provided candidates for a package containing all +// exported symbols. +// +// If successful, returns the resulting package. +func (s *symbolSearcher) search(ctx context.Context, candidates []pkgDistance, pkgName string, symbols map[string]bool) (*pkg, error) { + // Sort the candidates by their import package length, + // assuming that shorter package names are better than long + // ones. Note that this sorts by the de-vendored name, so + // there's no "penalty" for vendoring. + sort.Sort(byDistanceOrImportPathShortLength(candidates)) + if s.logf != nil { + for i, c := range candidates { + s.logf("%s candidate %d/%d: %v in %v", pkgName, i+1, len(candidates), c.pkg.importPathShort, c.pkg.dir) + } + } + + // Arrange rescv so that we can we can await results in order of relevance + // and exit as soon as we find the first match. + // + // Search with bounded concurrency, returning as soon as the first result + // among rescv is non-nil. + rescv := make([]chan *pkg, len(candidates)) + for i := range candidates { + rescv[i] = make(chan *pkg, 1) + } + const maxConcurrentPackageImport = 4 + loadExportsSem := make(chan struct{}, maxConcurrentPackageImport) + + // Ensure that all work is completed at exit. + ctx, cancel := context.WithCancel(ctx) + var wg sync.WaitGroup + defer func() { + cancel() + wg.Wait() + }() + + // Start the search. + wg.Go(func() { + for i, c := range candidates { + select { + case loadExportsSem <- struct{}{}: + case <-ctx.Done(): + return + } + + i := i + c := c + wg.Add(1) + go func() { + defer func() { + <-loadExportsSem + wg.Done() + }() + if s.logf != nil { + s.logf("loading exports in dir %s (seeking package %s)", c.pkg.dir, pkgName) + } + pkg, err := s.searchOne(ctx, c, symbols) + if err != nil { + if s.logf != nil && ctx.Err() == nil { + s.logf("loading exports in dir %s (seeking package %s): %v", c.pkg.dir, pkgName, err) + } + pkg = nil + } + rescv[i] <- pkg // may be nil + }() + } + }) + + // Await the first (best) result. + for _, resc := range rescv { + select { + case r := <-resc: + if r != nil { + return r, nil + } + case <-ctx.Done(): + return nil, ctx.Err() + } + } + return nil, nil +} + +func (s *symbolSearcher) searchOne(ctx context.Context, c pkgDistance, symbols map[string]bool) (*pkg, error) { + if ctx.Err() != nil { + return nil, ctx.Err() + } + // If we're considering the package under test from an x_test, load the + // test variant. + includeTest := s.xtest && c.pkg.dir == s.srcDir + _, exports, err := s.loadExports(ctx, c.pkg, includeTest) + if err != nil { + return nil, err + } + + exportsMap := make(map[string]bool, len(exports)) + for _, sym := range exports { + exportsMap[sym.Name] = true + } + for symbol := range symbols { + if !exportsMap[symbol] { + return nil, nil // no match + } + } + return c.pkg, nil +} + +// pkgIsCandidate reports whether pkg is a candidate for satisfying the +// finding which package pkgIdent in the file named by filename is trying +// to refer to. +// +// This check is purely lexical and is meant to be as fast as possible +// because it's run over all $GOPATH directories to filter out poor +// candidates in order to limit the CPU and I/O later parsing the +// exports in candidate packages. +// +// filename is the file being formatted. +// pkgIdent is the package being searched for, like "client" (if +// searching for "client.New") +func pkgIsCandidate(filename string, refs References, pkg *pkg) bool { + // Check "internal" and "vendor" visibility: + if !CanUse(filename, pkg.dir) { + return false + } + + // Speed optimization to minimize disk I/O: + // + // Use the matchesPath heuristic to filter to package paths that could + // reasonably match a dangling reference. + // + // This permits mismatch naming like directory "go-foo" being package "foo", + // or "pkg.v3" being "pkg", or directory + // "google.golang.org/api/cloudbilling/v1" being package "cloudbilling", but + // doesn't permit a directory "foo" to be package "bar", which is strongly + // discouraged anyway. There's no reason goimports needs to be slow just to + // accommodate that. + for pkgIdent := range refs { + if matchesPath(pkgIdent, pkg.importPathShort) { + return true + } + } + return false +} + +// CanUse reports whether the package in dir is usable from filename, +// respecting the Go "internal" and "vendor" visibility rules. +func CanUse(filename, dir string) bool { + // Fast path check, before any allocations. If it doesn't contain vendor + // or internal, it's not tricky: + // Note that this can false-negative on directories like "notinternal", + // but we check it correctly below. This is just a fast path. + if !strings.Contains(dir, "vendor") && !strings.Contains(dir, "internal") { + return true + } + + dirSlash := filepath.ToSlash(dir) + if !strings.Contains(dirSlash, "/vendor/") && !strings.Contains(dirSlash, "/internal/") && !strings.HasSuffix(dirSlash, "/internal") { + return true + } + // Vendor or internal directory only visible from children of parent. + // That means the path from the current directory to the target directory + // can contain ../vendor or ../internal but not ../foo/vendor or ../foo/internal + // or bar/vendor or bar/internal. + // After stripping all the leading ../, the only okay place to see vendor or internal + // is at the very beginning of the path. + absfile, err := filepath.Abs(filename) + if err != nil { + return false + } + absdir, err := filepath.Abs(dir) + if err != nil { + return false + } + rel, err := filepath.Rel(absfile, absdir) + if err != nil { + return false + } + relSlash := filepath.ToSlash(rel) + if i := strings.LastIndex(relSlash, "../"); i >= 0 { + relSlash = relSlash[i+len("../"):] + } + return !strings.Contains(relSlash, "/vendor/") && !strings.Contains(relSlash, "/internal/") && !strings.HasSuffix(relSlash, "/internal") +} + +// matchesPath reports whether ident may match a potential package name +// referred to by path, using heuristics to filter out unidiomatic package +// names. +// +// Specifically, it checks whether either of the last two '/'- or '\'-delimited +// path segments matches the identifier. The segment-matching heuristic must +// allow for various conventions around segment naming, including go-foo, +// foo-go, and foo.v3. To handle all of these, matching considers both (1) the +// entire segment, ignoring '-' and '.', as well as (2) the last subsegment +// separated by '-' or '.'. So the segment foo-go matches all of the following +// identifiers: foo, go, and foogo. All matches are case insensitive (for ASCII +// identifiers). +// +// See the docstring for [pkgIsCandidate] for an explanation of how this +// heuristic filters potential candidate packages. +func matchesPath(ident, path string) bool { + // Ignore case, for ASCII. + lowerIfASCII := func(b byte) byte { + if 'A' <= b && b <= 'Z' { + return b + ('a' - 'A') + } + return b + } + + // match reports whether path[start:end] matches ident, ignoring [.-]. + match := func(start, end int) bool { + ii := len(ident) - 1 // current byte in ident + pi := end - 1 // current byte in path + for ; pi >= start && ii >= 0; pi-- { + pb := path[pi] + if pb == '-' || pb == '.' { + continue + } + pb = lowerIfASCII(pb) + ib := lowerIfASCII(ident[ii]) + if pb != ib { + return false + } + ii-- + } + return ii < 0 && pi < start // all bytes matched + } + + // segmentEnd and subsegmentEnd hold the end points of the current segment + // and subsegment intervals. + segmentEnd := len(path) + subsegmentEnd := len(path) + + // Count slashes; we only care about the last two segments. + nslash := 0 + + for i := len(path) - 1; i >= 0; i-- { + switch b := path[i]; b { + // TODO(rfindley): we handle backlashes here only because the previous + // heuristic handled backslashes. This is perhaps overly defensive, but is + // the result of many lessons regarding Chesterton's fence and the + // goimports codebase. + // + // However, this function is only ever called with something called an + // 'importPath'. Is it possible that this is a real import path, and + // therefore we need only consider forward slashes? + case '/', '\\': + if match(i+1, segmentEnd) || match(i+1, subsegmentEnd) { + return true + } + nslash++ + if nslash == 2 { + return false // did not match above + } + segmentEnd, subsegmentEnd = i, i // reset + case '-', '.': + if match(i+1, subsegmentEnd) { + return true + } + subsegmentEnd = i + } + } + return match(0, segmentEnd) || match(0, subsegmentEnd) +} + +type visitFn func(node ast.Node) ast.Visitor + +func (fn visitFn) Visit(node ast.Node) ast.Visitor { + return fn(node) +} + +func symbolNameSet(symbols []stdlib.Symbol) map[string]bool { + names := make(map[string]bool) + for _, sym := range symbols { + switch sym.Kind { + case stdlib.Const, stdlib.Var, stdlib.Type, stdlib.Func: + names[sym.Name] = true + } + } + return names +} diff --git a/vendor/golang.org/x/tools/internal/imports/imports.go b/vendor/golang.org/x/tools/internal/imports/imports.go new file mode 100644 index 0000000..0722938 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/imports/imports.go @@ -0,0 +1,363 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package imports implements a Go pretty-printer (like package "go/format") +// that also adds or removes import statements as necessary. +package imports + +import ( + "bufio" + "bytes" + "context" + "fmt" + "go/ast" + "go/format" + "go/parser" + "go/printer" + "go/token" + "io" + "regexp" + "strconv" + "strings" + + "golang.org/x/tools/go/ast/astutil" + "golang.org/x/tools/internal/event" +) + +// Options is golang.org/x/tools/imports.Options with extra internal-only options. +type Options struct { + Env *ProcessEnv // The environment to use. Note: this contains the cached module and filesystem state. + + // LocalPrefix is a comma-separated string of import path prefixes, which, if + // set, instructs Process to sort the import paths with the given prefixes + // into another group after 3rd-party packages. + LocalPrefix string + + Fragment bool // Accept fragment of a source file (no package statement) + AllErrors bool // Report all errors (not just the first 10 on different lines) + + Comments bool // Print comments (true if nil *Options provided) + TabIndent bool // Use tabs for indent (true if nil *Options provided) + TabWidth int // Tab width (8 if nil *Options provided) + + FormatOnly bool // Disable the insertion and deletion of imports +} + +// Process implements golang.org/x/tools/imports.Process with explicit context in opt.Env. +func Process(filename string, src []byte, opt *Options) (formatted []byte, err error) { + fileSet := token.NewFileSet() + var parserMode parser.Mode + if opt.Comments { + parserMode |= parser.ParseComments + } + if opt.AllErrors { + parserMode |= parser.AllErrors + } + file, adjust, err := parse(fileSet, filename, src, parserMode, opt.Fragment) + if err != nil { + return nil, err + } + + if !opt.FormatOnly { + if err := fixImports(fileSet, file, filename, opt.Env); err != nil { + return nil, err + } + } + return formatFile(fileSet, file, src, adjust, opt) +} + +// FixImports returns a list of fixes to the imports that, when applied, +// will leave the imports in the same state as Process. src and opt must +// be specified. +// +// Note that filename's directory influences which imports can be chosen, +// so it is important that filename be accurate. +func FixImports(ctx context.Context, filename string, src []byte, goroot string, logf func(string, ...any), source Source) (fixes []*ImportFix, err error) { + if source == nil { + // In case someone adds a defective call from a new place + panic("source is nil") + } + ctx, done := event.Start(ctx, "imports.FixImports") + defer done() + + fileSet := token.NewFileSet() + // TODO(rfindley): these default values for ParseComments and AllErrors were + // extracted from gopls, but are they even needed? + file, _, err := parse(fileSet, filename, src, parser.ParseComments|parser.AllErrors, true) + if err != nil { + return nil, err + } + + return getFixesWithSource(ctx, fileSet, file, filename, goroot, logf, source) +} + +// ApplyFixes applies all of the fixes to the file and formats it. extraMode +// is added in when parsing the file. src and opts must be specified, but no +// env is needed. +func ApplyFixes(fixes []*ImportFix, filename string, src []byte, opt *Options, extraMode parser.Mode) (formatted []byte, err error) { + // Don't use parse() -- we don't care about fragments or statement lists + // here, and we need to work with unparsable files. + fileSet := token.NewFileSet() + parserMode := parser.SkipObjectResolution + if opt.Comments { + parserMode |= parser.ParseComments + } + if opt.AllErrors { + parserMode |= parser.AllErrors + } + parserMode |= extraMode + + file, err := parser.ParseFile(fileSet, filename, src, parserMode) + if file == nil { + return nil, err + } + + // Apply the fixes to the file. + apply(fileSet, file, fixes) + + return formatFile(fileSet, file, src, nil, opt) +} + +// formatFile formats the file syntax tree. +// It may mutate the token.FileSet and the ast.File. +// +// If an adjust function is provided, it is called after formatting +// with the original source (formatFile's src parameter) and the +// formatted file, and returns the postpocessed result. +func formatFile(fset *token.FileSet, file *ast.File, src []byte, adjust func(orig []byte, src []byte) []byte, opt *Options) ([]byte, error) { + mergeImports(file) + sortImports(opt.LocalPrefix, fset.File(file.FileStart), file) + var spacesBefore []string // import paths we need spaces before + for _, impSection := range astutil.Imports(fset, file) { + // Within each block of contiguous imports, see if any + // import lines are in different group numbers. If so, + // we'll need to put a space between them so it's + // compatible with gofmt. + lastGroup := -1 + for _, importSpec := range impSection { + importPath, _ := strconv.Unquote(importSpec.Path.Value) + groupNum := importGroup(opt.LocalPrefix, importPath) + if groupNum != lastGroup && lastGroup != -1 { + spacesBefore = append(spacesBefore, importPath) + } + lastGroup = groupNum + } + + } + + printerMode := printer.UseSpaces + if opt.TabIndent { + printerMode |= printer.TabIndent + } + printConfig := &printer.Config{Mode: printerMode, Tabwidth: opt.TabWidth} + + var buf bytes.Buffer + err := printConfig.Fprint(&buf, fset, file) + if err != nil { + return nil, err + } + out := buf.Bytes() + if adjust != nil { + out = adjust(src, out) + } + if len(spacesBefore) > 0 { + out, err = addImportSpaces(bytes.NewReader(out), spacesBefore) + if err != nil { + return nil, err + } + } + + out, err = format.Source(out) + if err != nil { + return nil, err + } + return out, nil +} + +// parse parses src, which was read from filename, +// as a Go source file or statement list. +func parse(fset *token.FileSet, filename string, src []byte, parserMode parser.Mode, fragment bool) (*ast.File, func(orig, src []byte) []byte, error) { + if parserMode&parser.SkipObjectResolution != 0 { + panic("legacy ast.Object resolution is required") + } + + // Try as whole source file. + file, err := parser.ParseFile(fset, filename, src, parserMode) + if err == nil { + return file, nil, nil + } + // If the error is that the source file didn't begin with a + // package line and we accept fragmented input, fall through to + // try as a source fragment. Stop and return on any other error. + if !fragment || !strings.Contains(err.Error(), "expected 'package'") { + return nil, nil, err + } + + // If this is a declaration list, make it a source file + // by inserting a package clause. + // Insert using a ;, not a newline, so that parse errors are on + // the correct line. + const prefix = "package main;" + psrc := append([]byte(prefix), src...) + file, err = parser.ParseFile(fset, filename, psrc, parserMode) + if err == nil { + // Gofmt will turn the ; into a \n. + // Do that ourselves now and update the file contents, + // so that positions and line numbers are correct going forward. + psrc[len(prefix)-1] = '\n' + fset.File(file.Package).SetLinesForContent(psrc) + + // If a main function exists, we will assume this is a main + // package and leave the file. + if containsMainFunc(file) { + return file, nil, nil + } + + adjust := func(orig, src []byte) []byte { + // Remove the package clause. + src = src[len(prefix):] + return matchSpace(orig, src) + } + return file, adjust, nil + } + // If the error is that the source file didn't begin with a + // declaration, fall through to try as a statement list. + // Stop and return on any other error. + if !strings.Contains(err.Error(), "expected declaration") { + return nil, nil, err + } + + // If this is a statement list, make it a source file + // by inserting a package clause and turning the list + // into a function body. This handles expressions too. + // Insert using a ;, not a newline, so that the line numbers + // in fsrc match the ones in src. + fsrc := append(append([]byte("package p; func _() {"), src...), '}') + file, err = parser.ParseFile(fset, filename, fsrc, parserMode) + if err == nil { + adjust := func(orig, src []byte) []byte { + // Remove the wrapping. + // Gofmt has turned the ; into a \n\n. + src = src[len("package p\n\nfunc _() {"):] + src = src[:len(src)-len("}\n")] + // Gofmt has also indented the function body one level. + // Remove that indent. + src = bytes.ReplaceAll(src, []byte("\n\t"), []byte("\n")) + return matchSpace(orig, src) + } + return file, adjust, nil + } + + // Failed, and out of options. + return nil, nil, err +} + +// containsMainFunc checks if a file contains a function declaration with the +// function signature 'func main()' +func containsMainFunc(file *ast.File) bool { + for _, decl := range file.Decls { + if f, ok := decl.(*ast.FuncDecl); ok { + if f.Name.Name != "main" { + continue + } + + if len(f.Type.Params.List) != 0 { + continue + } + + if f.Type.Results != nil && len(f.Type.Results.List) != 0 { + continue + } + + return true + } + } + + return false +} + +func cutSpace(b []byte) (before, middle, after []byte) { + i := 0 + for i < len(b) && (b[i] == ' ' || b[i] == '\t' || b[i] == '\n') { + i++ + } + j := len(b) + for j > 0 && (b[j-1] == ' ' || b[j-1] == '\t' || b[j-1] == '\n') { + j-- + } + if i <= j { + return b[:i], b[i:j], b[j:] + } + return nil, nil, b[j:] +} + +// matchSpace reformats src to use the same space context as orig. +// 1. If orig begins with blank lines, matchSpace inserts them at the beginning of src. +// 2. matchSpace copies the indentation of the first non-blank line in orig +// to every non-blank line in src. +// 3. matchSpace copies the trailing space from orig and uses it in place +// of src's trailing space. +func matchSpace(orig []byte, src []byte) []byte { + before, _, after := cutSpace(orig) + i := bytes.LastIndex(before, []byte{'\n'}) + before, indent := before[:i+1], before[i+1:] + + _, src, _ = cutSpace(src) + + var b bytes.Buffer + b.Write(before) + for len(src) > 0 { + line := src + if i := bytes.IndexByte(line, '\n'); i >= 0 { + line, src = line[:i+1], line[i+1:] + } else { + src = nil + } + if len(line) > 0 && line[0] != '\n' { // not blank + b.Write(indent) + } + b.Write(line) + } + b.Write(after) + return b.Bytes() +} + +var impLine = regexp.MustCompile(`^\s+(?:[\w\.]+\s+)?"(.+?)"`) + +func addImportSpaces(r io.Reader, breaks []string) ([]byte, error) { + var out bytes.Buffer + in := bufio.NewReader(r) + inImports := false + done := false + for { + s, err := in.ReadString('\n') + if err == io.EOF { + break + } else if err != nil { + return nil, err + } + + if !inImports && !done && strings.HasPrefix(s, "import") { + inImports = true + } + if inImports && (strings.HasPrefix(s, "var") || + strings.HasPrefix(s, "func") || + strings.HasPrefix(s, "const") || + strings.HasPrefix(s, "type")) { + done = true + inImports = false + } + if inImports && len(breaks) > 0 { + if m := impLine.FindStringSubmatch(s); m != nil { + if m[1] == breaks[0] { + out.WriteByte('\n') + breaks = breaks[1:] + } + } + } + + fmt.Fprint(&out, s) + } + return out.Bytes(), nil +} diff --git a/vendor/golang.org/x/tools/internal/imports/mod.go b/vendor/golang.org/x/tools/internal/imports/mod.go new file mode 100644 index 0000000..7eff4d5 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/imports/mod.go @@ -0,0 +1,827 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package imports + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "os" + "path" + "path/filepath" + "regexp" + "slices" + "sort" + "strconv" + "strings" + + "golang.org/x/mod/module" + "golang.org/x/tools/internal/event" + "golang.org/x/tools/internal/gocommand" + "golang.org/x/tools/internal/gopathwalk" + "golang.org/x/tools/internal/stdlib" +) + +// Notes(rfindley): ModuleResolver appears to be heavily optimized for scanning +// as fast as possible, which is desirable for a call to goimports from the +// command line, but it doesn't work as well for gopls, where it suffers from +// slow startup (golang/go#44863) and intermittent hanging (golang/go#59216), +// both caused by populating the cache, albeit in slightly different ways. +// +// A high level list of TODOs: +// - Optimize the scan itself, as there is some redundancy statting and +// reading go.mod files. +// - Invert the relationship between ProcessEnv and Resolver (see the +// docstring of ProcessEnv). +// - Make it easier to use an external resolver implementation. +// +// Smaller TODOs are annotated in the code below. + +// ModuleResolver implements the Resolver interface for a workspace using +// modules. +// +// A goal of the ModuleResolver is to invoke the Go command as little as +// possible. To this end, it runs the Go command only for listing module +// information (i.e. `go list -m -e -json ...`). Package scanning, the process +// of loading package information for the modules, is implemented internally +// via the scan method. +// +// It has two types of state: the state derived from the go command, which +// is populated by init, and the state derived from scans, which is populated +// via scan. A root is considered scanned if it has been walked to discover +// directories. However, if the scan did not require additional information +// from the directory (such as package name or exports), the directory +// information itself may be partially populated. It will be lazily filled in +// as needed by scans, using the scanCallback. +type ModuleResolver struct { + env *ProcessEnv + + // Module state, populated during construction + dummyVendorMod *gocommand.ModuleJSON // if vendoring is enabled, a pseudo-module to represent the /vendor directory + moduleCacheDir string // GOMODCACHE, inferred from GOPATH if unset + roots []gopathwalk.Root // roots to scan, in approximate order of importance + mains []*gocommand.ModuleJSON // main modules + mainByDir map[string]*gocommand.ModuleJSON // module information by dir, to join with roots + modsByModPath []*gocommand.ModuleJSON // all modules, ordered by # of path components in their module path + modsByDir []*gocommand.ModuleJSON // ...or by the number of path components in their Dir. + + // Scanning state, populated by scan + + // scanSema prevents concurrent scans, and guards scannedRoots and the cache + // fields below (though the caches themselves are concurrency safe). + // Receive to acquire, send to release. + scanSema chan struct{} + scannedRoots map[gopathwalk.Root]bool // if true, root has been walked + + // Caches of directory info, populated by scans and scan callbacks + // + // moduleCacheCache stores cached information about roots in the module + // cache, which are immutable and therefore do not need to be invalidated. + // + // otherCache stores information about all other roots (even GOROOT), which + // may change. + moduleCacheCache *DirInfoCache + otherCache *DirInfoCache +} + +// newModuleResolver returns a new module-aware goimports resolver. +// +// Note: use caution when modifying this constructor: changes must also be +// reflected in ModuleResolver.ClearForNewScan. +func newModuleResolver(e *ProcessEnv, moduleCacheCache *DirInfoCache) (*ModuleResolver, error) { + r := &ModuleResolver{ + env: e, + scanSema: make(chan struct{}, 1), + } + r.scanSema <- struct{}{} // release + + goenv, err := r.env.goEnv() + if err != nil { + return nil, err + } + + // TODO(rfindley): can we refactor to share logic with r.env.invokeGo? + inv := gocommand.Invocation{ + BuildFlags: r.env.BuildFlags, + ModFlag: r.env.ModFlag, + Env: r.env.env(), + Logf: r.env.Logf, + WorkingDir: r.env.WorkingDir, + } + + vendorEnabled := false + var mainModVendor *gocommand.ModuleJSON // for module vendoring + var mainModsVendor []*gocommand.ModuleJSON // for workspace vendoring + + goWork := r.env.Env["GOWORK"] + if len(goWork) == 0 { + // TODO(rfindley): VendorEnabled runs the go command to get GOFLAGS, but + // they should be available from the ProcessEnv. Can we avoid the redundant + // invocation? + vendorEnabled, mainModVendor, err = gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner) + if err != nil { + return nil, err + } + } else { + vendorEnabled, mainModsVendor, err = gocommand.WorkspaceVendorEnabled(context.Background(), inv, r.env.GocmdRunner) + if err != nil { + return nil, err + } + } + + if vendorEnabled { + if mainModVendor != nil { + // Module vendor mode is on, so all the non-Main modules are irrelevant, + // and we need to search /vendor for everything. + r.mains = []*gocommand.ModuleJSON{mainModVendor} + r.dummyVendorMod = &gocommand.ModuleJSON{ + Path: "", + Dir: filepath.Join(mainModVendor.Dir, "vendor"), + } + r.modsByModPath = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod} + r.modsByDir = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod} + } else { + // Workspace vendor mode is on, so all the non-Main modules are irrelevant, + // and we need to search /vendor for everything. + r.mains = mainModsVendor + r.dummyVendorMod = &gocommand.ModuleJSON{ + Path: "", + Dir: filepath.Join(filepath.Dir(goWork), "vendor"), + } + r.modsByModPath = append(slices.Clone(mainModsVendor), r.dummyVendorMod) + r.modsByDir = append(slices.Clone(mainModsVendor), r.dummyVendorMod) + } + } else { + // Vendor mode is off, so run go list -m ... to find everything. + err := r.initAllMods() + // We expect an error when running outside of a module with + // GO111MODULE=on. Other errors are fatal. + if err != nil { + if errMsg := err.Error(); !strings.Contains(errMsg, "working directory is not part of a module") && !strings.Contains(errMsg, "go.mod file not found") { + return nil, err + } + } + } + + r.moduleCacheDir = goenv["GOMODCACHE"] + + sort.Slice(r.modsByModPath, func(i, j int) bool { + count := func(x int) int { + return strings.Count(r.modsByModPath[x].Path, "/") + } + return count(j) < count(i) // descending order + }) + sort.Slice(r.modsByDir, func(i, j int) bool { + count := func(x int) int { + return strings.Count(r.modsByDir[x].Dir, string(filepath.Separator)) + } + return count(j) < count(i) // descending order + }) + + r.roots = []gopathwalk.Root{} + if goenv["GOROOT"] != "" { // "" happens in tests + r.roots = append(r.roots, gopathwalk.Root{Path: filepath.Join(goenv["GOROOT"], "/src"), Type: gopathwalk.RootGOROOT}) + } + r.mainByDir = make(map[string]*gocommand.ModuleJSON) + for _, main := range r.mains { + r.roots = append(r.roots, gopathwalk.Root{Path: main.Dir, Type: gopathwalk.RootCurrentModule}) + r.mainByDir[main.Dir] = main + } + if vendorEnabled { + r.roots = append(r.roots, gopathwalk.Root{Path: r.dummyVendorMod.Dir, Type: gopathwalk.RootOther}) + } else { + addDep := func(mod *gocommand.ModuleJSON) { + if mod.Replace == nil { + // This is redundant with the cache, but we'll skip it cheaply enough + // when we encounter it in the module cache scan. + // + // Including it at a lower index in r.roots than the module cache dir + // helps prioritize matches from within existing dependencies. + r.roots = append(r.roots, gopathwalk.Root{Path: mod.Dir, Type: gopathwalk.RootModuleCache}) + } else { + r.roots = append(r.roots, gopathwalk.Root{Path: mod.Dir, Type: gopathwalk.RootOther}) + } + } + // Walk dependent modules before scanning the full mod cache, direct deps first. + for _, mod := range r.modsByModPath { + if !mod.Indirect && !mod.Main { + addDep(mod) + } + } + for _, mod := range r.modsByModPath { + if mod.Indirect && !mod.Main { + addDep(mod) + } + } + // If provided, share the moduleCacheCache. + // + // TODO(rfindley): The module cache is immutable. However, the loaded + // exports do depend on GOOS and GOARCH. Fortunately, the + // ProcessEnv.buildContext does not adjust these from build.DefaultContext + // (even though it should). So for now, this is OK to share, but we need to + // add logic for handling GOOS/GOARCH. + r.moduleCacheCache = moduleCacheCache + r.roots = append(r.roots, gopathwalk.Root{Path: r.moduleCacheDir, Type: gopathwalk.RootModuleCache}) + } + + r.scannedRoots = map[gopathwalk.Root]bool{} + if r.moduleCacheCache == nil { + r.moduleCacheCache = NewDirInfoCache() + } + r.otherCache = NewDirInfoCache() + return r, nil +} + +func (r *ModuleResolver) initAllMods() error { + stdout, err := r.env.invokeGo(context.TODO(), "list", "-m", "-e", "-json", "...") + if err != nil { + return err + } + for dec := json.NewDecoder(stdout); dec.More(); { + mod := &gocommand.ModuleJSON{} + if err := dec.Decode(mod); err != nil { + return err + } + if mod.Dir == "" { + r.env.logf("module %v has not been downloaded and will be ignored", mod.Path) + // Can't do anything with a module that's not downloaded. + continue + } + // golang/go#36193: the go command doesn't always clean paths. + mod.Dir = filepath.Clean(mod.Dir) + r.modsByModPath = append(r.modsByModPath, mod) + r.modsByDir = append(r.modsByDir, mod) + if mod.Main { + r.mains = append(r.mains, mod) + } + } + return nil +} + +// ClearForNewScan invalidates the last scan. +// +// It preserves the set of roots, but forgets about the set of directories. +// Though it forgets the set of module cache directories, it remembers their +// contents, since they are assumed to be immutable. +func (r *ModuleResolver) ClearForNewScan() Resolver { + <-r.scanSema // acquire r, to guard scannedRoots + r2 := &ModuleResolver{ + env: r.env, + dummyVendorMod: r.dummyVendorMod, + moduleCacheDir: r.moduleCacheDir, + roots: r.roots, + mains: r.mains, + mainByDir: r.mainByDir, + modsByModPath: r.modsByModPath, + + scanSema: make(chan struct{}, 1), + scannedRoots: make(map[gopathwalk.Root]bool), + otherCache: NewDirInfoCache(), + moduleCacheCache: r.moduleCacheCache, + } + r2.scanSema <- struct{}{} // r2 must start released + // Invalidate root scans. We don't need to invalidate module cache roots, + // because they are immutable. + // (We don't support a use case where GOMODCACHE is cleaned in the middle of + // e.g. a gopls session: the user must restart gopls to get accurate + // imports.) + // + // Scanning for new directories in GOMODCACHE should be handled elsewhere, + // via a call to ScanModuleCache. + for _, root := range r.roots { + if root.Type == gopathwalk.RootModuleCache && r.scannedRoots[root] { + r2.scannedRoots[root] = true + } + } + r.scanSema <- struct{}{} // release r + return r2 +} + +// ClearModuleInfo invalidates resolver state that depends on go.mod file +// contents (essentially, the output of go list -m -json ...). +// +// Notably, it does not forget directory contents, which are reset +// asynchronously via ClearForNewScan. +// +// If the ProcessEnv is a GOPATH environment, ClearModuleInfo is a no op. +// +// TODO(rfindley): move this to a new env.go, consolidating ProcessEnv methods. +func (e *ProcessEnv) ClearModuleInfo() { + if r, ok := e.resolver.(*ModuleResolver); ok { + resolver, err := newModuleResolver(e, e.ModCache) + if err != nil { + e.resolver = nil + e.resolverErr = err + return + } + + <-r.scanSema // acquire (guards caches) + resolver.moduleCacheCache = r.moduleCacheCache + resolver.otherCache = r.otherCache + r.scanSema <- struct{}{} // release + + e.UpdateResolver(resolver) + } +} + +// UpdateResolver sets the resolver for the ProcessEnv to use in imports +// operations. Only for use with the result of [Resolver.ClearForNewScan]. +// +// TODO(rfindley): this awkward API is a result of the (arguably) inverted +// relationship between configuration and state described in the doc comment +// for [ProcessEnv]. +func (e *ProcessEnv) UpdateResolver(r Resolver) { + e.resolver = r + e.resolverErr = nil +} + +// findPackage returns the module and directory from within the main modules +// and their dependencies that contains the package at the given import path, +// or returns nil, "" if no module is in scope. +func (r *ModuleResolver) findPackage(importPath string) (*gocommand.ModuleJSON, string) { + // This can't find packages in the stdlib, but that's harmless for all + // the existing code paths. + for _, m := range r.modsByModPath { + if !strings.HasPrefix(importPath, m.Path) { + continue + } + pathInModule := importPath[len(m.Path):] + pkgDir := filepath.Join(m.Dir, pathInModule) + if r.dirIsNestedModule(pkgDir, m) { + continue + } + + if info, ok := r.cacheLoad(pkgDir); ok { + if loaded, err := info.reachedStatus(nameLoaded); loaded { + if err != nil { + continue // No package in this dir. + } + return m, pkgDir + } + if scanned, err := info.reachedStatus(directoryScanned); scanned && err != nil { + continue // Dir is unreadable, etc. + } + // This is slightly wrong: a directory doesn't have to have an + // importable package to count as a package for package-to-module + // resolution. package main or _test files should count but + // don't. + // TODO(heschi): fix this. + if _, err := r.cachePackageName(info); err == nil { + return m, pkgDir + } + } + + // Not cached. Read the filesystem. + pkgFiles, err := os.ReadDir(pkgDir) + if err != nil { + continue + } + // A module only contains a package if it has buildable go + // files in that directory. If not, it could be provided by an + // outer module. See #29736. + for _, fi := range pkgFiles { + if ok, _ := r.env.matchFile(pkgDir, fi.Name()); ok { + return m, pkgDir + } + } + } + return nil, "" +} + +func (r *ModuleResolver) cacheLoad(dir string) (directoryPackageInfo, bool) { + if info, ok := r.moduleCacheCache.Load(dir); ok { + return info, ok + } + return r.otherCache.Load(dir) +} + +func (r *ModuleResolver) cacheStore(info directoryPackageInfo) { + if info.rootType == gopathwalk.RootModuleCache { + r.moduleCacheCache.Store(info.dir, info) + } else { + r.otherCache.Store(info.dir, info) + } +} + +// cachePackageName caches the package name for a dir already in the cache. +func (r *ModuleResolver) cachePackageName(info directoryPackageInfo) (string, error) { + if info.rootType == gopathwalk.RootModuleCache { + return r.moduleCacheCache.CachePackageName(info) + } + return r.otherCache.CachePackageName(info) +} + +func (r *ModuleResolver) cacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []stdlib.Symbol, error) { + if info.rootType == gopathwalk.RootModuleCache { + return r.moduleCacheCache.CacheExports(ctx, env, info) + } + return r.otherCache.CacheExports(ctx, env, info) +} + +// findModuleByDir returns the module that contains dir, or nil if no such +// module is in scope. +func (r *ModuleResolver) findModuleByDir(dir string) *gocommand.ModuleJSON { + // This is quite tricky and may not be correct. dir could be: + // - a package in the main module. + // - a replace target underneath the main module's directory. + // - a nested module in the above. + // - a replace target somewhere totally random. + // - a nested module in the above. + // - in the mod cache. + // - in /vendor/ in -mod=vendor mode. + // - nested module? Dunno. + // Rumor has it that replace targets cannot contain other replace targets. + // + // Note that it is critical here that modsByDir is sorted to have deeper dirs + // first. This ensures that findModuleByDir finds the innermost module. + // See also golang/go#56291. + for _, m := range r.modsByDir { + if !strings.HasPrefix(dir, m.Dir) { + continue + } + + if r.dirIsNestedModule(dir, m) { + continue + } + + return m + } + return nil +} + +// dirIsNestedModule reports if dir is contained in a nested module underneath +// mod, not actually in mod. +func (r *ModuleResolver) dirIsNestedModule(dir string, mod *gocommand.ModuleJSON) bool { + if !strings.HasPrefix(dir, mod.Dir) { + return false + } + if r.dirInModuleCache(dir) { + // Nested modules in the module cache are pruned, + // so it cannot be a nested module. + return false + } + if mod != nil && mod == r.dummyVendorMod { + // The /vendor pseudomodule is flattened and doesn't actually count. + return false + } + modDir, _ := r.modInfo(dir) + if modDir == "" { + return false + } + return modDir != mod.Dir +} + +func readModName(modFile string) string { + modBytes, err := os.ReadFile(modFile) + if err != nil { + return "" + } + return modulePath(modBytes) +} + +func (r *ModuleResolver) modInfo(dir string) (modDir, modName string) { + if r.dirInModuleCache(dir) { + if matches := modCacheRegexp.FindStringSubmatch(dir); len(matches) == 3 { + index := strings.Index(dir, matches[1]+"@"+matches[2]) + modDir := filepath.Join(dir[:index], matches[1]+"@"+matches[2]) + return modDir, readModName(filepath.Join(modDir, "go.mod")) + } + } + for { + if info, ok := r.cacheLoad(dir); ok { + return info.moduleDir, info.moduleName + } + f := filepath.Join(dir, "go.mod") + info, err := os.Stat(f) + if err == nil && !info.IsDir() { + return dir, readModName(f) + } + + d := filepath.Dir(dir) + if len(d) >= len(dir) { + return "", "" // reached top of file system, no go.mod + } + dir = d + } +} + +func (r *ModuleResolver) dirInModuleCache(dir string) bool { + if r.moduleCacheDir == "" { + return false + } + return strings.HasPrefix(dir, r.moduleCacheDir) +} + +func (r *ModuleResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) { + names := map[string]string{} + for _, path := range importPaths { + // TODO(rfindley): shouldn't this use the dirInfoCache? + _, packageDir := r.findPackage(path) + if packageDir == "" { + continue + } + name, err := packageDirToName(packageDir) + if err != nil { + continue + } + names[path] = name + } + return names, nil +} + +func (r *ModuleResolver) scan(ctx context.Context, callback *scanCallback) error { + ctx, done := event.Start(ctx, "imports.ModuleResolver.scan") + defer done() + + processDir := func(info directoryPackageInfo) { + // Skip this directory if we were not able to get the package information successfully. + if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil { + return + } + pkg, err := r.canonicalize(info) + if err != nil { + return + } + if !callback.dirFound(pkg) { + return + } + + pkg.packageName, err = r.cachePackageName(info) + if err != nil { + return + } + if !callback.packageNameLoaded(pkg) { + return + } + + _, exports, err := r.loadExports(ctx, pkg, false) + if err != nil { + return + } + callback.exportsLoaded(pkg, exports) + } + + // Start processing everything in the cache, and listen for the new stuff + // we discover in the walk below. + stop1 := r.moduleCacheCache.ScanAndListen(ctx, processDir) + defer stop1() + stop2 := r.otherCache.ScanAndListen(ctx, processDir) + defer stop2() + + // We assume cached directories are fully cached, including all their + // children, and have not changed. We can skip them. + skip := func(root gopathwalk.Root, dir string) bool { + if r.env.SkipPathInScan != nil && root.Type == gopathwalk.RootCurrentModule { + if root.Path == dir { + return false + } + + if r.env.SkipPathInScan(filepath.Clean(dir)) { + return true + } + } + + info, ok := r.cacheLoad(dir) + if !ok { + return false + } + // This directory can be skipped as long as we have already scanned it. + // Packages with errors will continue to have errors, so there is no need + // to rescan them. + packageScanned, _ := info.reachedStatus(directoryScanned) + return packageScanned + } + + add := func(root gopathwalk.Root, dir string) { + r.cacheStore(r.scanDirForPackage(root, dir)) + } + + // r.roots and the callback are not necessarily safe to use in the + // goroutine below. Process them eagerly. + roots := filterRoots(r.roots, callback.rootFound) + // We can't cancel walks, because we need them to finish to have a usable + // cache. Instead, run them in a separate goroutine and detach. + scanDone := make(chan struct{}) + go func() { + select { + case <-ctx.Done(): + return + case <-r.scanSema: // acquire + } + defer func() { r.scanSema <- struct{}{} }() // release + // We have the lock on r.scannedRoots, and no other scans can run. + for _, root := range roots { + if ctx.Err() != nil { + return + } + + if r.scannedRoots[root] { + continue + } + gopathwalk.WalkSkip([]gopathwalk.Root{root}, add, skip, gopathwalk.Options{Logf: r.env.Logf, ModulesEnabled: true}) + r.scannedRoots[root] = true + } + close(scanDone) + }() + select { + case <-ctx.Done(): + case <-scanDone: + } + return nil +} + +func (r *ModuleResolver) scoreImportPath(ctx context.Context, path string) float64 { + if stdlib.HasPackage(path) { + return MaxRelevance + } + mod, _ := r.findPackage(path) + return modRelevance(mod) +} + +func modRelevance(mod *gocommand.ModuleJSON) float64 { + var relevance float64 + switch { + case mod == nil: // out of scope + return MaxRelevance - 4 + case mod.Indirect: + relevance = MaxRelevance - 3 + case !mod.Main: + relevance = MaxRelevance - 2 + default: + relevance = MaxRelevance - 1 // main module ties with stdlib + } + + _, versionString, ok := module.SplitPathVersion(mod.Path) + if ok { + _, after, ok := strings.Cut(versionString, "v") + if !ok { + return relevance + } + if versionNumber, err := strconv.ParseFloat(after, 64); err == nil { + relevance += versionNumber / 1000 + } + } + + return relevance +} + +// canonicalize gets the result of canonicalizing the packages using the results +// of initializing the resolver from 'go list -m'. +func (r *ModuleResolver) canonicalize(info directoryPackageInfo) (*pkg, error) { + // Packages in GOROOT are already canonical, regardless of the std/cmd modules. + if info.rootType == gopathwalk.RootGOROOT { + return &pkg{ + importPathShort: info.nonCanonicalImportPath, + dir: info.dir, + packageName: path.Base(info.nonCanonicalImportPath), + relevance: MaxRelevance, + }, nil + } + + importPath := info.nonCanonicalImportPath + mod := r.findModuleByDir(info.dir) + // Check if the directory is underneath a module that's in scope. + if mod != nil { + // It is. If dir is the target of a replace directive, + // our guessed import path is wrong. Use the real one. + if mod.Dir == info.dir { + importPath = mod.Path + } else { + dirInMod := info.dir[len(mod.Dir)+len("/"):] + importPath = path.Join(mod.Path, filepath.ToSlash(dirInMod)) + } + } else if !strings.HasPrefix(importPath, info.moduleName) { + // The module's name doesn't match the package's import path. It + // probably needs a replace directive we don't have. + return nil, fmt.Errorf("package in %q is not valid without a replace statement", info.dir) + } + + res := &pkg{ + importPathShort: importPath, + dir: info.dir, + relevance: modRelevance(mod), + } + // We may have discovered a package that has a different version + // in scope already. Canonicalize to that one if possible. + if _, canonicalDir := r.findPackage(importPath); canonicalDir != "" { + res.dir = canonicalDir + } + return res, nil +} + +func (r *ModuleResolver) loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []stdlib.Symbol, error) { + if info, ok := r.cacheLoad(pkg.dir); ok && !includeTest { + return r.cacheExports(ctx, r.env, info) + } + return loadExportsFromFiles(ctx, r.env, pkg.dir, includeTest) +} + +func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) directoryPackageInfo { + subdir := "" + base := root.Path + if root.Type == gopathwalk.RootModuleCache && r.dirInModuleCache(root.Path) { + // A RootModuleCache root may be either the module cache itself or + // a dependency's module directory within it (see addDep in + // newModuleResolver). In both cases, subdir must be relative to + // the module cache so that it contains the module@version + // component that modCacheRegexp expects. + base = r.moduleCacheDir + } + if prefix := base + string(filepath.Separator); strings.HasPrefix(dir, prefix) { + subdir = dir[len(prefix):] + } + importPath := filepath.ToSlash(subdir) + if strings.HasPrefix(importPath, "vendor/") { + // Only enter vendor directories if they're explicitly requested as a root. + return directoryPackageInfo{ + status: directoryScanned, + err: fmt.Errorf("unwanted vendor directory"), + } + } + switch root.Type { + case gopathwalk.RootCurrentModule: + importPath = path.Join(r.mainByDir[root.Path].Path, filepath.ToSlash(subdir)) + case gopathwalk.RootModuleCache: + matches := modCacheRegexp.FindStringSubmatch(subdir) + if len(matches) == 0 { + return directoryPackageInfo{ + status: directoryScanned, + err: fmt.Errorf("invalid module cache path: %v", subdir), + } + } + modPath, err := module.UnescapePath(filepath.ToSlash(matches[1])) + if err != nil { + r.env.logf("decoding module cache path %q: %v", subdir, err) + return directoryPackageInfo{ + status: directoryScanned, + err: fmt.Errorf("decoding module cache path %q: %v", subdir, err), + } + } + importPath = path.Join(modPath, filepath.ToSlash(matches[3])) + } + + modDir, modName := r.modInfo(dir) + result := directoryPackageInfo{ + status: directoryScanned, + dir: dir, + rootType: root.Type, + nonCanonicalImportPath: importPath, + moduleDir: modDir, + moduleName: modName, + } + if root.Type == gopathwalk.RootGOROOT { + // stdlib packages are always in scope, despite the confusing go.mod + return result + } + return result +} + +// modCacheRegexp splits a path in a module cache into module, module version, and package. +var modCacheRegexp = regexp.MustCompile(`(.*)@([^/\\]*)(.*)`) + +var ( + slashSlash = []byte("//") + moduleStr = []byte("module") +) + +// modulePath returns the module path from the gomod file text. +// If it cannot find a module path, it returns an empty string. +// It is tolerant of unrelated problems in the go.mod file. +// +// Copied from cmd/go/internal/modfile. +func modulePath(mod []byte) string { + for len(mod) > 0 { + line := mod + mod = nil + if i := bytes.IndexByte(line, '\n'); i >= 0 { + line, mod = line[:i], line[i+1:] + } + if i := bytes.Index(line, slashSlash); i >= 0 { + line = line[:i] + } + line = bytes.TrimSpace(line) + if !bytes.HasPrefix(line, moduleStr) { + continue + } + line = line[len(moduleStr):] + n := len(line) + line = bytes.TrimSpace(line) + if len(line) == n || len(line) == 0 { + continue + } + + if line[0] == '"' || line[0] == '`' { + p, err := strconv.Unquote(string(line)) + if err != nil { + return "" // malformed quoted string or multiline module path + } + return p + } + + return string(line) + } + return "" // missing module path +} diff --git a/vendor/golang.org/x/tools/internal/imports/mod_cache.go b/vendor/golang.org/x/tools/internal/imports/mod_cache.go new file mode 100644 index 0000000..b96c9d4 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/imports/mod_cache.go @@ -0,0 +1,331 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package imports + +import ( + "context" + "fmt" + "path" + "path/filepath" + "strings" + "sync" + + "golang.org/x/mod/module" + "golang.org/x/tools/internal/gopathwalk" + "golang.org/x/tools/internal/stdlib" +) + +// To find packages to import, the resolver needs to know about all of +// the packages that could be imported. This includes packages that are +// already in modules that are in (1) the current module, (2) replace targets, +// and (3) packages in the module cache. Packages in (1) and (2) may change over +// time, as the client may edit the current module and locally replaced modules. +// The module cache (which includes all of the packages in (3)) can only +// ever be added to. +// +// The resolver can thus save state about packages in the module cache +// and guarantee that this will not change over time. To obtain information +// about new modules added to the module cache, the module cache should be +// rescanned. +// +// It is OK to serve information about modules that have been deleted, +// as they do still exist. +// TODO(suzmue): can we share information with the caller about +// what module needs to be downloaded to import this package? + +type directoryPackageStatus int + +const ( + _ directoryPackageStatus = iota + directoryScanned + nameLoaded + exportsLoaded +) + +// directoryPackageInfo holds (possibly incomplete) information about packages +// contained in a given directory. +type directoryPackageInfo struct { + // status indicates the extent to which this struct has been filled in. + status directoryPackageStatus + // err is non-nil when there was an error trying to reach status. + err error + + // Set when status >= directoryScanned. + + // dir is the absolute directory of this package. + dir string + rootType gopathwalk.RootType + // nonCanonicalImportPath is the package's expected import path. It may + // not actually be importable at that path. + nonCanonicalImportPath string + + // Module-related information. + moduleDir string // The directory that is the module root of this dir. + moduleName string // The module name that contains this dir. + + // Set when status >= nameLoaded. + + packageName string // the package name, as declared in the source. + + // Set when status >= exportsLoaded. + // TODO(rfindley): it's hard to see this, but exports depend implicitly on + // the default build context GOOS and GOARCH. + // + // We can make this explicit, and key exports by GOOS, GOARCH. + exports []stdlib.Symbol +} + +// reachedStatus returns true when info has a status at least target and any error associated with +// an attempt to reach target. +func (info *directoryPackageInfo) reachedStatus(target directoryPackageStatus) (bool, error) { + if info.err == nil { + return info.status >= target, nil + } + if info.status == target { + return true, info.err + } + return true, nil +} + +// DirInfoCache is a concurrency-safe map for storing information about +// directories that may contain packages. +// +// The information in this cache is built incrementally. Entries are initialized in scan. +// No new keys should be added in any other functions, as all directories containing +// packages are identified in scan. +// +// Other functions, including loadExports and findPackage, may update entries in this cache +// as they discover new things about the directory. +// +// The information in the cache is not expected to change for the cache's +// lifetime, so there is no protection against competing writes. Users should +// take care not to hold the cache across changes to the underlying files. +type DirInfoCache struct { + mu sync.Mutex + // dirs stores information about packages in directories, keyed by absolute path. + dirs map[string]*directoryPackageInfo + listeners map[*int]cacheListener +} + +func NewDirInfoCache() *DirInfoCache { + return &DirInfoCache{ + dirs: make(map[string]*directoryPackageInfo), + listeners: make(map[*int]cacheListener), + } +} + +type cacheListener func(directoryPackageInfo) + +// ScanAndListen calls listener on all the items in the cache, and on anything +// newly added. The returned stop function waits for all in-flight callbacks to +// finish and blocks new ones. +func (d *DirInfoCache) ScanAndListen(ctx context.Context, listener cacheListener) func() { + ctx, cancel := context.WithCancel(ctx) + + // Flushing out all the callbacks is tricky without knowing how many there + // are going to be. Setting an arbitrary limit makes it much easier. + const maxInFlight = 10 + sema := make(chan struct{}, maxInFlight) + for range maxInFlight { + sema <- struct{}{} + } + + cookie := new(int) // A unique ID we can use for the listener. + + // We can't hold mu while calling the listener. + d.mu.Lock() + var keys []string + for key := range d.dirs { + keys = append(keys, key) + } + d.listeners[cookie] = func(info directoryPackageInfo) { + select { + case <-ctx.Done(): + return + case <-sema: + } + listener(info) + sema <- struct{}{} + } + d.mu.Unlock() + + stop := func() { + cancel() + d.mu.Lock() + delete(d.listeners, cookie) + d.mu.Unlock() + for range maxInFlight { + <-sema + } + } + + // Process the pre-existing keys. + for _, k := range keys { + select { + case <-ctx.Done(): + return stop + default: + } + if v, ok := d.Load(k); ok { + listener(v) + } + } + + return stop +} + +// Store stores the package info for dir. +func (d *DirInfoCache) Store(dir string, info directoryPackageInfo) { + d.mu.Lock() + // TODO(rfindley, golang/go#59216): should we overwrite an existing entry? + // That seems incorrect as the cache should be idempotent. + _, old := d.dirs[dir] + d.dirs[dir] = &info + var listeners []cacheListener + for _, l := range d.listeners { + listeners = append(listeners, l) + } + d.mu.Unlock() + + if !old { + for _, l := range listeners { + l(info) + } + } +} + +// Load returns a copy of the directoryPackageInfo for absolute directory dir. +func (d *DirInfoCache) Load(dir string) (directoryPackageInfo, bool) { + d.mu.Lock() + defer d.mu.Unlock() + info, ok := d.dirs[dir] + if !ok { + return directoryPackageInfo{}, false + } + return *info, true +} + +// Keys returns the keys currently present in d. +func (d *DirInfoCache) Keys() (keys []string) { + d.mu.Lock() + defer d.mu.Unlock() + for key := range d.dirs { + keys = append(keys, key) + } + return keys +} + +func (d *DirInfoCache) CachePackageName(info directoryPackageInfo) (string, error) { + if loaded, err := info.reachedStatus(nameLoaded); loaded { + return info.packageName, err + } + if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil { + return "", fmt.Errorf("cannot read package name, scan error: %v", err) + } + info.packageName, info.err = packageDirToName(info.dir) + info.status = nameLoaded + d.Store(info.dir, info) + return info.packageName, info.err +} + +func (d *DirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []stdlib.Symbol, error) { + if reached, _ := info.reachedStatus(exportsLoaded); reached { + return info.packageName, info.exports, info.err + } + if reached, err := info.reachedStatus(nameLoaded); reached && err != nil { + return "", nil, err + } + info.packageName, info.exports, info.err = loadExportsFromFiles(ctx, env, info.dir, false) + if info.err == context.Canceled || info.err == context.DeadlineExceeded { + return info.packageName, info.exports, info.err + } + // The cache structure wants things to proceed linearly. We can skip a + // step here, but only if we succeed. + if info.status == nameLoaded || info.err == nil { + info.status = exportsLoaded + } else { + info.status = nameLoaded + } + d.Store(info.dir, info) + return info.packageName, info.exports, info.err +} + +// ScanModuleCache walks the given directory, which must be a GOMODCACHE value, +// for directory package information, storing the results in cache. +func ScanModuleCache(dir string, cache *DirInfoCache, logf func(string, ...any)) { + // Note(rfindley): it's hard to see, but this function attempts to implement + // just the side effects on cache of calling PrimeCache with a ProcessEnv + // that has the given dir as its GOMODCACHE. + // + // Teasing out the control flow, we see that we can avoid any handling of + // vendor/ and can infer module info entirely from the path, simplifying the + // logic here. + + root := gopathwalk.Root{ + Path: filepath.Clean(dir), + Type: gopathwalk.RootModuleCache, + } + + directoryInfo := func(root gopathwalk.Root, dir string) directoryPackageInfo { + // This is a copy of ModuleResolver.scanDirForPackage, trimmed down to + // logic that applies to a module cache directory. + + subdir := "" + if dir != root.Path { + subdir = dir[len(root.Path)+len("/"):] + } + + matches := modCacheRegexp.FindStringSubmatch(subdir) + if len(matches) == 0 { + return directoryPackageInfo{ + status: directoryScanned, + err: fmt.Errorf("invalid module cache path: %v", subdir), + } + } + modPath, err := module.UnescapePath(filepath.ToSlash(matches[1])) + if err != nil { + if logf != nil { + logf("decoding module cache path %q: %v", subdir, err) + } + return directoryPackageInfo{ + status: directoryScanned, + err: fmt.Errorf("decoding module cache path %q: %v", subdir, err), + } + } + importPath := path.Join(modPath, filepath.ToSlash(matches[3])) + index := strings.Index(dir, matches[1]+"@"+matches[2]) + modDir := filepath.Join(dir[:index], matches[1]+"@"+matches[2]) + modName := readModName(filepath.Join(modDir, "go.mod")) + return directoryPackageInfo{ + status: directoryScanned, + dir: dir, + rootType: root.Type, + nonCanonicalImportPath: importPath, + moduleDir: modDir, + moduleName: modName, + } + } + + add := func(root gopathwalk.Root, dir string) { + info := directoryInfo(root, dir) + cache.Store(info.dir, info) + } + + skip := func(_ gopathwalk.Root, dir string) bool { + // Skip directories that have already been scanned. + // + // Note that gopathwalk only adds "package" directories, which must contain + // a .go file, and all such package directories in the module cache are + // immutable. So if we can load a dir, it can be skipped. + info, ok := cache.Load(dir) + if !ok { + return false + } + packageScanned, _ := info.reachedStatus(directoryScanned) + return packageScanned + } + + gopathwalk.WalkSkip([]gopathwalk.Root{root}, add, skip, gopathwalk.Options{Logf: logf, ModulesEnabled: true}) +} diff --git a/vendor/golang.org/x/tools/internal/imports/sortimports.go b/vendor/golang.org/x/tools/internal/imports/sortimports.go new file mode 100644 index 0000000..ca713cb --- /dev/null +++ b/vendor/golang.org/x/tools/internal/imports/sortimports.go @@ -0,0 +1,307 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Hacked up copy of go/ast/import.go +// Modified to use a single token.File in preference to a FileSet. + +package imports + +import ( + "go/ast" + "go/token" + "log" + "slices" + "sort" + "strconv" +) + +// sortImports sorts runs of consecutive import lines in import blocks in f. +// It also removes duplicate imports when it is possible to do so without data loss. +// +// It may mutate the token.File and the ast.File. +func sortImports(localPrefix string, tokFile *token.File, f *ast.File) { + for i, d := range f.Decls { + d, ok := d.(*ast.GenDecl) + if !ok || d.Tok != token.IMPORT { + // Not an import declaration, so we're done. + // Imports are always first. + break + } + + if len(d.Specs) == 0 { + // Empty import block, remove it. + f.Decls = slices.Delete(f.Decls, i, i+1) + } + + if !d.Lparen.IsValid() { + // Not a block: sorted by default. + continue + } + + // Identify and sort runs of specs on successive lines. + i := 0 + specs := d.Specs[:0] + for j, s := range d.Specs { + if j > i && tokFile.Line(s.Pos()) > 1+tokFile.Line(d.Specs[j-1].End()) { + // j begins a new run. End this one. + specs = append(specs, sortSpecs(localPrefix, tokFile, f, d.Specs[i:j])...) + i = j + } + } + specs = append(specs, sortSpecs(localPrefix, tokFile, f, d.Specs[i:])...) + d.Specs = specs + + // Deduping can leave a blank line before the rparen; clean that up. + // Ignore line directives. + if len(d.Specs) > 0 { + lastSpec := d.Specs[len(d.Specs)-1] + lastLine := tokFile.PositionFor(lastSpec.Pos(), false).Line + if rParenLine := tokFile.PositionFor(d.Rparen, false).Line; rParenLine > lastLine+1 { + tokFile.MergeLine(rParenLine - 1) // has side effects! + } + } + } +} + +// mergeImports merges all the import declarations into the first one. +// Taken from golang.org/x/tools/go/ast/astutil. +// This does not adjust line numbers properly +func mergeImports(f *ast.File) { + if len(f.Decls) <= 1 { + return + } + + // Merge all the import declarations into the first one. + var first *ast.GenDecl + for i := 0; i < len(f.Decls); i++ { + decl := f.Decls[i] + gen, ok := decl.(*ast.GenDecl) + if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") { + continue + } + if first == nil { + first = gen + continue // Don't touch the first one. + } + // We now know there is more than one package in this import + // declaration. Ensure that it ends up parenthesized. + first.Lparen = first.Pos() + // Move the imports of the other import declaration to the first one. + for _, spec := range gen.Specs { + updateBasicLitPos(spec.(*ast.ImportSpec).Path, first.Pos()) + first.Specs = append(first.Specs, spec) + } + f.Decls = slices.Delete(f.Decls, i, i+1) + i-- + } +} + +// declImports reports whether gen contains an import of path. +// Taken from golang.org/x/tools/go/ast/astutil. +func declImports(gen *ast.GenDecl, path string) bool { + if gen.Tok != token.IMPORT { + return false + } + for _, spec := range gen.Specs { + impspec := spec.(*ast.ImportSpec) + if importPath(impspec) == path { + return true + } + } + return false +} + +func importPath(s ast.Spec) string { + t, err := strconv.Unquote(s.(*ast.ImportSpec).Path.Value) + if err == nil { + return t + } + return "" +} + +func importName(s ast.Spec) string { + n := s.(*ast.ImportSpec).Name + if n == nil { + return "" + } + return n.Name +} + +func importComment(s ast.Spec) string { + c := s.(*ast.ImportSpec).Comment + if c == nil { + return "" + } + return c.Text() +} + +// collapse indicates whether prev may be removed, leaving only next. +func collapse(prev, next ast.Spec) bool { + if importPath(next) != importPath(prev) || importName(next) != importName(prev) { + return false + } + return prev.(*ast.ImportSpec).Comment == nil +} + +type posSpan struct { + Start token.Pos + End token.Pos +} + +// sortSpecs sorts the import specs within each import decl. +// It may mutate the token.File. +func sortSpecs(localPrefix string, tokFile *token.File, f *ast.File, specs []ast.Spec) []ast.Spec { + // Can't short-circuit here even if specs are already sorted, + // since they might yet need deduplication. + // A lone import, however, may be safely ignored. + if len(specs) <= 1 { + return specs + } + + // Record positions for specs. + pos := make([]posSpan, len(specs)) + for i, s := range specs { + pos[i] = posSpan{s.Pos(), s.End()} + } + + // Identify comments in this range. + // Any comment from pos[0].Start to the final line counts. + lastLine := tokFile.Line(pos[len(pos)-1].End) + cstart := len(f.Comments) + cend := len(f.Comments) + for i, g := range f.Comments { + if g.Pos() < pos[0].Start { + continue + } + if i < cstart { + cstart = i + } + if tokFile.Line(g.End()) > lastLine { + cend = i + break + } + } + comments := f.Comments[cstart:cend] + + // Assign each comment to the import spec preceding it. + importComment := map[*ast.ImportSpec][]*ast.CommentGroup{} + specIndex := 0 + for _, g := range comments { + for specIndex+1 < len(specs) && pos[specIndex+1].Start <= g.Pos() { + specIndex++ + } + s := specs[specIndex].(*ast.ImportSpec) + importComment[s] = append(importComment[s], g) + } + + // Sort the import specs by import path. + // Remove duplicates, when possible without data loss. + // Reassign the import paths to have the same position sequence. + // Reassign each comment to abut the end of its spec. + // Sort the comments by new position. + sort.Sort(byImportSpec{localPrefix, specs}) + + // Dedup. Thanks to our sorting, we can just consider + // adjacent pairs of imports. + deduped := specs[:0] + for i, s := range specs { + if i == len(specs)-1 || !collapse(s, specs[i+1]) { + deduped = append(deduped, s) + } else { + p := s.Pos() + tokFile.MergeLine(tokFile.Line(p)) // has side effects! + } + } + specs = deduped + + // Fix up comment positions + for i, s := range specs { + s := s.(*ast.ImportSpec) + if s.Name != nil { + s.Name.NamePos = pos[i].Start + } + updateBasicLitPos(s.Path, pos[i].Start) + s.EndPos = pos[i].End + nextSpecPos := pos[i].End + + for _, g := range importComment[s] { + for _, c := range g.List { + c.Slash = pos[i].End + nextSpecPos = c.End() + } + } + if i < len(specs)-1 { + pos[i+1].Start = nextSpecPos + pos[i+1].End = nextSpecPos + } + } + + sort.Sort(byCommentPos(comments)) + + // Fixup comments can insert blank lines, because import specs are on different lines. + // We remove those blank lines here by merging import spec to the first import spec line. + firstSpecLine := tokFile.Line(specs[0].Pos()) + for _, s := range specs[1:] { + p := s.Pos() + line := tokFile.Line(p) + for previousLine := line - 1; previousLine >= firstSpecLine; { + // MergeLine can panic. Avoid the panic at the cost of not removing the blank line + // golang/go#50329 + if previousLine > 0 && previousLine < tokFile.LineCount() { + tokFile.MergeLine(previousLine) // has side effects! + previousLine-- + } else { + // try to gather some data to diagnose how this could happen + req := "Please report what the imports section of your go file looked like." + log.Printf("panic avoided: first:%d line:%d previous:%d max:%d. %s", + firstSpecLine, line, previousLine, tokFile.LineCount(), req) + } + } + } + return specs +} + +type byImportSpec struct { + localPrefix string + specs []ast.Spec // slice of *ast.ImportSpec +} + +func (x byImportSpec) Len() int { return len(x.specs) } +func (x byImportSpec) Swap(i, j int) { x.specs[i], x.specs[j] = x.specs[j], x.specs[i] } +func (x byImportSpec) Less(i, j int) bool { + ipath := importPath(x.specs[i]) + jpath := importPath(x.specs[j]) + + igroup := importGroup(x.localPrefix, ipath) + jgroup := importGroup(x.localPrefix, jpath) + if igroup != jgroup { + return igroup < jgroup + } + + if ipath != jpath { + return ipath < jpath + } + iname := importName(x.specs[i]) + jname := importName(x.specs[j]) + + if iname != jname { + return iname < jname + } + return importComment(x.specs[i]) < importComment(x.specs[j]) +} + +type byCommentPos []*ast.CommentGroup + +func (x byCommentPos) Len() int { return len(x) } +func (x byCommentPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x byCommentPos) Less(i, j int) bool { return x[i].Pos() < x[j].Pos() } + +// updateBasicLitPos updates lit.Pos, +// ensuring that lit.End is displaced by the same amount. +// (See https://go.dev/issue/76395.) +func updateBasicLitPos(lit *ast.BasicLit, pos token.Pos) { + len := lit.End() - lit.Pos() + lit.ValuePos = pos + lit.ValueEnd = pos + len +} diff --git a/vendor/golang.org/x/tools/internal/imports/source.go b/vendor/golang.org/x/tools/internal/imports/source.go new file mode 100644 index 0000000..cbe4f3c --- /dev/null +++ b/vendor/golang.org/x/tools/internal/imports/source.go @@ -0,0 +1,63 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package imports + +import "context" + +// These types document the APIs below. +// +// TODO(rfindley): consider making these defined types rather than aliases. +type ( + ImportPath = string + PackageName = string + Symbol = string + + // References is set of References found in a Go file. The first map key is the + // left hand side of a selector expression, the second key is the right hand + // side, and the value should always be true. + References = map[PackageName]map[Symbol]bool +) + +// A Result satisfies a missing import. +// +// The Import field describes the missing import spec, and the Package field +// summarizes the package exports. +type Result struct { + Import *ImportInfo + Package *PackageInfo +} + +// An ImportInfo represents a single import statement. +type ImportInfo struct { + ImportPath string // import path, e.g. "crypto/rand". + Name string // import name, e.g. "crand", or "" if none. +} + +// A PackageInfo represents what's known about a package. +type PackageInfo struct { + Name string // package name in the package declaration, if known + Exports map[string]bool // set of names of known package level sortSymbols +} + +// A Source provides imports to satisfy unresolved references in the file being +// fixed. +type Source interface { + // LoadPackageNames queries PackageName information for the requested import + // paths, when operating from the provided srcDir. + // + // TODO(rfindley): try to refactor to remove this operation. + LoadPackageNames(ctx context.Context, srcDir string, paths []ImportPath) (map[ImportPath]PackageName, error) + + // ResolveReferences asks the Source for the best package name to satisfy + // each of the missing references, in the context of fixing the given + // filename. + // + // Returns a map from package name to a [Result] for that package name that + // provides the required symbols. Keys may be omitted in the map if no + // candidates satisfy all missing references for that package name. It is up + // to each data source to select the best result for each entry in the + // missing map. + ResolveReferences(ctx context.Context, filename string, missing References) ([]*Result, error) +} diff --git a/vendor/golang.org/x/tools/internal/imports/source_env.go b/vendor/golang.org/x/tools/internal/imports/source_env.go new file mode 100644 index 0000000..272ae80 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/imports/source_env.go @@ -0,0 +1,129 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package imports + +import ( + "context" + "path/filepath" + "strings" + "sync" + + "golang.org/x/sync/errgroup" + "golang.org/x/tools/internal/gopathwalk" +) + +// ProcessEnvSource implements the [Source] interface using the legacy +// [ProcessEnv] abstraction. +type ProcessEnvSource struct { + env *ProcessEnv + srcDir string + filename string + pkgName string +} + +// NewProcessEnvSource returns a [ProcessEnvSource] wrapping the given +// env, to be used for fixing imports in the file with name filename in package +// named pkgName. +func NewProcessEnvSource(env *ProcessEnv, filename, pkgName string) (*ProcessEnvSource, error) { + abs, err := filepath.Abs(filename) + if err != nil { + return nil, err + } + srcDir := filepath.Dir(abs) + return &ProcessEnvSource{ + env: env, + srcDir: srcDir, + filename: filename, + pkgName: pkgName, + }, nil +} + +func (s *ProcessEnvSource) LoadPackageNames(ctx context.Context, srcDir string, unknown []string) (map[string]string, error) { + r, err := s.env.GetResolver() + if err != nil { + return nil, err + } + return r.loadPackageNames(unknown, srcDir) +} + +func (s *ProcessEnvSource) ResolveReferences(ctx context.Context, filename string, refs map[string]map[string]bool) ([]*Result, error) { + var mu sync.Mutex + found := make(map[string][]pkgDistance) + callback := &scanCallback{ + rootFound: func(gopathwalk.Root) bool { + return true + }, + dirFound: func(pkg *pkg) bool { + return pkgIsCandidate(filename, refs, pkg) + }, + packageNameLoaded: func(pkg *pkg) bool { + if _, want := refs[pkg.packageName]; !want { + return false + } + if pkg.dir == s.srcDir && s.pkgName == pkg.packageName { + // The candidate is in the same directory and has the + // same package name. Don't try to import ourselves. + return false + } + if !CanUse(filename, pkg.dir) { + return false + } + mu.Lock() + defer mu.Unlock() + found[pkg.packageName] = append(found[pkg.packageName], pkgDistance{pkg, distance(s.srcDir, pkg.dir)}) + return false // We'll do our own loading after we sort. + }, + } + resolver, err := s.env.GetResolver() + if err != nil { + return nil, err + } + if err := resolver.scan(ctx, callback); err != nil { + return nil, err + } + + g, ctx := errgroup.WithContext(ctx) + + searcher := symbolSearcher{ + logf: s.env.logf, + srcDir: s.srcDir, + xtest: strings.HasSuffix(s.pkgName, "_test"), + loadExports: resolver.loadExports, + } + + var resultMu sync.Mutex + results := make(map[string]*Result, len(refs)) + for pkgName, symbols := range refs { + g.Go(func() error { + found, err := searcher.search(ctx, found[pkgName], pkgName, symbols) + if err != nil { + return err + } + if found == nil { + return nil // No matching package. + } + + imp := &ImportInfo{ + ImportPath: found.importPathShort, + } + pkg := &PackageInfo{ + Name: pkgName, + Exports: symbols, + } + resultMu.Lock() + results[pkgName] = &Result{Import: imp, Package: pkg} + resultMu.Unlock() + return nil + }) + } + if err := g.Wait(); err != nil { + return nil, err + } + var ans []*Result + for _, x := range results { + ans = append(ans, x) + } + return ans, nil +} diff --git a/vendor/golang.org/x/tools/internal/modindex/directories.go b/vendor/golang.org/x/tools/internal/modindex/directories.go new file mode 100644 index 0000000..9a96374 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/modindex/directories.go @@ -0,0 +1,131 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modindex + +import ( + "fmt" + "log" + "os" + "path/filepath" + "regexp" + "strings" + "sync" + "time" + + "golang.org/x/mod/semver" + "golang.org/x/tools/internal/gopathwalk" +) + +type directory struct { + path string // relative to GOMODCACHE + importPath string + version string // semantic version +} + +// bestDirByImportPath returns the best directory for each import +// path, where "best" means most recent semantic version. These import +// paths are inferred from the GOMODCACHE-relative dir names in dirs. +func bestDirByImportPath(dirs []string) (map[string]directory, error) { + dirsByPath := make(map[string]directory) + for _, dir := range dirs { + importPath, version, err := dirToImportPathVersion(dir) + if err != nil { + return nil, err + } + new := directory{ + path: dir, + importPath: importPath, + version: version, + } + if old, ok := dirsByPath[importPath]; !ok || compareDirectory(new, old) < 0 { + dirsByPath[importPath] = new + } + } + return dirsByPath, nil +} + +// compareDirectory defines an ordering of path@version directories, +// by descending version, then by ascending path. +func compareDirectory(x, y directory) int { + if sign := -semver.Compare(x.version, y.version); sign != 0 { + return sign // latest first + } + return strings.Compare(string(x.path), string(y.path)) +} + +// modCacheRegexp splits a relpathpath into module, module version, and package. +var modCacheRegexp = regexp.MustCompile(`(.*)@([^/\\]*)(.*)`) + +// dirToImportPathVersion computes import path and semantic version +// from a GOMODCACHE-relative directory name. +func dirToImportPathVersion(dir string) (string, string, error) { + m := modCacheRegexp.FindStringSubmatch(string(dir)) + // m[1] is the module path + // m[2] is the version major.minor.patch(-
 1 && flds[1][1] == 'D',
+			}
+			if px.Type == Func {
+				n, err := strconv.Atoi(flds[2])
+				if err != nil {
+					continue // should never happen
+				}
+				px.Results = int16(n)
+				if len(flds) >= 4 {
+					sig := strings.Split(flds[3], " ")
+					for i := range sig {
+						// $ cannot otherwise occur. removing the spaces
+						// almost works, but for chan struct{}, e.g.
+						sig[i] = strings.Replace(sig[i], "$", " ", -1)
+					}
+					px.Sig = toFields(sig)
+				}
+			}
+			ans = append(ans, px)
+		}
+	}
+	return ans
+}
+
+func toFields(sig []string) []Field {
+	ans := make([]Field, len(sig)/2)
+	for i := range ans {
+		ans[i] = Field{Arg: sig[2*i], Type: sig[2*i+1]}
+	}
+	return ans
+}
+
+// benchmarks show this is measurably better than strings.Split
+// split into first 4 fields separated by single space
+func fastSplit(x string) []string {
+	ans := make([]string, 0, 4)
+	nxt := 0
+	start := 0
+	for i := 0; i < len(x); i++ {
+		if x[i] != ' ' {
+			continue
+		}
+		ans = append(ans, x[start:i])
+		nxt++
+		start = i + 1
+		if nxt >= 3 {
+			break
+		}
+	}
+	ans = append(ans, x[start:])
+	return ans
+}
+
+func asLexType(c byte) LexType {
+	switch c {
+	case 'C':
+		return Const
+	case 'V':
+		return Var
+	case 'T':
+		return Type
+	case 'F':
+		return Func
+	}
+	return -1
+}
diff --git a/vendor/golang.org/x/tools/internal/modindex/modindex.go b/vendor/golang.org/x/tools/internal/modindex/modindex.go
new file mode 100644
index 0000000..16a7cab
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/modindex/modindex.go
@@ -0,0 +1,121 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package modindex contains code for building and searching an
+// [Index] of the Go module cache.
+package modindex
+
+// The directory containing the index, returned by
+// [IndexDir], contains a file index-name- that contains the name
+// of the current index. We believe writing that short file is atomic.
+// [Read] reads that file to get the file name of the index.
+// WriteIndex writes an index with a unique name and then
+// writes that name into a new version of index-name-.
+// ( stands for the CurrentVersion of the index format.)
+
+import (
+	"maps"
+	"os"
+	"path/filepath"
+	"slices"
+	"strings"
+	"time"
+
+	"golang.org/x/mod/semver"
+)
+
+// Update updates the index for the specified Go
+// module cache directory, creating it as needed.
+// On success it returns the current index.
+func Update(gomodcache string) (*Index, error) {
+	prev, err := Read(gomodcache)
+	if err != nil {
+		if !os.IsNotExist(err) {
+			return nil, err
+		}
+		prev = nil
+	}
+	return update(gomodcache, prev)
+}
+
+// update builds, writes, and returns the current index.
+//
+// If old is nil, the new index is built from all of GOMODCACHE;
+// otherwise it is built from the old index plus cache updates
+// since the previous index's time.
+func update(gomodcache string, old *Index) (*Index, error) {
+	gomodcache, err := filepath.Abs(gomodcache)
+	if err != nil {
+		return nil, err
+	}
+	new, changed, err := build(gomodcache, old)
+	if err != nil {
+		return nil, err
+	}
+	if old == nil || changed {
+		if err := write(gomodcache, new); err != nil {
+			return nil, err
+		}
+	}
+	return new, nil
+}
+
+// build returns a new index for the specified Go module cache (an
+// absolute path).
+//
+// If an old index is provided, only directories more recent than it
+// that it are scanned; older directories are provided by the old
+// Index.
+//
+// The boolean result indicates whether new entries were found.
+func build(gomodcache string, old *Index) (*Index, bool, error) {
+	// Set the time window.
+	var start time.Time // = dawn of time
+	if old != nil {
+		// -1s to accommodate skew between (fine-grained) time.Now
+		// and (coarse) file system's mtime clock.
+		start = old.ValidAt.Add(-1 * time.Second)
+	}
+	now := time.Now()
+	end := now.Add(24 * time.Hour) // safely in the future
+
+	// Enumerate GOMODCACHE package directories.
+	// Choose the best (latest) package for each import path.
+	pkgDirs := findDirs(gomodcache, start, end)
+	dirByPath, err := bestDirByImportPath(pkgDirs)
+	if err != nil {
+		return nil, false, err
+	}
+
+	// For each import path it might occur only in
+	// dirByPath, only in old, or in both.
+	// If both, use the semantically later one.
+	var entries []Entry
+	if old != nil {
+		for _, entry := range old.Entries {
+			dir, ok := dirByPath[entry.ImportPath]
+			if !ok || semver.Compare(dir.version, entry.Version) <= 0 {
+				// New dir is missing or not more recent; use old entry.
+				entries = append(entries, entry)
+				delete(dirByPath, entry.ImportPath)
+			}
+		}
+	}
+
+	// Extract symbol information for all the new directories.
+	newEntries := extractSymbols(gomodcache, maps.Values(dirByPath))
+	entries = append(entries, newEntries...)
+	slices.SortFunc(entries, func(x, y Entry) int {
+		if n := strings.Compare(x.PkgName, y.PkgName); n != 0 {
+			return n
+		}
+		return strings.Compare(x.ImportPath, y.ImportPath)
+	})
+
+	return &Index{
+		GOMODCACHE: gomodcache,
+		ValidAt:    now, // time before the directories were scanned
+		Entries:    entries,
+	}, len(newEntries) > 0, nil
+}
diff --git a/vendor/golang.org/x/tools/internal/modindex/symbols.go b/vendor/golang.org/x/tools/internal/modindex/symbols.go
new file mode 100644
index 0000000..8e9702d
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/modindex/symbols.go
@@ -0,0 +1,244 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package modindex
+
+import (
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"iter"
+	"os"
+	"path/filepath"
+	"runtime"
+	"slices"
+	"strings"
+	"sync"
+
+	"golang.org/x/sync/errgroup"
+)
+
+// The name of a symbol contains information about the symbol:
+//  T for types, TD if the type is deprecated
+//  C for consts, CD if the const is deprecated
+//  V for vars, VD if the var is deprecated
+// and for funcs:  F  ( )*
+// any spaces in  are replaced by $s so that the fields
+// of the name are space separated. F is replaced by FD if the func
+// is deprecated.
+type symbol struct {
+	pkg  string // name of the symbols's package
+	name string // declared name
+	kind string // T, C, V, or F, followed by D if deprecated
+	sig  string // signature information, for F
+}
+
+// extractSymbols returns a (new, unordered) array of Entries, one for
+// each provided package directory, describing its exported symbols.
+func extractSymbols(cwd string, dirs iter.Seq[directory]) []Entry {
+	var (
+		mu      sync.Mutex
+		entries []Entry
+	)
+
+	var g errgroup.Group
+	g.SetLimit(max(2, runtime.GOMAXPROCS(0)/2))
+	for dir := range dirs {
+		g.Go(func() error {
+			thedir := filepath.Join(cwd, string(dir.path))
+			mode := parser.SkipObjectResolution | parser.ParseComments
+
+			// Parse all Go files in dir and extract symbols.
+			dirents, err := os.ReadDir(thedir)
+			if err != nil {
+				return nil // log this someday?
+			}
+			var syms []symbol
+			for _, dirent := range dirents {
+				if !strings.HasSuffix(dirent.Name(), ".go") ||
+					strings.HasSuffix(dirent.Name(), "_test.go") {
+					continue
+				}
+				fname := filepath.Join(thedir, dirent.Name())
+				tr, err := parser.ParseFile(token.NewFileSet(), fname, nil, mode)
+				if err != nil {
+					continue // ignore errors, someday log them?
+				}
+				syms = append(syms, getFileExports(tr)...)
+			}
+
+			// Create an entry for the package.
+			pkg, names := processSyms(syms)
+			if pkg != "" {
+				mu.Lock()
+				defer mu.Unlock()
+				entries = append(entries, Entry{
+					PkgName:    pkg,
+					Dir:        dir.path,
+					ImportPath: dir.importPath,
+					Version:    dir.version,
+					Names:      names,
+				})
+			}
+
+			return nil
+		})
+	}
+	g.Wait() // ignore error
+
+	return entries
+}
+
+func getFileExports(f *ast.File) []symbol {
+	pkg := f.Name.Name
+	if pkg == "main" || pkg == "" {
+		return nil
+	}
+	var ans []symbol
+	// should we look for //go:build ignore?
+	for _, decl := range f.Decls {
+		switch decl := decl.(type) {
+		case *ast.FuncDecl:
+			if decl.Recv != nil {
+				// ignore methods, as we are completing package selections
+				continue
+			}
+			name := decl.Name.Name
+			dtype := decl.Type
+			// not looking at dtype.TypeParams. That is, treating
+			// generic functions just like non-generic ones.
+			sig := dtype.Params
+			kind := "F"
+			if isDeprecated(decl.Doc) {
+				kind += "D"
+			}
+			result := []string{fmt.Sprintf("%d", dtype.Results.NumFields())}
+			for _, x := range sig.List {
+				// This code creates a string representing the type.
+				// TODO(pjw): it may be fragile:
+				// 1. x.Type could be nil, perhaps in ill-formed code
+				// 2. ExprString might someday change incompatibly to
+				//    include struct tags, which can be arbitrary strings
+				if x.Type == nil {
+					// Can this happen without a parse error? (Files with parse
+					// errors are ignored in getSymbols)
+					continue // maybe report this someday
+				}
+				tp := types.ExprString(x.Type)
+				if len(tp) == 0 {
+					// Can this happen?
+					continue // maybe report this someday
+				}
+				// This is only safe if ExprString never returns anything with a $
+				// The only place a $ can occur seems to be in a struct tag, which
+				// can be an arbitrary string literal, and ExprString does not presently
+				// print struct tags. So for this to happen the type of a formal parameter
+				// has to be a explicit struct, e.g. foo(x struct{a int "$"}) and ExprString
+				// would have to show the struct tag. Even testing for this case seems
+				// a waste of effort, but let's remember the possibility
+				if strings.Contains(tp, "$") {
+					continue
+				}
+				tp = strings.Replace(tp, " ", "$", -1)
+				if len(x.Names) == 0 {
+					result = append(result, "_")
+					result = append(result, tp)
+				} else {
+					for _, y := range x.Names {
+						result = append(result, y.Name)
+						result = append(result, tp)
+					}
+				}
+			}
+			sigs := strings.Join(result, " ")
+			if s := newsym(pkg, name, kind, sigs); s != nil {
+				ans = append(ans, *s)
+			}
+		case *ast.GenDecl:
+			depr := isDeprecated(decl.Doc)
+			switch decl.Tok {
+			case token.CONST, token.VAR:
+				tp := "V"
+				if decl.Tok == token.CONST {
+					tp = "C"
+				}
+				if depr {
+					tp += "D"
+				}
+				for _, sp := range decl.Specs {
+					for _, x := range sp.(*ast.ValueSpec).Names {
+						if s := newsym(pkg, x.Name, tp, ""); s != nil {
+							ans = append(ans, *s)
+						}
+					}
+				}
+			case token.TYPE:
+				tp := "T"
+				if depr {
+					tp += "D"
+				}
+				for _, sp := range decl.Specs {
+					if s := newsym(pkg, sp.(*ast.TypeSpec).Name.Name, tp, ""); s != nil {
+						ans = append(ans, *s)
+					}
+				}
+			}
+		}
+	}
+	return ans
+}
+
+func newsym(pkg, name, kind, sig string) *symbol {
+	if len(name) == 0 || !ast.IsExported(name) {
+		return nil
+	}
+	sym := symbol{pkg: pkg, name: name, kind: kind, sig: sig}
+	return &sym
+}
+
+func isDeprecated(doc *ast.CommentGroup) bool {
+	if doc == nil {
+		return false
+	}
+	// go.dev/wiki/Deprecated Paragraph starting 'Deprecated:'
+	// This code fails for /* Deprecated: */, but it's the code from
+	// gopls/internal/analysis/deprecated
+	for line := range strings.SplitSeq(doc.Text(), "\n\n") {
+		if strings.HasPrefix(line, "Deprecated:") {
+			return true
+		}
+	}
+	return false
+}
+
+// return the package name and the value for the symbols.
+// if there are multiple packages, choose one arbitrarily
+// the returned slice is sorted lexicographically
+func processSyms(syms []symbol) (string, []string) {
+	if len(syms) == 0 {
+		return "", nil
+	}
+	slices.SortFunc(syms, func(l, r symbol) int {
+		return strings.Compare(l.name, r.name)
+	})
+	pkg := syms[0].pkg
+	var names []string
+	for _, s := range syms {
+		if s.pkg != pkg {
+			// Symbols came from two files in same dir
+			// with different package declarations.
+			continue
+		}
+		var nx string
+		if s.sig != "" {
+			nx = fmt.Sprintf("%s %s %s", s.name, s.kind, s.sig)
+		} else {
+			nx = fmt.Sprintf("%s %s", s.name, s.kind)
+		}
+		names = append(names, nx)
+	}
+	return pkg, names
+}
diff --git a/vendor/golang.org/x/tools/internal/moremaps/maps.go b/vendor/golang.org/x/tools/internal/moremaps/maps.go
new file mode 100644
index 0000000..a1bae07
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/moremaps/maps.go
@@ -0,0 +1,116 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package moremaps contains more functions for working with maps.
+package moremaps
+
+import (
+	"cmp"
+	"iter"
+	"maps"
+	"slices"
+)
+
+// Arbitrary returns an arbitrary (key, value) entry from the map and ok is true, if
+// the map is not empty. Otherwise, it returns zero values for K and V, and false.
+func Arbitrary[K comparable, V any](m map[K]V) (_ K, _ V, ok bool) {
+	for k, v := range m {
+		return k, v, true
+	}
+	return
+}
+
+// Group returns a new non-nil map containing the elements of s grouped by the
+// keys returned from the key func.
+func Group[K comparable, V any](s []V, key func(V) K) map[K][]V {
+	m := make(map[K][]V)
+	for _, v := range s {
+		k := key(v)
+		m[k] = append(m[k], v)
+	}
+	return m
+}
+
+// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)).
+func KeySlice[M ~map[K]V, K comparable, V any](m M) []K {
+	r := make([]K, 0, len(m))
+	for k := range m {
+		r = append(r, k)
+	}
+	return r
+}
+
+// ValueSlice returns the values of the map M, like slices.Collect(maps.Values(m)).
+func ValueSlice[M ~map[K]V, K comparable, V any](m M) []V {
+	r := make([]V, 0, len(m))
+	for _, v := range m {
+		r = append(r, v)
+	}
+	return r
+}
+
+// SameKeys reports whether x and y have equal sets of keys.
+func SameKeys[K comparable, V1, V2 any](x map[K]V1, y map[K]V2) bool {
+	ignoreValues := func(V1, V2) bool { return true }
+	return maps.EqualFunc(x, y, ignoreValues)
+}
+
+// Sorted returns an iterator over the entries of m in key order.
+func Sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] {
+	// TODO(adonovan): use maps.Sorted if proposal #68598 is accepted.
+	return func(yield func(K, V) bool) {
+		keys := KeySlice(m)
+		slices.Sort(keys)
+		for _, k := range keys {
+			if !yield(k, m[k]) {
+				break
+			}
+		}
+	}
+}
+
+// SortedFunc returns an iterator over the entries of m in the key order determined by cmp.
+func SortedFunc[M ~map[K]V, K comparable, V any](m M, cmp func(x, y K) int) iter.Seq2[K, V] {
+	// TODO(adonovan): use maps.SortedFunc if proposal #68598 is accepted.
+	return func(yield func(K, V) bool) {
+		keys := KeySlice(m)
+		slices.SortFunc(keys, cmp)
+		for _, k := range keys {
+			if !yield(k, m[k]) {
+				break
+			}
+		}
+	}
+}
+
+// Delete is like delete(m, k) but reports whether deletion occurred.
+func Delete[M ~map[K]V, K comparable, V any](m M, k K) bool {
+	pre := len(m)
+	delete(m, k)
+	return pre != len(m)
+}
+
+// Entry is a key-value pair obtained from a map.
+type Entry[K comparable, V any] struct {
+	Key   K
+	Value V
+}
+
+// Entries returns a new unordered array of the entries of a map.
+func Entries[M ~map[K]V, K comparable, V any](m M) []Entry[K, V] {
+	entries := make([]Entry[K, V], 0, len(m))
+	for k, v := range m {
+		entries = append(entries, Entry[K, V]{k, v})
+	}
+	return entries
+}
+
+// FromEntries returns a new map into which the entries have been inserted in order.
+func FromEntries[K comparable, V any](entries []Entry[K, V]) map[K]V {
+	m := make(map[K]V, len(entries))
+	for _, e := range entries {
+		m[e.Key] = e.Value
+	}
+	return m
+}
diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
new file mode 100644
index 0000000..929b470
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
@@ -0,0 +1,23 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package packagesinternal exposes internal-only fields from go/packages.
+package packagesinternal
+
+import "fmt"
+
+var GetDepsErrors = func(p any) []*PackageError { return nil }
+
+type PackageError struct {
+	ImportStack []string // shortest path from package named on command line to this one
+	Pos         string   // position of error (if present, file:line:col)
+	Err         string   // the error itself
+}
+
+func (err PackageError) String() string {
+	return fmt.Sprintf("%s: %s (import stack: %s)", err.Pos, err.Err, err.ImportStack)
+}
+
+var TypecheckCgo int
+var DepsErrors int // must be set as a LoadMode to call GetDepsErrors
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/codes.go b/vendor/golang.org/x/tools/internal/pkgbits/codes.go
new file mode 100644
index 0000000..21f44d9
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/codes.go
@@ -0,0 +1,79 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+// This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps.
+
+// A Code is an enum value that can be encoded into bitstreams.
+//
+// Code types are preferable for enum types, because they allow
+// Decoder to detect desyncs.
+type Code interface {
+	// Marker returns the SyncMarker for the Code's dynamic type.
+	Marker() SyncMarker
+
+	// Value returns the Code's ordinal value.
+	Value() int
+}
+
+// A CodeVal distinguishes among go/constant.Value encodings.
+type CodeVal int
+
+func (c CodeVal) Marker() SyncMarker { return SyncVal }
+func (c CodeVal) Value() int         { return int(c) }
+
+// Note: These values are public and cannot be changed without
+// updating the go/types importers.
+
+const (
+	ValBool CodeVal = iota
+	ValString
+	ValInt64
+	ValBigInt
+	ValBigRat
+	ValBigFloat
+)
+
+// A CodeType distinguishes among go/types.Type encodings.
+type CodeType int
+
+func (c CodeType) Marker() SyncMarker { return SyncType }
+func (c CodeType) Value() int         { return int(c) }
+
+// Note: These values are public and cannot be changed without
+// updating the go/types importers.
+
+const (
+	TypeBasic CodeType = iota
+	TypeNamed
+	TypePointer
+	TypeSlice
+	TypeArray
+	TypeChan
+	TypeMap
+	TypeSignature
+	TypeStruct
+	TypeInterface
+	TypeUnion
+	TypeTypeParam
+)
+
+// A CodeObj distinguishes among go/types.Object encodings.
+type CodeObj int
+
+func (c CodeObj) Marker() SyncMarker { return SyncCodeObj }
+func (c CodeObj) Value() int         { return int(c) }
+
+// Note: These values are public and cannot be changed without
+// updating the go/types importers.
+
+const (
+	ObjAlias CodeObj = iota
+	ObjConst
+	ObjType
+	ObjFunc
+	ObjVar
+	ObjStub
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go
new file mode 100644
index 0000000..f05e269
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go
@@ -0,0 +1,520 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"go/constant"
+	"go/token"
+	"io"
+	"math/big"
+	"os"
+	"runtime"
+	"strings"
+	// This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps.
+)
+
+// A PkgDecoder provides methods for decoding a package's Unified IR
+// export data.
+type PkgDecoder struct {
+	// version is the file format version.
+	version Version
+
+	// sync indicates whether the file uses sync markers.
+	sync bool
+
+	// pkgPath is the package path for the package to be decoded.
+	//
+	// TODO(mdempsky): Remove; unneeded since CL 391014.
+	pkgPath string
+
+	// elemData is the full data payload of the encoded package.
+	// Elements are densely and contiguously packed together.
+	//
+	// The last 8 bytes of elemData are the package fingerprint.
+	elemData string
+
+	// elemEnds stores the byte-offset end positions of element
+	// bitstreams within elemData.
+	//
+	// For example, element I's bitstream data starts at elemEnds[I-1]
+	// (or 0, if I==0) and ends at elemEnds[I].
+	//
+	// Note: elemEnds is indexed by absolute indices, not
+	// section-relative indices.
+	elemEnds []uint32
+
+	// elemEndsEnds stores the index-offset end positions of relocation
+	// sections within elemEnds.
+	//
+	// For example, section K's end positions start at elemEndsEnds[K-1]
+	// (or 0, if K==0) and end at elemEndsEnds[K].
+	elemEndsEnds [numRelocs]uint32
+
+	scratchRelocEnt []RelocEnt
+}
+
+// PkgPath returns the package path for the package
+//
+// TODO(mdempsky): Remove; unneeded since CL 391014.
+func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath }
+
+// SyncMarkers reports whether pr uses sync markers.
+func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync }
+
+// NewPkgDecoder returns a PkgDecoder initialized to read the Unified
+// IR export data from input. pkgPath is the package path for the
+// compilation unit that produced the export data.
+func NewPkgDecoder(pkgPath, input string) PkgDecoder {
+	pr := PkgDecoder{
+		pkgPath: pkgPath,
+	}
+
+	// TODO(mdempsky): Implement direct indexing of input string to
+	// avoid copying the position information.
+
+	r := strings.NewReader(input)
+
+	var ver uint32
+	assert(binary.Read(r, binary.LittleEndian, &ver) == nil)
+	pr.version = Version(ver)
+
+	if pr.version >= numVersions {
+		panic(fmt.Errorf("cannot decode %q, export data version %d is greater than maximum supported version %d", pkgPath, pr.version, numVersions-1))
+	}
+
+	if pr.version.Has(Flags) {
+		var flags uint32
+		assert(binary.Read(r, binary.LittleEndian, &flags) == nil)
+		pr.sync = flags&flagSyncMarkers != 0
+	}
+
+	assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil)
+
+	pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1])
+	assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil)
+
+	pos, err := r.Seek(0, io.SeekCurrent)
+	assert(err == nil)
+
+	pr.elemData = input[pos:]
+
+	const fingerprintSize = 8
+	assert(len(pr.elemData)-fingerprintSize == int(pr.elemEnds[len(pr.elemEnds)-1]))
+
+	return pr
+}
+
+// NumElems returns the number of elements in section k.
+func (pr *PkgDecoder) NumElems(k RelocKind) int {
+	count := int(pr.elemEndsEnds[k])
+	if k > 0 {
+		count -= int(pr.elemEndsEnds[k-1])
+	}
+	return count
+}
+
+// TotalElems returns the total number of elements across all sections.
+func (pr *PkgDecoder) TotalElems() int {
+	return len(pr.elemEnds)
+}
+
+// Fingerprint returns the package fingerprint.
+func (pr *PkgDecoder) Fingerprint() [8]byte {
+	var fp [8]byte
+	copy(fp[:], pr.elemData[len(pr.elemData)-8:])
+	return fp
+}
+
+// AbsIdx returns the absolute index for the given (section, index)
+// pair.
+func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int {
+	absIdx := int(idx)
+	if k > 0 {
+		absIdx += int(pr.elemEndsEnds[k-1])
+	}
+	if absIdx >= int(pr.elemEndsEnds[k]) {
+		panicf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds)
+	}
+	return absIdx
+}
+
+// DataIdx returns the raw element bitstream for the given (section,
+// index) pair.
+func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string {
+	absIdx := pr.AbsIdx(k, idx)
+
+	var start uint32
+	if absIdx > 0 {
+		start = pr.elemEnds[absIdx-1]
+	}
+	end := pr.elemEnds[absIdx]
+
+	return pr.elemData[start:end]
+}
+
+// StringIdx returns the string value for the given string index.
+func (pr *PkgDecoder) StringIdx(idx Index) string {
+	return pr.DataIdx(RelocString, idx)
+}
+
+// NewDecoder returns a Decoder for the given (section, index) pair,
+// and decodes the given SyncMarker from the element bitstream.
+func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder {
+	r := pr.NewDecoderRaw(k, idx)
+	r.Sync(marker)
+	return r
+}
+
+// TempDecoder returns a Decoder for the given (section, index) pair,
+// and decodes the given SyncMarker from the element bitstream.
+// If possible the Decoder should be RetireDecoder'd when it is no longer
+// needed, this will avoid heap allocations.
+func (pr *PkgDecoder) TempDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder {
+	r := pr.TempDecoderRaw(k, idx)
+	r.Sync(marker)
+	return r
+}
+
+func (pr *PkgDecoder) RetireDecoder(d *Decoder) {
+	pr.scratchRelocEnt = d.Relocs
+	d.Relocs = nil
+}
+
+// NewDecoderRaw returns a Decoder for the given (section, index) pair.
+//
+// Most callers should use NewDecoder instead.
+func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder {
+	r := Decoder{
+		common: pr,
+		k:      k,
+		Idx:    idx,
+	}
+
+	r.Data.Reset(pr.DataIdx(k, idx))
+	r.Sync(SyncRelocs)
+	r.Relocs = make([]RelocEnt, r.Len())
+	for i := range r.Relocs {
+		r.Sync(SyncReloc)
+		r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())}
+	}
+
+	return r
+}
+
+func (pr *PkgDecoder) TempDecoderRaw(k RelocKind, idx Index) Decoder {
+	r := Decoder{
+		common: pr,
+		k:      k,
+		Idx:    idx,
+	}
+
+	r.Data.Reset(pr.DataIdx(k, idx))
+	r.Sync(SyncRelocs)
+	l := r.Len()
+	if cap(pr.scratchRelocEnt) >= l {
+		r.Relocs = pr.scratchRelocEnt[:l]
+		pr.scratchRelocEnt = nil
+	} else {
+		r.Relocs = make([]RelocEnt, l)
+	}
+	for i := range r.Relocs {
+		r.Sync(SyncReloc)
+		r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())}
+	}
+
+	return r
+}
+
+// A Decoder provides methods for decoding an individual element's
+// bitstream data.
+type Decoder struct {
+	common *PkgDecoder
+
+	Relocs []RelocEnt
+	Data   strings.Reader
+
+	k   RelocKind
+	Idx Index
+}
+
+func (r *Decoder) checkErr(err error) {
+	if err != nil {
+		panicf("unexpected decoding error: %w", err)
+	}
+}
+
+func (r *Decoder) rawUvarint() uint64 {
+	x, err := readUvarint(&r.Data)
+	r.checkErr(err)
+	return x
+}
+
+// readUvarint is a type-specialized copy of encoding/binary.ReadUvarint.
+// This avoids the interface conversion and thus has better escape properties,
+// which flows up the stack.
+func readUvarint(r *strings.Reader) (uint64, error) {
+	var x uint64
+	var s uint
+	for i := range binary.MaxVarintLen64 {
+		b, err := r.ReadByte()
+		if err != nil {
+			if i > 0 && err == io.EOF {
+				err = io.ErrUnexpectedEOF
+			}
+			return x, err
+		}
+		if b < 0x80 {
+			if i == binary.MaxVarintLen64-1 && b > 1 {
+				return x, overflow
+			}
+			return x | uint64(b)<> 1)
+	if ux&1 != 0 {
+		x = ^x
+	}
+	return x
+}
+
+func (r *Decoder) rawReloc(k RelocKind, idx int) Index {
+	e := r.Relocs[idx]
+	assert(e.Kind == k)
+	return e.Idx
+}
+
+// Sync decodes a sync marker from the element bitstream and asserts
+// that it matches the expected marker.
+//
+// If r.common.sync is false, then Sync is a no-op.
+func (r *Decoder) Sync(mWant SyncMarker) {
+	if !r.common.sync {
+		return
+	}
+
+	pos, _ := r.Data.Seek(0, io.SeekCurrent)
+	mHave := SyncMarker(r.rawUvarint())
+	writerPCs := make([]int, r.rawUvarint())
+	for i := range writerPCs {
+		writerPCs[i] = int(r.rawUvarint())
+	}
+
+	if mHave == mWant {
+		return
+	}
+
+	// There's some tension here between printing:
+	//
+	// (1) full file paths that tools can recognize (e.g., so emacs
+	//     hyperlinks the "file:line" text for easy navigation), or
+	//
+	// (2) short file paths that are easier for humans to read (e.g., by
+	//     omitting redundant or irrelevant details, so it's easier to
+	//     focus on the useful bits that remain).
+	//
+	// The current formatting favors the former, as it seems more
+	// helpful in practice. But perhaps the formatting could be improved
+	// to better address both concerns. For example, use relative file
+	// paths if they would be shorter, or rewrite file paths to contain
+	// "$GOROOT" (like objabi.AbsFile does) if tools can be taught how
+	// to reliably expand that again.
+
+	fmt.Printf("export data desync: package %q, section %v, index %v, offset %v\n", r.common.pkgPath, r.k, r.Idx, pos)
+
+	fmt.Printf("\nfound %v, written at:\n", mHave)
+	if len(writerPCs) == 0 {
+		fmt.Printf("\t[stack trace unavailable; recompile package %q with -d=syncframes]\n", r.common.pkgPath)
+	}
+	for _, pc := range writerPCs {
+		fmt.Printf("\t%s\n", r.common.StringIdx(r.rawReloc(RelocString, pc)))
+	}
+
+	fmt.Printf("\nexpected %v, reading at:\n", mWant)
+	var readerPCs [32]uintptr // TODO(mdempsky): Dynamically size?
+	n := runtime.Callers(2, readerPCs[:])
+	for _, pc := range fmtFrames(readerPCs[:n]...) {
+		fmt.Printf("\t%s\n", pc)
+	}
+
+	// We already printed a stack trace for the reader, so now we can
+	// simply exit. Printing a second one with panic or base.Fatalf
+	// would just be noise.
+	os.Exit(1)
+}
+
+// Bool decodes and returns a bool value from the element bitstream.
+func (r *Decoder) Bool() bool {
+	r.Sync(SyncBool)
+	x, err := r.Data.ReadByte()
+	r.checkErr(err)
+	assert(x < 2)
+	return x != 0
+}
+
+// Int64 decodes and returns an int64 value from the element bitstream.
+func (r *Decoder) Int64() int64 {
+	r.Sync(SyncInt64)
+	return r.rawVarint()
+}
+
+// Uint64 decodes and returns a uint64 value from the element bitstream.
+func (r *Decoder) Uint64() uint64 {
+	r.Sync(SyncUint64)
+	return r.rawUvarint()
+}
+
+// Len decodes and returns a non-negative int value from the element bitstream.
+func (r *Decoder) Len() int { x := r.Uint64(); v := int(x); assert(uint64(v) == x); return v }
+
+// Int decodes and returns an int value from the element bitstream.
+func (r *Decoder) Int() int { x := r.Int64(); v := int(x); assert(int64(v) == x); return v }
+
+// Uint decodes and returns a uint value from the element bitstream.
+func (r *Decoder) Uint() uint { x := r.Uint64(); v := uint(x); assert(uint64(v) == x); return v }
+
+// Code decodes a Code value from the element bitstream and returns
+// its ordinal value. It's the caller's responsibility to convert the
+// result to an appropriate Code type.
+//
+// TODO(mdempsky): Ideally this method would have signature "Code[T
+// Code] T" instead, but we don't allow generic methods and the
+// compiler can't depend on generics yet anyway.
+func (r *Decoder) Code(mark SyncMarker) int {
+	r.Sync(mark)
+	return r.Len()
+}
+
+// Reloc decodes a relocation of expected section k from the element
+// bitstream and returns an index to the referenced element.
+func (r *Decoder) Reloc(k RelocKind) Index {
+	r.Sync(SyncUseReloc)
+	return r.rawReloc(k, r.Len())
+}
+
+// String decodes and returns a string value from the element
+// bitstream.
+func (r *Decoder) String() string {
+	r.Sync(SyncString)
+	return r.common.StringIdx(r.Reloc(RelocString))
+}
+
+// Strings decodes and returns a variable-length slice of strings from
+// the element bitstream.
+func (r *Decoder) Strings() []string {
+	res := make([]string, r.Len())
+	for i := range res {
+		res[i] = r.String()
+	}
+	return res
+}
+
+// Value decodes and returns a constant.Value from the element
+// bitstream.
+func (r *Decoder) Value() constant.Value {
+	r.Sync(SyncValue)
+	isComplex := r.Bool()
+	val := r.scalar()
+	if isComplex {
+		val = constant.BinaryOp(val, token.ADD, constant.MakeImag(r.scalar()))
+	}
+	return val
+}
+
+func (r *Decoder) scalar() constant.Value {
+	switch tag := CodeVal(r.Code(SyncVal)); tag {
+	default:
+		panic(fmt.Errorf("unexpected scalar tag: %v", tag))
+
+	case ValBool:
+		return constant.MakeBool(r.Bool())
+	case ValString:
+		return constant.MakeString(r.String())
+	case ValInt64:
+		return constant.MakeInt64(r.Int64())
+	case ValBigInt:
+		return constant.Make(r.bigInt())
+	case ValBigRat:
+		num := r.bigInt()
+		denom := r.bigInt()
+		return constant.Make(new(big.Rat).SetFrac(num, denom))
+	case ValBigFloat:
+		return constant.Make(r.bigFloat())
+	}
+}
+
+func (r *Decoder) bigInt() *big.Int {
+	v := new(big.Int).SetBytes([]byte(r.String()))
+	if r.Bool() {
+		v.Neg(v)
+	}
+	return v
+}
+
+func (r *Decoder) bigFloat() *big.Float {
+	v := new(big.Float).SetPrec(512)
+	assert(v.UnmarshalText([]byte(r.String())) == nil)
+	return v
+}
+
+// @@@ Helpers
+
+// TODO(mdempsky): These should probably be removed. I think they're a
+// smell that the export data format is not yet quite right.
+
+// PeekPkgPath returns the package path for the specified package
+// index.
+func (pr *PkgDecoder) PeekPkgPath(idx Index) string {
+	var path string
+	{
+		r := pr.TempDecoder(RelocPkg, idx, SyncPkgDef)
+		path = r.String()
+		pr.RetireDecoder(&r)
+	}
+	if path == "" {
+		path = pr.pkgPath
+	}
+	return path
+}
+
+// PeekObj returns the package path, object name, and CodeObj for the
+// specified object index.
+func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) {
+	var ridx Index
+	var name string
+	var rcode int
+	{
+		r := pr.TempDecoder(RelocName, idx, SyncObject1)
+		r.Sync(SyncSym)
+		r.Sync(SyncPkg)
+		ridx = r.Reloc(RelocPkg)
+		name = r.String()
+		rcode = r.Code(SyncCodeObj)
+		pr.RetireDecoder(&r)
+	}
+
+	path := pr.PeekPkgPath(ridx)
+	assert(name != "")
+
+	tag := CodeObj(rcode)
+
+	return path, name, tag
+}
+
+// Version reports the version of the bitstream.
+func (w *Decoder) Version() Version { return w.common.version }
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/doc.go b/vendor/golang.org/x/tools/internal/pkgbits/doc.go
new file mode 100644
index 0000000..f5a9bad
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/doc.go
@@ -0,0 +1,34 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package pkgbits implements low-level coding abstractions for
+// Unified IR's export data format.
+//
+// At a low-level, a package is a collection of bitstream elements.
+// Each element has a "kind" and a dense, non-negative index.
+// Elements can be randomly accessed given their kind and index.
+//
+// Individual elements are sequences of variable-length values (e.g.,
+// integers, booleans, strings, go/constant values, cross-references
+// to other elements). Package pkgbits provides APIs for encoding and
+// decoding these low-level values, but the details of mapping
+// higher-level Go constructs into elements is left to higher-level
+// abstractions.
+//
+// Elements may cross-reference each other with "relocations." For
+// example, an element representing a pointer type has a relocation
+// referring to the element type.
+//
+// Go constructs may be composed as a constellation of multiple
+// elements. For example, a declared function may have one element to
+// describe the object (e.g., its name, type, position), and a
+// separate element to describe its function body. This allows readers
+// some flexibility in efficiently seeking or re-reading data (e.g.,
+// inlining requires re-reading the function body for each inlined
+// call, without needing to re-read the object-level details).
+//
+// This is a copy of internal/pkgbits in the Go implementation.
+package pkgbits
+
+// This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps.
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go
new file mode 100644
index 0000000..ac9c8e8
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go
@@ -0,0 +1,393 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+import (
+	"bytes"
+	"crypto/md5"
+	"encoding/binary"
+	"go/constant"
+	"io"
+	"math/big"
+	"runtime"
+	"strings"
+	// This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps.
+)
+
+// A PkgEncoder provides methods for encoding a package's Unified IR
+// export data.
+type PkgEncoder struct {
+	// version of the bitstream.
+	version Version
+
+	// elems holds the bitstream for previously encoded elements.
+	elems [numRelocs][]string
+
+	// stringsIdx maps previously encoded strings to their index within
+	// the RelocString section, to allow deduplication. That is,
+	// elems[RelocString][stringsIdx[s]] == s (if present).
+	stringsIdx map[string]Index
+
+	// syncFrames is the number of frames to write at each sync
+	// marker. A negative value means sync markers are omitted.
+	syncFrames int
+}
+
+// SyncMarkers reports whether pw uses sync markers.
+func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 }
+
+// NewPkgEncoder returns an initialized PkgEncoder.
+//
+// syncFrames is the number of caller frames that should be serialized
+// at Sync points. Serializing additional frames results in larger
+// export data files, but can help diagnosing desync errors in
+// higher-level Unified IR reader/writer code. If syncFrames is
+// negative, then sync markers are omitted entirely.
+func NewPkgEncoder(version Version, syncFrames int) PkgEncoder {
+	return PkgEncoder{
+		version:    version,
+		stringsIdx: make(map[string]Index),
+		syncFrames: syncFrames,
+	}
+}
+
+// DumpTo writes the package's encoded data to out0 and returns the
+// package fingerprint.
+func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) {
+	h := md5.New()
+	out := io.MultiWriter(out0, h)
+
+	writeUint32 := func(x uint32) {
+		assert(binary.Write(out, binary.LittleEndian, x) == nil)
+	}
+
+	writeUint32(uint32(pw.version))
+
+	if pw.version.Has(Flags) {
+		var flags uint32
+		if pw.SyncMarkers() {
+			flags |= flagSyncMarkers
+		}
+		writeUint32(flags)
+	}
+
+	// Write elemEndsEnds.
+	var sum uint32
+	for _, elems := range &pw.elems {
+		sum += uint32(len(elems))
+		writeUint32(sum)
+	}
+
+	// Write elemEnds.
+	sum = 0
+	for _, elems := range &pw.elems {
+		for _, elem := range elems {
+			sum += uint32(len(elem))
+			writeUint32(sum)
+		}
+	}
+
+	// Write elemData.
+	for _, elems := range &pw.elems {
+		for _, elem := range elems {
+			_, err := io.WriteString(out, elem)
+			assert(err == nil)
+		}
+	}
+
+	// Write fingerprint.
+	copy(fingerprint[:], h.Sum(nil))
+	_, err := out0.Write(fingerprint[:])
+	assert(err == nil)
+
+	return
+}
+
+// StringIdx adds a string value to the strings section, if not
+// already present, and returns its index.
+func (pw *PkgEncoder) StringIdx(s string) Index {
+	if idx, ok := pw.stringsIdx[s]; ok {
+		assert(pw.elems[RelocString][idx] == s)
+		return idx
+	}
+
+	idx := Index(len(pw.elems[RelocString]))
+	pw.elems[RelocString] = append(pw.elems[RelocString], s)
+	pw.stringsIdx[s] = idx
+	return idx
+}
+
+// NewEncoder returns an Encoder for a new element within the given
+// section, and encodes the given SyncMarker as the start of the
+// element bitstream.
+func (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder {
+	e := pw.NewEncoderRaw(k)
+	e.Sync(marker)
+	return e
+}
+
+// NewEncoderRaw returns an Encoder for a new element within the given
+// section.
+//
+// Most callers should use NewEncoder instead.
+func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder {
+	idx := Index(len(pw.elems[k]))
+	pw.elems[k] = append(pw.elems[k], "") // placeholder
+
+	return Encoder{
+		p:   pw,
+		k:   k,
+		Idx: idx,
+	}
+}
+
+// An Encoder provides methods for encoding an individual element's
+// bitstream data.
+type Encoder struct {
+	p *PkgEncoder
+
+	Relocs   []RelocEnt
+	RelocMap map[RelocEnt]uint32
+	Data     bytes.Buffer // accumulated element bitstream data
+
+	encodingRelocHeader bool
+
+	k   RelocKind
+	Idx Index // index within relocation section
+}
+
+// Flush finalizes the element's bitstream and returns its Index.
+func (w *Encoder) Flush() Index {
+	var sb strings.Builder
+
+	// Backup the data so we write the relocations at the front.
+	var tmp bytes.Buffer
+	io.Copy(&tmp, &w.Data)
+
+	// TODO(mdempsky): Consider writing these out separately so they're
+	// easier to strip, along with function bodies, so that we can prune
+	// down to just the data that's relevant to go/types.
+	if w.encodingRelocHeader {
+		panic("encodingRelocHeader already true; recursive flush?")
+	}
+	w.encodingRelocHeader = true
+	w.Sync(SyncRelocs)
+	w.Len(len(w.Relocs))
+	for _, rEnt := range w.Relocs {
+		w.Sync(SyncReloc)
+		w.Len(int(rEnt.Kind))
+		w.Len(int(rEnt.Idx))
+	}
+
+	io.Copy(&sb, &w.Data)
+	io.Copy(&sb, &tmp)
+	w.p.elems[w.k][w.Idx] = sb.String()
+
+	return w.Idx
+}
+
+func (w *Encoder) checkErr(err error) {
+	if err != nil {
+		panicf("unexpected encoding error: %v", err)
+	}
+}
+
+func (w *Encoder) rawUvarint(x uint64) {
+	var buf [binary.MaxVarintLen64]byte
+	n := binary.PutUvarint(buf[:], x)
+	_, err := w.Data.Write(buf[:n])
+	w.checkErr(err)
+}
+
+func (w *Encoder) rawVarint(x int64) {
+	// Zig-zag encode.
+	ux := uint64(x) << 1
+	if x < 0 {
+		ux = ^ux
+	}
+
+	w.rawUvarint(ux)
+}
+
+func (w *Encoder) rawReloc(r RelocKind, idx Index) int {
+	e := RelocEnt{r, idx}
+	if w.RelocMap != nil {
+		if i, ok := w.RelocMap[e]; ok {
+			return int(i)
+		}
+	} else {
+		w.RelocMap = make(map[RelocEnt]uint32)
+	}
+
+	i := len(w.Relocs)
+	w.RelocMap[e] = uint32(i)
+	w.Relocs = append(w.Relocs, e)
+	return i
+}
+
+func (w *Encoder) Sync(m SyncMarker) {
+	if !w.p.SyncMarkers() {
+		return
+	}
+
+	// Writing out stack frame string references requires working
+	// relocations, but writing out the relocations themselves involves
+	// sync markers. To prevent infinite recursion, we simply trim the
+	// stack frame for sync markers within the relocation header.
+	var frames []string
+	if !w.encodingRelocHeader && w.p.syncFrames > 0 {
+		pcs := make([]uintptr, w.p.syncFrames)
+		n := runtime.Callers(2, pcs)
+		frames = fmtFrames(pcs[:n]...)
+	}
+
+	// TODO(mdempsky): Save space by writing out stack frames as a
+	// linked list so we can share common stack frames.
+	w.rawUvarint(uint64(m))
+	w.rawUvarint(uint64(len(frames)))
+	for _, frame := range frames {
+		w.rawUvarint(uint64(w.rawReloc(RelocString, w.p.StringIdx(frame))))
+	}
+}
+
+// Bool encodes and writes a bool value into the element bitstream,
+// and then returns the bool value.
+//
+// For simple, 2-alternative encodings, the idiomatic way to call Bool
+// is something like:
+//
+//	if w.Bool(x != 0) {
+//		// alternative #1
+//	} else {
+//		// alternative #2
+//	}
+//
+// For multi-alternative encodings, use Code instead.
+func (w *Encoder) Bool(b bool) bool {
+	w.Sync(SyncBool)
+	var x byte
+	if b {
+		x = 1
+	}
+	err := w.Data.WriteByte(x)
+	w.checkErr(err)
+	return b
+}
+
+// Int64 encodes and writes an int64 value into the element bitstream.
+func (w *Encoder) Int64(x int64) {
+	w.Sync(SyncInt64)
+	w.rawVarint(x)
+}
+
+// Uint64 encodes and writes a uint64 value into the element bitstream.
+func (w *Encoder) Uint64(x uint64) {
+	w.Sync(SyncUint64)
+	w.rawUvarint(x)
+}
+
+// Len encodes and writes a non-negative int value into the element bitstream.
+func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) }
+
+// Int encodes and writes an int value into the element bitstream.
+func (w *Encoder) Int(x int) { w.Int64(int64(x)) }
+
+// Uint encodes and writes a uint value into the element bitstream.
+func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) }
+
+// Reloc encodes and writes a relocation for the given (section,
+// index) pair into the element bitstream.
+//
+// Note: Only the index is formally written into the element
+// bitstream, so bitstream decoders must know from context which
+// section an encoded relocation refers to.
+func (w *Encoder) Reloc(r RelocKind, idx Index) {
+	w.Sync(SyncUseReloc)
+	w.Len(w.rawReloc(r, idx))
+}
+
+// Code encodes and writes a Code value into the element bitstream.
+func (w *Encoder) Code(c Code) {
+	w.Sync(c.Marker())
+	w.Len(c.Value())
+}
+
+// String encodes and writes a string value into the element
+// bitstream.
+//
+// Internally, strings are deduplicated by adding them to the strings
+// section (if not already present), and then writing a relocation
+// into the element bitstream.
+func (w *Encoder) String(s string) {
+	w.StringRef(w.p.StringIdx(s))
+}
+
+// StringRef writes a reference to the given index, which must be a
+// previously encoded string value.
+func (w *Encoder) StringRef(idx Index) {
+	w.Sync(SyncString)
+	w.Reloc(RelocString, idx)
+}
+
+// Strings encodes and writes a variable-length slice of strings into
+// the element bitstream.
+func (w *Encoder) Strings(ss []string) {
+	w.Len(len(ss))
+	for _, s := range ss {
+		w.String(s)
+	}
+}
+
+// Value encodes and writes a constant.Value into the element
+// bitstream.
+func (w *Encoder) Value(val constant.Value) {
+	w.Sync(SyncValue)
+	if w.Bool(val.Kind() == constant.Complex) {
+		w.scalar(constant.Real(val))
+		w.scalar(constant.Imag(val))
+	} else {
+		w.scalar(val)
+	}
+}
+
+func (w *Encoder) scalar(val constant.Value) {
+	switch v := constant.Val(val).(type) {
+	default:
+		panicf("unhandled %v (%v)", val, val.Kind())
+	case bool:
+		w.Code(ValBool)
+		w.Bool(v)
+	case string:
+		w.Code(ValString)
+		w.String(v)
+	case int64:
+		w.Code(ValInt64)
+		w.Int64(v)
+	case *big.Int:
+		w.Code(ValBigInt)
+		w.bigInt(v)
+	case *big.Rat:
+		w.Code(ValBigRat)
+		w.bigInt(v.Num())
+		w.bigInt(v.Denom())
+	case *big.Float:
+		w.Code(ValBigFloat)
+		w.bigFloat(v)
+	}
+}
+
+func (w *Encoder) bigInt(v *big.Int) {
+	b := v.Bytes()
+	w.String(string(b)) // TODO: More efficient encoding.
+	w.Bool(v.Sign() < 0)
+}
+
+func (w *Encoder) bigFloat(v *big.Float) {
+	b := v.Append(nil, 'p', -1)
+	w.String(string(b)) // TODO: More efficient encoding.
+}
+
+// Version reports the version of the bitstream.
+func (w *Encoder) Version() Version { return w.p.version }
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/flags.go b/vendor/golang.org/x/tools/internal/pkgbits/flags.go
new file mode 100644
index 0000000..6542227
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/flags.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+const (
+	flagSyncMarkers = 1 << iota // file format contains sync markers
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/reloc.go b/vendor/golang.org/x/tools/internal/pkgbits/reloc.go
new file mode 100644
index 0000000..99494aa
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/reloc.go
@@ -0,0 +1,44 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+// This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps.
+
+// A RelocKind indicates a particular section within a unified IR export.
+type RelocKind int32
+
+// An Index represents a bitstream element index within a particular
+// section.
+type Index int32
+
+// A relocEnt (relocation entry) is an entry in an element's local
+// reference table.
+//
+// TODO(mdempsky): Rename this too.
+type RelocEnt struct {
+	Kind RelocKind
+	Idx  Index
+}
+
+// Reserved indices within the meta relocation section.
+const (
+	PublicRootIdx  Index = 0
+	PrivateRootIdx Index = 1
+)
+
+const (
+	RelocString RelocKind = iota
+	RelocMeta
+	RelocPosBase
+	RelocPkg
+	RelocName
+	RelocType
+	RelocObj
+	RelocObjExt
+	RelocObjDict
+	RelocBody
+
+	numRelocs = iota
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/support.go b/vendor/golang.org/x/tools/internal/pkgbits/support.go
new file mode 100644
index 0000000..b001160
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/support.go
@@ -0,0 +1,18 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+// This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps.
+import "fmt"
+
+func assert(b bool) {
+	if !b {
+		panic("assertion failed")
+	}
+}
+
+func panicf(format string, args ...any) {
+	panic(fmt.Errorf(format, args...))
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/sync.go b/vendor/golang.org/x/tools/internal/pkgbits/sync.go
new file mode 100644
index 0000000..4cf7f1e
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/sync.go
@@ -0,0 +1,137 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+import (
+	"fmt"
+	"runtime"
+	"strings"
+	// This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps.
+)
+
+// fmtFrames formats a backtrace for reporting reader/writer desyncs.
+func fmtFrames(pcs ...uintptr) []string {
+	res := make([]string, 0, len(pcs))
+	walkFrames(pcs, func(file string, line int, name string, offset uintptr) {
+		// Trim package from function name. It's just redundant noise.
+		name = strings.TrimPrefix(name, "cmd/compile/internal/noder.")
+
+		res = append(res, fmt.Sprintf("%s:%v: %s +0x%v", file, line, name, offset))
+	})
+	return res
+}
+
+type frameVisitor func(file string, line int, name string, offset uintptr)
+
+// walkFrames calls visit for each call frame represented by pcs.
+//
+// pcs should be a slice of PCs, as returned by runtime.Callers.
+func walkFrames(pcs []uintptr, visit frameVisitor) {
+	if len(pcs) == 0 {
+		return
+	}
+
+	frames := runtime.CallersFrames(pcs)
+	for {
+		frame, more := frames.Next()
+		visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry)
+		if !more {
+			return
+		}
+	}
+}
+
+// SyncMarker is an enum type that represents markers that may be
+// written to export data to ensure the reader and writer stay
+// synchronized.
+type SyncMarker int
+
+//go:generate stringer -type=SyncMarker -trimprefix=Sync
+
+const (
+	_ SyncMarker = iota
+
+	// Public markers (known to go/types importers).
+
+	// Low-level coding markers.
+	SyncEOF
+	SyncBool
+	SyncInt64
+	SyncUint64
+	SyncString
+	SyncValue
+	SyncVal
+	SyncRelocs
+	SyncReloc
+	SyncUseReloc
+
+	// Higher-level object and type markers.
+	SyncPublic
+	SyncPos
+	SyncPosBase
+	SyncObject
+	SyncObject1
+	SyncPkg
+	SyncPkgDef
+	SyncMethod
+	SyncType
+	SyncTypeIdx
+	SyncTypeParamNames
+	SyncSignature
+	SyncParams
+	SyncParam
+	SyncCodeObj
+	SyncSym
+	SyncLocalIdent
+	SyncSelector
+
+	// Private markers (only known to cmd/compile).
+	SyncPrivate
+
+	SyncFuncExt
+	SyncVarExt
+	SyncTypeExt
+	SyncPragma
+
+	SyncExprList
+	SyncExprs
+	SyncExpr
+	SyncExprType
+	SyncAssign
+	SyncOp
+	SyncFuncLit
+	SyncCompLit
+
+	SyncDecl
+	SyncFuncBody
+	SyncOpenScope
+	SyncCloseScope
+	SyncCloseAnotherScope
+	SyncDeclNames
+	SyncDeclName
+
+	SyncStmts
+	SyncBlockStmt
+	SyncIfStmt
+	SyncForStmt
+	SyncSwitchStmt
+	SyncRangeStmt
+	SyncCaseClause
+	SyncCommClause
+	SyncSelectStmt
+	SyncDecls
+	SyncLabeledStmt
+	SyncUseObjLocal
+	SyncAddLocal
+	SyncLinkname
+	SyncStmt1
+	SyncStmtsEnd
+	SyncLabel
+	SyncOptLabel
+
+	SyncMultiExpr
+	SyncRType
+	SyncConvRTTI
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go
new file mode 100644
index 0000000..582ad56
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go
@@ -0,0 +1,92 @@
+// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT.
+
+package pkgbits
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[SyncEOF-1]
+	_ = x[SyncBool-2]
+	_ = x[SyncInt64-3]
+	_ = x[SyncUint64-4]
+	_ = x[SyncString-5]
+	_ = x[SyncValue-6]
+	_ = x[SyncVal-7]
+	_ = x[SyncRelocs-8]
+	_ = x[SyncReloc-9]
+	_ = x[SyncUseReloc-10]
+	_ = x[SyncPublic-11]
+	_ = x[SyncPos-12]
+	_ = x[SyncPosBase-13]
+	_ = x[SyncObject-14]
+	_ = x[SyncObject1-15]
+	_ = x[SyncPkg-16]
+	_ = x[SyncPkgDef-17]
+	_ = x[SyncMethod-18]
+	_ = x[SyncType-19]
+	_ = x[SyncTypeIdx-20]
+	_ = x[SyncTypeParamNames-21]
+	_ = x[SyncSignature-22]
+	_ = x[SyncParams-23]
+	_ = x[SyncParam-24]
+	_ = x[SyncCodeObj-25]
+	_ = x[SyncSym-26]
+	_ = x[SyncLocalIdent-27]
+	_ = x[SyncSelector-28]
+	_ = x[SyncPrivate-29]
+	_ = x[SyncFuncExt-30]
+	_ = x[SyncVarExt-31]
+	_ = x[SyncTypeExt-32]
+	_ = x[SyncPragma-33]
+	_ = x[SyncExprList-34]
+	_ = x[SyncExprs-35]
+	_ = x[SyncExpr-36]
+	_ = x[SyncExprType-37]
+	_ = x[SyncAssign-38]
+	_ = x[SyncOp-39]
+	_ = x[SyncFuncLit-40]
+	_ = x[SyncCompLit-41]
+	_ = x[SyncDecl-42]
+	_ = x[SyncFuncBody-43]
+	_ = x[SyncOpenScope-44]
+	_ = x[SyncCloseScope-45]
+	_ = x[SyncCloseAnotherScope-46]
+	_ = x[SyncDeclNames-47]
+	_ = x[SyncDeclName-48]
+	_ = x[SyncStmts-49]
+	_ = x[SyncBlockStmt-50]
+	_ = x[SyncIfStmt-51]
+	_ = x[SyncForStmt-52]
+	_ = x[SyncSwitchStmt-53]
+	_ = x[SyncRangeStmt-54]
+	_ = x[SyncCaseClause-55]
+	_ = x[SyncCommClause-56]
+	_ = x[SyncSelectStmt-57]
+	_ = x[SyncDecls-58]
+	_ = x[SyncLabeledStmt-59]
+	_ = x[SyncUseObjLocal-60]
+	_ = x[SyncAddLocal-61]
+	_ = x[SyncLinkname-62]
+	_ = x[SyncStmt1-63]
+	_ = x[SyncStmtsEnd-64]
+	_ = x[SyncLabel-65]
+	_ = x[SyncOptLabel-66]
+	_ = x[SyncMultiExpr-67]
+	_ = x[SyncRType-68]
+	_ = x[SyncConvRTTI-69]
+}
+
+const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabelMultiExprRTypeConvRTTI"
+
+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, 467, 472, 480}
+
+func (i SyncMarker) String() string {
+	i -= 1
+	if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) {
+		return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")"
+	}
+	return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]]
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/version.go b/vendor/golang.org/x/tools/internal/pkgbits/version.go
new file mode 100644
index 0000000..932a926
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/version.go
@@ -0,0 +1,113 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+// This package is dependency-restricted; see x/tools/go/gcexportdata.TestDeps.
+
+// Version indicates a version of a unified IR bitstream.
+// Each Version indicates the addition, removal, or change of
+// new data in the bitstream.
+//
+// These are serialized to disk and the interpretation remains fixed.
+type Version uint32
+
+const (
+	// V0: initial prototype.
+	//
+	// All data that is not assigned a Field is in version V0
+	// and has not been deprecated.
+	V0 Version = iota
+
+	// V1: adds the Flags uint32 word
+	V1
+
+	// V2: removes unused legacy fields and supports type parameters for aliases.
+	// - remove the legacy "has init" bool from the public root
+	// - remove obj's "derived func instance" bool
+	// - add a TypeParamNames field to ObjAlias
+	// - remove derived info "needed" bool
+	V2
+
+	// V3: introduces a more compact format for composite literal element lists
+	// - negative lengths indicate that (some) elements may have keys
+	// - positive lengths indicate that no element has a key
+	// - a negative struct field index indicates an embedded field
+	V3
+
+	// V4: encodes generic methods as standalone function objects
+	V4
+
+	// V5: encodes the index of methods to preserve relative order
+	// of nongeneric and generic methods (go.dev/issue/81188).
+	V5
+
+	numVersions = iota
+)
+
+// Field denotes a unit of data in the serialized unified IR bitstream.
+// It is conceptually a like field in a structure.
+//
+// We only really need Fields when the data may or may not be present
+// in a stream based on the Version of the bitstream.
+//
+// Unlike much of pkgbits, Fields are not serialized and
+// can change values as needed.
+type Field int
+
+const (
+	// Flags in a uint32 in the header of a bitstream
+	// that is used to indicate whether optional features are enabled.
+	Flags Field = iota
+
+	// Deprecated: HasInit was a bool indicating whether a package
+	// has any init functions.
+	HasInit
+
+	// Deprecated: DerivedFuncInstance was a bool indicating
+	// whether an object was a function instance.
+	DerivedFuncInstance
+
+	// ObjAlias has a list of TypeParamNames.
+	AliasTypeParamNames
+
+	// Deprecated: DerivedInfoNeeded was a bool indicating
+	// whether a type was a derived type.
+	DerivedInfoNeeded
+
+	// Composite literals use a more compact format for element lists.
+	CompactCompLiterals
+
+	// Generic methods may appear as standalone function objects.
+	GenericMethods
+
+	// Method index is encoded to preserve relative order of
+	// nongeneric and generic methods.
+	PreserveMethodOrder
+
+	numFields = iota
+)
+
+// introduced is the version a field was added.
+var introduced = [numFields]Version{
+	Flags:               V1,
+	AliasTypeParamNames: V2,
+	CompactCompLiterals: V3,
+	GenericMethods:      V4,
+	PreserveMethodOrder: V5,
+}
+
+// removed is the version a field was removed in or 0 for fields
+// that have not yet been deprecated.
+// (So removed[f]-1 is the last version it is included in.)
+var removed = [numFields]Version{
+	HasInit:             V2,
+	DerivedFuncInstance: V2,
+	DerivedInfoNeeded:   V2,
+}
+
+// Has reports whether field f is present in a bitstream at version v.
+func (v Version) Has(f Field) bool {
+	return introduced[f] <= v && (v < removed[f] || removed[f] == V0)
+}
diff --git a/vendor/golang.org/x/tools/internal/stdlib/deps.go b/vendor/golang.org/x/tools/internal/stdlib/deps.go
new file mode 100644
index 0000000..abd3c87
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/stdlib/deps.go
@@ -0,0 +1,550 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by generate.go. DO NOT EDIT.
+
+package stdlib
+
+type pkginfo struct {
+	name string
+	deps string // list of indices of dependencies, as varint-encoded deltas
+}
+
+var deps = [...]pkginfo{
+	{"archive/tar", "\x03|\x03F>\x01\n\x01&\x01\x01\x02\x05\b\x02\x01\x02\x02\r"},
+	{"archive/zip", "\x02\x04k\x0e\x03\x12\x022>\x01-\x05\x01\x0f\x03\x02\x0f\x04"},
+	{"bufio", "\x03|\x87\x01F\x15"},
+	{"bytes", "\x7f*]\x03\fJ\x02\x02"},
+	{"cmp", ""},
+	{"compress/bzip2", "\x02\x02\x82\x02C"},
+	{"compress/flate", "\x02}\x03\x84\x01\f\x034\x02\x03"},
+	{"compress/gzip", "\x02\x04k\x0e\x03\x14pW"},
+	{"compress/lzw", "\x02}\x03\x84\x01"},
+	{"compress/zlib", "\x02\x04k\x0e\x03\x12\x01q"},
+	{"container/heap", "\xca\x02"},
+	{"container/list", ""},
+	{"container/ring", ""},
+	{"context", "\x7f]r\x01\x0e"},
+	{"crypto", "\x94\x01rE"},
+	{"crypto/aes", "\x10\v\v\xa5\x02"},
+	{"crypto/cipher", "\x03#\x01\x01 \x13$+\\"},
+	{"crypto/des", "\x10\x18 7+\xa1\x01\x03"},
+	{"crypto/dsa", "H\x034\x87\x01\r"},
+	{"crypto/ecdh", "\x03\v\r\x12\x04\x17\x03\x10$\x87\x01"},
+	{"crypto/ecdsa", "\x0e\x05\x03\x05\x01\x12\b\v\x06\x01\x03\x0f\x01$\x87\x01\r\x05O\x01"},
+	{"crypto/ed25519", "\x0e!\x12\a\x03\t\a$I>E"},
+	{"crypto/elliptic", "6I\x87\x01\r;"},
+	{"crypto/fips140", "%\x05\x9e\x01\x9b\x01"},
+	{"crypto/hkdf", "2\x15\x017\x15"},
+	{"crypto/hmac", "\x1b\x18\x14\x01\x139"},
+	{"crypto/hpke", "\x03\v\x02\x03\x04\x01\x0e\x01\x05\x1f\x06\a\x01\x01%\x03\x12\x16\x9f\x01\x1d"},
+	{"crypto/internal/boring", "\x0e\x02\x0ev"},
+	{"crypto/internal/boring/bbig", "\x1b\xf8\x01P"},
+	{"crypto/internal/boring/bcache", "\xcf\x02\x14"},
+	{"crypto/internal/boring/sig", ""},
+	{"crypto/internal/constanttime", ""},
+	{"crypto/internal/cryptotest", "\x03\r\v\n%\x11\x1a\r\x12\x12!\x04\x06\n\x19\x01\x11\x11\x1d\x01\a\x03\x02\b\x02\x01\x04\x01\f"},
+	{"crypto/internal/cryptotest/wycheproof", "\x0e\x12T\x01\f\x01r@\x05\x03\x15\x10"},
+	{"crypto/internal/cryptotest/x509limbo", "u\n\x03\xba\x01\x03\x1e"},
+	{"crypto/internal/entropy", "M"},
+	{"crypto/internal/entropy/v1.0.0", "F9\x96\x01:\x14"},
+	{"crypto/internal/fips140", "E:\xc2\x01\v\x17"},
+	{"crypto/internal/fips140/aes", "\x03\"\x03\x02\x14\x05\x01\x01\x055\x96\x016"},
+	{"crypto/internal/fips140/aes/gcm", "%\x01\x02\x02\x02\x12\x05\x01\x065\x93\x01"},
+	{"crypto/internal/fips140/alias", "\xe3\x02"},
+	{"crypto/internal/fips140/bigmod", "*\x19\x01\x065\x96\x01"},
+	{"crypto/internal/fips140/check", "%\x0e\a\t\x02\xc1\x01]"},
+	{"crypto/internal/fips140/check/checktest", "*\x97\x02\""},
+	{"crypto/internal/fips140/drbg", "\x03!\x01\x01\x04\x14\x05\n2\x87\x01\x0f9\x01"},
+	{"crypto/internal/fips140/ecdh", "\x03\"\x05\x02\n\r<\x87\x01\x0f9"},
+	{"crypto/internal/fips140/ecdsa", "\x03\"\x04\x01\x02\a\x03\x06C\x15r\x0f9"},
+	{"crypto/internal/fips140/ed25519", "\x03\"\x05\x02\x04\fC\xcc\x01\x03"},
+	{"crypto/internal/fips140/edwards25519", "\x1f\v\a\x12<\x96\x019"},
+	{"crypto/internal/fips140/edwards25519/field", "*\x14\x05<\x96\x01"},
+	{"crypto/internal/fips140/hkdf", "\x03\"\x05\t\aE\x15"},
+	{"crypto/internal/fips140/hmac", "\x03\"\x15\x01\x01C\x15"},
+	{"crypto/internal/fips140/mldsa", "\x03\x1c\x06\x05\x02\x0e\x01\x03\x05<\x96\x019"},
+	{"crypto/internal/fips140/mlkem", "\x03\"\x05\x02\x0f\x03\x05<\xcf\x01"},
+	{"crypto/internal/fips140/nistec", "\x1f\v\r\f<\x96\x01,\r\x15"},
+	{"crypto/internal/fips140/nistec/fiat", "*\x14A\x96\x01"},
+	{"crypto/internal/fips140/pbkdf2", "\x03\"\x05\t\aE\x15"},
+	{"crypto/internal/fips140/rsa", "\x03\x1c\x06\x04\x01\x02\x0e\x01\x01\x02A\x15rH"},
+	{"crypto/internal/fips140/sha256", "\x03\"\x1e\x01\x065\x15\x81\x01"},
+	{"crypto/internal/fips140/sha3", "\x03\"\x19\x05\x01;\x96\x01N"},
+	{"crypto/internal/fips140/sha512", "\x03\"\x1e\x01\x065\x15\x81\x01"},
+	{"crypto/internal/fips140/ssh", "*j"},
+	{"crypto/internal/fips140/subtle", "\x1f\t\x1b\xd2\x01"},
+	{"crypto/internal/fips140/tls12", "\x03\"\x05\t\a\x02C\x15"},
+	{"crypto/internal/fips140/tls13", "\x03\"\x05\b\b\t<\x15"},
+	{"crypto/internal/fips140cache", "\xc1\x02\r."},
+	{"crypto/internal/fips140deps", ""},
+	{"crypto/internal/fips140deps/byteorder", "\xaa\x01"},
+	{"crypto/internal/fips140deps/cpu", "\xbf\x01\b"},
+	{"crypto/internal/fips140deps/godebug", "\xc8\x01"},
+	{"crypto/internal/fips140deps/time", "\xe3\x02"},
+	{"crypto/internal/fips140hash", ";\x1e;\xcf\x01"},
+	{"crypto/internal/fips140only", "\x17\x15\x0e\x01\x01Xr"},
+	{"crypto/internal/fips140test", ""},
+	{"crypto/internal/impl", "\xcc\x02"},
+	{"crypto/internal/rand", "\x1b\x11 |>]"},
+	{"crypto/internal/randutil", "\x86\x02\x12"},
+	{"crypto/internal/sysrand", "\x7fr!\"\r\r\x01\x01\r\x06"},
+	{"crypto/internal/sysrand/internal/seccomp", "\x7f"},
+	{"crypto/md5", "\x0e:7\x15\x16k"},
+	{"crypto/mldsa", "\x0e&K\x87\x01"},
+	{"crypto/mlkem", "\x0e'"},
+	{"crypto/mlkem/mlkemtest", "5\x13\t."},
+	{"crypto/pbkdf2", "8\x0f\x017\x15"},
+	{"crypto/rand", "\x1b\x11\x1c\x034\x87\x01\rP"},
+	{"crypto/rc4", "( 7\xcc\x01"},
+	{"crypto/rsa", "\x0e\r\x01\r\x10\x0e\x01\x03\t\a$\x03\x124>\f\x01"},
+	{"crypto/sha1", "\x0e\r-\x025\x15\x16\x15V"},
+	{"crypto/sha256", "\x0e\r\x1fZ"},
+	{"crypto/sha3", "\x0e-Y\xcf\x01"},
+	{"crypto/sha512", "\x0e\r!X"},
+	{"crypto/subtle", "\x1f\x1f\xa9\x01|"},
+	{"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x01\x01\x01\x01\x01\v\x01\x18\x01\x0f\x01\x01\x03\x01\x01\x01\x01\x02\x01\x02\x01\x1f\x02\x03\x12\x16\x15\t>\x16\x18\r\b\x01\x01\x01\x02\x01\x0e\x06\x03\x01\x15"},
+	{"crypto/tls/internal/fips140tls", "\x17\xb8\x02"},
+	{"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x01\x018\x01\x06\x01\x01\x02\x05\x0f\x06\t\x02\x03F\x03;\x01\x02\b\x01\x01\x02\a\x12\x05\x01\x06\a\b\x02\x01\x02\x0f\x02\x01\x01\x02\x04\x01"},
+	{"crypto/x509/pkix", "n\x06\x0e\x91\x019\x11"},
+	{"database/sql", "\x03\nT\x01\x1d\x03\x84\x01\v\a$\x05\b\x02\x03\x01\x0e\x02\x02\x02\x01"},
+	{"database/sql/driver", "\rU\x1d\x03\xba\x01\x0f\x12\a"},
+	{"database/sql/internal", ""},
+	{"debug/buildinfo", "\x03b\x02\x01\x01\b\x0e\x03h\x1a\x02\x01-\x0f "},
+	{"debug/dwarf", "\x03n\x0e\x03\x84\x013\x11\x01\x01"},
+	{"debug/elf", "\x03\x06[\r\x0e\x03h\x1b\x01\f\"\x17\x01\x17"},
+	{"debug/gosym", "\x03n\x11#\xa5\x01\x01\x01\x02"},
+	{"debug/macho", "\x03\x06[\r\x11h\x1c.\x17\x01"},
+	{"debug/pe", "\x03\x06[\r\x0e\x03h\x1c.\x17\x01\x17"},
+	{"debug/plan9obj", "q\x0e\x03h\x1c."},
+	{"embed", "\x7f*D\x19\x01V"},
+	{"embed/internal/embedtest", ""},
+	{"encoding", ""},
+	{"encoding/ascii85", "\x86\x02E"},
+	{"encoding/asn1", "\x03|\x03h(\x01)\x05\b\x02\x01\x11\x03\x01"},
+	{"encoding/base32", "\x86\x02C\x02"},
+	{"encoding/base64", "\xaa\x01\\C\x02"},
+	{"encoding/binary", "\x7f\x87\x01\f*\r\x05"},
+	{"encoding/csv", "\x02\x01|\x03\x84\x01F\x13\x02"},
+	{"encoding/gob", "\x02j\x05\x0e\x03h\x1c\v\x01\x03\x1f\b\x12\x01\x10\x02"},
+	{"encoding/hex", "\x7f\x03\x84\x01C\x03"},
+	{"encoding/json", "\x03\x01h\n\x01\x01\x02\x01\x01\x03\x03\x84\x016\x0f\x01"},
+	{"encoding/json/internal", "\x7f"},
+	{"encoding/json/internal/jsonflags", "v"},
+	{"encoding/json/internal/jsonopts", "v\x01"},
+	{"encoding/json/internal/jsontest", "\x03g\x15\x03\x83\x01\x01\x012\b\b\x03\x02\x0f"},
+	{"encoding/json/internal/jsonwire", "\x04s\b\x87\x01\f7\x02\x01\x13\x01\x01"},
+	{"encoding/json/jsontext", "\x03s\x01\x01\x02\x05\x87\x01\x03\t\x034\x02\x01\x02\x13"},
+	{"encoding/json/v2", "\x03\x01h\x03\x01\x01\x03\x02\x01\x01\x02\x01\x04\x03\x84\x01\f\x03'\r\x02\x01\x02\x0f\x02\x02"},
+	{"encoding/pem", "\x03m\x0f\x87\x01C\x03"},
+	{"encoding/xml", "\x02\x01i\x13\x03\x84\x016\x05\n\x01\x02\x11\x02"},
+	{"errors", "\xdc\x01\x87\x01"},
+	{"expvar", "uSB\b\v\x17\r\b\x02\x03\x01\x12"},
+	{"flag", "l\x13\x03\x84\x01.\b\x05\b\x02\x01\x11"},
+	{"fmt", "\x7fE)\x19\f\"\b\r\x02\x03\x13"},
+	{"go/ast", "\x03\x01~\x0e\x01u\x03+\b\r\x02\x01\x13\x02"},
+	{"go/build", "\x02\x01|\x03\x01\x02\x02\a\x02\x01\x17 \x04\x02\t\x1c\x13\x01-\x01\x04\x01\a\b\x02\x01\x13\x02\x02"},
+	{"go/build/constraint", "\x7f\xcc\x01\x01\x13\x02"},
+	{"go/constant", "\x82\x01\x0f\x81\x01\x01\x026\x01\x02\x13"},
+	{"go/doc", "\x04~\x01\x05\t>73\x10\x02\x01\x13\x02"},
+	{"go/doc/comment", "\x03\x7f\xc7\x01\x01\x01\x01\x13\x02"},
+	{"go/format", "\x03\x7f\x01\v\x01\x02uF"},
+	{"go/importer", "\x84\x01\a\x01\x01\x04\x01t;"},
+	{"go/internal/gccgoimporter", "\x02\x01b\x1a\x03\x04\v\x01r\x02.\x01\x05\x11\x01\r\b"},
+	{"go/internal/gcimporter", "\x02\x80\x01\x0f\x010\x140.\x15\x03\x02"},
+	{"go/internal/srcimporter", "\x82\x01\x01\x01\n\x03\x01t.\x01\x05\x12\x02\x15"},
+	{"go/parser", "\x03|\x03\x01\x02\v\x01u\x01-\x06\x12"},
+	{"go/printer", "\x82\x01\x01\x02\x03\tu\f\"\x15\x02\x01\x02\f\x05\x02"},
+	{"go/scanner", "\x03\x7f\x0fu4\x10\x01\x14\x02"},
+	{"go/token", "\x04~\x87\x01@\x02\x03\x01\x10\x02"},
+	{"go/types", "\x03\x01\x06u\x03\x01\x03\b\x03\x02\x0654\x04\x03\t\"\x06\a\b\x01\x01\x01\x02\x01\x10\x02\x02"},
+	{"go/version", "\xcd\x01\x7f"},
+	{"hash", "\x86\x02"},
+	{"hash/adler32", "\x7f\x15\x16"},
+	{"hash/crc32", "\x7f\x15\x16\x15\x8f\x01\x01\x14"},
+	{"hash/crc64", "\x7f\x15\x16\xa4\x01"},
+	{"hash/fnv", "\x7f\x15\x16k"},
+	{"hash/maphash", "\x94\x01\x11>\x80\x01"},
+	{"html", "\xcc\x02\x02\x13"},
+	{"html/template", "\x03r\r\x18.>\x01\n#\x05\x01\x02\x03\n\x02\x01\x02\r\x01\x03\x02"},
+	{"image", "\x02}\x1ei\x0f6\x03\x01"},
+	{"image/color", ""},
+	{"image/color/palette", "\x9d\x01"},
+	{"image/draw", "\x9c\x01\x01\x04"},
+	{"image/gif", "\x02\x01\x05w\x03\x1a\x01\x01\x01\v\\\x0f"},
+	{"image/internal/imageutil", "\x9c\x01"},
+	{"image/jpeg", "\x02}\x1d\x01\x04e"},
+	{"image/png", "\x02\ah\x11\x12\x02\x06\x01iE"},
+	{"index/suffixarray", "\x03n\x0e\x87\x01\f-\n\x01"},
+	{"internal/abi", "\xc7\x01\x9c\x01"},
+	{"internal/asan", "\xe3\x02"},
+	{"internal/bisect", "\xc1\x02\r\x01"},
+	{"internal/buildcfg", "\x82\x01Hj\x06\x02\x05\n\x01"},
+	{"internal/bytealg", "\xbf\x01\xa4\x01"},
+	{"internal/byteorder", ""},
+	{"internal/cfg", ""},
+	{"internal/cgrouptest", "\x82\x01\\V\x06\x0f\x02\x01\x04\x01"},
+	{"internal/chacha8rand", "\xaa\x01\x15\b\x9c\x01"},
+	{"internal/copyright", ""},
+	{"internal/coverage", ""},
+	{"internal/coverage/calloc", ""},
+	{"internal/coverage/cfile", "u\r\x16\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01$\x02'.\x06\a\n\x01\x03\x0e\x06"},
+	{"internal/coverage/cformat", "\x04~-\x04S\v8\x01\x02\x0e"},
+	{"internal/coverage/cmerge", "\x82\x01-c"},
+	{"internal/coverage/decodecounter", "q\x11-\v\x02J.\x17\x18"},
+	{"internal/coverage/decodemeta", "\x02o\x11\x16\x17\v\x02J."},
+	{"internal/coverage/encodecounter", "\x02o\x11-\f\x01\x02H\v#\x15"},
+	{"internal/coverage/encodemeta", "\x02\x01n\x11\x12\x04\x17\r\x02H./"},
+	{"internal/coverage/pods", "\x04~-\x85\x01\x06\x05\n\x02\x01"},
+	{"internal/coverage/rtcov", "\xe3\x02"},
+	{"internal/coverage/slicereader", "q\x11\x84\x01]"},
+	{"internal/coverage/slicewriter", "\x82\x01\x84\x01"},
+	{"internal/coverage/stringtab", "\x82\x018\x04H"},
+	{"internal/coverage/test", ""},
+	{"internal/coverage/uleb128", ""},
+	{"internal/cpu", "\xe3\x02"},
+	{"internal/dag", "\x04~\xc7\x01\x03"},
+	{"internal/diff", "\x03\x7f\xc8\x01\x02"},
+	{"internal/exportdata", "\x02\x01|\x03\x02f\x1c.\x01\x05\x11\x01\x02"},
+	{"internal/filepathlite", "\x7f*D\x1aB"},
+	{"internal/fmtsort", "\x04\xb8\x02\r"},
+	{"internal/fuzz", "\x03\nK\x19\x04\n\x03\x01\v\x037>\f\x03\x1f\x01\x05\x02\x05\n\x01\x02\x01\x01\r\x04\x02"},
+	{"internal/gate", "\r"},
+	{"internal/goarch", ""},
+	{"internal/godebug", "\xa7\x01\"\x85\x01\x01\x14"},
+	{"internal/godebugs", ""},
+	{"internal/goexperiment", ""},
+	{"internal/goos", ""},
+	{"internal/goroot", "\xb4\x02\x01\x05\x12\x02"},
+	{"internal/gover", "\x04"},
+	{"internal/goversion", ""},
+	{"internal/lazyregexp", "\xb4\x02\v\r\x02"},
+	{"internal/lazytemplate", "\x86\x02.\x18\x02\r"},
+	{"internal/msan", "\xe3\x02"},
+	{"internal/nettest", "\x03\nrG@\f\n\x12\x06\x15\x05\x0f"},
+	{"internal/nettrace", ""},
+	{"internal/obscuretestdata", "p\x96\x01."},
+	{"internal/oserror", "\x7f"},
+	{"internal/pkgbits", "\x03U\x19\x0e\x03\x04\vu\r!\r\n\x01"},
+	{"internal/platform", ""},
+	{"internal/poll", "\x7fm\x05\x15;\r\x01\x01\r\x06"},
+	{"internal/profile", "\x03\x04x\x03\x84\x019\n\x01\x01\x01\x11"},
+	{"internal/profilerecord", ""},
+	{"internal/race", "\xa5\x01\xbe\x01"},
+	{"internal/reflectlite", "\xa5\x01\"<>\""},
+	{"internal/runtime/atomic", "\xc7\x01\x9c\x01"},
+	{"internal/runtime/cgroup", "\xa9\x01?\x04w"},
+	{"internal/runtime/exithook", "\xdd\x01\x86\x01"},
+	{"internal/runtime/gc", "\xc7\x01"},
+	{"internal/runtime/gc/internal/gen", "\ng\x11\x17m\x04\v\x1f\b\x10\x02"},
+	{"internal/runtime/gc/scan", "\xbf\x01\b\x19\a|"},
+	{"internal/runtime/maps", "\xa5\x01\x01\x04\x15\b\x03\a\n\t\x03.N"},
+	{"internal/runtime/math", "\xc7\x01"},
+	{"internal/runtime/pprof/label", ""},
+	{"internal/runtime/startlinetest", ""},
+	{"internal/runtime/sys", "\xc7\x01\x04"},
+	{"internal/runtime/syscall/linux", "\xc7\x01\x9c\x01"},
+	{"internal/runtime/wasitest", ""},
+	{"internal/saferio", "\x86\x02]"},
+	{"internal/singleflight", "\xce\x02"},
+	{"internal/strconv", "\x95\x02N"},
+	{"internal/stringslite", "\xa9\x01\xba\x01"},
+	{"internal/sync", "\xa5\x01\"\x14t\x14"},
+	{"internal/synctest", "\xa5\x01\xbe\x01"},
+	{"internal/syscall/execenv", "\xd0\x02"},
+	{"internal/syscall/unix", "\xec\x01U\x0e\x01\x13"},
+	{"internal/sysinfo", "\x02\x01\xbc\x01G.\x18\x02"},
+	{"internal/syslist", ""},
+	{"internal/testenv", "\x03\nr\x02\x01)\x1c\x100-\x01\x05\a\n\x01\x02\x02\x01\f"},
+	{"internal/testhash", "\x03\x91\x01r\x11:\f"},
+	{"internal/testlog", "\xce\x02\x01\x14"},
+	{"internal/testpty", "\x7f\x03\xb2\x01"},
+	{"internal/trace", "\x02\x01\x01\x06g\x0e\x03x\x03\x03\x06\x03\t-\n\x01\x01\x01\x11\x06"},
+	{"internal/trace/internal/testgen", "\x03n\x11v\x03\x02\x03\x013\v\r\x11"},
+	{"internal/trace/internal/tracev1", "\x03\x01m\x0e\x03~\x06\f7\x01"},
+	{"internal/trace/raw", "\x02o\x11{\x03\x06E\x01\x13"},
+	{"internal/trace/testtrace", "\x02\x01|\x03r\x04\x03\x05\x01\x05.\v\x02\b\x02\x01\x05"},
+	{"internal/trace/tracev2", ""},
+	{"internal/trace/traceviewer", "\x02h\v\r\x19>\x1f\a\a\x04\b\v\x17\x01\x05\a\n\x01\x02\x0f"},
+	{"internal/trace/traceviewer/format", ""},
+	{"internal/trace/version", "\x82\x01{\t"},
+	{"internal/txtar", "\x03\x7f\xb2\x01\x18"},
+	{"internal/types/errors", "\xcb\x02"},
+	{"internal/unsafeheader", "\xe3\x02"},
+	{"internal/xcoff", "d\r\x0e\x03h\x1c.\x17\x01"},
+	{"internal/zstd", "q\x0e\x03\x84\x01\x0f"},
+	{"io", "\x7f\xcf\x01"},
+	{"io/fs", "\x7f*,13\x10\x14\x04"},
+	{"io/ioutil", "\x86\x02\x01-\x15\x03"},
+	{"iter", "\xdb\x01f\""},
+	{"log", "\x82\x01\x84\x01\x05)\r\r\x01\x0e"},
+	{"log/internal", ""},
+	{"log/slog", "\x03\n_\t\n\x03H<\x04\x01\x02\x02\x03*\x05\b\x02\x01\x02\x01\x0e\x02\x02\x02"},
+	{"log/slog/internal", ""},
+	{"log/slog/internal/benchmarks", "\rr\x03\x84\x01\x06\x03<\x12"},
+	{"log/slog/internal/buffer", "\xce\x02"},
+	{"log/syslog", "\x7f\x03\x88\x01\x12\x18\x18\x02\x0f"},
+	{"maps", "\x89\x02Z"},
+	{"math", "\xbf\x01VN"},
+	{"math/big", "\x03|\x03(\x15G\f\x03\x022\x02\x01\x02\x15"},
+	{"math/big/internal/asmgen", "\x03\x01~\x93\x014\x03"},
+	{"math/bits", "\xe3\x02"},
+	{"math/cmplx", "\x92\x02\x03"},
+	{"math/rand", "\xc8\x01J<\x01\x14"},
+	{"math/rand/v2", "\x7f+\x03e\x03N"},
+	{"mime", "\x02\x01m\x0f\x03\x84\x01\v#\x15\x03\x02\x11\x02"},
+	{"mime/multipart", "\x02\x01Q+\x03F>\v\x01\a\x02\x17\x02\x06\x0f\x02\x01\x17"},
+	{"mime/quotedprintable", "\x02\x01\x7f\x84\x01"},
+	{"net", "\x04\tr*\x1f\v\x05\x13\x01\x01\x04\x15\x01'\x06\r\b\x05\x01\x01\r\x06\t"},
+	{"net/http", "\x02\x01\x03\x01\x04\x02O\x14\x0f\x03F>\x01\x03\a\x01\x06\x01\x01\x02\x06\x02\x01\x01\f\x01\x01\x05\x01\x02\x05\b\x01\x01\x01\x02\x01\x0e\x02\x02\x02\n\x01\x03"},
+	{"net/http/cgi", "\x02Z#\x03\x84\x01\x04\a\v\x01\x15\x01\x01\x01\x04\x01\x05\x02\b\x02\x01\x11\x10"},
+	{"net/http/cookiejar", "\x04{\x03\x9a\x01\x01\b\t\x05\x16\x03\x02\x0f\x04"},
+	{"net/http/fcgi", "\x02\x01\nd\x0e\x03\x84\x01\x16\x01\x01\x16\x18\x02\x0f"},
+	{"net/http/httptest", "\x02\x01\nO\x02#\x01P4\x04\x12\x01\f\t\x02\r\n\x01\x02\x03\f\x06\n"},
+	{"net/http/httptrace", "\rOwI\x16+"},
+	{"net/http/httputil", "\x02\x01\nr\x03F>\x04\x0f\x03\x01\x05\x02\x01\r\x01\x19\x02\x0f\x10"},
+	{"net/http/internal", "\x02\x01n\x0e\x03\x84\x01"},
+	{"net/http/internal/ascii", "\xcc\x02\x13"},
+	{"net/http/internal/http2", "\x02\x01\x03\x01\x06G\b\x15\x0e\x03\x84\x01\x01\x03\b\x03\x02\x03\x02\x06\x02\x03\x01\n\x01\x01\b\x05\b\x02\x01\x02\x01\x0e\x10\x02\x02"},
+	{"net/http/internal/httpcommon", "\rr\x03\xa0\x01\x10\x01\x17\x01\x01\x02\x1f\x02"},
+	{"net/http/internal/httpsfv", "\xc9\x02\x02\x01\x11\x04"},
+	{"net/http/internal/testcert", "\xcc\x02"},
+	{"net/http/pprof", "\x02\x01\nu\x18.\x11-\x04\x13\x16\x01\r\x04\x03\x01\x02\x01\x11"},
+	{"net/internal/cgotest", ""},
+	{"net/internal/socktest", "\x82\x01\xcc\x01\x02"},
+	{"net/mail", "\x02}\x03\x84\x01\x04\x0f\x03\x16\x1a\x02\x0f\x04"},
+	{"net/netip", "\x04{*\x01h\x036\x17"},
+	{"net/rpc", "\x02q\f\x03\x0f\nk\x04\x12\x01\x1f\r\x03\x02"},
+	{"net/rpc/jsonrpc", "u\n\x03\x84\x01\x16\x13\x1f"},
+	{"net/smtp", "\x196\r\x14\x0f\x03\x84\x01\x16\x16\x1a"},
+	{"net/textproto", "\x02\x01|\x03\x84\x01\f\n/\x01\x02\x15"},
+	{"net/url", "\x03|\x03Ff\v\x10\x02\x01\x17"},
+	{"os", "\x7f*\x01\x19\x04\x11\x14\x01\x03\x01\x05\x10\x01:\b\x05\x01\x01\r\x06"},
+	{"os/exec", "\x03\nrI(\x01\x15\x01-\x06\a\n\x01\x03\x01\r"},
+	{"os/exec/internal/fdtest", "\xd0\x02"},
+	{"os/signal", "\r\xa7\x02\x15\x05\x02"},
+	{"os/user", "\x02\x01|\x03\x84\x01.\r\n\x01\x02"},
+	{"path", "\x7f*\xb8\x01"},
+	{"path/filepath", "\x7f*\x1aD-\r\b\x03\x04\x11"},
+	{"plugin", "\x7f"},
+	{"reflect", "\x7f&\x04\x1e\x03\x11\b\x04\x05\x17\x06\t/\n\x03\x11\x02\x02"},
+	{"reflect/internal/example1", ""},
+	{"reflect/internal/example2", ""},
+	{"regexp", "\x03\x83\x02\x037\t\x02\x01\x02\x11\x02"},
+	{"regexp/syntax", "\xc9\x02\x01\x01\x01\x02\x11\x02"},
+	{"runtime", "\xa5\x01\x04\x01\x03\f\x06\b\x02\x01\x01\x0f\x03\x01\x01\x01\x02\x01\x01\x01\x02\x01\x04\x01\x10\x18N"},
+	{"runtime/coverage", "\xb1\x01U"},
+	{"runtime/debug", "\x82\x01V\\\r\b\x02\x01\x11\x06"},
+	{"runtime/metrics", "\xc9\x01I/\""},
+	{"runtime/pprof", "\x02\x01\x01\x03\x06d\x0e\x03#5\v!\f\"\r\b\x01\x01\x01\x02\x02\n\x03\x06"},
+	{"runtime/race", "\xc7\x02"},
+	{"runtime/race/internal/amd64v1", ""},
+	{"runtime/trace", "\rr\x03{\t;\b\x05\x01\x0e\x06"},
+	{"slices", "\x04\x85\x02\fN"},
+	{"sort", "\xdc\x0194"},
+	{"strconv", "\x7f*C\x01t"},
+	{"strings", "\x7f&\x04D\x19\x03\f9\x11\x02\x02"},
+	{"structs", ""},
+	{"sync", "\xdb\x01\x02\x11\x01R\x0e\x14"},
+	{"sync/atomic", "\xe3\x02"},
+	{"syscall", "\x7f'\x03\x01\x1d\n\x04\x06\r\x04U\b\x05\x01\x14"},
+	{"testing", "\x03\nr\x02\x01Y\x17\x14\f\x05\x1d\x06\x02\x05\x02\x05\x01\x02\x01\x02\x01\x0e\x02\x04"},
+	{"testing/cryptotest", "TV\\\x126\x03\x12"},
+	{"testing/fstest", "\x7f\x03\x84\x01\x01\n(\x10\x03\t\b"},
+	{"testing/internal/testdeps", "\x02\v\xb8\x011\x10.\x03\x05\x03\x06\a\x02\x0f"},
+	{"testing/iotest", "\x03|\x03\x84\x01\x04"},
+	{"testing/quick", "\x81\x01\x01\x90\x01\x05%\x10\x11"},
+	{"testing/slogtest", "\rr\x03\x8a\x010\x05\x10\f"},
+	{"testing/synctest", "\xef\x01b\f\x06"},
+	{"text/scanner", "\x03\x7f\x84\x01.+\x02"},
+	{"text/tabwriter", "\x82\x01\x84\x01["},
+	{"text/template", "\x7f\x03BB\x01\n\"\x01\x05\x01\x02\x05\v\x02\x0e\x03\x02"},
+	{"text/template/parse", "\x03\x7f\xbf\x01\n\x01\x13\x02"},
+	{"time", "\x7f*D(,\r\x02\x13"},
+	{"time/tzdata", "\x7f\xd1\x01\x13"},
+	{"unicode", ""},
+	{"unicode/utf16", ""},
+	{"unicode/utf8", ""},
+	{"unique", "\xa5\x01\"&\x01S\r\x01\x14\x19"},
+	{"unsafe", ""},
+	{"uuid", "\x03\x01P\x1d\x03\v\xcf\x01\x0f"},
+	{"vendor/golang.org/x/crypto/chacha20", "\x10a\x0e\x96\x01,)"},
+	{"vendor/golang.org/x/crypto/chacha20poly1305", "\x10\aZ\x0e\xe6\x01\x05\x01\f"},
+	{"vendor/golang.org/x/crypto/cryptobyte", "n\x11\x03\x91\x01)!\v"},
+	{"vendor/golang.org/x/crypto/cryptobyte/asn1", ""},
+	{"vendor/golang.org/x/crypto/hkdf", "\x18\x01f\x15r"},
+	{"vendor/golang.org/x/crypto/internal/alias", "\xe3\x02"},
+	{"vendor/golang.org/x/crypto/internal/poly1305", "[\x16\xa4\x01"},
+	{"vendor/golang.org/x/net/dns/dnsmessage", "\x7f\xca\x01"},
+	{"vendor/golang.org/x/net/http/httpguts", "\x9c\x02\x16\x1a\x15\x10"},
+	{"vendor/golang.org/x/net/http/httpproxy", "\x7f\x03\x9a\x01\x12\x05\x01\x18\x15\x10"},
+	{"vendor/golang.org/x/net/http2/hpack", "\x03|\x03\x84\x01H"},
+	{"vendor/golang.org/x/net/http3", "\x9d\x02@\x06\x0f\x04"},
+	{"vendor/golang.org/x/net/idna", "\x82\x01\x90\x01:\x13\x02\x17\x02\x01"},
+	{"vendor/golang.org/x/net/internal/http3", "\rO#\x03\x84\x01\v\x04\a\x01\x05\x10\x01\x16\x02\x01\x02\x0f\x10\x02\x04\x03"},
+	{"vendor/golang.org/x/net/internal/httpcommon", "\rr\x03\xa0\x01\x10\x01\x17\x01\x01\x02\x1f\x02"},
+	{"vendor/golang.org/x/net/internal/quic/quicwire", "q"},
+	{"vendor/golang.org/x/net/nettest", "\x03n\x0e\x03\x84\x01\x11\x05\x18\x01\f\n\x01\x02\x02\x01\f"},
+	{"vendor/golang.org/x/net/quic", "\x03\n\x01\x01\x01\t;\x04\x04\x15\x03\v\x03\x12r\x06\x06\x06\x04\x12\x06\x15\x02\x01\x02\x01\x01\r\x06\x02\x01\x01\x02\v"},
+	{"vendor/golang.org/x/sys/cpu", "\xb4\x02\r\n\x01\x17"},
+	{"vendor/golang.org/x/text/secure/bidirule", "\x7f\xe2\x01\x18\x01"},
+	{"vendor/golang.org/x/text/transform", "\x03|\x87\x01["},
+	{"vendor/golang.org/x/text/unicode/bidi", "\x03\bw\x88\x01@\x17"},
+	{"vendor/golang.org/x/text/unicode/norm", "q\x11\x84\x01H\x13\x18"},
+	{"weak", "\xa5\x01\x9c\x01\""},
+}
+
+// bootstrap is the list of bootstrap packages extracted from cmd/dist.
+var bootstrap = map[string]bool{
+	"cmp":                                     true,
+	"cmd/asm":                                 true,
+	"cmd/asm/internal/arch":                   true,
+	"cmd/asm/internal/asm":                    true,
+	"cmd/asm/internal/flags":                  true,
+	"cmd/asm/internal/lex":                    true,
+	"cmd/cgo":                                 true,
+	"cmd/compile":                             true,
+	"cmd/compile/internal/abi":                true,
+	"cmd/compile/internal/abt":                true,
+	"cmd/compile/internal/amd64":              true,
+	"cmd/compile/internal/arm":                true,
+	"cmd/compile/internal/arm64":              true,
+	"cmd/compile/internal/base":               true,
+	"cmd/compile/internal/bitvec":             true,
+	"cmd/compile/internal/bloop":              true,
+	"cmd/compile/internal/compare":            true,
+	"cmd/compile/internal/coverage":           true,
+	"cmd/compile/internal/deadlocals":         true,
+	"cmd/compile/internal/devirtualize":       true,
+	"cmd/compile/internal/dwarfgen":           true,
+	"cmd/compile/internal/escape":             true,
+	"cmd/compile/internal/gc":                 true,
+	"cmd/compile/internal/importer":           true,
+	"cmd/compile/internal/inline":             true,
+	"cmd/compile/internal/inline/inlheur":     true,
+	"cmd/compile/internal/inline/interleaved": true,
+	"cmd/compile/internal/ir":                 true,
+	"cmd/compile/internal/liveness":           true,
+	"cmd/compile/internal/logopt":             true,
+	"cmd/compile/internal/loong64":            true,
+	"cmd/compile/internal/loopvar":            true,
+	"cmd/compile/internal/midway":             true,
+	"cmd/compile/internal/mips":               true,
+	"cmd/compile/internal/mips64":             true,
+	"cmd/compile/internal/noder":              true,
+	"cmd/compile/internal/objw":               true,
+	"cmd/compile/internal/pgoir":              true,
+	"cmd/compile/internal/pkginit":            true,
+	"cmd/compile/internal/ppc64":              true,
+	"cmd/compile/internal/rangefunc":          true,
+	"cmd/compile/internal/reflectdata":        true,
+	"cmd/compile/internal/riscv64":            true,
+	"cmd/compile/internal/rttype":             true,
+	"cmd/compile/internal/s390x":              true,
+	"cmd/compile/internal/slice":              true,
+	"cmd/compile/internal/ssa":                true,
+	"cmd/compile/internal/ssagen":             true,
+	"cmd/compile/internal/staticdata":         true,
+	"cmd/compile/internal/staticinit":         true,
+	"cmd/compile/internal/syntax":             true,
+	"cmd/compile/internal/test":               true,
+	"cmd/compile/internal/typebits":           true,
+	"cmd/compile/internal/typecheck":          true,
+	"cmd/compile/internal/types":              true,
+	"cmd/compile/internal/types2":             true,
+	"cmd/compile/internal/walk":               true,
+	"cmd/compile/internal/wasm":               true,
+	"cmd/compile/internal/x86":                true,
+	"cmd/internal/archive":                    true,
+	"cmd/internal/bio":                        true,
+	"cmd/internal/codesign":                   true,
+	"cmd/internal/dwarf":                      true,
+	"cmd/internal/edit":                       true,
+	"cmd/internal/gcprog":                     true,
+	"cmd/internal/goobj":                      true,
+	"cmd/internal/hash":                       true,
+	"cmd/internal/macho":                      true,
+	"cmd/internal/obj":                        true,
+	"cmd/internal/obj/arm":                    true,
+	"cmd/internal/obj/arm64":                  true,
+	"cmd/internal/obj/loong64":                true,
+	"cmd/internal/obj/mips":                   true,
+	"cmd/internal/obj/ppc64":                  true,
+	"cmd/internal/obj/riscv":                  true,
+	"cmd/internal/obj/s390x":                  true,
+	"cmd/internal/obj/wasm":                   true,
+	"cmd/internal/obj/x86":                    true,
+	"cmd/internal/objabi":                     true,
+	"cmd/internal/par":                        true,
+	"cmd/internal/pgo":                        true,
+	"cmd/internal/pkgpath":                    true,
+	"cmd/internal/quoted":                     true,
+	"cmd/internal/src":                        true,
+	"cmd/internal/sys":                        true,
+	"cmd/internal/telemetry":                  true,
+	"cmd/internal/telemetry/counter":          true,
+	"cmd/link":                                true,
+	"cmd/link/internal/amd64":                 true,
+	"cmd/link/internal/arm":                   true,
+	"cmd/link/internal/arm64":                 true,
+	"cmd/link/internal/benchmark":             true,
+	"cmd/link/internal/dwtest":                true,
+	"cmd/link/internal/ld":                    true,
+	"cmd/link/internal/loadelf":               true,
+	"cmd/link/internal/loader":                true,
+	"cmd/link/internal/loadmacho":             true,
+	"cmd/link/internal/loadpe":                true,
+	"cmd/link/internal/loadxcoff":             true,
+	"cmd/link/internal/loong64":               true,
+	"cmd/link/internal/mips":                  true,
+	"cmd/link/internal/mips64":                true,
+	"cmd/link/internal/ppc64":                 true,
+	"cmd/link/internal/riscv64":               true,
+	"cmd/link/internal/s390x":                 true,
+	"cmd/link/internal/sym":                   true,
+	"cmd/link/internal/wasm":                  true,
+	"cmd/link/internal/x86":                   true,
+	"compress/flate":                          true,
+	"compress/zlib":                           true,
+	"container/heap":                          true,
+	"debug/dwarf":                             true,
+	"debug/elf":                               true,
+	"debug/macho":                             true,
+	"debug/pe":                                true,
+	"go/build/constraint":                     true,
+	"go/constant":                             true,
+	"go/version":                              true,
+	"internal/abi":                            true,
+	"internal/coverage":                       true,
+	"cmd/internal/cov/covcmd":                 true,
+	"internal/bisect":                         true,
+	"internal/buildcfg":                       true,
+	"internal/exportdata":                     true,
+	"internal/goarch":                         true,
+	"internal/godebugs":                       true,
+	"internal/goexperiment":                   true,
+	"internal/goroot":                         true,
+	"internal/gover":                          true,
+	"internal/goversion":                      true,
+	"internal/lazyregexp":                     true,
+	"internal/pkgbits":                        true,
+	"internal/platform":                       true,
+	"internal/profile":                        true,
+	"internal/race":                           true,
+	"internal/runtime/gc":                     true,
+	"internal/saferio":                        true,
+	"internal/strconv":                        true,
+	"internal/syscall/unix":                   true,
+	"internal/types/errors":                   true,
+	"internal/unsafeheader":                   true,
+	"internal/xcoff":                          true,
+	"internal/zstd":                           true,
+	"math/bits":                               true,
+	"sort":                                    true,
+}
+
+// BootstrapVersion is the minor version of Go used during toolchain
+// bootstrapping. Packages for which [IsBootstrapPackage] must not use
+// features of Go newer than this version.
+const BootstrapVersion = Version(24) // go1.24.6
diff --git a/vendor/golang.org/x/tools/internal/stdlib/import.go b/vendor/golang.org/x/tools/internal/stdlib/import.go
new file mode 100644
index 0000000..8ecc672
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/stdlib/import.go
@@ -0,0 +1,97 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package stdlib
+
+// This file provides the API for the import graph of the standard library.
+//
+// Be aware that the compiler-generated code for every package
+// implicitly depends on package "runtime" and a handful of others
+// (see runtimePkgs in GOROOT/src/cmd/internal/objabi/pkgspecial.go).
+
+import (
+	"encoding/binary"
+	"iter"
+	"slices"
+	"strings"
+)
+
+// Imports returns the sequence of packages directly imported by the
+// named standard packages, in name order.
+// The imports of an unknown package are the empty set.
+//
+// The graph is built into the application and may differ from the
+// graph in the Go source tree being analyzed by the application.
+func Imports(pkgs ...string) iter.Seq[string] {
+	return func(yield func(string) bool) {
+		for _, pkg := range pkgs {
+			if i, ok := find(pkg); ok {
+				var depIndex uint64
+				for data := []byte(deps[i].deps); len(data) > 0; {
+					delta, n := binary.Uvarint(data)
+					depIndex += delta
+					if !yield(deps[depIndex].name) {
+						return
+					}
+					data = data[n:]
+				}
+			}
+		}
+	}
+}
+
+// Dependencies returns the set of all dependencies of the named
+// standard packages, including the initial package,
+// in a deterministic topological order.
+// The dependencies of an unknown package are the empty set.
+//
+// The graph is built into the application and may differ from the
+// graph in the Go source tree being analyzed by the application.
+func Dependencies(pkgs ...string) iter.Seq[string] {
+	return func(yield func(string) bool) {
+		for _, pkg := range pkgs {
+			if i, ok := find(pkg); ok {
+				var seen [1 + len(deps)/8]byte // bit set of seen packages
+				var visit func(i int) bool
+				visit = func(i int) bool {
+					bit := byte(1) << (i % 8)
+					if seen[i/8]&bit == 0 {
+						seen[i/8] |= bit
+						var depIndex uint64
+						for data := []byte(deps[i].deps); len(data) > 0; {
+							delta, n := binary.Uvarint(data)
+							depIndex += delta
+							if !visit(int(depIndex)) {
+								return false
+							}
+							data = data[n:]
+						}
+						if !yield(deps[i].name) {
+							return false
+						}
+					}
+					return true
+				}
+				if !visit(i) {
+					return
+				}
+			}
+		}
+	}
+}
+
+// find returns the index of pkg in the deps table.
+func find(pkg string) (int, bool) {
+	return slices.BinarySearchFunc(deps[:], pkg, func(p pkginfo, n string) int {
+		return strings.Compare(p.name, n)
+	})
+}
+
+// IsBootstrapPackage reports whether pkg is one of the low-level
+// packages in the Go distribution that must compile with the older
+// language version specified by [BootstrapVersion] during toolchain
+// bootstrapping; see golang.org/s/go15bootstrap.
+func IsBootstrapPackage(pkg string) bool {
+	return bootstrap[pkg]
+}
diff --git a/vendor/golang.org/x/tools/internal/stdlib/manifest.go b/vendor/golang.org/x/tools/internal/stdlib/manifest.go
new file mode 100644
index 0000000..e11abf0
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/stdlib/manifest.go
@@ -0,0 +1,18615 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by generate.go. DO NOT EDIT.
+
+package stdlib
+
+var PackageSymbols = map[string][]Symbol{
+	"archive/tar": {
+		{"(*Header).FileInfo", Method, 1, ""},
+		{"(*Reader).Next", Method, 0, ""},
+		{"(*Reader).Read", Method, 0, ""},
+		{"(*Writer).AddFS", Method, 22, ""},
+		{"(*Writer).Close", Method, 0, ""},
+		{"(*Writer).Flush", Method, 0, ""},
+		{"(*Writer).Write", Method, 0, ""},
+		{"(*Writer).WriteHeader", Method, 0, ""},
+		{"(FileInfoNames).Gname", Method, 23, ""},
+		{"(FileInfoNames).IsDir", Method, 23, ""},
+		{"(FileInfoNames).ModTime", Method, 23, ""},
+		{"(FileInfoNames).Mode", Method, 23, ""},
+		{"(FileInfoNames).Name", Method, 23, ""},
+		{"(FileInfoNames).Size", Method, 23, ""},
+		{"(FileInfoNames).Sys", Method, 23, ""},
+		{"(FileInfoNames).Uname", Method, 23, ""},
+		{"(Format).String", Method, 10, ""},
+		{"ErrFieldTooLong", Var, 0, ""},
+		{"ErrHeader", Var, 0, ""},
+		{"ErrInsecurePath", Var, 20, ""},
+		{"ErrWriteAfterClose", Var, 0, ""},
+		{"ErrWriteTooLong", Var, 0, ""},
+		{"FileInfoHeader", Func, 1, "func(fi fs.FileInfo, link string) (*Header, error)"},
+		{"FileInfoNames", Type, 23, ""},
+		{"Format", Type, 10, ""},
+		{"FormatGNU", Const, 10, ""},
+		{"FormatPAX", Const, 10, ""},
+		{"FormatUSTAR", Const, 10, ""},
+		{"FormatUnknown", Const, 10, ""},
+		{"Header", Type, 0, ""},
+		{"Header.AccessTime", Field, 0, ""},
+		{"Header.ChangeTime", Field, 0, ""},
+		{"Header.Devmajor", Field, 0, ""},
+		{"Header.Devminor", Field, 0, ""},
+		{"Header.Format", Field, 10, ""},
+		{"Header.Gid", Field, 0, ""},
+		{"Header.Gname", Field, 0, ""},
+		{"Header.Linkname", Field, 0, ""},
+		{"Header.ModTime", Field, 0, ""},
+		{"Header.Mode", Field, 0, ""},
+		{"Header.Name", Field, 0, ""},
+		{"Header.PAXRecords", Field, 10, ""},
+		{"Header.Size", Field, 0, ""},
+		{"Header.Typeflag", Field, 0, ""},
+		{"Header.Uid", Field, 0, ""},
+		{"Header.Uname", Field, 0, ""},
+		{"Header.Xattrs", Field, 3, ""},
+		{"NewReader", Func, 0, "func(r io.Reader) *Reader"},
+		{"NewWriter", Func, 0, "func(w io.Writer) *Writer"},
+		{"Reader", Type, 0, ""},
+		{"TypeBlock", Const, 0, ""},
+		{"TypeChar", Const, 0, ""},
+		{"TypeCont", Const, 0, ""},
+		{"TypeDir", Const, 0, ""},
+		{"TypeFifo", Const, 0, ""},
+		{"TypeGNULongLink", Const, 1, ""},
+		{"TypeGNULongName", Const, 1, ""},
+		{"TypeGNUSparse", Const, 3, ""},
+		{"TypeLink", Const, 0, ""},
+		{"TypeReg", Const, 0, ""},
+		{"TypeRegA", Const, 0, ""},
+		{"TypeSymlink", Const, 0, ""},
+		{"TypeXGlobalHeader", Const, 0, ""},
+		{"TypeXHeader", Const, 0, ""},
+		{"Writer", Type, 0, ""},
+	},
+	"archive/zip": {
+		{"(*File).DataOffset", Method, 2, ""},
+		{"(*File).FileInfo", Method, 0, ""},
+		{"(*File).ModTime", Method, 0, ""},
+		{"(*File).Mode", Method, 0, ""},
+		{"(*File).Open", Method, 0, ""},
+		{"(*File).OpenRaw", Method, 17, ""},
+		{"(*File).SetModTime", Method, 0, ""},
+		{"(*File).SetMode", Method, 0, ""},
+		{"(*FileHeader).FileInfo", Method, 0, ""},
+		{"(*FileHeader).ModTime", Method, 0, ""},
+		{"(*FileHeader).Mode", Method, 0, ""},
+		{"(*FileHeader).SetModTime", Method, 0, ""},
+		{"(*FileHeader).SetMode", Method, 0, ""},
+		{"(*ReadCloser).Close", Method, 0, ""},
+		{"(*ReadCloser).Open", Method, 16, ""},
+		{"(*ReadCloser).RegisterDecompressor", Method, 6, ""},
+		{"(*Reader).Open", Method, 16, ""},
+		{"(*Reader).RegisterDecompressor", Method, 6, ""},
+		{"(*Writer).AddFS", Method, 22, ""},
+		{"(*Writer).Close", Method, 0, ""},
+		{"(*Writer).Copy", Method, 17, ""},
+		{"(*Writer).Create", Method, 0, ""},
+		{"(*Writer).CreateHeader", Method, 0, ""},
+		{"(*Writer).CreateRaw", Method, 17, ""},
+		{"(*Writer).Flush", Method, 4, ""},
+		{"(*Writer).RegisterCompressor", Method, 6, ""},
+		{"(*Writer).SetComment", Method, 10, ""},
+		{"(*Writer).SetOffset", Method, 5, ""},
+		{"Compressor", Type, 2, ""},
+		{"Decompressor", Type, 2, ""},
+		{"Deflate", Const, 0, ""},
+		{"ErrAlgorithm", Var, 0, ""},
+		{"ErrChecksum", Var, 0, ""},
+		{"ErrFormat", Var, 0, ""},
+		{"ErrInsecurePath", Var, 20, ""},
+		{"File", Type, 0, ""},
+		{"File.FileHeader", Field, 0, ""},
+		{"FileHeader", Type, 0, ""},
+		{"FileHeader.CRC32", Field, 0, ""},
+		{"FileHeader.Comment", Field, 0, ""},
+		{"FileHeader.CompressedSize", Field, 0, ""},
+		{"FileHeader.CompressedSize64", Field, 1, ""},
+		{"FileHeader.CreatorVersion", Field, 0, ""},
+		{"FileHeader.ExternalAttrs", Field, 0, ""},
+		{"FileHeader.Extra", Field, 0, ""},
+		{"FileHeader.Flags", Field, 0, ""},
+		{"FileHeader.Method", Field, 0, ""},
+		{"FileHeader.Modified", Field, 10, ""},
+		{"FileHeader.ModifiedDate", Field, 0, ""},
+		{"FileHeader.ModifiedTime", Field, 0, ""},
+		{"FileHeader.Name", Field, 0, ""},
+		{"FileHeader.NonUTF8", Field, 10, ""},
+		{"FileHeader.ReaderVersion", Field, 0, ""},
+		{"FileHeader.UncompressedSize", Field, 0, ""},
+		{"FileHeader.UncompressedSize64", Field, 1, ""},
+		{"FileInfoHeader", Func, 0, "func(fi fs.FileInfo) (*FileHeader, error)"},
+		{"NewReader", Func, 0, "func(r io.ReaderAt, size int64) (*Reader, error)"},
+		{"NewWriter", Func, 0, "func(w io.Writer) *Writer"},
+		{"OpenReader", Func, 0, "func(name string) (*ReadCloser, error)"},
+		{"ReadCloser", Type, 0, ""},
+		{"ReadCloser.Reader", Field, 0, ""},
+		{"Reader", Type, 0, ""},
+		{"Reader.Comment", Field, 0, ""},
+		{"Reader.File", Field, 0, ""},
+		{"RegisterCompressor", Func, 2, "func(method uint16, comp Compressor)"},
+		{"RegisterDecompressor", Func, 2, "func(method uint16, dcomp Decompressor)"},
+		{"Store", Const, 0, ""},
+		{"Writer", Type, 0, ""},
+	},
+	"bufio": {
+		{"(*Reader).Buffered", Method, 0, ""},
+		{"(*Reader).Discard", Method, 5, ""},
+		{"(*Reader).Peek", Method, 0, ""},
+		{"(*Reader).Read", Method, 0, ""},
+		{"(*Reader).ReadByte", Method, 0, ""},
+		{"(*Reader).ReadBytes", Method, 0, ""},
+		{"(*Reader).ReadLine", Method, 0, ""},
+		{"(*Reader).ReadRune", Method, 0, ""},
+		{"(*Reader).ReadSlice", Method, 0, ""},
+		{"(*Reader).ReadString", Method, 0, ""},
+		{"(*Reader).Reset", Method, 2, ""},
+		{"(*Reader).Size", Method, 10, ""},
+		{"(*Reader).UnreadByte", Method, 0, ""},
+		{"(*Reader).UnreadRune", Method, 0, ""},
+		{"(*Reader).WriteTo", Method, 1, ""},
+		{"(*Scanner).Buffer", Method, 6, ""},
+		{"(*Scanner).Bytes", Method, 1, ""},
+		{"(*Scanner).Err", Method, 1, ""},
+		{"(*Scanner).Scan", Method, 1, ""},
+		{"(*Scanner).Split", Method, 1, ""},
+		{"(*Scanner).Text", Method, 1, ""},
+		{"(*Writer).Available", Method, 0, ""},
+		{"(*Writer).AvailableBuffer", Method, 18, ""},
+		{"(*Writer).Buffered", Method, 0, ""},
+		{"(*Writer).Flush", Method, 0, ""},
+		{"(*Writer).ReadFrom", Method, 1, ""},
+		{"(*Writer).Reset", Method, 2, ""},
+		{"(*Writer).Size", Method, 10, ""},
+		{"(*Writer).Write", Method, 0, ""},
+		{"(*Writer).WriteByte", Method, 0, ""},
+		{"(*Writer).WriteRune", Method, 0, ""},
+		{"(*Writer).WriteString", Method, 0, ""},
+		{"(ReadWriter).Available", Method, 0, ""},
+		{"(ReadWriter).AvailableBuffer", Method, 18, ""},
+		{"(ReadWriter).Discard", Method, 5, ""},
+		{"(ReadWriter).Flush", Method, 0, ""},
+		{"(ReadWriter).Peek", Method, 0, ""},
+		{"(ReadWriter).Read", Method, 0, ""},
+		{"(ReadWriter).ReadByte", Method, 0, ""},
+		{"(ReadWriter).ReadBytes", Method, 0, ""},
+		{"(ReadWriter).ReadFrom", Method, 1, ""},
+		{"(ReadWriter).ReadLine", Method, 0, ""},
+		{"(ReadWriter).ReadRune", Method, 0, ""},
+		{"(ReadWriter).ReadSlice", Method, 0, ""},
+		{"(ReadWriter).ReadString", Method, 0, ""},
+		{"(ReadWriter).UnreadByte", Method, 0, ""},
+		{"(ReadWriter).UnreadRune", Method, 0, ""},
+		{"(ReadWriter).Write", Method, 0, ""},
+		{"(ReadWriter).WriteByte", Method, 0, ""},
+		{"(ReadWriter).WriteRune", Method, 0, ""},
+		{"(ReadWriter).WriteString", Method, 0, ""},
+		{"(ReadWriter).WriteTo", Method, 1, ""},
+		{"ErrAdvanceTooFar", Var, 1, ""},
+		{"ErrBadReadCount", Var, 15, ""},
+		{"ErrBufferFull", Var, 0, ""},
+		{"ErrFinalToken", Var, 6, ""},
+		{"ErrInvalidUnreadByte", Var, 0, ""},
+		{"ErrInvalidUnreadRune", Var, 0, ""},
+		{"ErrNegativeAdvance", Var, 1, ""},
+		{"ErrNegativeCount", Var, 0, ""},
+		{"ErrTooLong", Var, 1, ""},
+		{"MaxScanTokenSize", Const, 1, ""},
+		{"NewReadWriter", Func, 0, "func(r *Reader, w *Writer) *ReadWriter"},
+		{"NewReader", Func, 0, "func(rd io.Reader) *Reader"},
+		{"NewReaderSize", Func, 0, "func(rd io.Reader, size int) *Reader"},
+		{"NewScanner", Func, 1, "func(r io.Reader) *Scanner"},
+		{"NewWriter", Func, 0, "func(w io.Writer) *Writer"},
+		{"NewWriterSize", Func, 0, "func(w io.Writer, size int) *Writer"},
+		{"ReadWriter", Type, 0, ""},
+		{"ReadWriter.Reader", Field, 0, ""},
+		{"ReadWriter.Writer", Field, 0, ""},
+		{"Reader", Type, 0, ""},
+		{"ScanBytes", Func, 1, "func(data []byte, atEOF bool) (advance int, token []byte, err error)"},
+		{"ScanLines", Func, 1, "func(data []byte, atEOF bool) (advance int, token []byte, err error)"},
+		{"ScanRunes", Func, 1, "func(data []byte, atEOF bool) (advance int, token []byte, err error)"},
+		{"ScanWords", Func, 1, "func(data []byte, atEOF bool) (advance int, token []byte, err error)"},
+		{"Scanner", Type, 1, ""},
+		{"SplitFunc", Type, 1, ""},
+		{"Writer", Type, 0, ""},
+	},
+	"bytes": {
+		{"(*Buffer).Available", Method, 21, ""},
+		{"(*Buffer).AvailableBuffer", Method, 21, ""},
+		{"(*Buffer).Bytes", Method, 0, ""},
+		{"(*Buffer).Cap", Method, 5, ""},
+		{"(*Buffer).Grow", Method, 1, ""},
+		{"(*Buffer).Len", Method, 0, ""},
+		{"(*Buffer).Next", Method, 0, ""},
+		{"(*Buffer).Peek", Method, 26, ""},
+		{"(*Buffer).Read", Method, 0, ""},
+		{"(*Buffer).ReadByte", Method, 0, ""},
+		{"(*Buffer).ReadBytes", Method, 0, ""},
+		{"(*Buffer).ReadFrom", Method, 0, ""},
+		{"(*Buffer).ReadRune", Method, 0, ""},
+		{"(*Buffer).ReadString", Method, 0, ""},
+		{"(*Buffer).Reset", Method, 0, ""},
+		{"(*Buffer).String", Method, 0, ""},
+		{"(*Buffer).Truncate", Method, 0, ""},
+		{"(*Buffer).UnreadByte", Method, 0, ""},
+		{"(*Buffer).UnreadRune", Method, 0, ""},
+		{"(*Buffer).Write", Method, 0, ""},
+		{"(*Buffer).WriteByte", Method, 0, ""},
+		{"(*Buffer).WriteRune", Method, 0, ""},
+		{"(*Buffer).WriteString", Method, 0, ""},
+		{"(*Buffer).WriteTo", Method, 0, ""},
+		{"(*Reader).Len", Method, 0, ""},
+		{"(*Reader).Read", Method, 0, ""},
+		{"(*Reader).ReadAt", Method, 0, ""},
+		{"(*Reader).ReadByte", Method, 0, ""},
+		{"(*Reader).ReadRune", Method, 0, ""},
+		{"(*Reader).Reset", Method, 7, ""},
+		{"(*Reader).Seek", Method, 0, ""},
+		{"(*Reader).Size", Method, 5, ""},
+		{"(*Reader).UnreadByte", Method, 0, ""},
+		{"(*Reader).UnreadRune", Method, 0, ""},
+		{"(*Reader).WriteTo", Method, 1, ""},
+		{"Buffer", Type, 0, ""},
+		{"Clone", Func, 20, "func(b []byte) []byte"},
+		{"Compare", Func, 0, "func(a []byte, b []byte) int"},
+		{"Contains", Func, 0, "func(b []byte, subslice []byte) bool"},
+		{"ContainsAny", Func, 7, "func(b []byte, chars string) bool"},
+		{"ContainsFunc", Func, 21, "func(b []byte, f func(rune) bool) bool"},
+		{"ContainsRune", Func, 7, "func(b []byte, r rune) bool"},
+		{"Count", Func, 0, "func(s []byte, sep []byte) int"},
+		{"Cut", Func, 18, "func(s []byte, sep []byte) (before []byte, after []byte, found bool)"},
+		{"CutLast", Func, 27, "func(s []byte, sep []byte) (before []byte, after []byte, found bool)"},
+		{"CutPrefix", Func, 20, "func(s []byte, prefix []byte) (after []byte, found bool)"},
+		{"CutSuffix", Func, 20, "func(s []byte, suffix []byte) (before []byte, found bool)"},
+		{"Equal", Func, 0, "func(a []byte, b []byte) bool"},
+		{"EqualFold", Func, 0, "func(s []byte, t []byte) bool"},
+		{"ErrTooLarge", Var, 0, ""},
+		{"Fields", Func, 0, "func(s []byte) [][]byte"},
+		{"FieldsFunc", Func, 0, "func(s []byte, f func(rune) bool) [][]byte"},
+		{"FieldsFuncSeq", Func, 24, "func(s []byte, f func(rune) bool) iter.Seq[[]byte]"},
+		{"FieldsSeq", Func, 24, "func(s []byte) iter.Seq[[]byte]"},
+		{"HasPrefix", Func, 0, "func(s []byte, prefix []byte) bool"},
+		{"HasSuffix", Func, 0, "func(s []byte, suffix []byte) bool"},
+		{"Index", Func, 0, "func(s []byte, sep []byte) int"},
+		{"IndexAny", Func, 0, "func(s []byte, chars string) int"},
+		{"IndexByte", Func, 0, "func(b []byte, c byte) int"},
+		{"IndexFunc", Func, 0, "func(s []byte, f func(r rune) bool) int"},
+		{"IndexRune", Func, 0, "func(s []byte, r rune) int"},
+		{"Join", Func, 0, "func(s [][]byte, sep []byte) []byte"},
+		{"LastIndex", Func, 0, "func(s []byte, sep []byte) int"},
+		{"LastIndexAny", Func, 0, "func(s []byte, chars string) int"},
+		{"LastIndexByte", Func, 5, "func(s []byte, c byte) int"},
+		{"LastIndexFunc", Func, 0, "func(s []byte, f func(r rune) bool) int"},
+		{"Lines", Func, 24, "func(s []byte) iter.Seq[[]byte]"},
+		{"Map", Func, 0, "func(mapping func(r rune) rune, s []byte) []byte"},
+		{"MinRead", Const, 0, ""},
+		{"NewBuffer", Func, 0, "func(buf []byte) *Buffer"},
+		{"NewBufferString", Func, 0, "func(s string) *Buffer"},
+		{"NewReader", Func, 0, "func(b []byte) *Reader"},
+		{"Reader", Type, 0, ""},
+		{"Repeat", Func, 0, "func(b []byte, count int) []byte"},
+		{"Replace", Func, 0, "func(s []byte, old []byte, new []byte, n int) []byte"},
+		{"ReplaceAll", Func, 12, "func(s []byte, old []byte, new []byte) []byte"},
+		{"Runes", Func, 0, "func(s []byte) []rune"},
+		{"Split", Func, 0, "func(s []byte, sep []byte) [][]byte"},
+		{"SplitAfter", Func, 0, "func(s []byte, sep []byte) [][]byte"},
+		{"SplitAfterN", Func, 0, "func(s []byte, sep []byte, n int) [][]byte"},
+		{"SplitAfterSeq", Func, 24, "func(s []byte, sep []byte) iter.Seq[[]byte]"},
+		{"SplitN", Func, 0, "func(s []byte, sep []byte, n int) [][]byte"},
+		{"SplitSeq", Func, 24, "func(s []byte, sep []byte) iter.Seq[[]byte]"},
+		{"Title", Func, 0, "func(s []byte) []byte"},
+		{"ToLower", Func, 0, "func(s []byte) []byte"},
+		{"ToLowerSpecial", Func, 0, "func(c unicode.SpecialCase, s []byte) []byte"},
+		{"ToTitle", Func, 0, "func(s []byte) []byte"},
+		{"ToTitleSpecial", Func, 0, "func(c unicode.SpecialCase, s []byte) []byte"},
+		{"ToUpper", Func, 0, "func(s []byte) []byte"},
+		{"ToUpperSpecial", Func, 0, "func(c unicode.SpecialCase, s []byte) []byte"},
+		{"ToValidUTF8", Func, 13, "func(s []byte, replacement []byte) []byte"},
+		{"Trim", Func, 0, "func(s []byte, cutset string) []byte"},
+		{"TrimFunc", Func, 0, "func(s []byte, f func(r rune) bool) []byte"},
+		{"TrimLeft", Func, 0, "func(s []byte, cutset string) []byte"},
+		{"TrimLeftFunc", Func, 0, "func(s []byte, f func(r rune) bool) []byte"},
+		{"TrimPrefix", Func, 1, "func(s []byte, prefix []byte) []byte"},
+		{"TrimRight", Func, 0, "func(s []byte, cutset string) []byte"},
+		{"TrimRightFunc", Func, 0, "func(s []byte, f func(r rune) bool) []byte"},
+		{"TrimSpace", Func, 0, "func(s []byte) []byte"},
+		{"TrimSuffix", Func, 1, "func(s []byte, suffix []byte) []byte"},
+	},
+	"cmp": {
+		{"Compare", Func, 21, "func[T Ordered](x T, y T) int"},
+		{"Less", Func, 21, "func[T Ordered](x T, y T) bool"},
+		{"Or", Func, 22, "func[T comparable](vals ...T) T"},
+		{"Ordered", Type, 21, ""},
+	},
+	"compress/bzip2": {
+		{"(StructuralError).Error", Method, 0, ""},
+		{"NewReader", Func, 0, "func(r io.Reader) io.Reader"},
+		{"StructuralError", Type, 0, ""},
+	},
+	"compress/flate": {
+		{"(*ReadError).Error", Method, 0, ""},
+		{"(*WriteError).Error", Method, 0, ""},
+		{"(*Writer).Close", Method, 0, ""},
+		{"(*Writer).Flush", Method, 0, ""},
+		{"(*Writer).Reset", Method, 2, ""},
+		{"(*Writer).Write", Method, 0, ""},
+		{"(CorruptInputError).Error", Method, 0, ""},
+		{"(InternalError).Error", Method, 0, ""},
+		{"(Reader).Read", Method, 0, ""},
+		{"(Reader).ReadByte", Method, 0, ""},
+		{"(Resetter).Reset", Method, 4, ""},
+		{"BestCompression", Const, 0, ""},
+		{"BestSpeed", Const, 0, ""},
+		{"CorruptInputError", Type, 0, ""},
+		{"DefaultCompression", Const, 0, ""},
+		{"HuffmanOnly", Const, 7, ""},
+		{"InternalError", Type, 0, ""},
+		{"NewReader", Func, 0, "func(r io.Reader) io.ReadCloser"},
+		{"NewReaderDict", Func, 0, "func(r io.Reader, dict []byte) io.ReadCloser"},
+		{"NewWriter", Func, 0, "func(w io.Writer, level int) (*Writer, error)"},
+		{"NewWriterDict", Func, 0, "func(w io.Writer, level int, dict []byte) (*Writer, error)"},
+		{"NoCompression", Const, 0, ""},
+		{"ReadError", Type, 0, ""},
+		{"ReadError.Err", Field, 0, ""},
+		{"ReadError.Offset", Field, 0, ""},
+		{"Reader", Type, 0, ""},
+		{"Resetter", Type, 4, ""},
+		{"WriteError", Type, 0, ""},
+		{"WriteError.Err", Field, 0, ""},
+		{"WriteError.Offset", Field, 0, ""},
+		{"Writer", Type, 0, ""},
+	},
+	"compress/gzip": {
+		{"(*Reader).Close", Method, 0, ""},
+		{"(*Reader).Multistream", Method, 4, ""},
+		{"(*Reader).Read", Method, 0, ""},
+		{"(*Reader).Reset", Method, 3, ""},
+		{"(*Writer).Close", Method, 0, ""},
+		{"(*Writer).Flush", Method, 1, ""},
+		{"(*Writer).Reset", Method, 2, ""},
+		{"(*Writer).Write", Method, 0, ""},
+		{"BestCompression", Const, 0, ""},
+		{"BestSpeed", Const, 0, ""},
+		{"DefaultCompression", Const, 0, ""},
+		{"ErrChecksum", Var, 0, ""},
+		{"ErrHeader", Var, 0, ""},
+		{"Header", Type, 0, ""},
+		{"Header.Comment", Field, 0, ""},
+		{"Header.Extra", Field, 0, ""},
+		{"Header.ModTime", Field, 0, ""},
+		{"Header.Name", Field, 0, ""},
+		{"Header.OS", Field, 0, ""},
+		{"HuffmanOnly", Const, 8, ""},
+		{"NewReader", Func, 0, "func(r io.Reader) (*Reader, error)"},
+		{"NewWriter", Func, 0, "func(w io.Writer) *Writer"},
+		{"NewWriterLevel", Func, 0, "func(w io.Writer, level int) (*Writer, error)"},
+		{"NoCompression", Const, 0, ""},
+		{"Reader", Type, 0, ""},
+		{"Reader.Header", Field, 0, ""},
+		{"Writer", Type, 0, ""},
+		{"Writer.Header", Field, 0, ""},
+	},
+	"compress/lzw": {
+		{"(*Reader).Close", Method, 17, ""},
+		{"(*Reader).Read", Method, 17, ""},
+		{"(*Reader).Reset", Method, 17, ""},
+		{"(*Writer).Close", Method, 17, ""},
+		{"(*Writer).Reset", Method, 17, ""},
+		{"(*Writer).Write", Method, 17, ""},
+		{"LSB", Const, 0, ""},
+		{"MSB", Const, 0, ""},
+		{"NewReader", Func, 0, "func(r io.Reader, order Order, litWidth int) io.ReadCloser"},
+		{"NewWriter", Func, 0, "func(w io.Writer, order Order, litWidth int) io.WriteCloser"},
+		{"Order", Type, 0, ""},
+		{"Reader", Type, 17, ""},
+		{"Writer", Type, 17, ""},
+	},
+	"compress/zlib": {
+		{"(*Writer).Close", Method, 0, ""},
+		{"(*Writer).Flush", Method, 0, ""},
+		{"(*Writer).Reset", Method, 2, ""},
+		{"(*Writer).Write", Method, 0, ""},
+		{"(Resetter).Reset", Method, 4, ""},
+		{"BestCompression", Const, 0, ""},
+		{"BestSpeed", Const, 0, ""},
+		{"DefaultCompression", Const, 0, ""},
+		{"ErrChecksum", Var, 0, ""},
+		{"ErrDictionary", Var, 0, ""},
+		{"ErrHeader", Var, 0, ""},
+		{"HuffmanOnly", Const, 8, ""},
+		{"NewReader", Func, 0, "func(r io.Reader) (io.ReadCloser, error)"},
+		{"NewReaderDict", Func, 0, "func(r io.Reader, dict []byte) (io.ReadCloser, error)"},
+		{"NewWriter", Func, 0, "func(w io.Writer) *Writer"},
+		{"NewWriterLevel", Func, 0, "func(w io.Writer, level int) (*Writer, error)"},
+		{"NewWriterLevelDict", Func, 0, "func(w io.Writer, level int, dict []byte) (*Writer, error)"},
+		{"NoCompression", Const, 0, ""},
+		{"Resetter", Type, 4, ""},
+		{"Writer", Type, 0, ""},
+	},
+	"container/heap": {
+		{"(Interface).Len", Method, 0, ""},
+		{"(Interface).Less", Method, 0, ""},
+		{"(Interface).Pop", Method, 0, ""},
+		{"(Interface).Push", Method, 0, ""},
+		{"(Interface).Swap", Method, 0, ""},
+		{"Fix", Func, 2, "func(h Interface, i int)"},
+		{"Init", Func, 0, "func(h Interface)"},
+		{"Interface", Type, 0, ""},
+		{"Pop", Func, 0, "func(h Interface) any"},
+		{"Push", Func, 0, "func(h Interface, x any)"},
+		{"Remove", Func, 0, "func(h Interface, i int) any"},
+	},
+	"container/list": {
+		{"(*Element).Next", Method, 0, ""},
+		{"(*Element).Prev", Method, 0, ""},
+		{"(*List).Back", Method, 0, ""},
+		{"(*List).Front", Method, 0, ""},
+		{"(*List).Init", Method, 0, ""},
+		{"(*List).InsertAfter", Method, 0, ""},
+		{"(*List).InsertBefore", Method, 0, ""},
+		{"(*List).Len", Method, 0, ""},
+		{"(*List).MoveAfter", Method, 2, ""},
+		{"(*List).MoveBefore", Method, 2, ""},
+		{"(*List).MoveToBack", Method, 0, ""},
+		{"(*List).MoveToFront", Method, 0, ""},
+		{"(*List).PushBack", Method, 0, ""},
+		{"(*List).PushBackList", Method, 0, ""},
+		{"(*List).PushFront", Method, 0, ""},
+		{"(*List).PushFrontList", Method, 0, ""},
+		{"(*List).Remove", Method, 0, ""},
+		{"Element", Type, 0, ""},
+		{"Element.Value", Field, 0, ""},
+		{"List", Type, 0, ""},
+		{"New", Func, 0, "func() *List"},
+	},
+	"container/ring": {
+		{"(*Ring).Do", Method, 0, ""},
+		{"(*Ring).Len", Method, 0, ""},
+		{"(*Ring).Link", Method, 0, ""},
+		{"(*Ring).Move", Method, 0, ""},
+		{"(*Ring).Next", Method, 0, ""},
+		{"(*Ring).Prev", Method, 0, ""},
+		{"(*Ring).Unlink", Method, 0, ""},
+		{"New", Func, 0, "func(n int) *Ring"},
+		{"Ring", Type, 0, ""},
+		{"Ring.Value", Field, 0, ""},
+	},
+	"context": {
+		{"(Context).Deadline", Method, 7, ""},
+		{"(Context).Done", Method, 7, ""},
+		{"(Context).Err", Method, 7, ""},
+		{"(Context).Value", Method, 7, ""},
+		{"AfterFunc", Func, 21, "func(ctx Context, f func()) (stop func() bool)"},
+		{"Background", Func, 7, "func() Context"},
+		{"CancelCauseFunc", Type, 20, ""},
+		{"CancelFunc", Type, 7, ""},
+		{"Canceled", Var, 7, ""},
+		{"Cause", Func, 20, "func(c Context) error"},
+		{"Context", Type, 7, ""},
+		{"DeadlineExceeded", Var, 7, ""},
+		{"TODO", Func, 7, "func() Context"},
+		{"WithCancel", Func, 7, "func(parent Context) (ctx Context, cancel CancelFunc)"},
+		{"WithCancelCause", Func, 20, "func(parent Context) (ctx Context, cancel CancelCauseFunc)"},
+		{"WithDeadline", Func, 7, "func(parent Context, d time.Time) (Context, CancelFunc)"},
+		{"WithDeadlineCause", Func, 21, "func(parent Context, d time.Time, cause error) (Context, CancelFunc)"},
+		{"WithTimeout", Func, 7, "func(parent Context, timeout time.Duration) (Context, CancelFunc)"},
+		{"WithTimeoutCause", Func, 21, "func(parent Context, timeout time.Duration, cause error) (Context, CancelFunc)"},
+		{"WithValue", Func, 7, "func(parent Context, key any, val any) Context"},
+		{"WithoutCancel", Func, 21, "func(parent Context) Context"},
+	},
+	"crypto": {
+		{"(Decapsulator).Decapsulate", Method, 26, ""},
+		{"(Decapsulator).Encapsulator", Method, 26, ""},
+		{"(Decrypter).Decrypt", Method, 5, ""},
+		{"(Decrypter).Public", Method, 5, ""},
+		{"(Encapsulator).Bytes", Method, 26, ""},
+		{"(Encapsulator).Encapsulate", Method, 26, ""},
+		{"(Hash).Available", Method, 0, ""},
+		{"(Hash).HashFunc", Method, 4, ""},
+		{"(Hash).New", Method, 0, ""},
+		{"(Hash).Size", Method, 0, ""},
+		{"(Hash).String", Method, 15, ""},
+		{"(MessageSigner).Public", Method, 25, ""},
+		{"(MessageSigner).Sign", Method, 25, ""},
+		{"(MessageSigner).SignMessage", Method, 25, ""},
+		{"(Signer).Public", Method, 4, ""},
+		{"(Signer).Sign", Method, 4, ""},
+		{"(SignerOpts).HashFunc", Method, 4, ""},
+		{"BLAKE2b_256", Const, 9, ""},
+		{"BLAKE2b_384", Const, 9, ""},
+		{"BLAKE2b_512", Const, 9, ""},
+		{"BLAKE2s_256", Const, 9, ""},
+		{"Decapsulator", Type, 26, ""},
+		{"Decrypter", Type, 5, ""},
+		{"DecrypterOpts", Type, 5, ""},
+		{"Encapsulator", Type, 26, ""},
+		{"Hash", Type, 0, ""},
+		{"MD4", Const, 0, ""},
+		{"MD5", Const, 0, ""},
+		{"MD5SHA1", Const, 0, ""},
+		{"MLDSAMu", Const, 27, ""},
+		{"MessageSigner", Type, 25, ""},
+		{"PrivateKey", Type, 0, ""},
+		{"PublicKey", Type, 2, ""},
+		{"RIPEMD160", Const, 0, ""},
+		{"RegisterHash", Func, 0, "func(h Hash, f func() hash.Hash)"},
+		{"SHA1", Const, 0, ""},
+		{"SHA224", Const, 0, ""},
+		{"SHA256", Const, 0, ""},
+		{"SHA384", Const, 0, ""},
+		{"SHA3_224", Const, 4, ""},
+		{"SHA3_256", Const, 4, ""},
+		{"SHA3_384", Const, 4, ""},
+		{"SHA3_512", Const, 4, ""},
+		{"SHA512", Const, 0, ""},
+		{"SHA512_224", Const, 5, ""},
+		{"SHA512_256", Const, 5, ""},
+		{"SignMessage", Func, 25, "func(signer Signer, rand io.Reader, msg []byte, opts SignerOpts) (signature []byte, err error)"},
+		{"Signer", Type, 4, ""},
+		{"SignerOpts", Type, 4, ""},
+	},
+	"crypto/aes": {
+		{"(KeySizeError).Error", Method, 0, ""},
+		{"BlockSize", Const, 0, ""},
+		{"KeySizeError", Type, 0, ""},
+		{"NewCipher", Func, 0, "func(key []byte) (cipher.Block, error)"},
+	},
+	"crypto/cipher": {
+		{"(AEAD).NonceSize", Method, 2, ""},
+		{"(AEAD).Open", Method, 2, ""},
+		{"(AEAD).Overhead", Method, 2, ""},
+		{"(AEAD).Seal", Method, 2, ""},
+		{"(Block).BlockSize", Method, 0, ""},
+		{"(Block).Decrypt", Method, 0, ""},
+		{"(Block).Encrypt", Method, 0, ""},
+		{"(BlockMode).BlockSize", Method, 0, ""},
+		{"(BlockMode).CryptBlocks", Method, 0, ""},
+		{"(Stream).XORKeyStream", Method, 0, ""},
+		{"(StreamReader).Read", Method, 0, ""},
+		{"(StreamWriter).Close", Method, 0, ""},
+		{"(StreamWriter).Write", Method, 0, ""},
+		{"AEAD", Type, 2, ""},
+		{"Block", Type, 0, ""},
+		{"BlockMode", Type, 0, ""},
+		{"NewCBCDecrypter", Func, 0, "func(b Block, iv []byte) BlockMode"},
+		{"NewCBCEncrypter", Func, 0, "func(b Block, iv []byte) BlockMode"},
+		{"NewCFBDecrypter", Func, 0, "func(block Block, iv []byte) Stream"},
+		{"NewCFBEncrypter", Func, 0, "func(block Block, iv []byte) Stream"},
+		{"NewCTR", Func, 0, "func(block Block, iv []byte) Stream"},
+		{"NewGCM", Func, 2, "func(cipher Block) (AEAD, error)"},
+		{"NewGCMWithNonceSize", Func, 5, "func(cipher Block, size int) (AEAD, error)"},
+		{"NewGCMWithRandomNonce", Func, 24, "func(cipher Block) (AEAD, error)"},
+		{"NewGCMWithTagSize", Func, 11, "func(cipher Block, tagSize int) (AEAD, error)"},
+		{"NewOFB", Func, 0, "func(b Block, iv []byte) Stream"},
+		{"Stream", Type, 0, ""},
+		{"StreamReader", Type, 0, ""},
+		{"StreamReader.R", Field, 0, ""},
+		{"StreamReader.S", Field, 0, ""},
+		{"StreamWriter", Type, 0, ""},
+		{"StreamWriter.Err", Field, 0, ""},
+		{"StreamWriter.S", Field, 0, ""},
+		{"StreamWriter.W", Field, 0, ""},
+	},
+	"crypto/des": {
+		{"(KeySizeError).Error", Method, 0, ""},
+		{"BlockSize", Const, 0, ""},
+		{"KeySizeError", Type, 0, ""},
+		{"NewCipher", Func, 0, "func(key []byte) (cipher.Block, error)"},
+		{"NewTripleDESCipher", Func, 0, "func(key []byte) (cipher.Block, error)"},
+	},
+	"crypto/dsa": {
+		{"ErrInvalidPublicKey", Var, 0, ""},
+		{"GenerateKey", Func, 0, "func(priv *PrivateKey, rand io.Reader) error"},
+		{"GenerateParameters", Func, 0, "func(params *Parameters, rand io.Reader, sizes ParameterSizes) error"},
+		{"L1024N160", Const, 0, ""},
+		{"L2048N224", Const, 0, ""},
+		{"L2048N256", Const, 0, ""},
+		{"L3072N256", Const, 0, ""},
+		{"ParameterSizes", Type, 0, ""},
+		{"Parameters", Type, 0, ""},
+		{"Parameters.G", Field, 0, ""},
+		{"Parameters.P", Field, 0, ""},
+		{"Parameters.Q", Field, 0, ""},
+		{"PrivateKey", Type, 0, ""},
+		{"PrivateKey.PublicKey", Field, 0, ""},
+		{"PrivateKey.X", Field, 0, ""},
+		{"PublicKey", Type, 0, ""},
+		{"PublicKey.Parameters", Field, 0, ""},
+		{"PublicKey.Y", Field, 0, ""},
+		{"Sign", Func, 0, "func(random io.Reader, priv *PrivateKey, hash []byte) (r *big.Int, s *big.Int, err error)"},
+		{"Verify", Func, 0, "func(pub *PublicKey, hash []byte, r *big.Int, s *big.Int) bool"},
+	},
+	"crypto/ecdh": {
+		{"(*PrivateKey).Bytes", Method, 20, ""},
+		{"(*PrivateKey).Curve", Method, 20, ""},
+		{"(*PrivateKey).ECDH", Method, 20, ""},
+		{"(*PrivateKey).Equal", Method, 20, ""},
+		{"(*PrivateKey).Public", Method, 20, ""},
+		{"(*PrivateKey).PublicKey", Method, 20, ""},
+		{"(*PublicKey).Bytes", Method, 20, ""},
+		{"(*PublicKey).Curve", Method, 20, ""},
+		{"(*PublicKey).Equal", Method, 20, ""},
+		{"(Curve).GenerateKey", Method, 20, ""},
+		{"(Curve).NewPrivateKey", Method, 20, ""},
+		{"(Curve).NewPublicKey", Method, 20, ""},
+		{"(KeyExchanger).Curve", Method, 26, ""},
+		{"(KeyExchanger).ECDH", Method, 26, ""},
+		{"(KeyExchanger).PublicKey", Method, 26, ""},
+		{"KeyExchanger", Type, 26, ""},
+		{"P256", Func, 20, "func() Curve"},
+		{"P384", Func, 20, "func() Curve"},
+		{"P521", Func, 20, "func() Curve"},
+		{"PrivateKey", Type, 20, ""},
+		{"PublicKey", Type, 20, ""},
+		{"X25519", Func, 20, "func() Curve"},
+	},
+	"crypto/ecdsa": {
+		{"(*PrivateKey).Bytes", Method, 25, ""},
+		{"(*PrivateKey).ECDH", Method, 20, ""},
+		{"(*PrivateKey).Equal", Method, 15, ""},
+		{"(*PrivateKey).Public", Method, 4, ""},
+		{"(*PrivateKey).Sign", Method, 4, ""},
+		{"(*PublicKey).Bytes", Method, 25, ""},
+		{"(*PublicKey).ECDH", Method, 20, ""},
+		{"(*PublicKey).Equal", Method, 15, ""},
+		{"(PrivateKey).Add", Method, 0, ""},
+		{"(PrivateKey).Double", Method, 0, ""},
+		{"(PrivateKey).IsOnCurve", Method, 0, ""},
+		{"(PrivateKey).Params", Method, 0, ""},
+		{"(PrivateKey).ScalarBaseMult", Method, 0, ""},
+		{"(PrivateKey).ScalarMult", Method, 0, ""},
+		{"(PublicKey).Add", Method, 0, ""},
+		{"(PublicKey).Double", Method, 0, ""},
+		{"(PublicKey).IsOnCurve", Method, 0, ""},
+		{"(PublicKey).Params", Method, 0, ""},
+		{"(PublicKey).ScalarBaseMult", Method, 0, ""},
+		{"(PublicKey).ScalarMult", Method, 0, ""},
+		{"GenerateKey", Func, 0, "func(c elliptic.Curve, r io.Reader) (*PrivateKey, error)"},
+		{"ParseRawPrivateKey", Func, 25, "func(curve elliptic.Curve, data []byte) (*PrivateKey, error)"},
+		{"ParseUncompressedPublicKey", Func, 25, "func(curve elliptic.Curve, data []byte) (*PublicKey, error)"},
+		{"PrivateKey", Type, 0, ""},
+		{"PrivateKey.D", Field, 0, ""},
+		{"PrivateKey.PublicKey", Field, 0, ""},
+		{"PublicKey", Type, 0, ""},
+		{"PublicKey.Curve", Field, 0, ""},
+		{"PublicKey.X", Field, 0, ""},
+		{"PublicKey.Y", Field, 0, ""},
+		{"Sign", Func, 0, "func(rand io.Reader, priv *PrivateKey, hash []byte) (r *big.Int, s *big.Int, err error)"},
+		{"SignASN1", Func, 15, "func(r io.Reader, priv *PrivateKey, hash []byte) ([]byte, error)"},
+		{"Verify", Func, 0, "func(pub *PublicKey, hash []byte, r *big.Int, s *big.Int) bool"},
+		{"VerifyASN1", Func, 15, "func(pub *PublicKey, hash []byte, sig []byte) bool"},
+	},
+	"crypto/ed25519": {
+		{"(*Options).HashFunc", Method, 20, ""},
+		{"(PrivateKey).Equal", Method, 15, ""},
+		{"(PrivateKey).Public", Method, 13, ""},
+		{"(PrivateKey).Seed", Method, 13, ""},
+		{"(PrivateKey).Sign", Method, 13, ""},
+		{"(PublicKey).Equal", Method, 15, ""},
+		{"GenerateKey", Func, 13, "func(random io.Reader) (PublicKey, PrivateKey, error)"},
+		{"NewKeyFromSeed", Func, 13, "func(seed []byte) PrivateKey"},
+		{"Options", Type, 20, ""},
+		{"Options.Context", Field, 20, ""},
+		{"Options.Hash", Field, 20, ""},
+		{"PrivateKey", Type, 13, ""},
+		{"PrivateKeySize", Const, 13, ""},
+		{"PublicKey", Type, 13, ""},
+		{"PublicKeySize", Const, 13, ""},
+		{"SeedSize", Const, 13, ""},
+		{"Sign", Func, 13, "func(privateKey PrivateKey, message []byte) []byte"},
+		{"SignatureSize", Const, 13, ""},
+		{"Verify", Func, 13, "func(publicKey PublicKey, message []byte, sig []byte) bool"},
+		{"VerifyWithOptions", Func, 20, "func(publicKey PublicKey, message []byte, sig []byte, opts *Options) error"},
+	},
+	"crypto/elliptic": {
+		{"(*CurveParams).Add", Method, 0, ""},
+		{"(*CurveParams).Double", Method, 0, ""},
+		{"(*CurveParams).IsOnCurve", Method, 0, ""},
+		{"(*CurveParams).Params", Method, 0, ""},
+		{"(*CurveParams).ScalarBaseMult", Method, 0, ""},
+		{"(*CurveParams).ScalarMult", Method, 0, ""},
+		{"(Curve).Add", Method, 0, ""},
+		{"(Curve).Double", Method, 0, ""},
+		{"(Curve).IsOnCurve", Method, 0, ""},
+		{"(Curve).Params", Method, 0, ""},
+		{"(Curve).ScalarBaseMult", Method, 0, ""},
+		{"(Curve).ScalarMult", Method, 0, ""},
+		{"Curve", Type, 0, ""},
+		{"CurveParams", Type, 0, ""},
+		{"CurveParams.B", Field, 0, ""},
+		{"CurveParams.BitSize", Field, 0, ""},
+		{"CurveParams.Gx", Field, 0, ""},
+		{"CurveParams.Gy", Field, 0, ""},
+		{"CurveParams.N", Field, 0, ""},
+		{"CurveParams.Name", Field, 5, ""},
+		{"CurveParams.P", Field, 0, ""},
+		{"GenerateKey", Func, 0, "func(curve Curve, rand io.Reader) (priv []byte, x *big.Int, y *big.Int, err error)"},
+		{"Marshal", Func, 0, "func(curve Curve, x *big.Int, y *big.Int) []byte"},
+		{"MarshalCompressed", Func, 15, "func(curve Curve, x *big.Int, y *big.Int) []byte"},
+		{"P224", Func, 0, "func() Curve"},
+		{"P256", Func, 0, "func() Curve"},
+		{"P384", Func, 0, "func() Curve"},
+		{"P521", Func, 0, "func() Curve"},
+		{"Unmarshal", Func, 0, "func(curve Curve, data []byte) (x *big.Int, y *big.Int)"},
+		{"UnmarshalCompressed", Func, 15, "func(curve Curve, data []byte) (x *big.Int, y *big.Int)"},
+	},
+	"crypto/fips140": {
+		{"Enabled", Func, 24, "func() bool"},
+		{"Enforced", Func, 26, "func() bool"},
+		{"Version", Func, 26, "func() string"},
+		{"WithoutEnforcement", Func, 26, "func(f func())"},
+	},
+	"crypto/hkdf": {
+		{"Expand", Func, 24, "func[H hash.Hash](h func() H, pseudorandomKey []byte, info string, keyLength int) ([]byte, error)"},
+		{"Extract", Func, 24, "func[H hash.Hash](h func() H, secret []byte, salt []byte) ([]byte, error)"},
+		{"Key", Func, 24, "func[Hash hash.Hash](h func() Hash, secret []byte, salt []byte, info string, keyLength int) ([]byte, error)"},
+	},
+	"crypto/hmac": {
+		{"Equal", Func, 1, "func(mac1 []byte, mac2 []byte) bool"},
+		{"New", Func, 0, "func(h func() hash.Hash, key []byte) hash.Hash"},
+	},
+	"crypto/hpke": {
+		{"(*Recipient).Export", Method, 26, ""},
+		{"(*Recipient).Open", Method, 26, ""},
+		{"(*Sender).Export", Method, 26, ""},
+		{"(*Sender).Seal", Method, 26, ""},
+		{"(AEAD).ID", Method, 26, ""},
+		{"(KDF).ID", Method, 26, ""},
+		{"(KEM).DeriveKeyPair", Method, 26, ""},
+		{"(KEM).GenerateKey", Method, 26, ""},
+		{"(KEM).ID", Method, 26, ""},
+		{"(KEM).NewPrivateKey", Method, 26, ""},
+		{"(KEM).NewPublicKey", Method, 26, ""},
+		{"(PrivateKey).Bytes", Method, 26, ""},
+		{"(PrivateKey).KEM", Method, 26, ""},
+		{"(PrivateKey).PublicKey", Method, 26, ""},
+		{"(PublicKey).Bytes", Method, 26, ""},
+		{"(PublicKey).KEM", Method, 26, ""},
+		{"AES128GCM", Func, 26, "func() AEAD"},
+		{"AES256GCM", Func, 26, "func() AEAD"},
+		{"ChaCha20Poly1305", Func, 26, "func() AEAD"},
+		{"DHKEM", Func, 26, "func(curve ecdh.Curve) KEM"},
+		{"ExportOnly", Func, 26, "func() AEAD"},
+		{"HKDFSHA256", Func, 26, "func() KDF"},
+		{"HKDFSHA384", Func, 26, "func() KDF"},
+		{"HKDFSHA512", Func, 26, "func() KDF"},
+		{"MLKEM1024", Func, 26, "func() KEM"},
+		{"MLKEM1024P384", Func, 26, "func() KEM"},
+		{"MLKEM768", Func, 26, "func() KEM"},
+		{"MLKEM768P256", Func, 26, "func() KEM"},
+		{"MLKEM768X25519", Func, 26, "func() KEM"},
+		{"NewAEAD", Func, 26, "func(id uint16) (AEAD, error)"},
+		{"NewDHKEMPrivateKey", Func, 26, "func(priv ecdh.KeyExchanger) (PrivateKey, error)"},
+		{"NewDHKEMPublicKey", Func, 26, "func(pub *ecdh.PublicKey) (PublicKey, error)"},
+		{"NewHybridPrivateKey", Func, 26, "func(pq crypto.Decapsulator, t ecdh.KeyExchanger) (PrivateKey, error)"},
+		{"NewHybridPublicKey", Func, 26, "func(pq crypto.Encapsulator, t *ecdh.PublicKey) (PublicKey, error)"},
+		{"NewKDF", Func, 26, "func(id uint16) (KDF, error)"},
+		{"NewKEM", Func, 26, "func(id uint16) (KEM, error)"},
+		{"NewMLKEMPrivateKey", Func, 26, "func(priv crypto.Decapsulator) (PrivateKey, error)"},
+		{"NewMLKEMPublicKey", Func, 26, "func(pub crypto.Encapsulator) (PublicKey, error)"},
+		{"NewRecipient", Func, 26, "func(enc []byte, k PrivateKey, kdf KDF, aead AEAD, info []byte) (*Recipient, error)"},
+		{"NewSender", Func, 26, "func(pk PublicKey, kdf KDF, aead AEAD, info []byte) (enc []byte, s *Sender, err error)"},
+		{"Open", Func, 26, "func(k PrivateKey, kdf KDF, aead AEAD, info []byte, ciphertext []byte) ([]byte, error)"},
+		{"Recipient", Type, 26, ""},
+		{"SHAKE128", Func, 26, "func() KDF"},
+		{"SHAKE256", Func, 26, "func() KDF"},
+		{"Seal", Func, 26, "func(pk PublicKey, kdf KDF, aead AEAD, info []byte, plaintext []byte) ([]byte, error)"},
+		{"Sender", Type, 26, ""},
+	},
+	"crypto/md5": {
+		{"BlockSize", Const, 0, ""},
+		{"New", Func, 0, "func() hash.Hash"},
+		{"Size", Const, 0, ""},
+		{"Sum", Func, 2, "func(data []byte) [16]byte"},
+	},
+	"crypto/mldsa": {
+		{"(*Options).HashFunc", Method, 27, ""},
+		{"(*PrivateKey).Bytes", Method, 27, ""},
+		{"(*PrivateKey).Equal", Method, 27, ""},
+		{"(*PrivateKey).Public", Method, 27, ""},
+		{"(*PrivateKey).PublicKey", Method, 27, ""},
+		{"(*PrivateKey).Sign", Method, 27, ""},
+		{"(*PrivateKey).SignDeterministic", Method, 27, ""},
+		{"(*PublicKey).Bytes", Method, 27, ""},
+		{"(*PublicKey).Equal", Method, 27, ""},
+		{"(*PublicKey).Parameters", Method, 27, ""},
+		{"(Parameters).PublicKeySize", Method, 27, ""},
+		{"(Parameters).SignatureSize", Method, 27, ""},
+		{"(Parameters).String", Method, 27, ""},
+		{"GenerateKey", Func, 27, "func(params Parameters) (*PrivateKey, error)"},
+		{"MLDSA44", Func, 27, "func() Parameters"},
+		{"MLDSA44PublicKeySize", Const, 27, ""},
+		{"MLDSA44SignatureSize", Const, 27, ""},
+		{"MLDSA65", Func, 27, "func() Parameters"},
+		{"MLDSA65PublicKeySize", Const, 27, ""},
+		{"MLDSA65SignatureSize", Const, 27, ""},
+		{"MLDSA87", Func, 27, "func() Parameters"},
+		{"MLDSA87PublicKeySize", Const, 27, ""},
+		{"MLDSA87SignatureSize", Const, 27, ""},
+		{"NewPrivateKey", Func, 27, "func(params Parameters, seed []byte) (*PrivateKey, error)"},
+		{"NewPublicKey", Func, 27, "func(params Parameters, encoding []byte) (*PublicKey, error)"},
+		{"Options", Type, 27, ""},
+		{"Options.Context", Field, 27, ""},
+		{"Parameters", Type, 27, ""},
+		{"PrivateKey", Type, 27, ""},
+		{"PrivateKeySize", Const, 27, ""},
+		{"PublicKey", Type, 27, ""},
+		{"Verify", Func, 27, "func(pk *PublicKey, message []byte, signature []byte, opts *Options) error"},
+	},
+	"crypto/mlkem": {
+		{"(*DecapsulationKey1024).Bytes", Method, 24, ""},
+		{"(*DecapsulationKey1024).Decapsulate", Method, 24, ""},
+		{"(*DecapsulationKey1024).EncapsulationKey", Method, 24, ""},
+		{"(*DecapsulationKey1024).Encapsulator", Method, 26, ""},
+		{"(*DecapsulationKey768).Bytes", Method, 24, ""},
+		{"(*DecapsulationKey768).Decapsulate", Method, 24, ""},
+		{"(*DecapsulationKey768).EncapsulationKey", Method, 24, ""},
+		{"(*DecapsulationKey768).Encapsulator", Method, 26, ""},
+		{"(*EncapsulationKey1024).Bytes", Method, 24, ""},
+		{"(*EncapsulationKey1024).Encapsulate", Method, 24, ""},
+		{"(*EncapsulationKey768).Bytes", Method, 24, ""},
+		{"(*EncapsulationKey768).Encapsulate", Method, 24, ""},
+		{"CiphertextSize1024", Const, 24, ""},
+		{"CiphertextSize768", Const, 24, ""},
+		{"DecapsulationKey1024", Type, 24, ""},
+		{"DecapsulationKey768", Type, 24, ""},
+		{"EncapsulationKey1024", Type, 24, ""},
+		{"EncapsulationKey768", Type, 24, ""},
+		{"EncapsulationKeySize1024", Const, 24, ""},
+		{"EncapsulationKeySize768", Const, 24, ""},
+		{"GenerateKey1024", Func, 24, "func() (*DecapsulationKey1024, error)"},
+		{"GenerateKey768", Func, 24, "func() (*DecapsulationKey768, error)"},
+		{"NewDecapsulationKey1024", Func, 24, "func(seed []byte) (*DecapsulationKey1024, error)"},
+		{"NewDecapsulationKey768", Func, 24, "func(seed []byte) (*DecapsulationKey768, error)"},
+		{"NewEncapsulationKey1024", Func, 24, "func(encapsulationKey []byte) (*EncapsulationKey1024, error)"},
+		{"NewEncapsulationKey768", Func, 24, "func(encapsulationKey []byte) (*EncapsulationKey768, error)"},
+		{"SeedSize", Const, 24, ""},
+		{"SharedKeySize", Const, 24, ""},
+	},
+	"crypto/mlkem/mlkemtest": {
+		{"Encapsulate1024", Func, 26, "func(ek *mlkem.EncapsulationKey1024, random []byte) (sharedKey []byte, ciphertext []byte, err error)"},
+		{"Encapsulate768", Func, 26, "func(ek *mlkem.EncapsulationKey768, random []byte) (sharedKey []byte, ciphertext []byte, err error)"},
+	},
+	"crypto/pbkdf2": {
+		{"Key", Func, 24, "func[Hash hash.Hash](h func() Hash, password string, salt []byte, iter int, keyLength int) ([]byte, error)"},
+	},
+	"crypto/rand": {
+		{"Int", Func, 0, "func(rand io.Reader, max *big.Int) (n *big.Int, err error)"},
+		{"Prime", Func, 0, "func(r io.Reader, bits int) (*big.Int, error)"},
+		{"Read", Func, 0, "func(b []byte) (n int, err error)"},
+		{"Reader", Var, 0, ""},
+		{"Text", Func, 24, "func() string"},
+	},
+	"crypto/rc4": {
+		{"(*Cipher).Reset", Method, 0, ""},
+		{"(*Cipher).XORKeyStream", Method, 0, ""},
+		{"(KeySizeError).Error", Method, 0, ""},
+		{"Cipher", Type, 0, ""},
+		{"KeySizeError", Type, 0, ""},
+		{"NewCipher", Func, 0, "func(key []byte) (*Cipher, error)"},
+	},
+	"crypto/rsa": {
+		{"(*PSSOptions).HashFunc", Method, 4, ""},
+		{"(*PrivateKey).Decrypt", Method, 5, ""},
+		{"(*PrivateKey).Equal", Method, 15, ""},
+		{"(*PrivateKey).Precompute", Method, 0, ""},
+		{"(*PrivateKey).Public", Method, 4, ""},
+		{"(*PrivateKey).Sign", Method, 4, ""},
+		{"(*PrivateKey).Size", Method, 11, ""},
+		{"(*PrivateKey).Validate", Method, 0, ""},
+		{"(*PublicKey).Equal", Method, 15, ""},
+		{"(*PublicKey).Size", Method, 11, ""},
+		{"CRTValue", Type, 0, ""},
+		{"CRTValue.Coeff", Field, 0, ""},
+		{"CRTValue.Exp", Field, 0, ""},
+		{"CRTValue.R", Field, 0, ""},
+		{"DecryptOAEP", Func, 0, "func(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error)"},
+		{"DecryptPKCS1v15", Func, 0, "func(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error)"},
+		{"DecryptPKCS1v15SessionKey", Func, 0, "func(random io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error"},
+		{"EncryptOAEP", Func, 0, "func(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error)"},
+		{"EncryptOAEPWithOptions", Func, 26, "func(random io.Reader, pub *PublicKey, msg []byte, opts *OAEPOptions) ([]byte, error)"},
+		{"EncryptPKCS1v15", Func, 0, "func(random io.Reader, pub *PublicKey, msg []byte) ([]byte, error)"},
+		{"ErrDecryption", Var, 0, ""},
+		{"ErrMessageTooLong", Var, 0, ""},
+		{"ErrVerification", Var, 0, ""},
+		{"GenerateKey", Func, 0, "func(random io.Reader, bits int) (*PrivateKey, error)"},
+		{"GenerateMultiPrimeKey", Func, 0, "func(random io.Reader, nprimes int, bits int) (*PrivateKey, error)"},
+		{"OAEPOptions", Type, 5, ""},
+		{"OAEPOptions.Hash", Field, 5, ""},
+		{"OAEPOptions.Label", Field, 5, ""},
+		{"OAEPOptions.MGFHash", Field, 20, ""},
+		{"PKCS1v15DecryptOptions", Type, 5, ""},
+		{"PKCS1v15DecryptOptions.SessionKeyLen", Field, 5, ""},
+		{"PSSOptions", Type, 2, ""},
+		{"PSSOptions.Hash", Field, 4, ""},
+		{"PSSOptions.SaltLength", Field, 2, ""},
+		{"PSSSaltLengthAuto", Const, 2, ""},
+		{"PSSSaltLengthEqualsHash", Const, 2, ""},
+		{"PrecomputedValues", Type, 0, ""},
+		{"PrecomputedValues.CRTValues", Field, 0, ""},
+		{"PrecomputedValues.Dp", Field, 0, ""},
+		{"PrecomputedValues.Dq", Field, 0, ""},
+		{"PrecomputedValues.Qinv", Field, 0, ""},
+		{"PrivateKey", Type, 0, ""},
+		{"PrivateKey.D", Field, 0, ""},
+		{"PrivateKey.Precomputed", Field, 0, ""},
+		{"PrivateKey.Primes", Field, 0, ""},
+		{"PrivateKey.PublicKey", Field, 0, ""},
+		{"PublicKey", Type, 0, ""},
+		{"PublicKey.E", Field, 0, ""},
+		{"PublicKey.N", Field, 0, ""},
+		{"SignPKCS1v15", Func, 0, "func(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error)"},
+		{"SignPSS", Func, 2, "func(random io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error)"},
+		{"VerifyPKCS1v15", Func, 0, "func(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error"},
+		{"VerifyPSS", Func, 2, "func(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error"},
+	},
+	"crypto/sha1": {
+		{"BlockSize", Const, 0, ""},
+		{"New", Func, 0, "func() hash.Hash"},
+		{"Size", Const, 0, ""},
+		{"Sum", Func, 2, "func(data []byte) [20]byte"},
+	},
+	"crypto/sha256": {
+		{"BlockSize", Const, 0, ""},
+		{"New", Func, 0, "func() hash.Hash"},
+		{"New224", Func, 0, "func() hash.Hash"},
+		{"Size", Const, 0, ""},
+		{"Size224", Const, 0, ""},
+		{"Sum224", Func, 2, "func(data []byte) [28]byte"},
+		{"Sum256", Func, 2, "func(data []byte) [32]byte"},
+	},
+	"crypto/sha3": {
+		{"(*SHA3).AppendBinary", Method, 24, ""},
+		{"(*SHA3).BlockSize", Method, 24, ""},
+		{"(*SHA3).Clone", Method, 25, ""},
+		{"(*SHA3).MarshalBinary", Method, 24, ""},
+		{"(*SHA3).Reset", Method, 24, ""},
+		{"(*SHA3).Size", Method, 24, ""},
+		{"(*SHA3).Sum", Method, 24, ""},
+		{"(*SHA3).UnmarshalBinary", Method, 24, ""},
+		{"(*SHA3).Write", Method, 24, ""},
+		{"(*SHAKE).AppendBinary", Method, 24, ""},
+		{"(*SHAKE).BlockSize", Method, 24, ""},
+		{"(*SHAKE).MarshalBinary", Method, 24, ""},
+		{"(*SHAKE).Read", Method, 24, ""},
+		{"(*SHAKE).Reset", Method, 24, ""},
+		{"(*SHAKE).UnmarshalBinary", Method, 24, ""},
+		{"(*SHAKE).Write", Method, 24, ""},
+		{"New224", Func, 24, "func() *SHA3"},
+		{"New256", Func, 24, "func() *SHA3"},
+		{"New384", Func, 24, "func() *SHA3"},
+		{"New512", Func, 24, "func() *SHA3"},
+		{"NewCSHAKE128", Func, 24, "func(N []byte, S []byte) *SHAKE"},
+		{"NewCSHAKE256", Func, 24, "func(N []byte, S []byte) *SHAKE"},
+		{"NewSHAKE128", Func, 24, "func() *SHAKE"},
+		{"NewSHAKE256", Func, 24, "func() *SHAKE"},
+		{"SHA3", Type, 24, ""},
+		{"SHAKE", Type, 24, ""},
+		{"Sum224", Func, 24, "func(data []byte) [28]byte"},
+		{"Sum256", Func, 24, "func(data []byte) [32]byte"},
+		{"Sum384", Func, 24, "func(data []byte) [48]byte"},
+		{"Sum512", Func, 24, "func(data []byte) [64]byte"},
+		{"SumSHAKE128", Func, 24, "func(data []byte, length int) []byte"},
+		{"SumSHAKE256", Func, 24, "func(data []byte, length int) []byte"},
+	},
+	"crypto/sha512": {
+		{"BlockSize", Const, 0, ""},
+		{"New", Func, 0, "func() hash.Hash"},
+		{"New384", Func, 0, "func() hash.Hash"},
+		{"New512_224", Func, 5, "func() hash.Hash"},
+		{"New512_256", Func, 5, "func() hash.Hash"},
+		{"Size", Const, 0, ""},
+		{"Size224", Const, 5, ""},
+		{"Size256", Const, 5, ""},
+		{"Size384", Const, 0, ""},
+		{"Sum384", Func, 2, "func(data []byte) [48]byte"},
+		{"Sum512", Func, 2, "func(data []byte) [64]byte"},
+		{"Sum512_224", Func, 5, "func(data []byte) [28]byte"},
+		{"Sum512_256", Func, 5, "func(data []byte) [32]byte"},
+	},
+	"crypto/subtle": {
+		{"ConstantTimeByteEq", Func, 0, "func(x uint8, y uint8) int"},
+		{"ConstantTimeCompare", Func, 0, "func(x []byte, y []byte) int"},
+		{"ConstantTimeCopy", Func, 0, "func(v int, x []byte, y []byte)"},
+		{"ConstantTimeEq", Func, 0, "func(x int32, y int32) int"},
+		{"ConstantTimeLessOrEq", Func, 2, "func(x int, y int) int"},
+		{"ConstantTimeSelect", Func, 0, "func(v int, x int, y int) int"},
+		{"WithDataIndependentTiming", Func, 24, "func(f func())"},
+		{"XORBytes", Func, 20, "func(dst []byte, x []byte, y []byte) int"},
+	},
+	"crypto/tls": {
+		{"(*CertificateRequestInfo).Context", Method, 17, ""},
+		{"(*CertificateRequestInfo).SupportsCertificate", Method, 14, ""},
+		{"(*CertificateVerificationError).Error", Method, 20, ""},
+		{"(*CertificateVerificationError).Unwrap", Method, 20, ""},
+		{"(*ClientHelloInfo).Context", Method, 17, ""},
+		{"(*ClientHelloInfo).SupportsCertificate", Method, 14, ""},
+		{"(*ClientSessionState).ResumptionState", Method, 21, ""},
+		{"(*Config).BuildNameToCertificate", Method, 0, ""},
+		{"(*Config).Clone", Method, 8, ""},
+		{"(*Config).DecryptTicket", Method, 21, ""},
+		{"(*Config).EncryptTicket", Method, 21, ""},
+		{"(*Config).SetSessionTicketKeys", Method, 5, ""},
+		{"(*Conn).Close", Method, 0, ""},
+		{"(*Conn).CloseWrite", Method, 8, ""},
+		{"(*Conn).ConnectionState", Method, 0, ""},
+		{"(*Conn).Handshake", Method, 0, ""},
+		{"(*Conn).HandshakeContext", Method, 17, ""},
+		{"(*Conn).LocalAddr", Method, 0, ""},
+		{"(*Conn).NetConn", Method, 18, ""},
+		{"(*Conn).OCSPResponse", Method, 0, ""},
+		{"(*Conn).Read", Method, 0, ""},
+		{"(*Conn).RemoteAddr", Method, 0, ""},
+		{"(*Conn).SetDeadline", Method, 0, ""},
+		{"(*Conn).SetReadDeadline", Method, 0, ""},
+		{"(*Conn).SetWriteDeadline", Method, 0, ""},
+		{"(*Conn).VerifyHostname", Method, 0, ""},
+		{"(*Conn).Write", Method, 0, ""},
+		{"(*ConnectionState).ExportKeyingMaterial", Method, 11, ""},
+		{"(*Dialer).Dial", Method, 15, ""},
+		{"(*Dialer).DialContext", Method, 15, ""},
+		{"(*ECHRejectionError).Error", Method, 23, ""},
+		{"(*QUICConn).Close", Method, 21, ""},
+		{"(*QUICConn).ConnectionState", Method, 21, ""},
+		{"(*QUICConn).HandleData", Method, 21, ""},
+		{"(*QUICConn).NextEvent", Method, 21, ""},
+		{"(*QUICConn).SendSessionTicket", Method, 21, ""},
+		{"(*QUICConn).SetTransportParameters", Method, 21, ""},
+		{"(*QUICConn).Start", Method, 21, ""},
+		{"(*QUICConn).StoreSession", Method, 23, ""},
+		{"(*SessionState).Bytes", Method, 21, ""},
+		{"(AlertError).Error", Method, 21, ""},
+		{"(ClientAuthType).String", Method, 15, ""},
+		{"(ClientSessionCache).Get", Method, 3, ""},
+		{"(ClientSessionCache).Put", Method, 3, ""},
+		{"(CurveID).String", Method, 15, ""},
+		{"(QUICEncryptionLevel).String", Method, 21, ""},
+		{"(RecordHeaderError).Error", Method, 6, ""},
+		{"(SignatureScheme).String", Method, 15, ""},
+		{"AlertError", Type, 21, ""},
+		{"Certificate", Type, 0, ""},
+		{"Certificate.Certificate", Field, 0, ""},
+		{"Certificate.Leaf", Field, 0, ""},
+		{"Certificate.OCSPStaple", Field, 0, ""},
+		{"Certificate.PrivateKey", Field, 0, ""},
+		{"Certificate.SignedCertificateTimestamps", Field, 5, ""},
+		{"Certificate.SupportedSignatureAlgorithms", Field, 14, ""},
+		{"CertificateRequestInfo", Type, 8, ""},
+		{"CertificateRequestInfo.AcceptableCAs", Field, 8, ""},
+		{"CertificateRequestInfo.SignatureSchemes", Field, 8, ""},
+		{"CertificateRequestInfo.Version", Field, 14, ""},
+		{"CertificateVerificationError", Type, 20, ""},
+		{"CertificateVerificationError.Err", Field, 20, ""},
+		{"CertificateVerificationError.UnverifiedCertificates", Field, 20, ""},
+		{"CipherSuite", Type, 14, ""},
+		{"CipherSuite.ID", Field, 14, ""},
+		{"CipherSuite.Insecure", Field, 14, ""},
+		{"CipherSuite.Name", Field, 14, ""},
+		{"CipherSuite.SupportedVersions", Field, 14, ""},
+		{"CipherSuiteName", Func, 14, "func(id uint16) string"},
+		{"CipherSuites", Func, 14, "func() []*CipherSuite"},
+		{"Client", Func, 0, "func(conn net.Conn, config *Config) *Conn"},
+		{"ClientAuthType", Type, 0, ""},
+		{"ClientHelloInfo", Type, 4, ""},
+		{"ClientHelloInfo.CipherSuites", Field, 4, ""},
+		{"ClientHelloInfo.Conn", Field, 8, ""},
+		{"ClientHelloInfo.Extensions", Field, 24, ""},
+		{"ClientHelloInfo.HelloRetryRequest", Field, 26, ""},
+		{"ClientHelloInfo.ServerName", Field, 4, ""},
+		{"ClientHelloInfo.SignatureSchemes", Field, 8, ""},
+		{"ClientHelloInfo.SupportedCurves", Field, 4, ""},
+		{"ClientHelloInfo.SupportedPoints", Field, 4, ""},
+		{"ClientHelloInfo.SupportedProtos", Field, 8, ""},
+		{"ClientHelloInfo.SupportedVersions", Field, 8, ""},
+		{"ClientSessionCache", Type, 3, ""},
+		{"ClientSessionState", Type, 3, ""},
+		{"Config", Type, 0, ""},
+		{"Config.Certificates", Field, 0, ""},
+		{"Config.CipherSuites", Field, 0, ""},
+		{"Config.ClientAuth", Field, 0, ""},
+		{"Config.ClientCAs", Field, 0, ""},
+		{"Config.ClientSessionCache", Field, 3, ""},
+		{"Config.CurvePreferences", Field, 3, ""},
+		{"Config.DynamicRecordSizingDisabled", Field, 7, ""},
+		{"Config.EncryptedClientHelloConfigList", Field, 23, ""},
+		{"Config.EncryptedClientHelloKeys", Field, 24, ""},
+		{"Config.EncryptedClientHelloRejectionVerify", Field, 23, ""},
+		{"Config.GetCertificate", Field, 4, ""},
+		{"Config.GetClientCertificate", Field, 8, ""},
+		{"Config.GetConfigForClient", Field, 8, ""},
+		{"Config.GetEncryptedClientHelloKeys", Field, 25, ""},
+		{"Config.InsecureSkipVerify", Field, 0, ""},
+		{"Config.KeyLogWriter", Field, 8, ""},
+		{"Config.MaxVersion", Field, 2, ""},
+		{"Config.MinVersion", Field, 2, ""},
+		{"Config.NameToCertificate", Field, 0, ""},
+		{"Config.NextProtos", Field, 0, ""},
+		{"Config.PreferServerCipherSuites", Field, 1, ""},
+		{"Config.Rand", Field, 0, ""},
+		{"Config.Renegotiation", Field, 7, ""},
+		{"Config.RootCAs", Field, 0, ""},
+		{"Config.ServerName", Field, 0, ""},
+		{"Config.SessionTicketKey", Field, 1, ""},
+		{"Config.SessionTicketsDisabled", Field, 1, ""},
+		{"Config.Time", Field, 0, ""},
+		{"Config.UnwrapSession", Field, 21, ""},
+		{"Config.VerifyConnection", Field, 15, ""},
+		{"Config.VerifyPeerCertificate", Field, 8, ""},
+		{"Config.WrapSession", Field, 21, ""},
+		{"Conn", Type, 0, ""},
+		{"ConnectionState", Type, 0, ""},
+		{"ConnectionState.CipherSuite", Field, 0, ""},
+		{"ConnectionState.CurveID", Field, 25, ""},
+		{"ConnectionState.DidResume", Field, 1, ""},
+		{"ConnectionState.ECHAccepted", Field, 23, ""},
+		{"ConnectionState.HandshakeComplete", Field, 0, ""},
+		{"ConnectionState.HelloRetryRequest", Field, 26, ""},
+		{"ConnectionState.LocalCertificate", Field, 27, ""},
+		{"ConnectionState.NegotiatedProtocol", Field, 0, ""},
+		{"ConnectionState.NegotiatedProtocolIsMutual", Field, 0, ""},
+		{"ConnectionState.OCSPResponse", Field, 5, ""},
+		{"ConnectionState.PeerCertificates", Field, 0, ""},
+		{"ConnectionState.ServerName", Field, 0, ""},
+		{"ConnectionState.SignedCertificateTimestamps", Field, 5, ""},
+		{"ConnectionState.TLSUnique", Field, 4, ""},
+		{"ConnectionState.VerifiedChains", Field, 0, ""},
+		{"ConnectionState.Version", Field, 3, ""},
+		{"CurveID", Type, 3, ""},
+		{"CurveP256", Const, 3, ""},
+		{"CurveP384", Const, 3, ""},
+		{"CurveP521", Const, 3, ""},
+		{"Dial", Func, 0, "func(network string, addr string, config *Config) (*Conn, error)"},
+		{"DialWithDialer", Func, 3, "func(dialer *net.Dialer, network string, addr string, config *Config) (*Conn, error)"},
+		{"Dialer", Type, 15, ""},
+		{"Dialer.Config", Field, 15, ""},
+		{"Dialer.NetDialer", Field, 15, ""},
+		{"ECDSAWithP256AndSHA256", Const, 8, ""},
+		{"ECDSAWithP384AndSHA384", Const, 8, ""},
+		{"ECDSAWithP521AndSHA512", Const, 8, ""},
+		{"ECDSAWithSHA1", Const, 10, ""},
+		{"ECHRejectionError", Type, 23, ""},
+		{"ECHRejectionError.RetryConfigList", Field, 23, ""},
+		{"Ed25519", Const, 13, ""},
+		{"EncryptedClientHelloKey", Type, 24, ""},
+		{"EncryptedClientHelloKey.Config", Field, 24, ""},
+		{"EncryptedClientHelloKey.PrivateKey", Field, 24, ""},
+		{"EncryptedClientHelloKey.SendAsRetry", Field, 24, ""},
+		{"InsecureCipherSuites", Func, 14, "func() []*CipherSuite"},
+		{"Listen", Func, 0, "func(network string, laddr string, config *Config) (net.Listener, error)"},
+		{"LoadX509KeyPair", Func, 0, "func(certFile string, keyFile string) (Certificate, error)"},
+		{"MLDSA44", Const, 27, ""},
+		{"MLDSA65", Const, 27, ""},
+		{"MLDSA87", Const, 27, ""},
+		{"MLKEM1024", Const, 27, ""},
+		{"NewLRUClientSessionCache", Func, 3, "func(capacity int) ClientSessionCache"},
+		{"NewListener", Func, 0, "func(inner net.Listener, config *Config) net.Listener"},
+		{"NewResumptionState", Func, 21, "func(ticket []byte, state *SessionState) (*ClientSessionState, error)"},
+		{"NoClientCert", Const, 0, ""},
+		{"PKCS1WithSHA1", Const, 8, ""},
+		{"PKCS1WithSHA256", Const, 8, ""},
+		{"PKCS1WithSHA384", Const, 8, ""},
+		{"PKCS1WithSHA512", Const, 8, ""},
+		{"PSSWithSHA256", Const, 8, ""},
+		{"PSSWithSHA384", Const, 8, ""},
+		{"PSSWithSHA512", Const, 8, ""},
+		{"ParseSessionState", Func, 21, "func(data []byte) (*SessionState, error)"},
+		{"QUICClient", Func, 21, "func(config *QUICConfig) *QUICConn"},
+		{"QUICConfig", Type, 21, ""},
+		{"QUICConfig.ClientHelloInfoConn", Field, 27, ""},
+		{"QUICConfig.EnableSessionEvents", Field, 23, ""},
+		{"QUICConfig.TLSConfig", Field, 21, ""},
+		{"QUICConn", Type, 21, ""},
+		{"QUICEncryptionLevel", Type, 21, ""},
+		{"QUICEncryptionLevelApplication", Const, 21, ""},
+		{"QUICEncryptionLevelEarly", Const, 21, ""},
+		{"QUICEncryptionLevelHandshake", Const, 21, ""},
+		{"QUICEncryptionLevelInitial", Const, 21, ""},
+		{"QUICErrorEvent", Const, 26, ""},
+		{"QUICEvent", Type, 21, ""},
+		{"QUICEvent.Data", Field, 21, ""},
+		{"QUICEvent.Err", Field, 26, ""},
+		{"QUICEvent.Kind", Field, 21, ""},
+		{"QUICEvent.Level", Field, 21, ""},
+		{"QUICEvent.SessionState", Field, 23, ""},
+		{"QUICEvent.Suite", Field, 21, ""},
+		{"QUICEventKind", Type, 21, ""},
+		{"QUICHandshakeDone", Const, 21, ""},
+		{"QUICNoEvent", Const, 21, ""},
+		{"QUICRejectedEarlyData", Const, 21, ""},
+		{"QUICResumeSession", Const, 23, ""},
+		{"QUICServer", Func, 21, "func(config *QUICConfig) *QUICConn"},
+		{"QUICSessionTicketOptions", Type, 21, ""},
+		{"QUICSessionTicketOptions.EarlyData", Field, 21, ""},
+		{"QUICSessionTicketOptions.Extra", Field, 23, ""},
+		{"QUICSetReadSecret", Const, 21, ""},
+		{"QUICSetWriteSecret", Const, 21, ""},
+		{"QUICStoreSession", Const, 23, ""},
+		{"QUICTransportParameters", Const, 21, ""},
+		{"QUICTransportParametersRequired", Const, 21, ""},
+		{"QUICWriteData", Const, 21, ""},
+		{"RecordHeaderError", Type, 6, ""},
+		{"RecordHeaderError.Conn", Field, 12, ""},
+		{"RecordHeaderError.Msg", Field, 6, ""},
+		{"RecordHeaderError.RecordHeader", Field, 6, ""},
+		{"RenegotiateFreelyAsClient", Const, 7, ""},
+		{"RenegotiateNever", Const, 7, ""},
+		{"RenegotiateOnceAsClient", Const, 7, ""},
+		{"RenegotiationSupport", Type, 7, ""},
+		{"RequestClientCert", Const, 0, ""},
+		{"RequireAndVerifyClientCert", Const, 0, ""},
+		{"RequireAnyClientCert", Const, 0, ""},
+		{"SecP256r1MLKEM768", Const, 26, ""},
+		{"SecP384r1MLKEM1024", Const, 26, ""},
+		{"Server", Func, 0, "func(conn net.Conn, config *Config) *Conn"},
+		{"SessionState", Type, 21, ""},
+		{"SessionState.EarlyData", Field, 21, ""},
+		{"SessionState.Extra", Field, 21, ""},
+		{"SignatureScheme", Type, 8, ""},
+		{"TLS_AES_128_GCM_SHA256", Const, 12, ""},
+		{"TLS_AES_256_GCM_SHA384", Const, 12, ""},
+		{"TLS_CHACHA20_POLY1305_SHA256", Const, 12, ""},
+		{"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", Const, 2, ""},
+		{"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", Const, 8, ""},
+		{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", Const, 2, ""},
+		{"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", Const, 2, ""},
+		{"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", Const, 5, ""},
+		{"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", Const, 8, ""},
+		{"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14, ""},
+		{"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", Const, 2, ""},
+		{"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0, ""},
+		{"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", Const, 0, ""},
+		{"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", Const, 8, ""},
+		{"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", Const, 2, ""},
+		{"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", Const, 1, ""},
+		{"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", Const, 5, ""},
+		{"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", Const, 8, ""},
+		{"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14, ""},
+		{"TLS_ECDHE_RSA_WITH_RC4_128_SHA", Const, 0, ""},
+		{"TLS_FALLBACK_SCSV", Const, 4, ""},
+		{"TLS_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0, ""},
+		{"TLS_RSA_WITH_AES_128_CBC_SHA", Const, 0, ""},
+		{"TLS_RSA_WITH_AES_128_CBC_SHA256", Const, 8, ""},
+		{"TLS_RSA_WITH_AES_128_GCM_SHA256", Const, 6, ""},
+		{"TLS_RSA_WITH_AES_256_CBC_SHA", Const, 1, ""},
+		{"TLS_RSA_WITH_AES_256_GCM_SHA384", Const, 6, ""},
+		{"TLS_RSA_WITH_RC4_128_SHA", Const, 0, ""},
+		{"VerifyClientCertIfGiven", Const, 0, ""},
+		{"VersionName", Func, 21, "func(version uint16) string"},
+		{"VersionSSL30", Const, 2, ""},
+		{"VersionTLS10", Const, 2, ""},
+		{"VersionTLS11", Const, 2, ""},
+		{"VersionTLS12", Const, 2, ""},
+		{"VersionTLS13", Const, 12, ""},
+		{"X25519", Const, 8, ""},
+		{"X25519MLKEM768", Const, 24, ""},
+		{"X509KeyPair", Func, 0, "func(certPEMBlock []byte, keyPEMBlock []byte) (Certificate, error)"},
+	},
+	"crypto/x509": {
+		{"(*CertPool).AddCert", Method, 0, ""},
+		{"(*CertPool).AddCertWithConstraint", Method, 22, ""},
+		{"(*CertPool).AppendCertsFromPEM", Method, 0, ""},
+		{"(*CertPool).Clone", Method, 19, ""},
+		{"(*CertPool).Equal", Method, 19, ""},
+		{"(*CertPool).Subjects", Method, 0, ""},
+		{"(*Certificate).CheckCRLSignature", Method, 0, ""},
+		{"(*Certificate).CheckSignature", Method, 0, ""},
+		{"(*Certificate).CheckSignatureFrom", Method, 0, ""},
+		{"(*Certificate).CreateCRL", Method, 0, ""},
+		{"(*Certificate).Equal", Method, 0, ""},
+		{"(*Certificate).Verify", Method, 0, ""},
+		{"(*Certificate).VerifyHostname", Method, 0, ""},
+		{"(*CertificateRequest).CheckSignature", Method, 5, ""},
+		{"(*OID).UnmarshalBinary", Method, 23, ""},
+		{"(*OID).UnmarshalText", Method, 23, ""},
+		{"(*RevocationList).CheckSignatureFrom", Method, 19, ""},
+		{"(CertificateInvalidError).Error", Method, 0, ""},
+		{"(ConstraintViolationError).Error", Method, 0, ""},
+		{"(ExtKeyUsage).OID", Method, 26, ""},
+		{"(ExtKeyUsage).String", Method, 26, ""},
+		{"(HostnameError).Error", Method, 0, ""},
+		{"(InsecureAlgorithmError).Error", Method, 6, ""},
+		{"(KeyUsage).String", Method, 26, ""},
+		{"(OID).AppendBinary", Method, 24, ""},
+		{"(OID).AppendText", Method, 24, ""},
+		{"(OID).Equal", Method, 22, ""},
+		{"(OID).EqualASN1OID", Method, 22, ""},
+		{"(OID).MarshalBinary", Method, 23, ""},
+		{"(OID).MarshalText", Method, 23, ""},
+		{"(OID).String", Method, 22, ""},
+		{"(PublicKeyAlgorithm).String", Method, 10, ""},
+		{"(SignatureAlgorithm).String", Method, 6, ""},
+		{"(SystemRootsError).Error", Method, 1, ""},
+		{"(SystemRootsError).Unwrap", Method, 16, ""},
+		{"(UnhandledCriticalExtension).Error", Method, 0, ""},
+		{"(UnknownAuthorityError).Error", Method, 0, ""},
+		{"CANotAuthorizedForExtKeyUsage", Const, 10, ""},
+		{"CANotAuthorizedForThisName", Const, 0, ""},
+		{"CertPool", Type, 0, ""},
+		{"Certificate", Type, 0, ""},
+		{"Certificate.AuthorityKeyId", Field, 0, ""},
+		{"Certificate.BasicConstraintsValid", Field, 0, ""},
+		{"Certificate.CRLDistributionPoints", Field, 2, ""},
+		{"Certificate.DNSNames", Field, 0, ""},
+		{"Certificate.EmailAddresses", Field, 0, ""},
+		{"Certificate.ExcludedDNSDomains", Field, 9, ""},
+		{"Certificate.ExcludedEmailAddresses", Field, 10, ""},
+		{"Certificate.ExcludedIPRanges", Field, 10, ""},
+		{"Certificate.ExcludedURIDomains", Field, 10, ""},
+		{"Certificate.ExtKeyUsage", Field, 0, ""},
+		{"Certificate.Extensions", Field, 2, ""},
+		{"Certificate.ExtraExtensions", Field, 2, ""},
+		{"Certificate.IPAddresses", Field, 1, ""},
+		{"Certificate.InhibitAnyPolicy", Field, 24, ""},
+		{"Certificate.InhibitAnyPolicyZero", Field, 24, ""},
+		{"Certificate.InhibitPolicyMapping", Field, 24, ""},
+		{"Certificate.InhibitPolicyMappingZero", Field, 24, ""},
+		{"Certificate.IsCA", Field, 0, ""},
+		{"Certificate.Issuer", Field, 0, ""},
+		{"Certificate.IssuingCertificateURL", Field, 2, ""},
+		{"Certificate.KeyUsage", Field, 0, ""},
+		{"Certificate.MaxPathLen", Field, 0, ""},
+		{"Certificate.MaxPathLenZero", Field, 4, ""},
+		{"Certificate.NotAfter", Field, 0, ""},
+		{"Certificate.NotBefore", Field, 0, ""},
+		{"Certificate.OCSPServer", Field, 2, ""},
+		{"Certificate.PermittedDNSDomains", Field, 0, ""},
+		{"Certificate.PermittedDNSDomainsCritical", Field, 0, ""},
+		{"Certificate.PermittedEmailAddresses", Field, 10, ""},
+		{"Certificate.PermittedIPRanges", Field, 10, ""},
+		{"Certificate.PermittedURIDomains", Field, 10, ""},
+		{"Certificate.Policies", Field, 22, ""},
+		{"Certificate.PolicyIdentifiers", Field, 0, ""},
+		{"Certificate.PolicyMappings", Field, 24, ""},
+		{"Certificate.PublicKey", Field, 0, ""},
+		{"Certificate.PublicKeyAlgorithm", Field, 0, ""},
+		{"Certificate.Raw", Field, 0, ""},
+		{"Certificate.RawIssuer", Field, 0, ""},
+		{"Certificate.RawSignatureAlgorithm", Field, 27, ""},
+		{"Certificate.RawSubject", Field, 0, ""},
+		{"Certificate.RawSubjectPublicKeyInfo", Field, 0, ""},
+		{"Certificate.RawTBSCertificate", Field, 0, ""},
+		{"Certificate.RequireExplicitPolicy", Field, 24, ""},
+		{"Certificate.RequireExplicitPolicyZero", Field, 24, ""},
+		{"Certificate.SerialNumber", Field, 0, ""},
+		{"Certificate.Signature", Field, 0, ""},
+		{"Certificate.SignatureAlgorithm", Field, 0, ""},
+		{"Certificate.Subject", Field, 0, ""},
+		{"Certificate.SubjectKeyId", Field, 0, ""},
+		{"Certificate.URIs", Field, 10, ""},
+		{"Certificate.UnhandledCriticalExtensions", Field, 5, ""},
+		{"Certificate.UnknownExtKeyUsage", Field, 0, ""},
+		{"Certificate.Version", Field, 0, ""},
+		{"CertificateInvalidError", Type, 0, ""},
+		{"CertificateInvalidError.Cert", Field, 0, ""},
+		{"CertificateInvalidError.Detail", Field, 10, ""},
+		{"CertificateInvalidError.Reason", Field, 0, ""},
+		{"CertificateRequest", Type, 3, ""},
+		{"CertificateRequest.Attributes", Field, 3, ""},
+		{"CertificateRequest.DNSNames", Field, 3, ""},
+		{"CertificateRequest.EmailAddresses", Field, 3, ""},
+		{"CertificateRequest.Extensions", Field, 3, ""},
+		{"CertificateRequest.ExtraExtensions", Field, 3, ""},
+		{"CertificateRequest.IPAddresses", Field, 3, ""},
+		{"CertificateRequest.PublicKey", Field, 3, ""},
+		{"CertificateRequest.PublicKeyAlgorithm", Field, 3, ""},
+		{"CertificateRequest.Raw", Field, 3, ""},
+		{"CertificateRequest.RawSignatureAlgorithm", Field, 27, ""},
+		{"CertificateRequest.RawSubject", Field, 3, ""},
+		{"CertificateRequest.RawSubjectPublicKeyInfo", Field, 3, ""},
+		{"CertificateRequest.RawTBSCertificateRequest", Field, 3, ""},
+		{"CertificateRequest.Signature", Field, 3, ""},
+		{"CertificateRequest.SignatureAlgorithm", Field, 3, ""},
+		{"CertificateRequest.Subject", Field, 3, ""},
+		{"CertificateRequest.URIs", Field, 10, ""},
+		{"CertificateRequest.Version", Field, 3, ""},
+		{"ConstraintViolationError", Type, 0, ""},
+		{"CreateCertificate", Func, 0, "func(rand io.Reader, template *Certificate, parent *Certificate, pub any, priv any) ([]byte, error)"},
+		{"CreateCertificateRequest", Func, 3, "func(rand io.Reader, template *CertificateRequest, priv any) (csr []byte, err error)"},
+		{"CreateRevocationList", Func, 15, "func(rand io.Reader, template *RevocationList, issuer *Certificate, priv crypto.Signer) ([]byte, error)"},
+		{"DSA", Const, 0, ""},
+		{"DSAWithSHA1", Const, 0, ""},
+		{"DSAWithSHA256", Const, 0, ""},
+		{"DecryptPEMBlock", Func, 1, "func(b *pem.Block, password []byte) ([]byte, error)"},
+		{"ECDSA", Const, 1, ""},
+		{"ECDSAWithSHA1", Const, 1, ""},
+		{"ECDSAWithSHA256", Const, 1, ""},
+		{"ECDSAWithSHA384", Const, 1, ""},
+		{"ECDSAWithSHA512", Const, 1, ""},
+		{"Ed25519", Const, 13, ""},
+		{"EncryptPEMBlock", Func, 1, "func(rand io.Reader, blockType string, data []byte, password []byte, alg PEMCipher) (*pem.Block, error)"},
+		{"ErrUnsupportedAlgorithm", Var, 0, ""},
+		{"Expired", Const, 0, ""},
+		{"ExtKeyUsage", Type, 0, ""},
+		{"ExtKeyUsageAny", Const, 0, ""},
+		{"ExtKeyUsageClientAuth", Const, 0, ""},
+		{"ExtKeyUsageCodeSigning", Const, 0, ""},
+		{"ExtKeyUsageEmailProtection", Const, 0, ""},
+		{"ExtKeyUsageIPSECEndSystem", Const, 1, ""},
+		{"ExtKeyUsageIPSECTunnel", Const, 1, ""},
+		{"ExtKeyUsageIPSECUser", Const, 1, ""},
+		{"ExtKeyUsageMicrosoftCommercialCodeSigning", Const, 10, ""},
+		{"ExtKeyUsageMicrosoftKernelCodeSigning", Const, 10, ""},
+		{"ExtKeyUsageMicrosoftServerGatedCrypto", Const, 1, ""},
+		{"ExtKeyUsageNetscapeServerGatedCrypto", Const, 1, ""},
+		{"ExtKeyUsageOCSPSigning", Const, 0, ""},
+		{"ExtKeyUsageServerAuth", Const, 0, ""},
+		{"ExtKeyUsageTimeStamping", Const, 0, ""},
+		{"HostnameError", Type, 0, ""},
+		{"HostnameError.Certificate", Field, 0, ""},
+		{"HostnameError.Host", Field, 0, ""},
+		{"IncompatibleUsage", Const, 1, ""},
+		{"IncorrectPasswordError", Var, 1, ""},
+		{"InsecureAlgorithmError", Type, 6, ""},
+		{"InvalidReason", Type, 0, ""},
+		{"IsEncryptedPEMBlock", Func, 1, "func(b *pem.Block) bool"},
+		{"KeyUsage", Type, 0, ""},
+		{"KeyUsageCRLSign", Const, 0, ""},
+		{"KeyUsageCertSign", Const, 0, ""},
+		{"KeyUsageContentCommitment", Const, 0, ""},
+		{"KeyUsageDataEncipherment", Const, 0, ""},
+		{"KeyUsageDecipherOnly", Const, 0, ""},
+		{"KeyUsageDigitalSignature", Const, 0, ""},
+		{"KeyUsageEncipherOnly", Const, 0, ""},
+		{"KeyUsageKeyAgreement", Const, 0, ""},
+		{"KeyUsageKeyEncipherment", Const, 0, ""},
+		{"MD2WithRSA", Const, 0, ""},
+		{"MD5WithRSA", Const, 0, ""},
+		{"MLDSA", Const, 27, ""},
+		{"MLDSA44", Const, 27, ""},
+		{"MLDSA65", Const, 27, ""},
+		{"MLDSA87", Const, 27, ""},
+		{"MarshalECPrivateKey", Func, 2, "func(key *ecdsa.PrivateKey) ([]byte, error)"},
+		{"MarshalPKCS1PrivateKey", Func, 0, "func(key *rsa.PrivateKey) []byte"},
+		{"MarshalPKCS1PublicKey", Func, 10, "func(key *rsa.PublicKey) []byte"},
+		{"MarshalPKCS8PrivateKey", Func, 10, "func(key any) ([]byte, error)"},
+		{"MarshalPKIXPublicKey", Func, 0, "func(pub any) ([]byte, error)"},
+		{"NameConstraintsWithoutSANs", Const, 10, ""},
+		{"NameMismatch", Const, 8, ""},
+		{"NewCertPool", Func, 0, "func() *CertPool"},
+		{"NoValidChains", Const, 24, ""},
+		{"NotAuthorizedToSign", Const, 0, ""},
+		{"OID", Type, 22, ""},
+		{"OIDFromASN1OID", Func, 26, "func(asn1OID asn1.ObjectIdentifier) (OID, error)"},
+		{"OIDFromInts", Func, 22, "func(oid []uint64) (OID, error)"},
+		{"PEMCipher", Type, 1, ""},
+		{"PEMCipher3DES", Const, 1, ""},
+		{"PEMCipherAES128", Const, 1, ""},
+		{"PEMCipherAES192", Const, 1, ""},
+		{"PEMCipherAES256", Const, 1, ""},
+		{"PEMCipherDES", Const, 1, ""},
+		{"ParseCRL", Func, 0, "func(crlBytes []byte) (*pkix.CertificateList, error)"},
+		{"ParseCertificate", Func, 0, "func(der []byte) (*Certificate, error)"},
+		{"ParseCertificateRequest", Func, 3, "func(asn1Data []byte) (*CertificateRequest, error)"},
+		{"ParseCertificates", Func, 0, "func(der []byte) ([]*Certificate, error)"},
+		{"ParseDERCRL", Func, 0, "func(derBytes []byte) (*pkix.CertificateList, error)"},
+		{"ParseECPrivateKey", Func, 1, "func(der []byte) (*ecdsa.PrivateKey, error)"},
+		{"ParseOID", Func, 23, "func(oid string) (OID, error)"},
+		{"ParsePKCS1PrivateKey", Func, 0, "func(der []byte) (*rsa.PrivateKey, error)"},
+		{"ParsePKCS1PublicKey", Func, 10, "func(der []byte) (*rsa.PublicKey, error)"},
+		{"ParsePKCS8PrivateKey", Func, 0, "func(der []byte) (key any, err error)"},
+		{"ParsePKIXPublicKey", Func, 0, "func(derBytes []byte) (pub any, err error)"},
+		{"ParseRevocationList", Func, 19, "func(der []byte) (*RevocationList, error)"},
+		{"PolicyMapping", Type, 24, ""},
+		{"PolicyMapping.IssuerDomainPolicy", Field, 24, ""},
+		{"PolicyMapping.SubjectDomainPolicy", Field, 24, ""},
+		{"PublicKeyAlgorithm", Type, 0, ""},
+		{"PureEd25519", Const, 13, ""},
+		{"RSA", Const, 0, ""},
+		{"RevocationList", Type, 15, ""},
+		{"RevocationList.AuthorityKeyId", Field, 19, ""},
+		{"RevocationList.Extensions", Field, 19, ""},
+		{"RevocationList.ExtraExtensions", Field, 15, ""},
+		{"RevocationList.Issuer", Field, 19, ""},
+		{"RevocationList.NextUpdate", Field, 15, ""},
+		{"RevocationList.Number", Field, 15, ""},
+		{"RevocationList.Raw", Field, 19, ""},
+		{"RevocationList.RawIssuer", Field, 19, ""},
+		{"RevocationList.RawSignatureAlgorithm", Field, 27, ""},
+		{"RevocationList.RawTBSRevocationList", Field, 19, ""},
+		{"RevocationList.RevokedCertificateEntries", Field, 21, ""},
+		{"RevocationList.RevokedCertificates", Field, 15, ""},
+		{"RevocationList.Signature", Field, 19, ""},
+		{"RevocationList.SignatureAlgorithm", Field, 15, ""},
+		{"RevocationList.ThisUpdate", Field, 15, ""},
+		{"RevocationListEntry", Type, 21, ""},
+		{"RevocationListEntry.Extensions", Field, 21, ""},
+		{"RevocationListEntry.ExtraExtensions", Field, 21, ""},
+		{"RevocationListEntry.Raw", Field, 21, ""},
+		{"RevocationListEntry.ReasonCode", Field, 21, ""},
+		{"RevocationListEntry.RevocationTime", Field, 21, ""},
+		{"RevocationListEntry.SerialNumber", Field, 21, ""},
+		{"SHA1WithRSA", Const, 0, ""},
+		{"SHA256WithRSA", Const, 0, ""},
+		{"SHA256WithRSAPSS", Const, 8, ""},
+		{"SHA384WithRSA", Const, 0, ""},
+		{"SHA384WithRSAPSS", Const, 8, ""},
+		{"SHA512WithRSA", Const, 0, ""},
+		{"SHA512WithRSAPSS", Const, 8, ""},
+		{"SetFallbackRoots", Func, 20, "func(roots *CertPool)"},
+		{"SignatureAlgorithm", Type, 0, ""},
+		{"SystemCertPool", Func, 7, "func() (*CertPool, error)"},
+		{"SystemRootsError", Type, 1, ""},
+		{"SystemRootsError.Err", Field, 7, ""},
+		{"TooManyConstraints", Const, 10, ""},
+		{"TooManyIntermediates", Const, 0, ""},
+		{"UnconstrainedName", Const, 10, ""},
+		{"UnhandledCriticalExtension", Type, 0, ""},
+		{"UnknownAuthorityError", Type, 0, ""},
+		{"UnknownAuthorityError.Cert", Field, 8, ""},
+		{"UnknownPublicKeyAlgorithm", Const, 0, ""},
+		{"UnknownSignatureAlgorithm", Const, 0, ""},
+		{"VerifyOptions", Type, 0, ""},
+		{"VerifyOptions.CertificatePolicies", Field, 24, ""},
+		{"VerifyOptions.CurrentTime", Field, 0, ""},
+		{"VerifyOptions.DNSName", Field, 0, ""},
+		{"VerifyOptions.Intermediates", Field, 0, ""},
+		{"VerifyOptions.KeyUsages", Field, 1, ""},
+		{"VerifyOptions.MaxConstraintComparisions", Field, 10, ""},
+		{"VerifyOptions.Roots", Field, 0, ""},
+	},
+	"crypto/x509/pkix": {
+		{"(*CertificateList).HasExpired", Method, 0, ""},
+		{"(*Name).FillFromRDNSequence", Method, 0, ""},
+		{"(Name).String", Method, 10, ""},
+		{"(Name).ToRDNSequence", Method, 0, ""},
+		{"(RDNSequence).String", Method, 10, ""},
+		{"AlgorithmIdentifier", Type, 0, ""},
+		{"AlgorithmIdentifier.Algorithm", Field, 0, ""},
+		{"AlgorithmIdentifier.Parameters", Field, 0, ""},
+		{"AttributeTypeAndValue", Type, 0, ""},
+		{"AttributeTypeAndValue.Type", Field, 0, ""},
+		{"AttributeTypeAndValue.Value", Field, 0, ""},
+		{"AttributeTypeAndValueSET", Type, 3, ""},
+		{"AttributeTypeAndValueSET.Type", Field, 3, ""},
+		{"AttributeTypeAndValueSET.Value", Field, 3, ""},
+		{"CertificateList", Type, 0, ""},
+		{"CertificateList.SignatureAlgorithm", Field, 0, ""},
+		{"CertificateList.SignatureValue", Field, 0, ""},
+		{"CertificateList.TBSCertList", Field, 0, ""},
+		{"Extension", Type, 0, ""},
+		{"Extension.Critical", Field, 0, ""},
+		{"Extension.Id", Field, 0, ""},
+		{"Extension.Value", Field, 0, ""},
+		{"Name", Type, 0, ""},
+		{"Name.CommonName", Field, 0, ""},
+		{"Name.Country", Field, 0, ""},
+		{"Name.ExtraNames", Field, 5, ""},
+		{"Name.Locality", Field, 0, ""},
+		{"Name.Names", Field, 0, ""},
+		{"Name.Organization", Field, 0, ""},
+		{"Name.OrganizationalUnit", Field, 0, ""},
+		{"Name.PostalCode", Field, 0, ""},
+		{"Name.Province", Field, 0, ""},
+		{"Name.SerialNumber", Field, 0, ""},
+		{"Name.StreetAddress", Field, 0, ""},
+		{"RDNSequence", Type, 0, ""},
+		{"RelativeDistinguishedNameSET", Type, 0, ""},
+		{"RevokedCertificate", Type, 0, ""},
+		{"RevokedCertificate.Extensions", Field, 0, ""},
+		{"RevokedCertificate.RevocationTime", Field, 0, ""},
+		{"RevokedCertificate.SerialNumber", Field, 0, ""},
+		{"TBSCertificateList", Type, 0, ""},
+		{"TBSCertificateList.Extensions", Field, 0, ""},
+		{"TBSCertificateList.Issuer", Field, 0, ""},
+		{"TBSCertificateList.NextUpdate", Field, 0, ""},
+		{"TBSCertificateList.Raw", Field, 0, ""},
+		{"TBSCertificateList.RevokedCertificates", Field, 0, ""},
+		{"TBSCertificateList.Signature", Field, 0, ""},
+		{"TBSCertificateList.ThisUpdate", Field, 0, ""},
+		{"TBSCertificateList.Version", Field, 0, ""},
+	},
+	"database/sql": {
+		{"(*ColumnType).DatabaseTypeName", Method, 8, ""},
+		{"(*ColumnType).DecimalSize", Method, 8, ""},
+		{"(*ColumnType).Length", Method, 8, ""},
+		{"(*ColumnType).Name", Method, 8, ""},
+		{"(*ColumnType).Nullable", Method, 8, ""},
+		{"(*ColumnType).ScanType", Method, 8, ""},
+		{"(*Conn).BeginTx", Method, 9, ""},
+		{"(*Conn).Close", Method, 9, ""},
+		{"(*Conn).ExecContext", Method, 9, ""},
+		{"(*Conn).PingContext", Method, 9, ""},
+		{"(*Conn).PrepareContext", Method, 9, ""},
+		{"(*Conn).QueryContext", Method, 9, ""},
+		{"(*Conn).QueryRowContext", Method, 9, ""},
+		{"(*Conn).Raw", Method, 13, ""},
+		{"(*DB).Begin", Method, 0, ""},
+		{"(*DB).BeginTx", Method, 8, ""},
+		{"(*DB).Close", Method, 0, ""},
+		{"(*DB).Conn", Method, 9, ""},
+		{"(*DB).Driver", Method, 0, ""},
+		{"(*DB).Exec", Method, 0, ""},
+		{"(*DB).ExecContext", Method, 8, ""},
+		{"(*DB).Ping", Method, 1, ""},
+		{"(*DB).PingContext", Method, 8, ""},
+		{"(*DB).Prepare", Method, 0, ""},
+		{"(*DB).PrepareContext", Method, 8, ""},
+		{"(*DB).Query", Method, 0, ""},
+		{"(*DB).QueryContext", Method, 8, ""},
+		{"(*DB).QueryRow", Method, 0, ""},
+		{"(*DB).QueryRowContext", Method, 8, ""},
+		{"(*DB).SetConnMaxIdleTime", Method, 15, ""},
+		{"(*DB).SetConnMaxLifetime", Method, 6, ""},
+		{"(*DB).SetMaxIdleConns", Method, 1, ""},
+		{"(*DB).SetMaxOpenConns", Method, 2, ""},
+		{"(*DB).Stats", Method, 5, ""},
+		{"(*Null).Scan", Method, 22, ""},
+		{"(*NullBool).Scan", Method, 0, ""},
+		{"(*NullByte).Scan", Method, 17, ""},
+		{"(*NullFloat64).Scan", Method, 0, ""},
+		{"(*NullInt16).Scan", Method, 17, ""},
+		{"(*NullInt32).Scan", Method, 13, ""},
+		{"(*NullInt64).Scan", Method, 0, ""},
+		{"(*NullString).Scan", Method, 0, ""},
+		{"(*NullTime).Scan", Method, 13, ""},
+		{"(*Row).Err", Method, 15, ""},
+		{"(*Row).Scan", Method, 0, ""},
+		{"(*Rows).Close", Method, 0, ""},
+		{"(*Rows).ColumnTypes", Method, 8, ""},
+		{"(*Rows).Columns", Method, 0, ""},
+		{"(*Rows).Err", Method, 0, ""},
+		{"(*Rows).Next", Method, 0, ""},
+		{"(*Rows).NextResultSet", Method, 8, ""},
+		{"(*Rows).Scan", Method, 0, ""},
+		{"(*Stmt).Close", Method, 0, ""},
+		{"(*Stmt).Exec", Method, 0, ""},
+		{"(*Stmt).ExecContext", Method, 8, ""},
+		{"(*Stmt).Query", Method, 0, ""},
+		{"(*Stmt).QueryContext", Method, 8, ""},
+		{"(*Stmt).QueryRow", Method, 0, ""},
+		{"(*Stmt).QueryRowContext", Method, 8, ""},
+		{"(*Tx).Commit", Method, 0, ""},
+		{"(*Tx).Exec", Method, 0, ""},
+		{"(*Tx).ExecContext", Method, 8, ""},
+		{"(*Tx).Prepare", Method, 0, ""},
+		{"(*Tx).PrepareContext", Method, 8, ""},
+		{"(*Tx).Query", Method, 0, ""},
+		{"(*Tx).QueryContext", Method, 8, ""},
+		{"(*Tx).QueryRow", Method, 0, ""},
+		{"(*Tx).QueryRowContext", Method, 8, ""},
+		{"(*Tx).Rollback", Method, 0, ""},
+		{"(*Tx).Stmt", Method, 0, ""},
+		{"(*Tx).StmtContext", Method, 8, ""},
+		{"(IsolationLevel).String", Method, 11, ""},
+		{"(Null).Value", Method, 22, ""},
+		{"(NullBool).Value", Method, 0, ""},
+		{"(NullByte).Value", Method, 17, ""},
+		{"(NullFloat64).Value", Method, 0, ""},
+		{"(NullInt16).Value", Method, 17, ""},
+		{"(NullInt32).Value", Method, 13, ""},
+		{"(NullInt64).Value", Method, 0, ""},
+		{"(NullString).Value", Method, 0, ""},
+		{"(NullTime).Value", Method, 13, ""},
+		{"(Result).LastInsertId", Method, 0, ""},
+		{"(Result).RowsAffected", Method, 0, ""},
+		{"(Scanner).Scan", Method, 0, ""},
+		{"ColumnType", Type, 8, ""},
+		{"Conn", Type, 9, ""},
+		{"ConvertAssign", Func, 27, "func(scanCtx driver.ScanContext, dest any, src driver.Value) error"},
+		{"DB", Type, 0, ""},
+		{"DBStats", Type, 5, ""},
+		{"DBStats.Idle", Field, 11, ""},
+		{"DBStats.InUse", Field, 11, ""},
+		{"DBStats.MaxIdleClosed", Field, 11, ""},
+		{"DBStats.MaxIdleTimeClosed", Field, 15, ""},
+		{"DBStats.MaxLifetimeClosed", Field, 11, ""},
+		{"DBStats.MaxOpenConnections", Field, 11, ""},
+		{"DBStats.OpenConnections", Field, 5, ""},
+		{"DBStats.WaitCount", Field, 11, ""},
+		{"DBStats.WaitDuration", Field, 11, ""},
+		{"Drivers", Func, 4, "func() []string"},
+		{"ErrConnDone", Var, 9, ""},
+		{"ErrNoRows", Var, 0, ""},
+		{"ErrTxDone", Var, 0, ""},
+		{"IsolationLevel", Type, 8, ""},
+		{"LevelDefault", Const, 8, ""},
+		{"LevelLinearizable", Const, 8, ""},
+		{"LevelReadCommitted", Const, 8, ""},
+		{"LevelReadUncommitted", Const, 8, ""},
+		{"LevelRepeatableRead", Const, 8, ""},
+		{"LevelSerializable", Const, 8, ""},
+		{"LevelSnapshot", Const, 8, ""},
+		{"LevelWriteCommitted", Const, 8, ""},
+		{"Named", Func, 8, "func(name string, value any) NamedArg"},
+		{"NamedArg", Type, 8, ""},
+		{"NamedArg.Name", Field, 8, ""},
+		{"NamedArg.Value", Field, 8, ""},
+		{"Null", Type, 22, ""},
+		{"NullBool", Type, 0, ""},
+		{"NullBool.Bool", Field, 0, ""},
+		{"NullBool.Valid", Field, 0, ""},
+		{"NullByte", Type, 17, ""},
+		{"NullByte.Byte", Field, 17, ""},
+		{"NullByte.Valid", Field, 17, ""},
+		{"NullFloat64", Type, 0, ""},
+		{"NullFloat64.Float64", Field, 0, ""},
+		{"NullFloat64.Valid", Field, 0, ""},
+		{"NullInt16", Type, 17, ""},
+		{"NullInt16.Int16", Field, 17, ""},
+		{"NullInt16.Valid", Field, 17, ""},
+		{"NullInt32", Type, 13, ""},
+		{"NullInt32.Int32", Field, 13, ""},
+		{"NullInt32.Valid", Field, 13, ""},
+		{"NullInt64", Type, 0, ""},
+		{"NullInt64.Int64", Field, 0, ""},
+		{"NullInt64.Valid", Field, 0, ""},
+		{"NullString", Type, 0, ""},
+		{"NullString.String", Field, 0, ""},
+		{"NullString.Valid", Field, 0, ""},
+		{"NullTime", Type, 13, ""},
+		{"NullTime.Time", Field, 13, ""},
+		{"NullTime.Valid", Field, 13, ""},
+		{"Open", Func, 0, "func(driverName string, dataSourceName string) (*DB, error)"},
+		{"OpenDB", Func, 10, "func(c driver.Connector) *DB"},
+		{"Out", Type, 9, ""},
+		{"Out.Dest", Field, 9, ""},
+		{"Out.In", Field, 9, ""},
+		{"RawBytes", Type, 0, ""},
+		{"Register", Func, 0, "func(name string, driver driver.Driver)"},
+		{"Result", Type, 0, ""},
+		{"Row", Type, 0, ""},
+		{"Rows", Type, 0, ""},
+		{"Scanner", Type, 0, ""},
+		{"Stmt", Type, 0, ""},
+		{"Tx", Type, 0, ""},
+		{"TxOptions", Type, 8, ""},
+		{"TxOptions.Isolation", Field, 8, ""},
+		{"TxOptions.ReadOnly", Field, 8, ""},
+	},
+	"database/sql/driver": {
+		{"(ColumnConverter).ColumnConverter", Method, 0, ""},
+		{"(Conn).Begin", Method, 0, ""},
+		{"(Conn).Close", Method, 0, ""},
+		{"(Conn).Prepare", Method, 0, ""},
+		{"(ConnBeginTx).BeginTx", Method, 8, ""},
+		{"(ConnPrepareContext).PrepareContext", Method, 8, ""},
+		{"(Connector).Connect", Method, 10, ""},
+		{"(Connector).Driver", Method, 10, ""},
+		{"(Driver).Open", Method, 0, ""},
+		{"(DriverContext).OpenConnector", Method, 10, ""},
+		{"(Execer).Exec", Method, 0, ""},
+		{"(ExecerContext).ExecContext", Method, 8, ""},
+		{"(NamedValueChecker).CheckNamedValue", Method, 9, ""},
+		{"(NotNull).ConvertValue", Method, 0, ""},
+		{"(Null).ConvertValue", Method, 0, ""},
+		{"(Pinger).Ping", Method, 8, ""},
+		{"(Queryer).Query", Method, 1, ""},
+		{"(QueryerContext).QueryContext", Method, 8, ""},
+		{"(Result).LastInsertId", Method, 0, ""},
+		{"(Result).RowsAffected", Method, 0, ""},
+		{"(Rows).Close", Method, 0, ""},
+		{"(Rows).Columns", Method, 0, ""},
+		{"(Rows).Next", Method, 0, ""},
+		{"(RowsAffected).LastInsertId", Method, 0, ""},
+		{"(RowsAffected).RowsAffected", Method, 0, ""},
+		{"(RowsColumnScanner).Close", Method, 27, ""},
+		{"(RowsColumnScanner).Columns", Method, 27, ""},
+		{"(RowsColumnScanner).Next", Method, 27, ""},
+		{"(RowsColumnScanner).NextRow", Method, 27, ""},
+		{"(RowsColumnScanner).ScanColumn", Method, 27, ""},
+		{"(RowsColumnTypeDatabaseTypeName).Close", Method, 8, ""},
+		{"(RowsColumnTypeDatabaseTypeName).ColumnTypeDatabaseTypeName", Method, 8, ""},
+		{"(RowsColumnTypeDatabaseTypeName).Columns", Method, 8, ""},
+		{"(RowsColumnTypeDatabaseTypeName).Next", Method, 8, ""},
+		{"(RowsColumnTypeLength).Close", Method, 8, ""},
+		{"(RowsColumnTypeLength).ColumnTypeLength", Method, 8, ""},
+		{"(RowsColumnTypeLength).Columns", Method, 8, ""},
+		{"(RowsColumnTypeLength).Next", Method, 8, ""},
+		{"(RowsColumnTypeNullable).Close", Method, 8, ""},
+		{"(RowsColumnTypeNullable).ColumnTypeNullable", Method, 8, ""},
+		{"(RowsColumnTypeNullable).Columns", Method, 8, ""},
+		{"(RowsColumnTypeNullable).Next", Method, 8, ""},
+		{"(RowsColumnTypePrecisionScale).Close", Method, 8, ""},
+		{"(RowsColumnTypePrecisionScale).ColumnTypePrecisionScale", Method, 8, ""},
+		{"(RowsColumnTypePrecisionScale).Columns", Method, 8, ""},
+		{"(RowsColumnTypePrecisionScale).Next", Method, 8, ""},
+		{"(RowsColumnTypeScanType).Close", Method, 8, ""},
+		{"(RowsColumnTypeScanType).ColumnTypeScanType", Method, 8, ""},
+		{"(RowsColumnTypeScanType).Columns", Method, 8, ""},
+		{"(RowsColumnTypeScanType).Next", Method, 8, ""},
+		{"(RowsNextResultSet).Close", Method, 8, ""},
+		{"(RowsNextResultSet).Columns", Method, 8, ""},
+		{"(RowsNextResultSet).HasNextResultSet", Method, 8, ""},
+		{"(RowsNextResultSet).Next", Method, 8, ""},
+		{"(RowsNextResultSet).NextResultSet", Method, 8, ""},
+		{"(SessionResetter).ResetSession", Method, 10, ""},
+		{"(Stmt).Close", Method, 0, ""},
+		{"(Stmt).Exec", Method, 0, ""},
+		{"(Stmt).NumInput", Method, 0, ""},
+		{"(Stmt).Query", Method, 0, ""},
+		{"(StmtExecContext).ExecContext", Method, 8, ""},
+		{"(StmtQueryContext).QueryContext", Method, 8, ""},
+		{"(Tx).Commit", Method, 0, ""},
+		{"(Tx).Rollback", Method, 0, ""},
+		{"(Validator).IsValid", Method, 15, ""},
+		{"(ValueConverter).ConvertValue", Method, 0, ""},
+		{"(Valuer).Value", Method, 0, ""},
+		{"Bool", Var, 0, ""},
+		{"ColumnConverter", Type, 0, ""},
+		{"Conn", Type, 0, ""},
+		{"ConnBeginTx", Type, 8, ""},
+		{"ConnPrepareContext", Type, 8, ""},
+		{"Connector", Type, 10, ""},
+		{"DefaultParameterConverter", Var, 0, ""},
+		{"Driver", Type, 0, ""},
+		{"DriverContext", Type, 10, ""},
+		{"ErrBadConn", Var, 0, ""},
+		{"ErrRemoveArgument", Var, 9, ""},
+		{"ErrSkip", Var, 0, ""},
+		{"Execer", Type, 0, ""},
+		{"ExecerContext", Type, 8, ""},
+		{"Int32", Var, 0, ""},
+		{"IsScanValue", Func, 0, "func(v any) bool"},
+		{"IsValue", Func, 0, "func(v any) bool"},
+		{"IsolationLevel", Type, 8, ""},
+		{"NamedValue", Type, 8, ""},
+		{"NamedValue.Name", Field, 8, ""},
+		{"NamedValue.Ordinal", Field, 8, ""},
+		{"NamedValue.Value", Field, 8, ""},
+		{"NamedValueChecker", Type, 9, ""},
+		{"NotNull", Type, 0, ""},
+		{"NotNull.Converter", Field, 0, ""},
+		{"Null", Type, 0, ""},
+		{"Null.Converter", Field, 0, ""},
+		{"Pinger", Type, 8, ""},
+		{"Queryer", Type, 1, ""},
+		{"QueryerContext", Type, 8, ""},
+		{"Result", Type, 0, ""},
+		{"ResultNoRows", Var, 0, ""},
+		{"Rows", Type, 0, ""},
+		{"RowsAffected", Type, 0, ""},
+		{"RowsColumnScanner", Type, 27, ""},
+		{"RowsColumnTypeDatabaseTypeName", Type, 8, ""},
+		{"RowsColumnTypeLength", Type, 8, ""},
+		{"RowsColumnTypeNullable", Type, 8, ""},
+		{"RowsColumnTypePrecisionScale", Type, 8, ""},
+		{"RowsColumnTypeScanType", Type, 8, ""},
+		{"RowsNextResultSet", Type, 8, ""},
+		{"ScanContext", Type, 27, ""},
+		{"SessionResetter", Type, 10, ""},
+		{"Stmt", Type, 0, ""},
+		{"StmtExecContext", Type, 8, ""},
+		{"StmtQueryContext", Type, 8, ""},
+		{"String", Var, 0, ""},
+		{"Tx", Type, 0, ""},
+		{"TxOptions", Type, 8, ""},
+		{"TxOptions.Isolation", Field, 8, ""},
+		{"TxOptions.ReadOnly", Field, 8, ""},
+		{"Validator", Type, 15, ""},
+		{"Value", Type, 0, ""},
+		{"ValueConverter", Type, 0, ""},
+		{"Valuer", Type, 0, ""},
+	},
+	"debug/buildinfo": {
+		{"BuildInfo", Type, 18, ""},
+		{"Read", Func, 18, "func(r io.ReaderAt) (*BuildInfo, error)"},
+		{"ReadFile", Func, 18, "func(name string) (info *BuildInfo, err error)"},
+	},
+	"debug/dwarf": {
+		{"(*AddrType).Basic", Method, 0, ""},
+		{"(*AddrType).Common", Method, 0, ""},
+		{"(*AddrType).Size", Method, 0, ""},
+		{"(*AddrType).String", Method, 0, ""},
+		{"(*ArrayType).Common", Method, 0, ""},
+		{"(*ArrayType).Size", Method, 0, ""},
+		{"(*ArrayType).String", Method, 0, ""},
+		{"(*BasicType).Basic", Method, 0, ""},
+		{"(*BasicType).Common", Method, 0, ""},
+		{"(*BasicType).Size", Method, 0, ""},
+		{"(*BasicType).String", Method, 0, ""},
+		{"(*BoolType).Basic", Method, 0, ""},
+		{"(*BoolType).Common", Method, 0, ""},
+		{"(*BoolType).Size", Method, 0, ""},
+		{"(*BoolType).String", Method, 0, ""},
+		{"(*CharType).Basic", Method, 0, ""},
+		{"(*CharType).Common", Method, 0, ""},
+		{"(*CharType).Size", Method, 0, ""},
+		{"(*CharType).String", Method, 0, ""},
+		{"(*CommonType).Common", Method, 0, ""},
+		{"(*CommonType).Size", Method, 0, ""},
+		{"(*ComplexType).Basic", Method, 0, ""},
+		{"(*ComplexType).Common", Method, 0, ""},
+		{"(*ComplexType).Size", Method, 0, ""},
+		{"(*ComplexType).String", Method, 0, ""},
+		{"(*Data).AddSection", Method, 14, ""},
+		{"(*Data).AddTypes", Method, 3, ""},
+		{"(*Data).LineReader", Method, 5, ""},
+		{"(*Data).Ranges", Method, 7, ""},
+		{"(*Data).Reader", Method, 0, ""},
+		{"(*Data).Type", Method, 0, ""},
+		{"(*DotDotDotType).Common", Method, 0, ""},
+		{"(*DotDotDotType).Size", Method, 0, ""},
+		{"(*DotDotDotType).String", Method, 0, ""},
+		{"(*Entry).AttrField", Method, 5, ""},
+		{"(*Entry).Val", Method, 0, ""},
+		{"(*EnumType).Common", Method, 0, ""},
+		{"(*EnumType).Size", Method, 0, ""},
+		{"(*EnumType).String", Method, 0, ""},
+		{"(*FloatType).Basic", Method, 0, ""},
+		{"(*FloatType).Common", Method, 0, ""},
+		{"(*FloatType).Size", Method, 0, ""},
+		{"(*FloatType).String", Method, 0, ""},
+		{"(*FuncType).Common", Method, 0, ""},
+		{"(*FuncType).Size", Method, 0, ""},
+		{"(*FuncType).String", Method, 0, ""},
+		{"(*IntType).Basic", Method, 0, ""},
+		{"(*IntType).Common", Method, 0, ""},
+		{"(*IntType).Size", Method, 0, ""},
+		{"(*IntType).String", Method, 0, ""},
+		{"(*LineReader).Files", Method, 14, ""},
+		{"(*LineReader).Next", Method, 5, ""},
+		{"(*LineReader).Reset", Method, 5, ""},
+		{"(*LineReader).Seek", Method, 5, ""},
+		{"(*LineReader).SeekPC", Method, 5, ""},
+		{"(*LineReader).Tell", Method, 5, ""},
+		{"(*PtrType).Common", Method, 0, ""},
+		{"(*PtrType).Size", Method, 0, ""},
+		{"(*PtrType).String", Method, 0, ""},
+		{"(*QualType).Common", Method, 0, ""},
+		{"(*QualType).Size", Method, 0, ""},
+		{"(*QualType).String", Method, 0, ""},
+		{"(*Reader).AddressSize", Method, 5, ""},
+		{"(*Reader).ByteOrder", Method, 14, ""},
+		{"(*Reader).Next", Method, 0, ""},
+		{"(*Reader).Seek", Method, 0, ""},
+		{"(*Reader).SeekPC", Method, 7, ""},
+		{"(*Reader).SkipChildren", Method, 0, ""},
+		{"(*StructType).Common", Method, 0, ""},
+		{"(*StructType).Defn", Method, 0, ""},
+		{"(*StructType).Size", Method, 0, ""},
+		{"(*StructType).String", Method, 0, ""},
+		{"(*TypedefType).Common", Method, 0, ""},
+		{"(*TypedefType).Size", Method, 0, ""},
+		{"(*TypedefType).String", Method, 0, ""},
+		{"(*UcharType).Basic", Method, 0, ""},
+		{"(*UcharType).Common", Method, 0, ""},
+		{"(*UcharType).Size", Method, 0, ""},
+		{"(*UcharType).String", Method, 0, ""},
+		{"(*UintType).Basic", Method, 0, ""},
+		{"(*UintType).Common", Method, 0, ""},
+		{"(*UintType).Size", Method, 0, ""},
+		{"(*UintType).String", Method, 0, ""},
+		{"(*UnspecifiedType).Basic", Method, 4, ""},
+		{"(*UnspecifiedType).Common", Method, 4, ""},
+		{"(*UnspecifiedType).Size", Method, 4, ""},
+		{"(*UnspecifiedType).String", Method, 4, ""},
+		{"(*UnsupportedType).Common", Method, 13, ""},
+		{"(*UnsupportedType).Size", Method, 13, ""},
+		{"(*UnsupportedType).String", Method, 13, ""},
+		{"(*VoidType).Common", Method, 0, ""},
+		{"(*VoidType).Size", Method, 0, ""},
+		{"(*VoidType).String", Method, 0, ""},
+		{"(Attr).GoString", Method, 0, ""},
+		{"(Attr).String", Method, 0, ""},
+		{"(Class).GoString", Method, 5, ""},
+		{"(Class).String", Method, 5, ""},
+		{"(DecodeError).Error", Method, 0, ""},
+		{"(Tag).GoString", Method, 0, ""},
+		{"(Tag).String", Method, 0, ""},
+		{"(Type).Common", Method, 0, ""},
+		{"(Type).Size", Method, 0, ""},
+		{"(Type).String", Method, 0, ""},
+		{"AddrType", Type, 0, ""},
+		{"AddrType.BasicType", Field, 0, ""},
+		{"ArrayType", Type, 0, ""},
+		{"ArrayType.CommonType", Field, 0, ""},
+		{"ArrayType.Count", Field, 0, ""},
+		{"ArrayType.StrideBitSize", Field, 0, ""},
+		{"ArrayType.Type", Field, 0, ""},
+		{"Attr", Type, 0, ""},
+		{"AttrAbstractOrigin", Const, 0, ""},
+		{"AttrAccessibility", Const, 0, ""},
+		{"AttrAddrBase", Const, 14, ""},
+		{"AttrAddrClass", Const, 0, ""},
+		{"AttrAlignment", Const, 14, ""},
+		{"AttrAllocated", Const, 0, ""},
+		{"AttrArtificial", Const, 0, ""},
+		{"AttrAssociated", Const, 0, ""},
+		{"AttrBaseTypes", Const, 0, ""},
+		{"AttrBinaryScale", Const, 14, ""},
+		{"AttrBitOffset", Const, 0, ""},
+		{"AttrBitSize", Const, 0, ""},
+		{"AttrByteSize", Const, 0, ""},
+		{"AttrCallAllCalls", Const, 14, ""},
+		{"AttrCallAllSourceCalls", Const, 14, ""},
+		{"AttrCallAllTailCalls", Const, 14, ""},
+		{"AttrCallColumn", Const, 0, ""},
+		{"AttrCallDataLocation", Const, 14, ""},
+		{"AttrCallDataValue", Const, 14, ""},
+		{"AttrCallFile", Const, 0, ""},
+		{"AttrCallLine", Const, 0, ""},
+		{"AttrCallOrigin", Const, 14, ""},
+		{"AttrCallPC", Const, 14, ""},
+		{"AttrCallParameter", Const, 14, ""},
+		{"AttrCallReturnPC", Const, 14, ""},
+		{"AttrCallTailCall", Const, 14, ""},
+		{"AttrCallTarget", Const, 14, ""},
+		{"AttrCallTargetClobbered", Const, 14, ""},
+		{"AttrCallValue", Const, 14, ""},
+		{"AttrCalling", Const, 0, ""},
+		{"AttrCommonRef", Const, 0, ""},
+		{"AttrCompDir", Const, 0, ""},
+		{"AttrConstExpr", Const, 14, ""},
+		{"AttrConstValue", Const, 0, ""},
+		{"AttrContainingType", Const, 0, ""},
+		{"AttrCount", Const, 0, ""},
+		{"AttrDataBitOffset", Const, 14, ""},
+		{"AttrDataLocation", Const, 0, ""},
+		{"AttrDataMemberLoc", Const, 0, ""},
+		{"AttrDecimalScale", Const, 14, ""},
+		{"AttrDecimalSign", Const, 14, ""},
+		{"AttrDeclColumn", Const, 0, ""},
+		{"AttrDeclFile", Const, 0, ""},
+		{"AttrDeclLine", Const, 0, ""},
+		{"AttrDeclaration", Const, 0, ""},
+		{"AttrDefaultValue", Const, 0, ""},
+		{"AttrDefaulted", Const, 14, ""},
+		{"AttrDeleted", Const, 14, ""},
+		{"AttrDescription", Const, 0, ""},
+		{"AttrDigitCount", Const, 14, ""},
+		{"AttrDiscr", Const, 0, ""},
+		{"AttrDiscrList", Const, 0, ""},
+		{"AttrDiscrValue", Const, 0, ""},
+		{"AttrDwoName", Const, 14, ""},
+		{"AttrElemental", Const, 14, ""},
+		{"AttrEncoding", Const, 0, ""},
+		{"AttrEndianity", Const, 14, ""},
+		{"AttrEntrypc", Const, 0, ""},
+		{"AttrEnumClass", Const, 14, ""},
+		{"AttrExplicit", Const, 14, ""},
+		{"AttrExportSymbols", Const, 14, ""},
+		{"AttrExtension", Const, 0, ""},
+		{"AttrExternal", Const, 0, ""},
+		{"AttrFrameBase", Const, 0, ""},
+		{"AttrFriend", Const, 0, ""},
+		{"AttrHighpc", Const, 0, ""},
+		{"AttrIdentifierCase", Const, 0, ""},
+		{"AttrImport", Const, 0, ""},
+		{"AttrInline", Const, 0, ""},
+		{"AttrIsOptional", Const, 0, ""},
+		{"AttrLanguage", Const, 0, ""},
+		{"AttrLinkageName", Const, 14, ""},
+		{"AttrLocation", Const, 0, ""},
+		{"AttrLoclistsBase", Const, 14, ""},
+		{"AttrLowerBound", Const, 0, ""},
+		{"AttrLowpc", Const, 0, ""},
+		{"AttrMacroInfo", Const, 0, ""},
+		{"AttrMacros", Const, 14, ""},
+		{"AttrMainSubprogram", Const, 14, ""},
+		{"AttrMutable", Const, 14, ""},
+		{"AttrName", Const, 0, ""},
+		{"AttrNamelistItem", Const, 0, ""},
+		{"AttrNoreturn", Const, 14, ""},
+		{"AttrObjectPointer", Const, 14, ""},
+		{"AttrOrdering", Const, 0, ""},
+		{"AttrPictureString", Const, 14, ""},
+		{"AttrPriority", Const, 0, ""},
+		{"AttrProducer", Const, 0, ""},
+		{"AttrPrototyped", Const, 0, ""},
+		{"AttrPure", Const, 14, ""},
+		{"AttrRanges", Const, 0, ""},
+		{"AttrRank", Const, 14, ""},
+		{"AttrRecursive", Const, 14, ""},
+		{"AttrReference", Const, 14, ""},
+		{"AttrReturnAddr", Const, 0, ""},
+		{"AttrRnglistsBase", Const, 14, ""},
+		{"AttrRvalueReference", Const, 14, ""},
+		{"AttrSegment", Const, 0, ""},
+		{"AttrSibling", Const, 0, ""},
+		{"AttrSignature", Const, 14, ""},
+		{"AttrSmall", Const, 14, ""},
+		{"AttrSpecification", Const, 0, ""},
+		{"AttrStartScope", Const, 0, ""},
+		{"AttrStaticLink", Const, 0, ""},
+		{"AttrStmtList", Const, 0, ""},
+		{"AttrStrOffsetsBase", Const, 14, ""},
+		{"AttrStride", Const, 0, ""},
+		{"AttrStrideSize", Const, 0, ""},
+		{"AttrStringLength", Const, 0, ""},
+		{"AttrStringLengthBitSize", Const, 14, ""},
+		{"AttrStringLengthByteSize", Const, 14, ""},
+		{"AttrThreadsScaled", Const, 14, ""},
+		{"AttrTrampoline", Const, 0, ""},
+		{"AttrType", Const, 0, ""},
+		{"AttrUpperBound", Const, 0, ""},
+		{"AttrUseLocation", Const, 0, ""},
+		{"AttrUseUTF8", Const, 0, ""},
+		{"AttrVarParam", Const, 0, ""},
+		{"AttrVirtuality", Const, 0, ""},
+		{"AttrVisibility", Const, 0, ""},
+		{"AttrVtableElemLoc", Const, 0, ""},
+		{"BasicType", Type, 0, ""},
+		{"BasicType.BitOffset", Field, 0, ""},
+		{"BasicType.BitSize", Field, 0, ""},
+		{"BasicType.CommonType", Field, 0, ""},
+		{"BasicType.DataBitOffset", Field, 18, ""},
+		{"BoolType", Type, 0, ""},
+		{"BoolType.BasicType", Field, 0, ""},
+		{"CharType", Type, 0, ""},
+		{"CharType.BasicType", Field, 0, ""},
+		{"Class", Type, 5, ""},
+		{"ClassAddrPtr", Const, 14, ""},
+		{"ClassAddress", Const, 5, ""},
+		{"ClassBlock", Const, 5, ""},
+		{"ClassConstant", Const, 5, ""},
+		{"ClassExprLoc", Const, 5, ""},
+		{"ClassFlag", Const, 5, ""},
+		{"ClassLinePtr", Const, 5, ""},
+		{"ClassLocList", Const, 14, ""},
+		{"ClassLocListPtr", Const, 5, ""},
+		{"ClassMacPtr", Const, 5, ""},
+		{"ClassRangeListPtr", Const, 5, ""},
+		{"ClassReference", Const, 5, ""},
+		{"ClassReferenceAlt", Const, 5, ""},
+		{"ClassReferenceSig", Const, 5, ""},
+		{"ClassRngList", Const, 14, ""},
+		{"ClassRngListsPtr", Const, 14, ""},
+		{"ClassStrOffsetsPtr", Const, 14, ""},
+		{"ClassString", Const, 5, ""},
+		{"ClassStringAlt", Const, 5, ""},
+		{"ClassUnknown", Const, 6, ""},
+		{"CommonType", Type, 0, ""},
+		{"CommonType.ByteSize", Field, 0, ""},
+		{"CommonType.Name", Field, 0, ""},
+		{"ComplexType", Type, 0, ""},
+		{"ComplexType.BasicType", Field, 0, ""},
+		{"Data", Type, 0, ""},
+		{"DecodeError", Type, 0, ""},
+		{"DecodeError.Err", Field, 0, ""},
+		{"DecodeError.Name", Field, 0, ""},
+		{"DecodeError.Offset", Field, 0, ""},
+		{"DotDotDotType", Type, 0, ""},
+		{"DotDotDotType.CommonType", Field, 0, ""},
+		{"Entry", Type, 0, ""},
+		{"Entry.Children", Field, 0, ""},
+		{"Entry.Field", Field, 0, ""},
+		{"Entry.Offset", Field, 0, ""},
+		{"Entry.Tag", Field, 0, ""},
+		{"EnumType", Type, 0, ""},
+		{"EnumType.CommonType", Field, 0, ""},
+		{"EnumType.EnumName", Field, 0, ""},
+		{"EnumType.Val", Field, 0, ""},
+		{"EnumValue", Type, 0, ""},
+		{"EnumValue.Name", Field, 0, ""},
+		{"EnumValue.Val", Field, 0, ""},
+		{"ErrUnknownPC", Var, 5, ""},
+		{"Field", Type, 0, ""},
+		{"Field.Attr", Field, 0, ""},
+		{"Field.Class", Field, 5, ""},
+		{"Field.Val", Field, 0, ""},
+		{"FloatType", Type, 0, ""},
+		{"FloatType.BasicType", Field, 0, ""},
+		{"FuncType", Type, 0, ""},
+		{"FuncType.CommonType", Field, 0, ""},
+		{"FuncType.ParamType", Field, 0, ""},
+		{"FuncType.ReturnType", Field, 0, ""},
+		{"IntType", Type, 0, ""},
+		{"IntType.BasicType", Field, 0, ""},
+		{"LineEntry", Type, 5, ""},
+		{"LineEntry.Address", Field, 5, ""},
+		{"LineEntry.BasicBlock", Field, 5, ""},
+		{"LineEntry.Column", Field, 5, ""},
+		{"LineEntry.Discriminator", Field, 5, ""},
+		{"LineEntry.EndSequence", Field, 5, ""},
+		{"LineEntry.EpilogueBegin", Field, 5, ""},
+		{"LineEntry.File", Field, 5, ""},
+		{"LineEntry.ISA", Field, 5, ""},
+		{"LineEntry.IsStmt", Field, 5, ""},
+		{"LineEntry.Line", Field, 5, ""},
+		{"LineEntry.OpIndex", Field, 5, ""},
+		{"LineEntry.PrologueEnd", Field, 5, ""},
+		{"LineFile", Type, 5, ""},
+		{"LineFile.Length", Field, 5, ""},
+		{"LineFile.Mtime", Field, 5, ""},
+		{"LineFile.Name", Field, 5, ""},
+		{"LineReader", Type, 5, ""},
+		{"LineReaderPos", Type, 5, ""},
+		{"New", Func, 0, "func(abbrev []byte, aranges []byte, frame []byte, info []byte, line []byte, pubnames []byte, ranges []byte, str []byte) (*Data, error)"},
+		{"Offset", Type, 0, ""},
+		{"PtrType", Type, 0, ""},
+		{"PtrType.CommonType", Field, 0, ""},
+		{"PtrType.Type", Field, 0, ""},
+		{"QualType", Type, 0, ""},
+		{"QualType.CommonType", Field, 0, ""},
+		{"QualType.Qual", Field, 0, ""},
+		{"QualType.Type", Field, 0, ""},
+		{"Reader", Type, 0, ""},
+		{"StructField", Type, 0, ""},
+		{"StructField.BitOffset", Field, 0, ""},
+		{"StructField.BitSize", Field, 0, ""},
+		{"StructField.ByteOffset", Field, 0, ""},
+		{"StructField.ByteSize", Field, 0, ""},
+		{"StructField.DataBitOffset", Field, 18, ""},
+		{"StructField.Name", Field, 0, ""},
+		{"StructField.Type", Field, 0, ""},
+		{"StructType", Type, 0, ""},
+		{"StructType.CommonType", Field, 0, ""},
+		{"StructType.Field", Field, 0, ""},
+		{"StructType.Incomplete", Field, 0, ""},
+		{"StructType.Kind", Field, 0, ""},
+		{"StructType.StructName", Field, 0, ""},
+		{"Tag", Type, 0, ""},
+		{"TagAccessDeclaration", Const, 0, ""},
+		{"TagArrayType", Const, 0, ""},
+		{"TagAtomicType", Const, 14, ""},
+		{"TagBaseType", Const, 0, ""},
+		{"TagCallSite", Const, 14, ""},
+		{"TagCallSiteParameter", Const, 14, ""},
+		{"TagCatchDwarfBlock", Const, 0, ""},
+		{"TagClassType", Const, 0, ""},
+		{"TagCoarrayType", Const, 14, ""},
+		{"TagCommonDwarfBlock", Const, 0, ""},
+		{"TagCommonInclusion", Const, 0, ""},
+		{"TagCompileUnit", Const, 0, ""},
+		{"TagCondition", Const, 3, ""},
+		{"TagConstType", Const, 0, ""},
+		{"TagConstant", Const, 0, ""},
+		{"TagDwarfProcedure", Const, 0, ""},
+		{"TagDynamicType", Const, 14, ""},
+		{"TagEntryPoint", Const, 0, ""},
+		{"TagEnumerationType", Const, 0, ""},
+		{"TagEnumerator", Const, 0, ""},
+		{"TagFileType", Const, 0, ""},
+		{"TagFormalParameter", Const, 0, ""},
+		{"TagFriend", Const, 0, ""},
+		{"TagGenericSubrange", Const, 14, ""},
+		{"TagImmutableType", Const, 14, ""},
+		{"TagImportedDeclaration", Const, 0, ""},
+		{"TagImportedModule", Const, 0, ""},
+		{"TagImportedUnit", Const, 0, ""},
+		{"TagInheritance", Const, 0, ""},
+		{"TagInlinedSubroutine", Const, 0, ""},
+		{"TagInterfaceType", Const, 0, ""},
+		{"TagLabel", Const, 0, ""},
+		{"TagLexDwarfBlock", Const, 0, ""},
+		{"TagMember", Const, 0, ""},
+		{"TagModule", Const, 0, ""},
+		{"TagMutableType", Const, 0, ""},
+		{"TagNamelist", Const, 0, ""},
+		{"TagNamelistItem", Const, 0, ""},
+		{"TagNamespace", Const, 0, ""},
+		{"TagPackedType", Const, 0, ""},
+		{"TagPartialUnit", Const, 0, ""},
+		{"TagPointerType", Const, 0, ""},
+		{"TagPtrToMemberType", Const, 0, ""},
+		{"TagReferenceType", Const, 0, ""},
+		{"TagRestrictType", Const, 0, ""},
+		{"TagRvalueReferenceType", Const, 3, ""},
+		{"TagSetType", Const, 0, ""},
+		{"TagSharedType", Const, 3, ""},
+		{"TagSkeletonUnit", Const, 14, ""},
+		{"TagStringType", Const, 0, ""},
+		{"TagStructType", Const, 0, ""},
+		{"TagSubprogram", Const, 0, ""},
+		{"TagSubrangeType", Const, 0, ""},
+		{"TagSubroutineType", Const, 0, ""},
+		{"TagTemplateAlias", Const, 3, ""},
+		{"TagTemplateTypeParameter", Const, 0, ""},
+		{"TagTemplateValueParameter", Const, 0, ""},
+		{"TagThrownType", Const, 0, ""},
+		{"TagTryDwarfBlock", Const, 0, ""},
+		{"TagTypeUnit", Const, 3, ""},
+		{"TagTypedef", Const, 0, ""},
+		{"TagUnionType", Const, 0, ""},
+		{"TagUnspecifiedParameters", Const, 0, ""},
+		{"TagUnspecifiedType", Const, 0, ""},
+		{"TagVariable", Const, 0, ""},
+		{"TagVariant", Const, 0, ""},
+		{"TagVariantPart", Const, 0, ""},
+		{"TagVolatileType", Const, 0, ""},
+		{"TagWithStmt", Const, 0, ""},
+		{"Type", Type, 0, ""},
+		{"TypedefType", Type, 0, ""},
+		{"TypedefType.CommonType", Field, 0, ""},
+		{"TypedefType.Type", Field, 0, ""},
+		{"UcharType", Type, 0, ""},
+		{"UcharType.BasicType", Field, 0, ""},
+		{"UintType", Type, 0, ""},
+		{"UintType.BasicType", Field, 0, ""},
+		{"UnspecifiedType", Type, 4, ""},
+		{"UnspecifiedType.BasicType", Field, 4, ""},
+		{"UnsupportedType", Type, 13, ""},
+		{"UnsupportedType.CommonType", Field, 13, ""},
+		{"UnsupportedType.Tag", Field, 13, ""},
+		{"VoidType", Type, 0, ""},
+		{"VoidType.CommonType", Field, 0, ""},
+	},
+	"debug/elf": {
+		{"(*File).Close", Method, 0, ""},
+		{"(*File).DWARF", Method, 0, ""},
+		{"(*File).DynString", Method, 1, ""},
+		{"(*File).DynValue", Method, 21, ""},
+		{"(*File).DynamicSymbols", Method, 4, ""},
+		{"(*File).DynamicVersionNeeds", Method, 24, ""},
+		{"(*File).DynamicVersions", Method, 24, ""},
+		{"(*File).ImportedLibraries", Method, 0, ""},
+		{"(*File).ImportedSymbols", Method, 0, ""},
+		{"(*File).Section", Method, 0, ""},
+		{"(*File).SectionByType", Method, 0, ""},
+		{"(*File).Symbols", Method, 0, ""},
+		{"(*FormatError).Error", Method, 0, ""},
+		{"(*Prog).Open", Method, 0, ""},
+		{"(*Section).Data", Method, 0, ""},
+		{"(*Section).Open", Method, 0, ""},
+		{"(Class).GoString", Method, 0, ""},
+		{"(Class).String", Method, 0, ""},
+		{"(CompressionType).GoString", Method, 6, ""},
+		{"(CompressionType).String", Method, 6, ""},
+		{"(Data).GoString", Method, 0, ""},
+		{"(Data).String", Method, 0, ""},
+		{"(DynFlag).GoString", Method, 0, ""},
+		{"(DynFlag).String", Method, 0, ""},
+		{"(DynFlag1).GoString", Method, 21, ""},
+		{"(DynFlag1).String", Method, 21, ""},
+		{"(DynTag).GoString", Method, 0, ""},
+		{"(DynTag).String", Method, 0, ""},
+		{"(Machine).GoString", Method, 0, ""},
+		{"(Machine).String", Method, 0, ""},
+		{"(NType).GoString", Method, 0, ""},
+		{"(NType).String", Method, 0, ""},
+		{"(OSABI).GoString", Method, 0, ""},
+		{"(OSABI).String", Method, 0, ""},
+		{"(Prog).ReadAt", Method, 0, ""},
+		{"(ProgFlag).GoString", Method, 0, ""},
+		{"(ProgFlag).String", Method, 0, ""},
+		{"(ProgType).GoString", Method, 0, ""},
+		{"(ProgType).String", Method, 0, ""},
+		{"(R_386).GoString", Method, 0, ""},
+		{"(R_386).String", Method, 0, ""},
+		{"(R_390).GoString", Method, 7, ""},
+		{"(R_390).String", Method, 7, ""},
+		{"(R_AARCH64).GoString", Method, 4, ""},
+		{"(R_AARCH64).String", Method, 4, ""},
+		{"(R_ALPHA).GoString", Method, 0, ""},
+		{"(R_ALPHA).String", Method, 0, ""},
+		{"(R_ARM).GoString", Method, 0, ""},
+		{"(R_ARM).String", Method, 0, ""},
+		{"(R_LARCH).GoString", Method, 19, ""},
+		{"(R_LARCH).String", Method, 19, ""},
+		{"(R_MIPS).GoString", Method, 6, ""},
+		{"(R_MIPS).String", Method, 6, ""},
+		{"(R_PPC).GoString", Method, 0, ""},
+		{"(R_PPC).String", Method, 0, ""},
+		{"(R_PPC64).GoString", Method, 5, ""},
+		{"(R_PPC64).String", Method, 5, ""},
+		{"(R_RISCV).GoString", Method, 11, ""},
+		{"(R_RISCV).String", Method, 11, ""},
+		{"(R_SPARC).GoString", Method, 0, ""},
+		{"(R_SPARC).String", Method, 0, ""},
+		{"(R_X86_64).GoString", Method, 0, ""},
+		{"(R_X86_64).String", Method, 0, ""},
+		{"(Section).ReadAt", Method, 0, ""},
+		{"(SectionFlag).GoString", Method, 0, ""},
+		{"(SectionFlag).String", Method, 0, ""},
+		{"(SectionIndex).GoString", Method, 0, ""},
+		{"(SectionIndex).String", Method, 0, ""},
+		{"(SectionType).GoString", Method, 0, ""},
+		{"(SectionType).String", Method, 0, ""},
+		{"(SymBind).GoString", Method, 0, ""},
+		{"(SymBind).String", Method, 0, ""},
+		{"(SymType).GoString", Method, 0, ""},
+		{"(SymType).String", Method, 0, ""},
+		{"(SymVis).GoString", Method, 0, ""},
+		{"(SymVis).String", Method, 0, ""},
+		{"(Type).GoString", Method, 0, ""},
+		{"(Type).String", Method, 0, ""},
+		{"(Version).GoString", Method, 0, ""},
+		{"(Version).String", Method, 0, ""},
+		{"(VersionIndex).Index", Method, 24, ""},
+		{"(VersionIndex).IsHidden", Method, 24, ""},
+		{"ARM_MAGIC_TRAMP_NUMBER", Const, 0, ""},
+		{"COMPRESS_HIOS", Const, 6, ""},
+		{"COMPRESS_HIPROC", Const, 6, ""},
+		{"COMPRESS_LOOS", Const, 6, ""},
+		{"COMPRESS_LOPROC", Const, 6, ""},
+		{"COMPRESS_ZLIB", Const, 6, ""},
+		{"COMPRESS_ZSTD", Const, 21, ""},
+		{"Chdr32", Type, 6, ""},
+		{"Chdr32.Addralign", Field, 6, ""},
+		{"Chdr32.Size", Field, 6, ""},
+		{"Chdr32.Type", Field, 6, ""},
+		{"Chdr64", Type, 6, ""},
+		{"Chdr64.Addralign", Field, 6, ""},
+		{"Chdr64.Size", Field, 6, ""},
+		{"Chdr64.Type", Field, 6, ""},
+		{"Class", Type, 0, ""},
+		{"CompressionType", Type, 6, ""},
+		{"DF_1_CONFALT", Const, 21, ""},
+		{"DF_1_DIRECT", Const, 21, ""},
+		{"DF_1_DISPRELDNE", Const, 21, ""},
+		{"DF_1_DISPRELPND", Const, 21, ""},
+		{"DF_1_EDITED", Const, 21, ""},
+		{"DF_1_ENDFILTEE", Const, 21, ""},
+		{"DF_1_GLOBAL", Const, 21, ""},
+		{"DF_1_GLOBAUDIT", Const, 21, ""},
+		{"DF_1_GROUP", Const, 21, ""},
+		{"DF_1_IGNMULDEF", Const, 21, ""},
+		{"DF_1_INITFIRST", Const, 21, ""},
+		{"DF_1_INTERPOSE", Const, 21, ""},
+		{"DF_1_KMOD", Const, 21, ""},
+		{"DF_1_LOADFLTR", Const, 21, ""},
+		{"DF_1_NOCOMMON", Const, 21, ""},
+		{"DF_1_NODEFLIB", Const, 21, ""},
+		{"DF_1_NODELETE", Const, 21, ""},
+		{"DF_1_NODIRECT", Const, 21, ""},
+		{"DF_1_NODUMP", Const, 21, ""},
+		{"DF_1_NOHDR", Const, 21, ""},
+		{"DF_1_NOKSYMS", Const, 21, ""},
+		{"DF_1_NOOPEN", Const, 21, ""},
+		{"DF_1_NORELOC", Const, 21, ""},
+		{"DF_1_NOW", Const, 21, ""},
+		{"DF_1_ORIGIN", Const, 21, ""},
+		{"DF_1_PIE", Const, 21, ""},
+		{"DF_1_SINGLETON", Const, 21, ""},
+		{"DF_1_STUB", Const, 21, ""},
+		{"DF_1_SYMINTPOSE", Const, 21, ""},
+		{"DF_1_TRANS", Const, 21, ""},
+		{"DF_1_WEAKFILTER", Const, 21, ""},
+		{"DF_BIND_NOW", Const, 0, ""},
+		{"DF_ORIGIN", Const, 0, ""},
+		{"DF_STATIC_TLS", Const, 0, ""},
+		{"DF_SYMBOLIC", Const, 0, ""},
+		{"DF_TEXTREL", Const, 0, ""},
+		{"DT_ADDRRNGHI", Const, 16, ""},
+		{"DT_ADDRRNGLO", Const, 16, ""},
+		{"DT_AUDIT", Const, 16, ""},
+		{"DT_AUXILIARY", Const, 16, ""},
+		{"DT_BIND_NOW", Const, 0, ""},
+		{"DT_CHECKSUM", Const, 16, ""},
+		{"DT_CONFIG", Const, 16, ""},
+		{"DT_DEBUG", Const, 0, ""},
+		{"DT_DEPAUDIT", Const, 16, ""},
+		{"DT_ENCODING", Const, 0, ""},
+		{"DT_FEATURE", Const, 16, ""},
+		{"DT_FILTER", Const, 16, ""},
+		{"DT_FINI", Const, 0, ""},
+		{"DT_FINI_ARRAY", Const, 0, ""},
+		{"DT_FINI_ARRAYSZ", Const, 0, ""},
+		{"DT_FLAGS", Const, 0, ""},
+		{"DT_FLAGS_1", Const, 16, ""},
+		{"DT_GNU_CONFLICT", Const, 16, ""},
+		{"DT_GNU_CONFLICTSZ", Const, 16, ""},
+		{"DT_GNU_HASH", Const, 16, ""},
+		{"DT_GNU_LIBLIST", Const, 16, ""},
+		{"DT_GNU_LIBLISTSZ", Const, 16, ""},
+		{"DT_GNU_PRELINKED", Const, 16, ""},
+		{"DT_HASH", Const, 0, ""},
+		{"DT_HIOS", Const, 0, ""},
+		{"DT_HIPROC", Const, 0, ""},
+		{"DT_INIT", Const, 0, ""},
+		{"DT_INIT_ARRAY", Const, 0, ""},
+		{"DT_INIT_ARRAYSZ", Const, 0, ""},
+		{"DT_JMPREL", Const, 0, ""},
+		{"DT_LOOS", Const, 0, ""},
+		{"DT_LOPROC", Const, 0, ""},
+		{"DT_MIPS_AUX_DYNAMIC", Const, 16, ""},
+		{"DT_MIPS_BASE_ADDRESS", Const, 16, ""},
+		{"DT_MIPS_COMPACT_SIZE", Const, 16, ""},
+		{"DT_MIPS_CONFLICT", Const, 16, ""},
+		{"DT_MIPS_CONFLICTNO", Const, 16, ""},
+		{"DT_MIPS_CXX_FLAGS", Const, 16, ""},
+		{"DT_MIPS_DELTA_CLASS", Const, 16, ""},
+		{"DT_MIPS_DELTA_CLASSSYM", Const, 16, ""},
+		{"DT_MIPS_DELTA_CLASSSYM_NO", Const, 16, ""},
+		{"DT_MIPS_DELTA_CLASS_NO", Const, 16, ""},
+		{"DT_MIPS_DELTA_INSTANCE", Const, 16, ""},
+		{"DT_MIPS_DELTA_INSTANCE_NO", Const, 16, ""},
+		{"DT_MIPS_DELTA_RELOC", Const, 16, ""},
+		{"DT_MIPS_DELTA_RELOC_NO", Const, 16, ""},
+		{"DT_MIPS_DELTA_SYM", Const, 16, ""},
+		{"DT_MIPS_DELTA_SYM_NO", Const, 16, ""},
+		{"DT_MIPS_DYNSTR_ALIGN", Const, 16, ""},
+		{"DT_MIPS_FLAGS", Const, 16, ""},
+		{"DT_MIPS_GOTSYM", Const, 16, ""},
+		{"DT_MIPS_GP_VALUE", Const, 16, ""},
+		{"DT_MIPS_HIDDEN_GOTIDX", Const, 16, ""},
+		{"DT_MIPS_HIPAGENO", Const, 16, ""},
+		{"DT_MIPS_ICHECKSUM", Const, 16, ""},
+		{"DT_MIPS_INTERFACE", Const, 16, ""},
+		{"DT_MIPS_INTERFACE_SIZE", Const, 16, ""},
+		{"DT_MIPS_IVERSION", Const, 16, ""},
+		{"DT_MIPS_LIBLIST", Const, 16, ""},
+		{"DT_MIPS_LIBLISTNO", Const, 16, ""},
+		{"DT_MIPS_LOCALPAGE_GOTIDX", Const, 16, ""},
+		{"DT_MIPS_LOCAL_GOTIDX", Const, 16, ""},
+		{"DT_MIPS_LOCAL_GOTNO", Const, 16, ""},
+		{"DT_MIPS_MSYM", Const, 16, ""},
+		{"DT_MIPS_OPTIONS", Const, 16, ""},
+		{"DT_MIPS_PERF_SUFFIX", Const, 16, ""},
+		{"DT_MIPS_PIXIE_INIT", Const, 16, ""},
+		{"DT_MIPS_PLTGOT", Const, 16, ""},
+		{"DT_MIPS_PROTECTED_GOTIDX", Const, 16, ""},
+		{"DT_MIPS_RLD_MAP", Const, 16, ""},
+		{"DT_MIPS_RLD_MAP_REL", Const, 16, ""},
+		{"DT_MIPS_RLD_TEXT_RESOLVE_ADDR", Const, 16, ""},
+		{"DT_MIPS_RLD_VERSION", Const, 16, ""},
+		{"DT_MIPS_RWPLT", Const, 16, ""},
+		{"DT_MIPS_SYMBOL_LIB", Const, 16, ""},
+		{"DT_MIPS_SYMTABNO", Const, 16, ""},
+		{"DT_MIPS_TIME_STAMP", Const, 16, ""},
+		{"DT_MIPS_UNREFEXTNO", Const, 16, ""},
+		{"DT_MOVEENT", Const, 16, ""},
+		{"DT_MOVESZ", Const, 16, ""},
+		{"DT_MOVETAB", Const, 16, ""},
+		{"DT_NEEDED", Const, 0, ""},
+		{"DT_NULL", Const, 0, ""},
+		{"DT_PLTGOT", Const, 0, ""},
+		{"DT_PLTPAD", Const, 16, ""},
+		{"DT_PLTPADSZ", Const, 16, ""},
+		{"DT_PLTREL", Const, 0, ""},
+		{"DT_PLTRELSZ", Const, 0, ""},
+		{"DT_POSFLAG_1", Const, 16, ""},
+		{"DT_PPC64_GLINK", Const, 16, ""},
+		{"DT_PPC64_OPD", Const, 16, ""},
+		{"DT_PPC64_OPDSZ", Const, 16, ""},
+		{"DT_PPC64_OPT", Const, 16, ""},
+		{"DT_PPC_GOT", Const, 16, ""},
+		{"DT_PPC_OPT", Const, 16, ""},
+		{"DT_PREINIT_ARRAY", Const, 0, ""},
+		{"DT_PREINIT_ARRAYSZ", Const, 0, ""},
+		{"DT_REL", Const, 0, ""},
+		{"DT_RELA", Const, 0, ""},
+		{"DT_RELACOUNT", Const, 16, ""},
+		{"DT_RELAENT", Const, 0, ""},
+		{"DT_RELASZ", Const, 0, ""},
+		{"DT_RELCOUNT", Const, 16, ""},
+		{"DT_RELENT", Const, 0, ""},
+		{"DT_RELSZ", Const, 0, ""},
+		{"DT_RPATH", Const, 0, ""},
+		{"DT_RUNPATH", Const, 0, ""},
+		{"DT_SONAME", Const, 0, ""},
+		{"DT_SPARC_REGISTER", Const, 16, ""},
+		{"DT_STRSZ", Const, 0, ""},
+		{"DT_STRTAB", Const, 0, ""},
+		{"DT_SYMBOLIC", Const, 0, ""},
+		{"DT_SYMENT", Const, 0, ""},
+		{"DT_SYMINENT", Const, 16, ""},
+		{"DT_SYMINFO", Const, 16, ""},
+		{"DT_SYMINSZ", Const, 16, ""},
+		{"DT_SYMTAB", Const, 0, ""},
+		{"DT_SYMTAB_SHNDX", Const, 16, ""},
+		{"DT_TEXTREL", Const, 0, ""},
+		{"DT_TLSDESC_GOT", Const, 16, ""},
+		{"DT_TLSDESC_PLT", Const, 16, ""},
+		{"DT_USED", Const, 16, ""},
+		{"DT_VALRNGHI", Const, 16, ""},
+		{"DT_VALRNGLO", Const, 16, ""},
+		{"DT_VERDEF", Const, 16, ""},
+		{"DT_VERDEFNUM", Const, 16, ""},
+		{"DT_VERNEED", Const, 0, ""},
+		{"DT_VERNEEDNUM", Const, 0, ""},
+		{"DT_VERSYM", Const, 0, ""},
+		{"Data", Type, 0, ""},
+		{"Dyn32", Type, 0, ""},
+		{"Dyn32.Tag", Field, 0, ""},
+		{"Dyn32.Val", Field, 0, ""},
+		{"Dyn64", Type, 0, ""},
+		{"Dyn64.Tag", Field, 0, ""},
+		{"Dyn64.Val", Field, 0, ""},
+		{"DynFlag", Type, 0, ""},
+		{"DynFlag1", Type, 21, ""},
+		{"DynTag", Type, 0, ""},
+		{"DynamicVersion", Type, 24, ""},
+		{"DynamicVersion.Deps", Field, 24, ""},
+		{"DynamicVersion.Flags", Field, 24, ""},
+		{"DynamicVersion.Index", Field, 24, ""},
+		{"DynamicVersion.Name", Field, 24, ""},
+		{"DynamicVersionDep", Type, 24, ""},
+		{"DynamicVersionDep.Dep", Field, 24, ""},
+		{"DynamicVersionDep.Flags", Field, 24, ""},
+		{"DynamicVersionDep.Index", Field, 24, ""},
+		{"DynamicVersionFlag", Type, 24, ""},
+		{"DynamicVersionNeed", Type, 24, ""},
+		{"DynamicVersionNeed.Name", Field, 24, ""},
+		{"DynamicVersionNeed.Needs", Field, 24, ""},
+		{"EI_ABIVERSION", Const, 0, ""},
+		{"EI_CLASS", Const, 0, ""},
+		{"EI_DATA", Const, 0, ""},
+		{"EI_NIDENT", Const, 0, ""},
+		{"EI_OSABI", Const, 0, ""},
+		{"EI_PAD", Const, 0, ""},
+		{"EI_VERSION", Const, 0, ""},
+		{"ELFCLASS32", Const, 0, ""},
+		{"ELFCLASS64", Const, 0, ""},
+		{"ELFCLASSNONE", Const, 0, ""},
+		{"ELFDATA2LSB", Const, 0, ""},
+		{"ELFDATA2MSB", Const, 0, ""},
+		{"ELFDATANONE", Const, 0, ""},
+		{"ELFMAG", Const, 0, ""},
+		{"ELFOSABI_86OPEN", Const, 0, ""},
+		{"ELFOSABI_AIX", Const, 0, ""},
+		{"ELFOSABI_ARM", Const, 0, ""},
+		{"ELFOSABI_AROS", Const, 11, ""},
+		{"ELFOSABI_CLOUDABI", Const, 11, ""},
+		{"ELFOSABI_FENIXOS", Const, 11, ""},
+		{"ELFOSABI_FREEBSD", Const, 0, ""},
+		{"ELFOSABI_HPUX", Const, 0, ""},
+		{"ELFOSABI_HURD", Const, 0, ""},
+		{"ELFOSABI_IRIX", Const, 0, ""},
+		{"ELFOSABI_LINUX", Const, 0, ""},
+		{"ELFOSABI_MODESTO", Const, 0, ""},
+		{"ELFOSABI_NETBSD", Const, 0, ""},
+		{"ELFOSABI_NONE", Const, 0, ""},
+		{"ELFOSABI_NSK", Const, 0, ""},
+		{"ELFOSABI_OPENBSD", Const, 0, ""},
+		{"ELFOSABI_OPENVMS", Const, 0, ""},
+		{"ELFOSABI_SOLARIS", Const, 0, ""},
+		{"ELFOSABI_STANDALONE", Const, 0, ""},
+		{"ELFOSABI_TRU64", Const, 0, ""},
+		{"EM_386", Const, 0, ""},
+		{"EM_486", Const, 0, ""},
+		{"EM_56800EX", Const, 11, ""},
+		{"EM_68HC05", Const, 11, ""},
+		{"EM_68HC08", Const, 11, ""},
+		{"EM_68HC11", Const, 11, ""},
+		{"EM_68HC12", Const, 0, ""},
+		{"EM_68HC16", Const, 11, ""},
+		{"EM_68K", Const, 0, ""},
+		{"EM_78KOR", Const, 11, ""},
+		{"EM_8051", Const, 11, ""},
+		{"EM_860", Const, 0, ""},
+		{"EM_88K", Const, 0, ""},
+		{"EM_960", Const, 0, ""},
+		{"EM_AARCH64", Const, 4, ""},
+		{"EM_ALPHA", Const, 0, ""},
+		{"EM_ALPHA_STD", Const, 0, ""},
+		{"EM_ALTERA_NIOS2", Const, 11, ""},
+		{"EM_AMDGPU", Const, 11, ""},
+		{"EM_ARC", Const, 0, ""},
+		{"EM_ARCA", Const, 11, ""},
+		{"EM_ARC_COMPACT", Const, 11, ""},
+		{"EM_ARC_COMPACT2", Const, 11, ""},
+		{"EM_ARM", Const, 0, ""},
+		{"EM_AVR", Const, 11, ""},
+		{"EM_AVR32", Const, 11, ""},
+		{"EM_BA1", Const, 11, ""},
+		{"EM_BA2", Const, 11, ""},
+		{"EM_BLACKFIN", Const, 11, ""},
+		{"EM_BPF", Const, 11, ""},
+		{"EM_C166", Const, 11, ""},
+		{"EM_CDP", Const, 11, ""},
+		{"EM_CE", Const, 11, ""},
+		{"EM_CLOUDSHIELD", Const, 11, ""},
+		{"EM_COGE", Const, 11, ""},
+		{"EM_COLDFIRE", Const, 0, ""},
+		{"EM_COOL", Const, 11, ""},
+		{"EM_COREA_1ST", Const, 11, ""},
+		{"EM_COREA_2ND", Const, 11, ""},
+		{"EM_CR", Const, 11, ""},
+		{"EM_CR16", Const, 11, ""},
+		{"EM_CRAYNV2", Const, 11, ""},
+		{"EM_CRIS", Const, 11, ""},
+		{"EM_CRX", Const, 11, ""},
+		{"EM_CSR_KALIMBA", Const, 11, ""},
+		{"EM_CUDA", Const, 11, ""},
+		{"EM_CYPRESS_M8C", Const, 11, ""},
+		{"EM_D10V", Const, 11, ""},
+		{"EM_D30V", Const, 11, ""},
+		{"EM_DSP24", Const, 11, ""},
+		{"EM_DSPIC30F", Const, 11, ""},
+		{"EM_DXP", Const, 11, ""},
+		{"EM_ECOG1", Const, 11, ""},
+		{"EM_ECOG16", Const, 11, ""},
+		{"EM_ECOG1X", Const, 11, ""},
+		{"EM_ECOG2", Const, 11, ""},
+		{"EM_ETPU", Const, 11, ""},
+		{"EM_EXCESS", Const, 11, ""},
+		{"EM_F2MC16", Const, 11, ""},
+		{"EM_FIREPATH", Const, 11, ""},
+		{"EM_FR20", Const, 0, ""},
+		{"EM_FR30", Const, 11, ""},
+		{"EM_FT32", Const, 11, ""},
+		{"EM_FX66", Const, 11, ""},
+		{"EM_H8S", Const, 0, ""},
+		{"EM_H8_300", Const, 0, ""},
+		{"EM_H8_300H", Const, 0, ""},
+		{"EM_H8_500", Const, 0, ""},
+		{"EM_HUANY", Const, 11, ""},
+		{"EM_IA_64", Const, 0, ""},
+		{"EM_INTEL205", Const, 11, ""},
+		{"EM_INTEL206", Const, 11, ""},
+		{"EM_INTEL207", Const, 11, ""},
+		{"EM_INTEL208", Const, 11, ""},
+		{"EM_INTEL209", Const, 11, ""},
+		{"EM_IP2K", Const, 11, ""},
+		{"EM_JAVELIN", Const, 11, ""},
+		{"EM_K10M", Const, 11, ""},
+		{"EM_KM32", Const, 11, ""},
+		{"EM_KMX16", Const, 11, ""},
+		{"EM_KMX32", Const, 11, ""},
+		{"EM_KMX8", Const, 11, ""},
+		{"EM_KVARC", Const, 11, ""},
+		{"EM_L10M", Const, 11, ""},
+		{"EM_LANAI", Const, 11, ""},
+		{"EM_LATTICEMICO32", Const, 11, ""},
+		{"EM_LOONGARCH", Const, 19, ""},
+		{"EM_M16C", Const, 11, ""},
+		{"EM_M32", Const, 0, ""},
+		{"EM_M32C", Const, 11, ""},
+		{"EM_M32R", Const, 11, ""},
+		{"EM_MANIK", Const, 11, ""},
+		{"EM_MAX", Const, 11, ""},
+		{"EM_MAXQ30", Const, 11, ""},
+		{"EM_MCHP_PIC", Const, 11, ""},
+		{"EM_MCST_ELBRUS", Const, 11, ""},
+		{"EM_ME16", Const, 0, ""},
+		{"EM_METAG", Const, 11, ""},
+		{"EM_MICROBLAZE", Const, 11, ""},
+		{"EM_MIPS", Const, 0, ""},
+		{"EM_MIPS_RS3_LE", Const, 0, ""},
+		{"EM_MIPS_RS4_BE", Const, 0, ""},
+		{"EM_MIPS_X", Const, 0, ""},
+		{"EM_MMA", Const, 0, ""},
+		{"EM_MMDSP_PLUS", Const, 11, ""},
+		{"EM_MMIX", Const, 11, ""},
+		{"EM_MN10200", Const, 11, ""},
+		{"EM_MN10300", Const, 11, ""},
+		{"EM_MOXIE", Const, 11, ""},
+		{"EM_MSP430", Const, 11, ""},
+		{"EM_NCPU", Const, 0, ""},
+		{"EM_NDR1", Const, 0, ""},
+		{"EM_NDS32", Const, 11, ""},
+		{"EM_NONE", Const, 0, ""},
+		{"EM_NORC", Const, 11, ""},
+		{"EM_NS32K", Const, 11, ""},
+		{"EM_OPEN8", Const, 11, ""},
+		{"EM_OPENRISC", Const, 11, ""},
+		{"EM_PARISC", Const, 0, ""},
+		{"EM_PCP", Const, 0, ""},
+		{"EM_PDP10", Const, 11, ""},
+		{"EM_PDP11", Const, 11, ""},
+		{"EM_PDSP", Const, 11, ""},
+		{"EM_PJ", Const, 11, ""},
+		{"EM_PPC", Const, 0, ""},
+		{"EM_PPC64", Const, 0, ""},
+		{"EM_PRISM", Const, 11, ""},
+		{"EM_QDSP6", Const, 11, ""},
+		{"EM_R32C", Const, 11, ""},
+		{"EM_RCE", Const, 0, ""},
+		{"EM_RH32", Const, 0, ""},
+		{"EM_RISCV", Const, 11, ""},
+		{"EM_RL78", Const, 11, ""},
+		{"EM_RS08", Const, 11, ""},
+		{"EM_RX", Const, 11, ""},
+		{"EM_S370", Const, 0, ""},
+		{"EM_S390", Const, 0, ""},
+		{"EM_SCORE7", Const, 11, ""},
+		{"EM_SEP", Const, 11, ""},
+		{"EM_SE_C17", Const, 11, ""},
+		{"EM_SE_C33", Const, 11, ""},
+		{"EM_SH", Const, 0, ""},
+		{"EM_SHARC", Const, 11, ""},
+		{"EM_SLE9X", Const, 11, ""},
+		{"EM_SNP1K", Const, 11, ""},
+		{"EM_SPARC", Const, 0, ""},
+		{"EM_SPARC32PLUS", Const, 0, ""},
+		{"EM_SPARCV9", Const, 0, ""},
+		{"EM_ST100", Const, 0, ""},
+		{"EM_ST19", Const, 11, ""},
+		{"EM_ST200", Const, 11, ""},
+		{"EM_ST7", Const, 11, ""},
+		{"EM_ST9PLUS", Const, 11, ""},
+		{"EM_STARCORE", Const, 0, ""},
+		{"EM_STM8", Const, 11, ""},
+		{"EM_STXP7X", Const, 11, ""},
+		{"EM_SVX", Const, 11, ""},
+		{"EM_TILE64", Const, 11, ""},
+		{"EM_TILEGX", Const, 11, ""},
+		{"EM_TILEPRO", Const, 11, ""},
+		{"EM_TINYJ", Const, 0, ""},
+		{"EM_TI_ARP32", Const, 11, ""},
+		{"EM_TI_C2000", Const, 11, ""},
+		{"EM_TI_C5500", Const, 11, ""},
+		{"EM_TI_C6000", Const, 11, ""},
+		{"EM_TI_PRU", Const, 11, ""},
+		{"EM_TMM_GPP", Const, 11, ""},
+		{"EM_TPC", Const, 11, ""},
+		{"EM_TRICORE", Const, 0, ""},
+		{"EM_TRIMEDIA", Const, 11, ""},
+		{"EM_TSK3000", Const, 11, ""},
+		{"EM_UNICORE", Const, 11, ""},
+		{"EM_V800", Const, 0, ""},
+		{"EM_V850", Const, 11, ""},
+		{"EM_VAX", Const, 11, ""},
+		{"EM_VIDEOCORE", Const, 11, ""},
+		{"EM_VIDEOCORE3", Const, 11, ""},
+		{"EM_VIDEOCORE5", Const, 11, ""},
+		{"EM_VISIUM", Const, 11, ""},
+		{"EM_VPP500", Const, 0, ""},
+		{"EM_X86_64", Const, 0, ""},
+		{"EM_XCORE", Const, 11, ""},
+		{"EM_XGATE", Const, 11, ""},
+		{"EM_XIMO16", Const, 11, ""},
+		{"EM_XTENSA", Const, 11, ""},
+		{"EM_Z80", Const, 11, ""},
+		{"EM_ZSP", Const, 11, ""},
+		{"ET_CORE", Const, 0, ""},
+		{"ET_DYN", Const, 0, ""},
+		{"ET_EXEC", Const, 0, ""},
+		{"ET_HIOS", Const, 0, ""},
+		{"ET_HIPROC", Const, 0, ""},
+		{"ET_LOOS", Const, 0, ""},
+		{"ET_LOPROC", Const, 0, ""},
+		{"ET_NONE", Const, 0, ""},
+		{"ET_REL", Const, 0, ""},
+		{"EV_CURRENT", Const, 0, ""},
+		{"EV_NONE", Const, 0, ""},
+		{"ErrNoSymbols", Var, 4, ""},
+		{"File", Type, 0, ""},
+		{"File.FileHeader", Field, 0, ""},
+		{"File.Progs", Field, 0, ""},
+		{"File.Sections", Field, 0, ""},
+		{"FileHeader", Type, 0, ""},
+		{"FileHeader.ABIVersion", Field, 0, ""},
+		{"FileHeader.ByteOrder", Field, 0, ""},
+		{"FileHeader.Class", Field, 0, ""},
+		{"FileHeader.Data", Field, 0, ""},
+		{"FileHeader.Entry", Field, 1, ""},
+		{"FileHeader.Machine", Field, 0, ""},
+		{"FileHeader.OSABI", Field, 0, ""},
+		{"FileHeader.Type", Field, 0, ""},
+		{"FileHeader.Version", Field, 0, ""},
+		{"FormatError", Type, 0, ""},
+		{"Header32", Type, 0, ""},
+		{"Header32.Ehsize", Field, 0, ""},
+		{"Header32.Entry", Field, 0, ""},
+		{"Header32.Flags", Field, 0, ""},
+		{"Header32.Ident", Field, 0, ""},
+		{"Header32.Machine", Field, 0, ""},
+		{"Header32.Phentsize", Field, 0, ""},
+		{"Header32.Phnum", Field, 0, ""},
+		{"Header32.Phoff", Field, 0, ""},
+		{"Header32.Shentsize", Field, 0, ""},
+		{"Header32.Shnum", Field, 0, ""},
+		{"Header32.Shoff", Field, 0, ""},
+		{"Header32.Shstrndx", Field, 0, ""},
+		{"Header32.Type", Field, 0, ""},
+		{"Header32.Version", Field, 0, ""},
+		{"Header64", Type, 0, ""},
+		{"Header64.Ehsize", Field, 0, ""},
+		{"Header64.Entry", Field, 0, ""},
+		{"Header64.Flags", Field, 0, ""},
+		{"Header64.Ident", Field, 0, ""},
+		{"Header64.Machine", Field, 0, ""},
+		{"Header64.Phentsize", Field, 0, ""},
+		{"Header64.Phnum", Field, 0, ""},
+		{"Header64.Phoff", Field, 0, ""},
+		{"Header64.Shentsize", Field, 0, ""},
+		{"Header64.Shnum", Field, 0, ""},
+		{"Header64.Shoff", Field, 0, ""},
+		{"Header64.Shstrndx", Field, 0, ""},
+		{"Header64.Type", Field, 0, ""},
+		{"Header64.Version", Field, 0, ""},
+		{"ImportedSymbol", Type, 0, ""},
+		{"ImportedSymbol.Library", Field, 0, ""},
+		{"ImportedSymbol.Name", Field, 0, ""},
+		{"ImportedSymbol.Version", Field, 0, ""},
+		{"Machine", Type, 0, ""},
+		{"NT_FPREGSET", Const, 0, ""},
+		{"NT_PRPSINFO", Const, 0, ""},
+		{"NT_PRSTATUS", Const, 0, ""},
+		{"NType", Type, 0, ""},
+		{"NewFile", Func, 0, "func(r io.ReaderAt) (*File, error)"},
+		{"OSABI", Type, 0, ""},
+		{"Open", Func, 0, "func(name string) (*File, error)"},
+		{"PF_MASKOS", Const, 0, ""},
+		{"PF_MASKPROC", Const, 0, ""},
+		{"PF_R", Const, 0, ""},
+		{"PF_W", Const, 0, ""},
+		{"PF_X", Const, 0, ""},
+		{"PT_AARCH64_ARCHEXT", Const, 16, ""},
+		{"PT_AARCH64_UNWIND", Const, 16, ""},
+		{"PT_ARM_ARCHEXT", Const, 16, ""},
+		{"PT_ARM_EXIDX", Const, 16, ""},
+		{"PT_DYNAMIC", Const, 0, ""},
+		{"PT_GNU_EH_FRAME", Const, 16, ""},
+		{"PT_GNU_MBIND_HI", Const, 16, ""},
+		{"PT_GNU_MBIND_LO", Const, 16, ""},
+		{"PT_GNU_PROPERTY", Const, 16, ""},
+		{"PT_GNU_RELRO", Const, 16, ""},
+		{"PT_GNU_STACK", Const, 16, ""},
+		{"PT_HIOS", Const, 0, ""},
+		{"PT_HIPROC", Const, 0, ""},
+		{"PT_INTERP", Const, 0, ""},
+		{"PT_LOAD", Const, 0, ""},
+		{"PT_LOOS", Const, 0, ""},
+		{"PT_LOPROC", Const, 0, ""},
+		{"PT_MIPS_ABIFLAGS", Const, 16, ""},
+		{"PT_MIPS_OPTIONS", Const, 16, ""},
+		{"PT_MIPS_REGINFO", Const, 16, ""},
+		{"PT_MIPS_RTPROC", Const, 16, ""},
+		{"PT_NOTE", Const, 0, ""},
+		{"PT_NULL", Const, 0, ""},
+		{"PT_OPENBSD_BOOTDATA", Const, 16, ""},
+		{"PT_OPENBSD_NOBTCFI", Const, 23, ""},
+		{"PT_OPENBSD_RANDOMIZE", Const, 16, ""},
+		{"PT_OPENBSD_WXNEEDED", Const, 16, ""},
+		{"PT_PAX_FLAGS", Const, 16, ""},
+		{"PT_PHDR", Const, 0, ""},
+		{"PT_RISCV_ATTRIBUTES", Const, 25, ""},
+		{"PT_S390_PGSTE", Const, 16, ""},
+		{"PT_SHLIB", Const, 0, ""},
+		{"PT_SUNWSTACK", Const, 16, ""},
+		{"PT_SUNW_EH_FRAME", Const, 16, ""},
+		{"PT_TLS", Const, 0, ""},
+		{"Prog", Type, 0, ""},
+		{"Prog.ProgHeader", Field, 0, ""},
+		{"Prog.ReaderAt", Field, 0, ""},
+		{"Prog32", Type, 0, ""},
+		{"Prog32.Align", Field, 0, ""},
+		{"Prog32.Filesz", Field, 0, ""},
+		{"Prog32.Flags", Field, 0, ""},
+		{"Prog32.Memsz", Field, 0, ""},
+		{"Prog32.Off", Field, 0, ""},
+		{"Prog32.Paddr", Field, 0, ""},
+		{"Prog32.Type", Field, 0, ""},
+		{"Prog32.Vaddr", Field, 0, ""},
+		{"Prog64", Type, 0, ""},
+		{"Prog64.Align", Field, 0, ""},
+		{"Prog64.Filesz", Field, 0, ""},
+		{"Prog64.Flags", Field, 0, ""},
+		{"Prog64.Memsz", Field, 0, ""},
+		{"Prog64.Off", Field, 0, ""},
+		{"Prog64.Paddr", Field, 0, ""},
+		{"Prog64.Type", Field, 0, ""},
+		{"Prog64.Vaddr", Field, 0, ""},
+		{"ProgFlag", Type, 0, ""},
+		{"ProgHeader", Type, 0, ""},
+		{"ProgHeader.Align", Field, 0, ""},
+		{"ProgHeader.Filesz", Field, 0, ""},
+		{"ProgHeader.Flags", Field, 0, ""},
+		{"ProgHeader.Memsz", Field, 0, ""},
+		{"ProgHeader.Off", Field, 0, ""},
+		{"ProgHeader.Paddr", Field, 0, ""},
+		{"ProgHeader.Type", Field, 0, ""},
+		{"ProgHeader.Vaddr", Field, 0, ""},
+		{"ProgType", Type, 0, ""},
+		{"R_386", Type, 0, ""},
+		{"R_386_16", Const, 10, ""},
+		{"R_386_32", Const, 0, ""},
+		{"R_386_32PLT", Const, 10, ""},
+		{"R_386_8", Const, 10, ""},
+		{"R_386_COPY", Const, 0, ""},
+		{"R_386_GLOB_DAT", Const, 0, ""},
+		{"R_386_GOT32", Const, 0, ""},
+		{"R_386_GOT32X", Const, 10, ""},
+		{"R_386_GOTOFF", Const, 0, ""},
+		{"R_386_GOTPC", Const, 0, ""},
+		{"R_386_IRELATIVE", Const, 10, ""},
+		{"R_386_JMP_SLOT", Const, 0, ""},
+		{"R_386_NONE", Const, 0, ""},
+		{"R_386_PC16", Const, 10, ""},
+		{"R_386_PC32", Const, 0, ""},
+		{"R_386_PC8", Const, 10, ""},
+		{"R_386_PLT32", Const, 0, ""},
+		{"R_386_RELATIVE", Const, 0, ""},
+		{"R_386_SIZE32", Const, 10, ""},
+		{"R_386_TLS_DESC", Const, 10, ""},
+		{"R_386_TLS_DESC_CALL", Const, 10, ""},
+		{"R_386_TLS_DTPMOD32", Const, 0, ""},
+		{"R_386_TLS_DTPOFF32", Const, 0, ""},
+		{"R_386_TLS_GD", Const, 0, ""},
+		{"R_386_TLS_GD_32", Const, 0, ""},
+		{"R_386_TLS_GD_CALL", Const, 0, ""},
+		{"R_386_TLS_GD_POP", Const, 0, ""},
+		{"R_386_TLS_GD_PUSH", Const, 0, ""},
+		{"R_386_TLS_GOTDESC", Const, 10, ""},
+		{"R_386_TLS_GOTIE", Const, 0, ""},
+		{"R_386_TLS_IE", Const, 0, ""},
+		{"R_386_TLS_IE_32", Const, 0, ""},
+		{"R_386_TLS_LDM", Const, 0, ""},
+		{"R_386_TLS_LDM_32", Const, 0, ""},
+		{"R_386_TLS_LDM_CALL", Const, 0, ""},
+		{"R_386_TLS_LDM_POP", Const, 0, ""},
+		{"R_386_TLS_LDM_PUSH", Const, 0, ""},
+		{"R_386_TLS_LDO_32", Const, 0, ""},
+		{"R_386_TLS_LE", Const, 0, ""},
+		{"R_386_TLS_LE_32", Const, 0, ""},
+		{"R_386_TLS_TPOFF", Const, 0, ""},
+		{"R_386_TLS_TPOFF32", Const, 0, ""},
+		{"R_390", Type, 7, ""},
+		{"R_390_12", Const, 7, ""},
+		{"R_390_16", Const, 7, ""},
+		{"R_390_20", Const, 7, ""},
+		{"R_390_32", Const, 7, ""},
+		{"R_390_64", Const, 7, ""},
+		{"R_390_8", Const, 7, ""},
+		{"R_390_COPY", Const, 7, ""},
+		{"R_390_GLOB_DAT", Const, 7, ""},
+		{"R_390_GOT12", Const, 7, ""},
+		{"R_390_GOT16", Const, 7, ""},
+		{"R_390_GOT20", Const, 7, ""},
+		{"R_390_GOT32", Const, 7, ""},
+		{"R_390_GOT64", Const, 7, ""},
+		{"R_390_GOTENT", Const, 7, ""},
+		{"R_390_GOTOFF", Const, 7, ""},
+		{"R_390_GOTOFF16", Const, 7, ""},
+		{"R_390_GOTOFF64", Const, 7, ""},
+		{"R_390_GOTPC", Const, 7, ""},
+		{"R_390_GOTPCDBL", Const, 7, ""},
+		{"R_390_GOTPLT12", Const, 7, ""},
+		{"R_390_GOTPLT16", Const, 7, ""},
+		{"R_390_GOTPLT20", Const, 7, ""},
+		{"R_390_GOTPLT32", Const, 7, ""},
+		{"R_390_GOTPLT64", Const, 7, ""},
+		{"R_390_GOTPLTENT", Const, 7, ""},
+		{"R_390_GOTPLTOFF16", Const, 7, ""},
+		{"R_390_GOTPLTOFF32", Const, 7, ""},
+		{"R_390_GOTPLTOFF64", Const, 7, ""},
+		{"R_390_JMP_SLOT", Const, 7, ""},
+		{"R_390_NONE", Const, 7, ""},
+		{"R_390_PC16", Const, 7, ""},
+		{"R_390_PC16DBL", Const, 7, ""},
+		{"R_390_PC32", Const, 7, ""},
+		{"R_390_PC32DBL", Const, 7, ""},
+		{"R_390_PC64", Const, 7, ""},
+		{"R_390_PLT16DBL", Const, 7, ""},
+		{"R_390_PLT32", Const, 7, ""},
+		{"R_390_PLT32DBL", Const, 7, ""},
+		{"R_390_PLT64", Const, 7, ""},
+		{"R_390_RELATIVE", Const, 7, ""},
+		{"R_390_TLS_DTPMOD", Const, 7, ""},
+		{"R_390_TLS_DTPOFF", Const, 7, ""},
+		{"R_390_TLS_GD32", Const, 7, ""},
+		{"R_390_TLS_GD64", Const, 7, ""},
+		{"R_390_TLS_GDCALL", Const, 7, ""},
+		{"R_390_TLS_GOTIE12", Const, 7, ""},
+		{"R_390_TLS_GOTIE20", Const, 7, ""},
+		{"R_390_TLS_GOTIE32", Const, 7, ""},
+		{"R_390_TLS_GOTIE64", Const, 7, ""},
+		{"R_390_TLS_IE32", Const, 7, ""},
+		{"R_390_TLS_IE64", Const, 7, ""},
+		{"R_390_TLS_IEENT", Const, 7, ""},
+		{"R_390_TLS_LDCALL", Const, 7, ""},
+		{"R_390_TLS_LDM32", Const, 7, ""},
+		{"R_390_TLS_LDM64", Const, 7, ""},
+		{"R_390_TLS_LDO32", Const, 7, ""},
+		{"R_390_TLS_LDO64", Const, 7, ""},
+		{"R_390_TLS_LE32", Const, 7, ""},
+		{"R_390_TLS_LE64", Const, 7, ""},
+		{"R_390_TLS_LOAD", Const, 7, ""},
+		{"R_390_TLS_TPOFF", Const, 7, ""},
+		{"R_AARCH64", Type, 4, ""},
+		{"R_AARCH64_ABS16", Const, 4, ""},
+		{"R_AARCH64_ABS32", Const, 4, ""},
+		{"R_AARCH64_ABS64", Const, 4, ""},
+		{"R_AARCH64_ADD_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_ADR_GOT_PAGE", Const, 4, ""},
+		{"R_AARCH64_ADR_PREL_LO21", Const, 4, ""},
+		{"R_AARCH64_ADR_PREL_PG_HI21", Const, 4, ""},
+		{"R_AARCH64_ADR_PREL_PG_HI21_NC", Const, 4, ""},
+		{"R_AARCH64_CALL26", Const, 4, ""},
+		{"R_AARCH64_CONDBR19", Const, 4, ""},
+		{"R_AARCH64_COPY", Const, 4, ""},
+		{"R_AARCH64_GLOB_DAT", Const, 4, ""},
+		{"R_AARCH64_GOT_LD_PREL19", Const, 4, ""},
+		{"R_AARCH64_IRELATIVE", Const, 4, ""},
+		{"R_AARCH64_JUMP26", Const, 4, ""},
+		{"R_AARCH64_JUMP_SLOT", Const, 4, ""},
+		{"R_AARCH64_LD64_GOTOFF_LO15", Const, 10, ""},
+		{"R_AARCH64_LD64_GOTPAGE_LO15", Const, 10, ""},
+		{"R_AARCH64_LD64_GOT_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_LDST128_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_LDST16_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_LDST32_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_LDST64_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_LDST8_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_LD_PREL_LO19", Const, 4, ""},
+		{"R_AARCH64_MOVW_SABS_G0", Const, 4, ""},
+		{"R_AARCH64_MOVW_SABS_G1", Const, 4, ""},
+		{"R_AARCH64_MOVW_SABS_G2", Const, 4, ""},
+		{"R_AARCH64_MOVW_UABS_G0", Const, 4, ""},
+		{"R_AARCH64_MOVW_UABS_G0_NC", Const, 4, ""},
+		{"R_AARCH64_MOVW_UABS_G1", Const, 4, ""},
+		{"R_AARCH64_MOVW_UABS_G1_NC", Const, 4, ""},
+		{"R_AARCH64_MOVW_UABS_G2", Const, 4, ""},
+		{"R_AARCH64_MOVW_UABS_G2_NC", Const, 4, ""},
+		{"R_AARCH64_MOVW_UABS_G3", Const, 4, ""},
+		{"R_AARCH64_NONE", Const, 4, ""},
+		{"R_AARCH64_NULL", Const, 4, ""},
+		{"R_AARCH64_P32_ABS16", Const, 4, ""},
+		{"R_AARCH64_P32_ABS32", Const, 4, ""},
+		{"R_AARCH64_P32_ADD_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_ADR_GOT_PAGE", Const, 4, ""},
+		{"R_AARCH64_P32_ADR_PREL_LO21", Const, 4, ""},
+		{"R_AARCH64_P32_ADR_PREL_PG_HI21", Const, 4, ""},
+		{"R_AARCH64_P32_CALL26", Const, 4, ""},
+		{"R_AARCH64_P32_CONDBR19", Const, 4, ""},
+		{"R_AARCH64_P32_COPY", Const, 4, ""},
+		{"R_AARCH64_P32_GLOB_DAT", Const, 4, ""},
+		{"R_AARCH64_P32_GOT_LD_PREL19", Const, 4, ""},
+		{"R_AARCH64_P32_IRELATIVE", Const, 4, ""},
+		{"R_AARCH64_P32_JUMP26", Const, 4, ""},
+		{"R_AARCH64_P32_JUMP_SLOT", Const, 4, ""},
+		{"R_AARCH64_P32_LD32_GOT_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_LDST128_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_LDST16_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_LDST32_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_LDST64_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_LDST8_ABS_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_LD_PREL_LO19", Const, 4, ""},
+		{"R_AARCH64_P32_MOVW_SABS_G0", Const, 4, ""},
+		{"R_AARCH64_P32_MOVW_UABS_G0", Const, 4, ""},
+		{"R_AARCH64_P32_MOVW_UABS_G0_NC", Const, 4, ""},
+		{"R_AARCH64_P32_MOVW_UABS_G1", Const, 4, ""},
+		{"R_AARCH64_P32_PREL16", Const, 4, ""},
+		{"R_AARCH64_P32_PREL32", Const, 4, ""},
+		{"R_AARCH64_P32_RELATIVE", Const, 4, ""},
+		{"R_AARCH64_P32_TLSDESC", Const, 4, ""},
+		{"R_AARCH64_P32_TLSDESC_ADD_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_TLSDESC_ADR_PAGE21", Const, 4, ""},
+		{"R_AARCH64_P32_TLSDESC_ADR_PREL21", Const, 4, ""},
+		{"R_AARCH64_P32_TLSDESC_CALL", Const, 4, ""},
+		{"R_AARCH64_P32_TLSDESC_LD32_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_TLSDESC_LD_PREL19", Const, 4, ""},
+		{"R_AARCH64_P32_TLSGD_ADD_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_TLSGD_ADR_PAGE21", Const, 4, ""},
+		{"R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4, ""},
+		{"R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19", Const, 4, ""},
+		{"R_AARCH64_P32_TLSLE_ADD_TPREL_HI12", Const, 4, ""},
+		{"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12", Const, 4, ""},
+		{"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0", Const, 4, ""},
+		{"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC", Const, 4, ""},
+		{"R_AARCH64_P32_TLSLE_MOVW_TPREL_G1", Const, 4, ""},
+		{"R_AARCH64_P32_TLS_DTPMOD", Const, 4, ""},
+		{"R_AARCH64_P32_TLS_DTPREL", Const, 4, ""},
+		{"R_AARCH64_P32_TLS_TPREL", Const, 4, ""},
+		{"R_AARCH64_P32_TSTBR14", Const, 4, ""},
+		{"R_AARCH64_PREL16", Const, 4, ""},
+		{"R_AARCH64_PREL32", Const, 4, ""},
+		{"R_AARCH64_PREL64", Const, 4, ""},
+		{"R_AARCH64_RELATIVE", Const, 4, ""},
+		{"R_AARCH64_TLSDESC", Const, 4, ""},
+		{"R_AARCH64_TLSDESC_ADD", Const, 4, ""},
+		{"R_AARCH64_TLSDESC_ADD_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_TLSDESC_ADR_PAGE21", Const, 4, ""},
+		{"R_AARCH64_TLSDESC_ADR_PREL21", Const, 4, ""},
+		{"R_AARCH64_TLSDESC_CALL", Const, 4, ""},
+		{"R_AARCH64_TLSDESC_LD64_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_TLSDESC_LDR", Const, 4, ""},
+		{"R_AARCH64_TLSDESC_LD_PREL19", Const, 4, ""},
+		{"R_AARCH64_TLSDESC_OFF_G0_NC", Const, 4, ""},
+		{"R_AARCH64_TLSDESC_OFF_G1", Const, 4, ""},
+		{"R_AARCH64_TLSGD_ADD_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_TLSGD_ADR_PAGE21", Const, 4, ""},
+		{"R_AARCH64_TLSGD_ADR_PREL21", Const, 10, ""},
+		{"R_AARCH64_TLSGD_MOVW_G0_NC", Const, 10, ""},
+		{"R_AARCH64_TLSGD_MOVW_G1", Const, 10, ""},
+		{"R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4, ""},
+		{"R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_TLSIE_LD_GOTTPREL_PREL19", Const, 4, ""},
+		{"R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC", Const, 4, ""},
+		{"R_AARCH64_TLSIE_MOVW_GOTTPREL_G1", Const, 4, ""},
+		{"R_AARCH64_TLSLD_ADR_PAGE21", Const, 10, ""},
+		{"R_AARCH64_TLSLD_ADR_PREL21", Const, 10, ""},
+		{"R_AARCH64_TLSLD_LDST128_DTPREL_LO12", Const, 10, ""},
+		{"R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC", Const, 10, ""},
+		{"R_AARCH64_TLSLE_ADD_TPREL_HI12", Const, 4, ""},
+		{"R_AARCH64_TLSLE_ADD_TPREL_LO12", Const, 4, ""},
+		{"R_AARCH64_TLSLE_ADD_TPREL_LO12_NC", Const, 4, ""},
+		{"R_AARCH64_TLSLE_LDST128_TPREL_LO12", Const, 10, ""},
+		{"R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC", Const, 10, ""},
+		{"R_AARCH64_TLSLE_MOVW_TPREL_G0", Const, 4, ""},
+		{"R_AARCH64_TLSLE_MOVW_TPREL_G0_NC", Const, 4, ""},
+		{"R_AARCH64_TLSLE_MOVW_TPREL_G1", Const, 4, ""},
+		{"R_AARCH64_TLSLE_MOVW_TPREL_G1_NC", Const, 4, ""},
+		{"R_AARCH64_TLSLE_MOVW_TPREL_G2", Const, 4, ""},
+		{"R_AARCH64_TLS_DTPMOD64", Const, 4, ""},
+		{"R_AARCH64_TLS_DTPREL64", Const, 4, ""},
+		{"R_AARCH64_TLS_TPREL64", Const, 4, ""},
+		{"R_AARCH64_TSTBR14", Const, 4, ""},
+		{"R_ALPHA", Type, 0, ""},
+		{"R_ALPHA_BRADDR", Const, 0, ""},
+		{"R_ALPHA_COPY", Const, 0, ""},
+		{"R_ALPHA_GLOB_DAT", Const, 0, ""},
+		{"R_ALPHA_GPDISP", Const, 0, ""},
+		{"R_ALPHA_GPREL32", Const, 0, ""},
+		{"R_ALPHA_GPRELHIGH", Const, 0, ""},
+		{"R_ALPHA_GPRELLOW", Const, 0, ""},
+		{"R_ALPHA_GPVALUE", Const, 0, ""},
+		{"R_ALPHA_HINT", Const, 0, ""},
+		{"R_ALPHA_IMMED_BR_HI32", Const, 0, ""},
+		{"R_ALPHA_IMMED_GP_16", Const, 0, ""},
+		{"R_ALPHA_IMMED_GP_HI32", Const, 0, ""},
+		{"R_ALPHA_IMMED_LO32", Const, 0, ""},
+		{"R_ALPHA_IMMED_SCN_HI32", Const, 0, ""},
+		{"R_ALPHA_JMP_SLOT", Const, 0, ""},
+		{"R_ALPHA_LITERAL", Const, 0, ""},
+		{"R_ALPHA_LITUSE", Const, 0, ""},
+		{"R_ALPHA_NONE", Const, 0, ""},
+		{"R_ALPHA_OP_PRSHIFT", Const, 0, ""},
+		{"R_ALPHA_OP_PSUB", Const, 0, ""},
+		{"R_ALPHA_OP_PUSH", Const, 0, ""},
+		{"R_ALPHA_OP_STORE", Const, 0, ""},
+		{"R_ALPHA_REFLONG", Const, 0, ""},
+		{"R_ALPHA_REFQUAD", Const, 0, ""},
+		{"R_ALPHA_RELATIVE", Const, 0, ""},
+		{"R_ALPHA_SREL16", Const, 0, ""},
+		{"R_ALPHA_SREL32", Const, 0, ""},
+		{"R_ALPHA_SREL64", Const, 0, ""},
+		{"R_ARM", Type, 0, ""},
+		{"R_ARM_ABS12", Const, 0, ""},
+		{"R_ARM_ABS16", Const, 0, ""},
+		{"R_ARM_ABS32", Const, 0, ""},
+		{"R_ARM_ABS32_NOI", Const, 10, ""},
+		{"R_ARM_ABS8", Const, 0, ""},
+		{"R_ARM_ALU_PCREL_15_8", Const, 10, ""},
+		{"R_ARM_ALU_PCREL_23_15", Const, 10, ""},
+		{"R_ARM_ALU_PCREL_7_0", Const, 10, ""},
+		{"R_ARM_ALU_PC_G0", Const, 10, ""},
+		{"R_ARM_ALU_PC_G0_NC", Const, 10, ""},
+		{"R_ARM_ALU_PC_G1", Const, 10, ""},
+		{"R_ARM_ALU_PC_G1_NC", Const, 10, ""},
+		{"R_ARM_ALU_PC_G2", Const, 10, ""},
+		{"R_ARM_ALU_SBREL_19_12_NC", Const, 10, ""},
+		{"R_ARM_ALU_SBREL_27_20_CK", Const, 10, ""},
+		{"R_ARM_ALU_SB_G0", Const, 10, ""},
+		{"R_ARM_ALU_SB_G0_NC", Const, 10, ""},
+		{"R_ARM_ALU_SB_G1", Const, 10, ""},
+		{"R_ARM_ALU_SB_G1_NC", Const, 10, ""},
+		{"R_ARM_ALU_SB_G2", Const, 10, ""},
+		{"R_ARM_AMP_VCALL9", Const, 0, ""},
+		{"R_ARM_BASE_ABS", Const, 10, ""},
+		{"R_ARM_CALL", Const, 10, ""},
+		{"R_ARM_COPY", Const, 0, ""},
+		{"R_ARM_GLOB_DAT", Const, 0, ""},
+		{"R_ARM_GNU_VTENTRY", Const, 0, ""},
+		{"R_ARM_GNU_VTINHERIT", Const, 0, ""},
+		{"R_ARM_GOT32", Const, 0, ""},
+		{"R_ARM_GOTOFF", Const, 0, ""},
+		{"R_ARM_GOTOFF12", Const, 10, ""},
+		{"R_ARM_GOTPC", Const, 0, ""},
+		{"R_ARM_GOTRELAX", Const, 10, ""},
+		{"R_ARM_GOT_ABS", Const, 10, ""},
+		{"R_ARM_GOT_BREL12", Const, 10, ""},
+		{"R_ARM_GOT_PREL", Const, 10, ""},
+		{"R_ARM_IRELATIVE", Const, 10, ""},
+		{"R_ARM_JUMP24", Const, 10, ""},
+		{"R_ARM_JUMP_SLOT", Const, 0, ""},
+		{"R_ARM_LDC_PC_G0", Const, 10, ""},
+		{"R_ARM_LDC_PC_G1", Const, 10, ""},
+		{"R_ARM_LDC_PC_G2", Const, 10, ""},
+		{"R_ARM_LDC_SB_G0", Const, 10, ""},
+		{"R_ARM_LDC_SB_G1", Const, 10, ""},
+		{"R_ARM_LDC_SB_G2", Const, 10, ""},
+		{"R_ARM_LDRS_PC_G0", Const, 10, ""},
+		{"R_ARM_LDRS_PC_G1", Const, 10, ""},
+		{"R_ARM_LDRS_PC_G2", Const, 10, ""},
+		{"R_ARM_LDRS_SB_G0", Const, 10, ""},
+		{"R_ARM_LDRS_SB_G1", Const, 10, ""},
+		{"R_ARM_LDRS_SB_G2", Const, 10, ""},
+		{"R_ARM_LDR_PC_G1", Const, 10, ""},
+		{"R_ARM_LDR_PC_G2", Const, 10, ""},
+		{"R_ARM_LDR_SBREL_11_10_NC", Const, 10, ""},
+		{"R_ARM_LDR_SB_G0", Const, 10, ""},
+		{"R_ARM_LDR_SB_G1", Const, 10, ""},
+		{"R_ARM_LDR_SB_G2", Const, 10, ""},
+		{"R_ARM_ME_TOO", Const, 10, ""},
+		{"R_ARM_MOVT_ABS", Const, 10, ""},
+		{"R_ARM_MOVT_BREL", Const, 10, ""},
+		{"R_ARM_MOVT_PREL", Const, 10, ""},
+		{"R_ARM_MOVW_ABS_NC", Const, 10, ""},
+		{"R_ARM_MOVW_BREL", Const, 10, ""},
+		{"R_ARM_MOVW_BREL_NC", Const, 10, ""},
+		{"R_ARM_MOVW_PREL_NC", Const, 10, ""},
+		{"R_ARM_NONE", Const, 0, ""},
+		{"R_ARM_PC13", Const, 0, ""},
+		{"R_ARM_PC24", Const, 0, ""},
+		{"R_ARM_PLT32", Const, 0, ""},
+		{"R_ARM_PLT32_ABS", Const, 10, ""},
+		{"R_ARM_PREL31", Const, 10, ""},
+		{"R_ARM_PRIVATE_0", Const, 10, ""},
+		{"R_ARM_PRIVATE_1", Const, 10, ""},
+		{"R_ARM_PRIVATE_10", Const, 10, ""},
+		{"R_ARM_PRIVATE_11", Const, 10, ""},
+		{"R_ARM_PRIVATE_12", Const, 10, ""},
+		{"R_ARM_PRIVATE_13", Const, 10, ""},
+		{"R_ARM_PRIVATE_14", Const, 10, ""},
+		{"R_ARM_PRIVATE_15", Const, 10, ""},
+		{"R_ARM_PRIVATE_2", Const, 10, ""},
+		{"R_ARM_PRIVATE_3", Const, 10, ""},
+		{"R_ARM_PRIVATE_4", Const, 10, ""},
+		{"R_ARM_PRIVATE_5", Const, 10, ""},
+		{"R_ARM_PRIVATE_6", Const, 10, ""},
+		{"R_ARM_PRIVATE_7", Const, 10, ""},
+		{"R_ARM_PRIVATE_8", Const, 10, ""},
+		{"R_ARM_PRIVATE_9", Const, 10, ""},
+		{"R_ARM_RABS32", Const, 0, ""},
+		{"R_ARM_RBASE", Const, 0, ""},
+		{"R_ARM_REL32", Const, 0, ""},
+		{"R_ARM_REL32_NOI", Const, 10, ""},
+		{"R_ARM_RELATIVE", Const, 0, ""},
+		{"R_ARM_RPC24", Const, 0, ""},
+		{"R_ARM_RREL32", Const, 0, ""},
+		{"R_ARM_RSBREL32", Const, 0, ""},
+		{"R_ARM_RXPC25", Const, 10, ""},
+		{"R_ARM_SBREL31", Const, 10, ""},
+		{"R_ARM_SBREL32", Const, 0, ""},
+		{"R_ARM_SWI24", Const, 0, ""},
+		{"R_ARM_TARGET1", Const, 10, ""},
+		{"R_ARM_TARGET2", Const, 10, ""},
+		{"R_ARM_THM_ABS5", Const, 0, ""},
+		{"R_ARM_THM_ALU_ABS_G0_NC", Const, 10, ""},
+		{"R_ARM_THM_ALU_ABS_G1_NC", Const, 10, ""},
+		{"R_ARM_THM_ALU_ABS_G2_NC", Const, 10, ""},
+		{"R_ARM_THM_ALU_ABS_G3", Const, 10, ""},
+		{"R_ARM_THM_ALU_PREL_11_0", Const, 10, ""},
+		{"R_ARM_THM_GOT_BREL12", Const, 10, ""},
+		{"R_ARM_THM_JUMP11", Const, 10, ""},
+		{"R_ARM_THM_JUMP19", Const, 10, ""},
+		{"R_ARM_THM_JUMP24", Const, 10, ""},
+		{"R_ARM_THM_JUMP6", Const, 10, ""},
+		{"R_ARM_THM_JUMP8", Const, 10, ""},
+		{"R_ARM_THM_MOVT_ABS", Const, 10, ""},
+		{"R_ARM_THM_MOVT_BREL", Const, 10, ""},
+		{"R_ARM_THM_MOVT_PREL", Const, 10, ""},
+		{"R_ARM_THM_MOVW_ABS_NC", Const, 10, ""},
+		{"R_ARM_THM_MOVW_BREL", Const, 10, ""},
+		{"R_ARM_THM_MOVW_BREL_NC", Const, 10, ""},
+		{"R_ARM_THM_MOVW_PREL_NC", Const, 10, ""},
+		{"R_ARM_THM_PC12", Const, 10, ""},
+		{"R_ARM_THM_PC22", Const, 0, ""},
+		{"R_ARM_THM_PC8", Const, 0, ""},
+		{"R_ARM_THM_RPC22", Const, 0, ""},
+		{"R_ARM_THM_SWI8", Const, 0, ""},
+		{"R_ARM_THM_TLS_CALL", Const, 10, ""},
+		{"R_ARM_THM_TLS_DESCSEQ16", Const, 10, ""},
+		{"R_ARM_THM_TLS_DESCSEQ32", Const, 10, ""},
+		{"R_ARM_THM_XPC22", Const, 0, ""},
+		{"R_ARM_TLS_CALL", Const, 10, ""},
+		{"R_ARM_TLS_DESCSEQ", Const, 10, ""},
+		{"R_ARM_TLS_DTPMOD32", Const, 10, ""},
+		{"R_ARM_TLS_DTPOFF32", Const, 10, ""},
+		{"R_ARM_TLS_GD32", Const, 10, ""},
+		{"R_ARM_TLS_GOTDESC", Const, 10, ""},
+		{"R_ARM_TLS_IE12GP", Const, 10, ""},
+		{"R_ARM_TLS_IE32", Const, 10, ""},
+		{"R_ARM_TLS_LDM32", Const, 10, ""},
+		{"R_ARM_TLS_LDO12", Const, 10, ""},
+		{"R_ARM_TLS_LDO32", Const, 10, ""},
+		{"R_ARM_TLS_LE12", Const, 10, ""},
+		{"R_ARM_TLS_LE32", Const, 10, ""},
+		{"R_ARM_TLS_TPOFF32", Const, 10, ""},
+		{"R_ARM_V4BX", Const, 10, ""},
+		{"R_ARM_XPC25", Const, 0, ""},
+		{"R_INFO", Func, 0, "func(sym uint32, typ uint32) uint64"},
+		{"R_INFO32", Func, 0, "func(sym uint32, typ uint32) uint32"},
+		{"R_LARCH", Type, 19, ""},
+		{"R_LARCH_32", Const, 19, ""},
+		{"R_LARCH_32_PCREL", Const, 20, ""},
+		{"R_LARCH_64", Const, 19, ""},
+		{"R_LARCH_64_PCREL", Const, 22, ""},
+		{"R_LARCH_ABS64_HI12", Const, 20, ""},
+		{"R_LARCH_ABS64_LO20", Const, 20, ""},
+		{"R_LARCH_ABS_HI20", Const, 20, ""},
+		{"R_LARCH_ABS_LO12", Const, 20, ""},
+		{"R_LARCH_ADD16", Const, 19, ""},
+		{"R_LARCH_ADD24", Const, 19, ""},
+		{"R_LARCH_ADD32", Const, 19, ""},
+		{"R_LARCH_ADD6", Const, 22, ""},
+		{"R_LARCH_ADD64", Const, 19, ""},
+		{"R_LARCH_ADD8", Const, 19, ""},
+		{"R_LARCH_ADD_ULEB128", Const, 22, ""},
+		{"R_LARCH_ALIGN", Const, 22, ""},
+		{"R_LARCH_B16", Const, 20, ""},
+		{"R_LARCH_B21", Const, 20, ""},
+		{"R_LARCH_B26", Const, 20, ""},
+		{"R_LARCH_CALL36", Const, 26, ""},
+		{"R_LARCH_CFA", Const, 22, ""},
+		{"R_LARCH_COPY", Const, 19, ""},
+		{"R_LARCH_DELETE", Const, 22, ""},
+		{"R_LARCH_GNU_VTENTRY", Const, 20, ""},
+		{"R_LARCH_GNU_VTINHERIT", Const, 20, ""},
+		{"R_LARCH_GOT64_HI12", Const, 20, ""},
+		{"R_LARCH_GOT64_LO20", Const, 20, ""},
+		{"R_LARCH_GOT64_PC_HI12", Const, 20, ""},
+		{"R_LARCH_GOT64_PC_LO20", Const, 20, ""},
+		{"R_LARCH_GOT_HI20", Const, 20, ""},
+		{"R_LARCH_GOT_LO12", Const, 20, ""},
+		{"R_LARCH_GOT_PC_HI20", Const, 20, ""},
+		{"R_LARCH_GOT_PC_LO12", Const, 20, ""},
+		{"R_LARCH_IRELATIVE", Const, 19, ""},
+		{"R_LARCH_JUMP_SLOT", Const, 19, ""},
+		{"R_LARCH_MARK_LA", Const, 19, ""},
+		{"R_LARCH_MARK_PCREL", Const, 19, ""},
+		{"R_LARCH_NONE", Const, 19, ""},
+		{"R_LARCH_PCALA64_HI12", Const, 20, ""},
+		{"R_LARCH_PCALA64_LO20", Const, 20, ""},
+		{"R_LARCH_PCALA_HI20", Const, 20, ""},
+		{"R_LARCH_PCALA_LO12", Const, 20, ""},
+		{"R_LARCH_PCREL20_S2", Const, 22, ""},
+		{"R_LARCH_RELATIVE", Const, 19, ""},
+		{"R_LARCH_RELAX", Const, 20, ""},
+		{"R_LARCH_SOP_ADD", Const, 19, ""},
+		{"R_LARCH_SOP_AND", Const, 19, ""},
+		{"R_LARCH_SOP_ASSERT", Const, 19, ""},
+		{"R_LARCH_SOP_IF_ELSE", Const, 19, ""},
+		{"R_LARCH_SOP_NOT", Const, 19, ""},
+		{"R_LARCH_SOP_POP_32_S_0_10_10_16_S2", Const, 19, ""},
+		{"R_LARCH_SOP_POP_32_S_0_5_10_16_S2", Const, 19, ""},
+		{"R_LARCH_SOP_POP_32_S_10_12", Const, 19, ""},
+		{"R_LARCH_SOP_POP_32_S_10_16", Const, 19, ""},
+		{"R_LARCH_SOP_POP_32_S_10_16_S2", Const, 19, ""},
+		{"R_LARCH_SOP_POP_32_S_10_5", Const, 19, ""},
+		{"R_LARCH_SOP_POP_32_S_5_20", Const, 19, ""},
+		{"R_LARCH_SOP_POP_32_U", Const, 19, ""},
+		{"R_LARCH_SOP_POP_32_U_10_12", Const, 19, ""},
+		{"R_LARCH_SOP_PUSH_ABSOLUTE", Const, 19, ""},
+		{"R_LARCH_SOP_PUSH_DUP", Const, 19, ""},
+		{"R_LARCH_SOP_PUSH_GPREL", Const, 19, ""},
+		{"R_LARCH_SOP_PUSH_PCREL", Const, 19, ""},
+		{"R_LARCH_SOP_PUSH_PLT_PCREL", Const, 19, ""},
+		{"R_LARCH_SOP_PUSH_TLS_GD", Const, 19, ""},
+		{"R_LARCH_SOP_PUSH_TLS_GOT", Const, 19, ""},
+		{"R_LARCH_SOP_PUSH_TLS_TPREL", Const, 19, ""},
+		{"R_LARCH_SOP_SL", Const, 19, ""},
+		{"R_LARCH_SOP_SR", Const, 19, ""},
+		{"R_LARCH_SOP_SUB", Const, 19, ""},
+		{"R_LARCH_SUB16", Const, 19, ""},
+		{"R_LARCH_SUB24", Const, 19, ""},
+		{"R_LARCH_SUB32", Const, 19, ""},
+		{"R_LARCH_SUB6", Const, 22, ""},
+		{"R_LARCH_SUB64", Const, 19, ""},
+		{"R_LARCH_SUB8", Const, 19, ""},
+		{"R_LARCH_SUB_ULEB128", Const, 22, ""},
+		{"R_LARCH_TLS_DESC32", Const, 26, ""},
+		{"R_LARCH_TLS_DESC64", Const, 26, ""},
+		{"R_LARCH_TLS_DESC64_HI12", Const, 26, ""},
+		{"R_LARCH_TLS_DESC64_LO20", Const, 26, ""},
+		{"R_LARCH_TLS_DESC64_PC_HI12", Const, 26, ""},
+		{"R_LARCH_TLS_DESC64_PC_LO20", Const, 26, ""},
+		{"R_LARCH_TLS_DESC_CALL", Const, 26, ""},
+		{"R_LARCH_TLS_DESC_HI20", Const, 26, ""},
+		{"R_LARCH_TLS_DESC_LD", Const, 26, ""},
+		{"R_LARCH_TLS_DESC_LO12", Const, 26, ""},
+		{"R_LARCH_TLS_DESC_PCREL20_S2", Const, 26, ""},
+		{"R_LARCH_TLS_DESC_PC_HI20", Const, 26, ""},
+		{"R_LARCH_TLS_DESC_PC_LO12", Const, 26, ""},
+		{"R_LARCH_TLS_DTPMOD32", Const, 19, ""},
+		{"R_LARCH_TLS_DTPMOD64", Const, 19, ""},
+		{"R_LARCH_TLS_DTPREL32", Const, 19, ""},
+		{"R_LARCH_TLS_DTPREL64", Const, 19, ""},
+		{"R_LARCH_TLS_GD_HI20", Const, 20, ""},
+		{"R_LARCH_TLS_GD_PCREL20_S2", Const, 26, ""},
+		{"R_LARCH_TLS_GD_PC_HI20", Const, 20, ""},
+		{"R_LARCH_TLS_IE64_HI12", Const, 20, ""},
+		{"R_LARCH_TLS_IE64_LO20", Const, 20, ""},
+		{"R_LARCH_TLS_IE64_PC_HI12", Const, 20, ""},
+		{"R_LARCH_TLS_IE64_PC_LO20", Const, 20, ""},
+		{"R_LARCH_TLS_IE_HI20", Const, 20, ""},
+		{"R_LARCH_TLS_IE_LO12", Const, 20, ""},
+		{"R_LARCH_TLS_IE_PC_HI20", Const, 20, ""},
+		{"R_LARCH_TLS_IE_PC_LO12", Const, 20, ""},
+		{"R_LARCH_TLS_LD_HI20", Const, 20, ""},
+		{"R_LARCH_TLS_LD_PCREL20_S2", Const, 26, ""},
+		{"R_LARCH_TLS_LD_PC_HI20", Const, 20, ""},
+		{"R_LARCH_TLS_LE64_HI12", Const, 20, ""},
+		{"R_LARCH_TLS_LE64_LO20", Const, 20, ""},
+		{"R_LARCH_TLS_LE_ADD_R", Const, 26, ""},
+		{"R_LARCH_TLS_LE_HI20", Const, 20, ""},
+		{"R_LARCH_TLS_LE_HI20_R", Const, 26, ""},
+		{"R_LARCH_TLS_LE_LO12", Const, 20, ""},
+		{"R_LARCH_TLS_LE_LO12_R", Const, 26, ""},
+		{"R_LARCH_TLS_TPREL32", Const, 19, ""},
+		{"R_LARCH_TLS_TPREL64", Const, 19, ""},
+		{"R_MIPS", Type, 6, ""},
+		{"R_MIPS_16", Const, 6, ""},
+		{"R_MIPS_26", Const, 6, ""},
+		{"R_MIPS_32", Const, 6, ""},
+		{"R_MIPS_64", Const, 6, ""},
+		{"R_MIPS_ADD_IMMEDIATE", Const, 6, ""},
+		{"R_MIPS_CALL16", Const, 6, ""},
+		{"R_MIPS_CALL_HI16", Const, 6, ""},
+		{"R_MIPS_CALL_LO16", Const, 6, ""},
+		{"R_MIPS_DELETE", Const, 6, ""},
+		{"R_MIPS_GOT16", Const, 6, ""},
+		{"R_MIPS_GOT_DISP", Const, 6, ""},
+		{"R_MIPS_GOT_HI16", Const, 6, ""},
+		{"R_MIPS_GOT_LO16", Const, 6, ""},
+		{"R_MIPS_GOT_OFST", Const, 6, ""},
+		{"R_MIPS_GOT_PAGE", Const, 6, ""},
+		{"R_MIPS_GPREL16", Const, 6, ""},
+		{"R_MIPS_GPREL32", Const, 6, ""},
+		{"R_MIPS_HI16", Const, 6, ""},
+		{"R_MIPS_HIGHER", Const, 6, ""},
+		{"R_MIPS_HIGHEST", Const, 6, ""},
+		{"R_MIPS_INSERT_A", Const, 6, ""},
+		{"R_MIPS_INSERT_B", Const, 6, ""},
+		{"R_MIPS_JALR", Const, 6, ""},
+		{"R_MIPS_LITERAL", Const, 6, ""},
+		{"R_MIPS_LO16", Const, 6, ""},
+		{"R_MIPS_NONE", Const, 6, ""},
+		{"R_MIPS_PC16", Const, 6, ""},
+		{"R_MIPS_PC32", Const, 22, ""},
+		{"R_MIPS_PJUMP", Const, 6, ""},
+		{"R_MIPS_REL16", Const, 6, ""},
+		{"R_MIPS_REL32", Const, 6, ""},
+		{"R_MIPS_RELGOT", Const, 6, ""},
+		{"R_MIPS_SCN_DISP", Const, 6, ""},
+		{"R_MIPS_SHIFT5", Const, 6, ""},
+		{"R_MIPS_SHIFT6", Const, 6, ""},
+		{"R_MIPS_SUB", Const, 6, ""},
+		{"R_MIPS_TLS_DTPMOD32", Const, 6, ""},
+		{"R_MIPS_TLS_DTPMOD64", Const, 6, ""},
+		{"R_MIPS_TLS_DTPREL32", Const, 6, ""},
+		{"R_MIPS_TLS_DTPREL64", Const, 6, ""},
+		{"R_MIPS_TLS_DTPREL_HI16", Const, 6, ""},
+		{"R_MIPS_TLS_DTPREL_LO16", Const, 6, ""},
+		{"R_MIPS_TLS_GD", Const, 6, ""},
+		{"R_MIPS_TLS_GOTTPREL", Const, 6, ""},
+		{"R_MIPS_TLS_LDM", Const, 6, ""},
+		{"R_MIPS_TLS_TPREL32", Const, 6, ""},
+		{"R_MIPS_TLS_TPREL64", Const, 6, ""},
+		{"R_MIPS_TLS_TPREL_HI16", Const, 6, ""},
+		{"R_MIPS_TLS_TPREL_LO16", Const, 6, ""},
+		{"R_PPC", Type, 0, ""},
+		{"R_PPC64", Type, 5, ""},
+		{"R_PPC64_ADDR14", Const, 5, ""},
+		{"R_PPC64_ADDR14_BRNTAKEN", Const, 5, ""},
+		{"R_PPC64_ADDR14_BRTAKEN", Const, 5, ""},
+		{"R_PPC64_ADDR16", Const, 5, ""},
+		{"R_PPC64_ADDR16_DS", Const, 5, ""},
+		{"R_PPC64_ADDR16_HA", Const, 5, ""},
+		{"R_PPC64_ADDR16_HI", Const, 5, ""},
+		{"R_PPC64_ADDR16_HIGH", Const, 10, ""},
+		{"R_PPC64_ADDR16_HIGHA", Const, 10, ""},
+		{"R_PPC64_ADDR16_HIGHER", Const, 5, ""},
+		{"R_PPC64_ADDR16_HIGHER34", Const, 20, ""},
+		{"R_PPC64_ADDR16_HIGHERA", Const, 5, ""},
+		{"R_PPC64_ADDR16_HIGHERA34", Const, 20, ""},
+		{"R_PPC64_ADDR16_HIGHEST", Const, 5, ""},
+		{"R_PPC64_ADDR16_HIGHEST34", Const, 20, ""},
+		{"R_PPC64_ADDR16_HIGHESTA", Const, 5, ""},
+		{"R_PPC64_ADDR16_HIGHESTA34", Const, 20, ""},
+		{"R_PPC64_ADDR16_LO", Const, 5, ""},
+		{"R_PPC64_ADDR16_LO_DS", Const, 5, ""},
+		{"R_PPC64_ADDR24", Const, 5, ""},
+		{"R_PPC64_ADDR32", Const, 5, ""},
+		{"R_PPC64_ADDR64", Const, 5, ""},
+		{"R_PPC64_ADDR64_LOCAL", Const, 10, ""},
+		{"R_PPC64_COPY", Const, 20, ""},
+		{"R_PPC64_D28", Const, 20, ""},
+		{"R_PPC64_D34", Const, 20, ""},
+		{"R_PPC64_D34_HA30", Const, 20, ""},
+		{"R_PPC64_D34_HI30", Const, 20, ""},
+		{"R_PPC64_D34_LO", Const, 20, ""},
+		{"R_PPC64_DTPMOD64", Const, 5, ""},
+		{"R_PPC64_DTPREL16", Const, 5, ""},
+		{"R_PPC64_DTPREL16_DS", Const, 5, ""},
+		{"R_PPC64_DTPREL16_HA", Const, 5, ""},
+		{"R_PPC64_DTPREL16_HI", Const, 5, ""},
+		{"R_PPC64_DTPREL16_HIGH", Const, 10, ""},
+		{"R_PPC64_DTPREL16_HIGHA", Const, 10, ""},
+		{"R_PPC64_DTPREL16_HIGHER", Const, 5, ""},
+		{"R_PPC64_DTPREL16_HIGHERA", Const, 5, ""},
+		{"R_PPC64_DTPREL16_HIGHEST", Const, 5, ""},
+		{"R_PPC64_DTPREL16_HIGHESTA", Const, 5, ""},
+		{"R_PPC64_DTPREL16_LO", Const, 5, ""},
+		{"R_PPC64_DTPREL16_LO_DS", Const, 5, ""},
+		{"R_PPC64_DTPREL34", Const, 20, ""},
+		{"R_PPC64_DTPREL64", Const, 5, ""},
+		{"R_PPC64_ENTRY", Const, 10, ""},
+		{"R_PPC64_GLOB_DAT", Const, 20, ""},
+		{"R_PPC64_GNU_VTENTRY", Const, 20, ""},
+		{"R_PPC64_GNU_VTINHERIT", Const, 20, ""},
+		{"R_PPC64_GOT16", Const, 5, ""},
+		{"R_PPC64_GOT16_DS", Const, 5, ""},
+		{"R_PPC64_GOT16_HA", Const, 5, ""},
+		{"R_PPC64_GOT16_HI", Const, 5, ""},
+		{"R_PPC64_GOT16_LO", Const, 5, ""},
+		{"R_PPC64_GOT16_LO_DS", Const, 5, ""},
+		{"R_PPC64_GOT_DTPREL16_DS", Const, 5, ""},
+		{"R_PPC64_GOT_DTPREL16_HA", Const, 5, ""},
+		{"R_PPC64_GOT_DTPREL16_HI", Const, 5, ""},
+		{"R_PPC64_GOT_DTPREL16_LO_DS", Const, 5, ""},
+		{"R_PPC64_GOT_DTPREL_PCREL34", Const, 20, ""},
+		{"R_PPC64_GOT_PCREL34", Const, 20, ""},
+		{"R_PPC64_GOT_TLSGD16", Const, 5, ""},
+		{"R_PPC64_GOT_TLSGD16_HA", Const, 5, ""},
+		{"R_PPC64_GOT_TLSGD16_HI", Const, 5, ""},
+		{"R_PPC64_GOT_TLSGD16_LO", Const, 5, ""},
+		{"R_PPC64_GOT_TLSGD_PCREL34", Const, 20, ""},
+		{"R_PPC64_GOT_TLSLD16", Const, 5, ""},
+		{"R_PPC64_GOT_TLSLD16_HA", Const, 5, ""},
+		{"R_PPC64_GOT_TLSLD16_HI", Const, 5, ""},
+		{"R_PPC64_GOT_TLSLD16_LO", Const, 5, ""},
+		{"R_PPC64_GOT_TLSLD_PCREL34", Const, 20, ""},
+		{"R_PPC64_GOT_TPREL16_DS", Const, 5, ""},
+		{"R_PPC64_GOT_TPREL16_HA", Const, 5, ""},
+		{"R_PPC64_GOT_TPREL16_HI", Const, 5, ""},
+		{"R_PPC64_GOT_TPREL16_LO_DS", Const, 5, ""},
+		{"R_PPC64_GOT_TPREL_PCREL34", Const, 20, ""},
+		{"R_PPC64_IRELATIVE", Const, 10, ""},
+		{"R_PPC64_JMP_IREL", Const, 10, ""},
+		{"R_PPC64_JMP_SLOT", Const, 5, ""},
+		{"R_PPC64_NONE", Const, 5, ""},
+		{"R_PPC64_PCREL28", Const, 20, ""},
+		{"R_PPC64_PCREL34", Const, 20, ""},
+		{"R_PPC64_PCREL_OPT", Const, 20, ""},
+		{"R_PPC64_PLT16_HA", Const, 20, ""},
+		{"R_PPC64_PLT16_HI", Const, 20, ""},
+		{"R_PPC64_PLT16_LO", Const, 20, ""},
+		{"R_PPC64_PLT16_LO_DS", Const, 10, ""},
+		{"R_PPC64_PLT32", Const, 20, ""},
+		{"R_PPC64_PLT64", Const, 20, ""},
+		{"R_PPC64_PLTCALL", Const, 20, ""},
+		{"R_PPC64_PLTCALL_NOTOC", Const, 20, ""},
+		{"R_PPC64_PLTGOT16", Const, 10, ""},
+		{"R_PPC64_PLTGOT16_DS", Const, 10, ""},
+		{"R_PPC64_PLTGOT16_HA", Const, 10, ""},
+		{"R_PPC64_PLTGOT16_HI", Const, 10, ""},
+		{"R_PPC64_PLTGOT16_LO", Const, 10, ""},
+		{"R_PPC64_PLTGOT_LO_DS", Const, 10, ""},
+		{"R_PPC64_PLTREL32", Const, 20, ""},
+		{"R_PPC64_PLTREL64", Const, 20, ""},
+		{"R_PPC64_PLTSEQ", Const, 20, ""},
+		{"R_PPC64_PLTSEQ_NOTOC", Const, 20, ""},
+		{"R_PPC64_PLT_PCREL34", Const, 20, ""},
+		{"R_PPC64_PLT_PCREL34_NOTOC", Const, 20, ""},
+		{"R_PPC64_REL14", Const, 5, ""},
+		{"R_PPC64_REL14_BRNTAKEN", Const, 5, ""},
+		{"R_PPC64_REL14_BRTAKEN", Const, 5, ""},
+		{"R_PPC64_REL16", Const, 5, ""},
+		{"R_PPC64_REL16DX_HA", Const, 10, ""},
+		{"R_PPC64_REL16_HA", Const, 5, ""},
+		{"R_PPC64_REL16_HI", Const, 5, ""},
+		{"R_PPC64_REL16_HIGH", Const, 20, ""},
+		{"R_PPC64_REL16_HIGHA", Const, 20, ""},
+		{"R_PPC64_REL16_HIGHER", Const, 20, ""},
+		{"R_PPC64_REL16_HIGHER34", Const, 20, ""},
+		{"R_PPC64_REL16_HIGHERA", Const, 20, ""},
+		{"R_PPC64_REL16_HIGHERA34", Const, 20, ""},
+		{"R_PPC64_REL16_HIGHEST", Const, 20, ""},
+		{"R_PPC64_REL16_HIGHEST34", Const, 20, ""},
+		{"R_PPC64_REL16_HIGHESTA", Const, 20, ""},
+		{"R_PPC64_REL16_HIGHESTA34", Const, 20, ""},
+		{"R_PPC64_REL16_LO", Const, 5, ""},
+		{"R_PPC64_REL24", Const, 5, ""},
+		{"R_PPC64_REL24_NOTOC", Const, 10, ""},
+		{"R_PPC64_REL24_P9NOTOC", Const, 21, ""},
+		{"R_PPC64_REL30", Const, 20, ""},
+		{"R_PPC64_REL32", Const, 5, ""},
+		{"R_PPC64_REL64", Const, 5, ""},
+		{"R_PPC64_RELATIVE", Const, 18, ""},
+		{"R_PPC64_SECTOFF", Const, 20, ""},
+		{"R_PPC64_SECTOFF_DS", Const, 10, ""},
+		{"R_PPC64_SECTOFF_HA", Const, 20, ""},
+		{"R_PPC64_SECTOFF_HI", Const, 20, ""},
+		{"R_PPC64_SECTOFF_LO", Const, 20, ""},
+		{"R_PPC64_SECTOFF_LO_DS", Const, 10, ""},
+		{"R_PPC64_TLS", Const, 5, ""},
+		{"R_PPC64_TLSGD", Const, 5, ""},
+		{"R_PPC64_TLSLD", Const, 5, ""},
+		{"R_PPC64_TOC", Const, 5, ""},
+		{"R_PPC64_TOC16", Const, 5, ""},
+		{"R_PPC64_TOC16_DS", Const, 5, ""},
+		{"R_PPC64_TOC16_HA", Const, 5, ""},
+		{"R_PPC64_TOC16_HI", Const, 5, ""},
+		{"R_PPC64_TOC16_LO", Const, 5, ""},
+		{"R_PPC64_TOC16_LO_DS", Const, 5, ""},
+		{"R_PPC64_TOCSAVE", Const, 10, ""},
+		{"R_PPC64_TPREL16", Const, 5, ""},
+		{"R_PPC64_TPREL16_DS", Const, 5, ""},
+		{"R_PPC64_TPREL16_HA", Const, 5, ""},
+		{"R_PPC64_TPREL16_HI", Const, 5, ""},
+		{"R_PPC64_TPREL16_HIGH", Const, 10, ""},
+		{"R_PPC64_TPREL16_HIGHA", Const, 10, ""},
+		{"R_PPC64_TPREL16_HIGHER", Const, 5, ""},
+		{"R_PPC64_TPREL16_HIGHERA", Const, 5, ""},
+		{"R_PPC64_TPREL16_HIGHEST", Const, 5, ""},
+		{"R_PPC64_TPREL16_HIGHESTA", Const, 5, ""},
+		{"R_PPC64_TPREL16_LO", Const, 5, ""},
+		{"R_PPC64_TPREL16_LO_DS", Const, 5, ""},
+		{"R_PPC64_TPREL34", Const, 20, ""},
+		{"R_PPC64_TPREL64", Const, 5, ""},
+		{"R_PPC64_UADDR16", Const, 20, ""},
+		{"R_PPC64_UADDR32", Const, 20, ""},
+		{"R_PPC64_UADDR64", Const, 20, ""},
+		{"R_PPC_ADDR14", Const, 0, ""},
+		{"R_PPC_ADDR14_BRNTAKEN", Const, 0, ""},
+		{"R_PPC_ADDR14_BRTAKEN", Const, 0, ""},
+		{"R_PPC_ADDR16", Const, 0, ""},
+		{"R_PPC_ADDR16_HA", Const, 0, ""},
+		{"R_PPC_ADDR16_HI", Const, 0, ""},
+		{"R_PPC_ADDR16_LO", Const, 0, ""},
+		{"R_PPC_ADDR24", Const, 0, ""},
+		{"R_PPC_ADDR32", Const, 0, ""},
+		{"R_PPC_COPY", Const, 0, ""},
+		{"R_PPC_DTPMOD32", Const, 0, ""},
+		{"R_PPC_DTPREL16", Const, 0, ""},
+		{"R_PPC_DTPREL16_HA", Const, 0, ""},
+		{"R_PPC_DTPREL16_HI", Const, 0, ""},
+		{"R_PPC_DTPREL16_LO", Const, 0, ""},
+		{"R_PPC_DTPREL32", Const, 0, ""},
+		{"R_PPC_EMB_BIT_FLD", Const, 0, ""},
+		{"R_PPC_EMB_MRKREF", Const, 0, ""},
+		{"R_PPC_EMB_NADDR16", Const, 0, ""},
+		{"R_PPC_EMB_NADDR16_HA", Const, 0, ""},
+		{"R_PPC_EMB_NADDR16_HI", Const, 0, ""},
+		{"R_PPC_EMB_NADDR16_LO", Const, 0, ""},
+		{"R_PPC_EMB_NADDR32", Const, 0, ""},
+		{"R_PPC_EMB_RELSDA", Const, 0, ""},
+		{"R_PPC_EMB_RELSEC16", Const, 0, ""},
+		{"R_PPC_EMB_RELST_HA", Const, 0, ""},
+		{"R_PPC_EMB_RELST_HI", Const, 0, ""},
+		{"R_PPC_EMB_RELST_LO", Const, 0, ""},
+		{"R_PPC_EMB_SDA21", Const, 0, ""},
+		{"R_PPC_EMB_SDA2I16", Const, 0, ""},
+		{"R_PPC_EMB_SDA2REL", Const, 0, ""},
+		{"R_PPC_EMB_SDAI16", Const, 0, ""},
+		{"R_PPC_GLOB_DAT", Const, 0, ""},
+		{"R_PPC_GOT16", Const, 0, ""},
+		{"R_PPC_GOT16_HA", Const, 0, ""},
+		{"R_PPC_GOT16_HI", Const, 0, ""},
+		{"R_PPC_GOT16_LO", Const, 0, ""},
+		{"R_PPC_GOT_TLSGD16", Const, 0, ""},
+		{"R_PPC_GOT_TLSGD16_HA", Const, 0, ""},
+		{"R_PPC_GOT_TLSGD16_HI", Const, 0, ""},
+		{"R_PPC_GOT_TLSGD16_LO", Const, 0, ""},
+		{"R_PPC_GOT_TLSLD16", Const, 0, ""},
+		{"R_PPC_GOT_TLSLD16_HA", Const, 0, ""},
+		{"R_PPC_GOT_TLSLD16_HI", Const, 0, ""},
+		{"R_PPC_GOT_TLSLD16_LO", Const, 0, ""},
+		{"R_PPC_GOT_TPREL16", Const, 0, ""},
+		{"R_PPC_GOT_TPREL16_HA", Const, 0, ""},
+		{"R_PPC_GOT_TPREL16_HI", Const, 0, ""},
+		{"R_PPC_GOT_TPREL16_LO", Const, 0, ""},
+		{"R_PPC_JMP_SLOT", Const, 0, ""},
+		{"R_PPC_LOCAL24PC", Const, 0, ""},
+		{"R_PPC_NONE", Const, 0, ""},
+		{"R_PPC_PLT16_HA", Const, 0, ""},
+		{"R_PPC_PLT16_HI", Const, 0, ""},
+		{"R_PPC_PLT16_LO", Const, 0, ""},
+		{"R_PPC_PLT32", Const, 0, ""},
+		{"R_PPC_PLTREL24", Const, 0, ""},
+		{"R_PPC_PLTREL32", Const, 0, ""},
+		{"R_PPC_REL14", Const, 0, ""},
+		{"R_PPC_REL14_BRNTAKEN", Const, 0, ""},
+		{"R_PPC_REL14_BRTAKEN", Const, 0, ""},
+		{"R_PPC_REL24", Const, 0, ""},
+		{"R_PPC_REL32", Const, 0, ""},
+		{"R_PPC_RELATIVE", Const, 0, ""},
+		{"R_PPC_SDAREL16", Const, 0, ""},
+		{"R_PPC_SECTOFF", Const, 0, ""},
+		{"R_PPC_SECTOFF_HA", Const, 0, ""},
+		{"R_PPC_SECTOFF_HI", Const, 0, ""},
+		{"R_PPC_SECTOFF_LO", Const, 0, ""},
+		{"R_PPC_TLS", Const, 0, ""},
+		{"R_PPC_TPREL16", Const, 0, ""},
+		{"R_PPC_TPREL16_HA", Const, 0, ""},
+		{"R_PPC_TPREL16_HI", Const, 0, ""},
+		{"R_PPC_TPREL16_LO", Const, 0, ""},
+		{"R_PPC_TPREL32", Const, 0, ""},
+		{"R_PPC_UADDR16", Const, 0, ""},
+		{"R_PPC_UADDR32", Const, 0, ""},
+		{"R_RISCV", Type, 11, ""},
+		{"R_RISCV_32", Const, 11, ""},
+		{"R_RISCV_32_PCREL", Const, 12, ""},
+		{"R_RISCV_64", Const, 11, ""},
+		{"R_RISCV_ADD16", Const, 11, ""},
+		{"R_RISCV_ADD32", Const, 11, ""},
+		{"R_RISCV_ADD64", Const, 11, ""},
+		{"R_RISCV_ADD8", Const, 11, ""},
+		{"R_RISCV_ALIGN", Const, 11, ""},
+		{"R_RISCV_BRANCH", Const, 11, ""},
+		{"R_RISCV_CALL", Const, 11, ""},
+		{"R_RISCV_CALL_PLT", Const, 11, ""},
+		{"R_RISCV_COPY", Const, 11, ""},
+		{"R_RISCV_GNU_VTENTRY", Const, 11, ""},
+		{"R_RISCV_GNU_VTINHERIT", Const, 11, ""},
+		{"R_RISCV_GOT_HI20", Const, 11, ""},
+		{"R_RISCV_GPREL_I", Const, 11, ""},
+		{"R_RISCV_GPREL_S", Const, 11, ""},
+		{"R_RISCV_HI20", Const, 11, ""},
+		{"R_RISCV_JAL", Const, 11, ""},
+		{"R_RISCV_JUMP_SLOT", Const, 11, ""},
+		{"R_RISCV_LO12_I", Const, 11, ""},
+		{"R_RISCV_LO12_S", Const, 11, ""},
+		{"R_RISCV_NONE", Const, 11, ""},
+		{"R_RISCV_PCREL_HI20", Const, 11, ""},
+		{"R_RISCV_PCREL_LO12_I", Const, 11, ""},
+		{"R_RISCV_PCREL_LO12_S", Const, 11, ""},
+		{"R_RISCV_RELATIVE", Const, 11, ""},
+		{"R_RISCV_RELAX", Const, 11, ""},
+		{"R_RISCV_RVC_BRANCH", Const, 11, ""},
+		{"R_RISCV_RVC_JUMP", Const, 11, ""},
+		{"R_RISCV_RVC_LUI", Const, 11, ""},
+		{"R_RISCV_SET16", Const, 11, ""},
+		{"R_RISCV_SET32", Const, 11, ""},
+		{"R_RISCV_SET6", Const, 11, ""},
+		{"R_RISCV_SET8", Const, 11, ""},
+		{"R_RISCV_SUB16", Const, 11, ""},
+		{"R_RISCV_SUB32", Const, 11, ""},
+		{"R_RISCV_SUB6", Const, 11, ""},
+		{"R_RISCV_SUB64", Const, 11, ""},
+		{"R_RISCV_SUB8", Const, 11, ""},
+		{"R_RISCV_TLS_DTPMOD32", Const, 11, ""},
+		{"R_RISCV_TLS_DTPMOD64", Const, 11, ""},
+		{"R_RISCV_TLS_DTPREL32", Const, 11, ""},
+		{"R_RISCV_TLS_DTPREL64", Const, 11, ""},
+		{"R_RISCV_TLS_GD_HI20", Const, 11, ""},
+		{"R_RISCV_TLS_GOT_HI20", Const, 11, ""},
+		{"R_RISCV_TLS_TPREL32", Const, 11, ""},
+		{"R_RISCV_TLS_TPREL64", Const, 11, ""},
+		{"R_RISCV_TPREL_ADD", Const, 11, ""},
+		{"R_RISCV_TPREL_HI20", Const, 11, ""},
+		{"R_RISCV_TPREL_I", Const, 11, ""},
+		{"R_RISCV_TPREL_LO12_I", Const, 11, ""},
+		{"R_RISCV_TPREL_LO12_S", Const, 11, ""},
+		{"R_RISCV_TPREL_S", Const, 11, ""},
+		{"R_SPARC", Type, 0, ""},
+		{"R_SPARC_10", Const, 0, ""},
+		{"R_SPARC_11", Const, 0, ""},
+		{"R_SPARC_13", Const, 0, ""},
+		{"R_SPARC_16", Const, 0, ""},
+		{"R_SPARC_22", Const, 0, ""},
+		{"R_SPARC_32", Const, 0, ""},
+		{"R_SPARC_5", Const, 0, ""},
+		{"R_SPARC_6", Const, 0, ""},
+		{"R_SPARC_64", Const, 0, ""},
+		{"R_SPARC_7", Const, 0, ""},
+		{"R_SPARC_8", Const, 0, ""},
+		{"R_SPARC_COPY", Const, 0, ""},
+		{"R_SPARC_DISP16", Const, 0, ""},
+		{"R_SPARC_DISP32", Const, 0, ""},
+		{"R_SPARC_DISP64", Const, 0, ""},
+		{"R_SPARC_DISP8", Const, 0, ""},
+		{"R_SPARC_GLOB_DAT", Const, 0, ""},
+		{"R_SPARC_GLOB_JMP", Const, 0, ""},
+		{"R_SPARC_GOT10", Const, 0, ""},
+		{"R_SPARC_GOT13", Const, 0, ""},
+		{"R_SPARC_GOT22", Const, 0, ""},
+		{"R_SPARC_H44", Const, 0, ""},
+		{"R_SPARC_HH22", Const, 0, ""},
+		{"R_SPARC_HI22", Const, 0, ""},
+		{"R_SPARC_HIPLT22", Const, 0, ""},
+		{"R_SPARC_HIX22", Const, 0, ""},
+		{"R_SPARC_HM10", Const, 0, ""},
+		{"R_SPARC_JMP_SLOT", Const, 0, ""},
+		{"R_SPARC_L44", Const, 0, ""},
+		{"R_SPARC_LM22", Const, 0, ""},
+		{"R_SPARC_LO10", Const, 0, ""},
+		{"R_SPARC_LOPLT10", Const, 0, ""},
+		{"R_SPARC_LOX10", Const, 0, ""},
+		{"R_SPARC_M44", Const, 0, ""},
+		{"R_SPARC_NONE", Const, 0, ""},
+		{"R_SPARC_OLO10", Const, 0, ""},
+		{"R_SPARC_PC10", Const, 0, ""},
+		{"R_SPARC_PC22", Const, 0, ""},
+		{"R_SPARC_PCPLT10", Const, 0, ""},
+		{"R_SPARC_PCPLT22", Const, 0, ""},
+		{"R_SPARC_PCPLT32", Const, 0, ""},
+		{"R_SPARC_PC_HH22", Const, 0, ""},
+		{"R_SPARC_PC_HM10", Const, 0, ""},
+		{"R_SPARC_PC_LM22", Const, 0, ""},
+		{"R_SPARC_PLT32", Const, 0, ""},
+		{"R_SPARC_PLT64", Const, 0, ""},
+		{"R_SPARC_REGISTER", Const, 0, ""},
+		{"R_SPARC_RELATIVE", Const, 0, ""},
+		{"R_SPARC_UA16", Const, 0, ""},
+		{"R_SPARC_UA32", Const, 0, ""},
+		{"R_SPARC_UA64", Const, 0, ""},
+		{"R_SPARC_WDISP16", Const, 0, ""},
+		{"R_SPARC_WDISP19", Const, 0, ""},
+		{"R_SPARC_WDISP22", Const, 0, ""},
+		{"R_SPARC_WDISP30", Const, 0, ""},
+		{"R_SPARC_WPLT30", Const, 0, ""},
+		{"R_SYM32", Func, 0, "func(info uint32) uint32"},
+		{"R_SYM64", Func, 0, "func(info uint64) uint32"},
+		{"R_TYPE32", Func, 0, "func(info uint32) uint32"},
+		{"R_TYPE64", Func, 0, "func(info uint64) uint32"},
+		{"R_X86_64", Type, 0, ""},
+		{"R_X86_64_16", Const, 0, ""},
+		{"R_X86_64_32", Const, 0, ""},
+		{"R_X86_64_32S", Const, 0, ""},
+		{"R_X86_64_64", Const, 0, ""},
+		{"R_X86_64_8", Const, 0, ""},
+		{"R_X86_64_COPY", Const, 0, ""},
+		{"R_X86_64_DTPMOD64", Const, 0, ""},
+		{"R_X86_64_DTPOFF32", Const, 0, ""},
+		{"R_X86_64_DTPOFF64", Const, 0, ""},
+		{"R_X86_64_GLOB_DAT", Const, 0, ""},
+		{"R_X86_64_GOT32", Const, 0, ""},
+		{"R_X86_64_GOT64", Const, 10, ""},
+		{"R_X86_64_GOTOFF64", Const, 10, ""},
+		{"R_X86_64_GOTPC32", Const, 10, ""},
+		{"R_X86_64_GOTPC32_TLSDESC", Const, 10, ""},
+		{"R_X86_64_GOTPC64", Const, 10, ""},
+		{"R_X86_64_GOTPCREL", Const, 0, ""},
+		{"R_X86_64_GOTPCREL64", Const, 10, ""},
+		{"R_X86_64_GOTPCRELX", Const, 10, ""},
+		{"R_X86_64_GOTPLT64", Const, 10, ""},
+		{"R_X86_64_GOTTPOFF", Const, 0, ""},
+		{"R_X86_64_IRELATIVE", Const, 10, ""},
+		{"R_X86_64_JMP_SLOT", Const, 0, ""},
+		{"R_X86_64_NONE", Const, 0, ""},
+		{"R_X86_64_PC16", Const, 0, ""},
+		{"R_X86_64_PC32", Const, 0, ""},
+		{"R_X86_64_PC32_BND", Const, 10, ""},
+		{"R_X86_64_PC64", Const, 10, ""},
+		{"R_X86_64_PC8", Const, 0, ""},
+		{"R_X86_64_PLT32", Const, 0, ""},
+		{"R_X86_64_PLT32_BND", Const, 10, ""},
+		{"R_X86_64_PLTOFF64", Const, 10, ""},
+		{"R_X86_64_RELATIVE", Const, 0, ""},
+		{"R_X86_64_RELATIVE64", Const, 10, ""},
+		{"R_X86_64_REX_GOTPCRELX", Const, 10, ""},
+		{"R_X86_64_SIZE32", Const, 10, ""},
+		{"R_X86_64_SIZE64", Const, 10, ""},
+		{"R_X86_64_TLSDESC", Const, 10, ""},
+		{"R_X86_64_TLSDESC_CALL", Const, 10, ""},
+		{"R_X86_64_TLSGD", Const, 0, ""},
+		{"R_X86_64_TLSLD", Const, 0, ""},
+		{"R_X86_64_TPOFF32", Const, 0, ""},
+		{"R_X86_64_TPOFF64", Const, 0, ""},
+		{"Rel32", Type, 0, ""},
+		{"Rel32.Info", Field, 0, ""},
+		{"Rel32.Off", Field, 0, ""},
+		{"Rel64", Type, 0, ""},
+		{"Rel64.Info", Field, 0, ""},
+		{"Rel64.Off", Field, 0, ""},
+		{"Rela32", Type, 0, ""},
+		{"Rela32.Addend", Field, 0, ""},
+		{"Rela32.Info", Field, 0, ""},
+		{"Rela32.Off", Field, 0, ""},
+		{"Rela64", Type, 0, ""},
+		{"Rela64.Addend", Field, 0, ""},
+		{"Rela64.Info", Field, 0, ""},
+		{"Rela64.Off", Field, 0, ""},
+		{"SHF_ALLOC", Const, 0, ""},
+		{"SHF_COMPRESSED", Const, 6, ""},
+		{"SHF_EXECINSTR", Const, 0, ""},
+		{"SHF_GROUP", Const, 0, ""},
+		{"SHF_INFO_LINK", Const, 0, ""},
+		{"SHF_LINK_ORDER", Const, 0, ""},
+		{"SHF_MASKOS", Const, 0, ""},
+		{"SHF_MASKPROC", Const, 0, ""},
+		{"SHF_MERGE", Const, 0, ""},
+		{"SHF_OS_NONCONFORMING", Const, 0, ""},
+		{"SHF_STRINGS", Const, 0, ""},
+		{"SHF_TLS", Const, 0, ""},
+		{"SHF_WRITE", Const, 0, ""},
+		{"SHN_ABS", Const, 0, ""},
+		{"SHN_COMMON", Const, 0, ""},
+		{"SHN_HIOS", Const, 0, ""},
+		{"SHN_HIPROC", Const, 0, ""},
+		{"SHN_HIRESERVE", Const, 0, ""},
+		{"SHN_LOOS", Const, 0, ""},
+		{"SHN_LOPROC", Const, 0, ""},
+		{"SHN_LORESERVE", Const, 0, ""},
+		{"SHN_UNDEF", Const, 0, ""},
+		{"SHN_XINDEX", Const, 0, ""},
+		{"SHT_DYNAMIC", Const, 0, ""},
+		{"SHT_DYNSYM", Const, 0, ""},
+		{"SHT_FINI_ARRAY", Const, 0, ""},
+		{"SHT_GNU_ATTRIBUTES", Const, 0, ""},
+		{"SHT_GNU_HASH", Const, 0, ""},
+		{"SHT_GNU_LIBLIST", Const, 0, ""},
+		{"SHT_GNU_VERDEF", Const, 0, ""},
+		{"SHT_GNU_VERNEED", Const, 0, ""},
+		{"SHT_GNU_VERSYM", Const, 0, ""},
+		{"SHT_GROUP", Const, 0, ""},
+		{"SHT_HASH", Const, 0, ""},
+		{"SHT_HIOS", Const, 0, ""},
+		{"SHT_HIPROC", Const, 0, ""},
+		{"SHT_HIUSER", Const, 0, ""},
+		{"SHT_INIT_ARRAY", Const, 0, ""},
+		{"SHT_LOOS", Const, 0, ""},
+		{"SHT_LOPROC", Const, 0, ""},
+		{"SHT_LOUSER", Const, 0, ""},
+		{"SHT_MIPS_ABIFLAGS", Const, 17, ""},
+		{"SHT_NOBITS", Const, 0, ""},
+		{"SHT_NOTE", Const, 0, ""},
+		{"SHT_NULL", Const, 0, ""},
+		{"SHT_PREINIT_ARRAY", Const, 0, ""},
+		{"SHT_PROGBITS", Const, 0, ""},
+		{"SHT_REL", Const, 0, ""},
+		{"SHT_RELA", Const, 0, ""},
+		{"SHT_RISCV_ATTRIBUTES", Const, 25, ""},
+		{"SHT_SHLIB", Const, 0, ""},
+		{"SHT_STRTAB", Const, 0, ""},
+		{"SHT_SYMTAB", Const, 0, ""},
+		{"SHT_SYMTAB_SHNDX", Const, 0, ""},
+		{"STB_GLOBAL", Const, 0, ""},
+		{"STB_HIOS", Const, 0, ""},
+		{"STB_HIPROC", Const, 0, ""},
+		{"STB_LOCAL", Const, 0, ""},
+		{"STB_LOOS", Const, 0, ""},
+		{"STB_LOPROC", Const, 0, ""},
+		{"STB_WEAK", Const, 0, ""},
+		{"STT_COMMON", Const, 0, ""},
+		{"STT_FILE", Const, 0, ""},
+		{"STT_FUNC", Const, 0, ""},
+		{"STT_GNU_IFUNC", Const, 23, ""},
+		{"STT_HIOS", Const, 0, ""},
+		{"STT_HIPROC", Const, 0, ""},
+		{"STT_LOOS", Const, 0, ""},
+		{"STT_LOPROC", Const, 0, ""},
+		{"STT_NOTYPE", Const, 0, ""},
+		{"STT_OBJECT", Const, 0, ""},
+		{"STT_RELC", Const, 23, ""},
+		{"STT_SECTION", Const, 0, ""},
+		{"STT_SRELC", Const, 23, ""},
+		{"STT_TLS", Const, 0, ""},
+		{"STV_DEFAULT", Const, 0, ""},
+		{"STV_HIDDEN", Const, 0, ""},
+		{"STV_INTERNAL", Const, 0, ""},
+		{"STV_PROTECTED", Const, 0, ""},
+		{"ST_BIND", Func, 0, "func(info uint8) SymBind"},
+		{"ST_INFO", Func, 0, "func(bind SymBind, typ SymType) uint8"},
+		{"ST_TYPE", Func, 0, "func(info uint8) SymType"},
+		{"ST_VISIBILITY", Func, 0, "func(other uint8) SymVis"},
+		{"Section", Type, 0, ""},
+		{"Section.ReaderAt", Field, 0, ""},
+		{"Section.SectionHeader", Field, 0, ""},
+		{"Section32", Type, 0, ""},
+		{"Section32.Addr", Field, 0, ""},
+		{"Section32.Addralign", Field, 0, ""},
+		{"Section32.Entsize", Field, 0, ""},
+		{"Section32.Flags", Field, 0, ""},
+		{"Section32.Info", Field, 0, ""},
+		{"Section32.Link", Field, 0, ""},
+		{"Section32.Name", Field, 0, ""},
+		{"Section32.Off", Field, 0, ""},
+		{"Section32.Size", Field, 0, ""},
+		{"Section32.Type", Field, 0, ""},
+		{"Section64", Type, 0, ""},
+		{"Section64.Addr", Field, 0, ""},
+		{"Section64.Addralign", Field, 0, ""},
+		{"Section64.Entsize", Field, 0, ""},
+		{"Section64.Flags", Field, 0, ""},
+		{"Section64.Info", Field, 0, ""},
+		{"Section64.Link", Field, 0, ""},
+		{"Section64.Name", Field, 0, ""},
+		{"Section64.Off", Field, 0, ""},
+		{"Section64.Size", Field, 0, ""},
+		{"Section64.Type", Field, 0, ""},
+		{"SectionFlag", Type, 0, ""},
+		{"SectionHeader", Type, 0, ""},
+		{"SectionHeader.Addr", Field, 0, ""},
+		{"SectionHeader.Addralign", Field, 0, ""},
+		{"SectionHeader.Entsize", Field, 0, ""},
+		{"SectionHeader.FileSize", Field, 6, ""},
+		{"SectionHeader.Flags", Field, 0, ""},
+		{"SectionHeader.Info", Field, 0, ""},
+		{"SectionHeader.Link", Field, 0, ""},
+		{"SectionHeader.Name", Field, 0, ""},
+		{"SectionHeader.Offset", Field, 0, ""},
+		{"SectionHeader.Size", Field, 0, ""},
+		{"SectionHeader.Type", Field, 0, ""},
+		{"SectionIndex", Type, 0, ""},
+		{"SectionType", Type, 0, ""},
+		{"Sym32", Type, 0, ""},
+		{"Sym32.Info", Field, 0, ""},
+		{"Sym32.Name", Field, 0, ""},
+		{"Sym32.Other", Field, 0, ""},
+		{"Sym32.Shndx", Field, 0, ""},
+		{"Sym32.Size", Field, 0, ""},
+		{"Sym32.Value", Field, 0, ""},
+		{"Sym32Size", Const, 0, ""},
+		{"Sym64", Type, 0, ""},
+		{"Sym64.Info", Field, 0, ""},
+		{"Sym64.Name", Field, 0, ""},
+		{"Sym64.Other", Field, 0, ""},
+		{"Sym64.Shndx", Field, 0, ""},
+		{"Sym64.Size", Field, 0, ""},
+		{"Sym64.Value", Field, 0, ""},
+		{"Sym64Size", Const, 0, ""},
+		{"SymBind", Type, 0, ""},
+		{"SymType", Type, 0, ""},
+		{"SymVis", Type, 0, ""},
+		{"Symbol", Type, 0, ""},
+		{"Symbol.HasVersion", Field, 24, ""},
+		{"Symbol.Info", Field, 0, ""},
+		{"Symbol.Library", Field, 13, ""},
+		{"Symbol.Name", Field, 0, ""},
+		{"Symbol.Other", Field, 0, ""},
+		{"Symbol.Section", Field, 0, ""},
+		{"Symbol.Size", Field, 0, ""},
+		{"Symbol.Value", Field, 0, ""},
+		{"Symbol.Version", Field, 13, ""},
+		{"Symbol.VersionIndex", Field, 24, ""},
+		{"Type", Type, 0, ""},
+		{"VER_FLG_BASE", Const, 24, ""},
+		{"VER_FLG_INFO", Const, 24, ""},
+		{"VER_FLG_WEAK", Const, 24, ""},
+		{"Version", Type, 0, ""},
+		{"VersionIndex", Type, 24, ""},
+	},
+	"debug/gosym": {
+		{"(*DecodingError).Error", Method, 0, ""},
+		{"(*LineTable).LineToPC", Method, 0, ""},
+		{"(*LineTable).PCToLine", Method, 0, ""},
+		{"(*Sym).BaseName", Method, 0, ""},
+		{"(*Sym).PackageName", Method, 0, ""},
+		{"(*Sym).ReceiverName", Method, 0, ""},
+		{"(*Sym).Static", Method, 0, ""},
+		{"(*Table).LineToPC", Method, 0, ""},
+		{"(*Table).LookupFunc", Method, 0, ""},
+		{"(*Table).LookupSym", Method, 0, ""},
+		{"(*Table).PCToFunc", Method, 0, ""},
+		{"(*Table).PCToLine", Method, 0, ""},
+		{"(*Table).SymByAddr", Method, 0, ""},
+		{"(*UnknownLineError).Error", Method, 0, ""},
+		{"(Func).BaseName", Method, 0, ""},
+		{"(Func).PackageName", Method, 0, ""},
+		{"(Func).ReceiverName", Method, 0, ""},
+		{"(Func).Static", Method, 0, ""},
+		{"(UnknownFileError).Error", Method, 0, ""},
+		{"DecodingError", Type, 0, ""},
+		{"Func", Type, 0, ""},
+		{"Func.End", Field, 0, ""},
+		{"Func.Entry", Field, 0, ""},
+		{"Func.FrameSize", Field, 0, ""},
+		{"Func.LineTable", Field, 0, ""},
+		{"Func.Locals", Field, 0, ""},
+		{"Func.Obj", Field, 0, ""},
+		{"Func.Params", Field, 0, ""},
+		{"Func.Sym", Field, 0, ""},
+		{"LineTable", Type, 0, ""},
+		{"LineTable.Data", Field, 0, ""},
+		{"LineTable.Line", Field, 0, ""},
+		{"LineTable.PC", Field, 0, ""},
+		{"NewLineTable", Func, 0, "func(data []byte, text uint64) *LineTable"},
+		{"NewTable", Func, 0, "func(symtab []byte, pcln *LineTable) (*Table, error)"},
+		{"Obj", Type, 0, ""},
+		{"Obj.Funcs", Field, 0, ""},
+		{"Obj.Paths", Field, 0, ""},
+		{"Sym", Type, 0, ""},
+		{"Sym.Func", Field, 0, ""},
+		{"Sym.GoType", Field, 0, ""},
+		{"Sym.Name", Field, 0, ""},
+		{"Sym.Type", Field, 0, ""},
+		{"Sym.Value", Field, 0, ""},
+		{"Table", Type, 0, ""},
+		{"Table.Files", Field, 0, ""},
+		{"Table.Funcs", Field, 0, ""},
+		{"Table.Objs", Field, 0, ""},
+		{"Table.Syms", Field, 0, ""},
+		{"UnknownFileError", Type, 0, ""},
+		{"UnknownLineError", Type, 0, ""},
+		{"UnknownLineError.File", Field, 0, ""},
+		{"UnknownLineError.Line", Field, 0, ""},
+	},
+	"debug/macho": {
+		{"(*FatFile).Close", Method, 3, ""},
+		{"(*File).Close", Method, 0, ""},
+		{"(*File).DWARF", Method, 0, ""},
+		{"(*File).ImportedLibraries", Method, 0, ""},
+		{"(*File).ImportedSymbols", Method, 0, ""},
+		{"(*File).Section", Method, 0, ""},
+		{"(*File).Segment", Method, 0, ""},
+		{"(*FormatError).Error", Method, 0, ""},
+		{"(*Section).Data", Method, 0, ""},
+		{"(*Section).Open", Method, 0, ""},
+		{"(*Segment).Data", Method, 0, ""},
+		{"(*Segment).Open", Method, 0, ""},
+		{"(Cpu).GoString", Method, 0, ""},
+		{"(Cpu).String", Method, 0, ""},
+		{"(Dylib).Raw", Method, 0, ""},
+		{"(Dysymtab).Raw", Method, 0, ""},
+		{"(FatArch).Close", Method, 3, ""},
+		{"(FatArch).DWARF", Method, 3, ""},
+		{"(FatArch).ImportedLibraries", Method, 3, ""},
+		{"(FatArch).ImportedSymbols", Method, 3, ""},
+		{"(FatArch).Section", Method, 3, ""},
+		{"(FatArch).Segment", Method, 3, ""},
+		{"(Load).Raw", Method, 0, ""},
+		{"(LoadBytes).Raw", Method, 0, ""},
+		{"(LoadCmd).GoString", Method, 0, ""},
+		{"(LoadCmd).String", Method, 0, ""},
+		{"(RelocTypeARM).GoString", Method, 10, ""},
+		{"(RelocTypeARM).String", Method, 10, ""},
+		{"(RelocTypeARM64).GoString", Method, 10, ""},
+		{"(RelocTypeARM64).String", Method, 10, ""},
+		{"(RelocTypeGeneric).GoString", Method, 10, ""},
+		{"(RelocTypeGeneric).String", Method, 10, ""},
+		{"(RelocTypeX86_64).GoString", Method, 10, ""},
+		{"(RelocTypeX86_64).String", Method, 10, ""},
+		{"(Rpath).Raw", Method, 10, ""},
+		{"(Section).ReadAt", Method, 0, ""},
+		{"(Segment).Raw", Method, 0, ""},
+		{"(Segment).ReadAt", Method, 0, ""},
+		{"(Symtab).Raw", Method, 0, ""},
+		{"(Type).GoString", Method, 10, ""},
+		{"(Type).String", Method, 10, ""},
+		{"ARM64_RELOC_ADDEND", Const, 10, ""},
+		{"ARM64_RELOC_BRANCH26", Const, 10, ""},
+		{"ARM64_RELOC_GOT_LOAD_PAGE21", Const, 10, ""},
+		{"ARM64_RELOC_GOT_LOAD_PAGEOFF12", Const, 10, ""},
+		{"ARM64_RELOC_PAGE21", Const, 10, ""},
+		{"ARM64_RELOC_PAGEOFF12", Const, 10, ""},
+		{"ARM64_RELOC_POINTER_TO_GOT", Const, 10, ""},
+		{"ARM64_RELOC_SUBTRACTOR", Const, 10, ""},
+		{"ARM64_RELOC_TLVP_LOAD_PAGE21", Const, 10, ""},
+		{"ARM64_RELOC_TLVP_LOAD_PAGEOFF12", Const, 10, ""},
+		{"ARM64_RELOC_UNSIGNED", Const, 10, ""},
+		{"ARM_RELOC_BR24", Const, 10, ""},
+		{"ARM_RELOC_HALF", Const, 10, ""},
+		{"ARM_RELOC_HALF_SECTDIFF", Const, 10, ""},
+		{"ARM_RELOC_LOCAL_SECTDIFF", Const, 10, ""},
+		{"ARM_RELOC_PAIR", Const, 10, ""},
+		{"ARM_RELOC_PB_LA_PTR", Const, 10, ""},
+		{"ARM_RELOC_SECTDIFF", Const, 10, ""},
+		{"ARM_RELOC_VANILLA", Const, 10, ""},
+		{"ARM_THUMB_32BIT_BRANCH", Const, 10, ""},
+		{"ARM_THUMB_RELOC_BR22", Const, 10, ""},
+		{"Cpu", Type, 0, ""},
+		{"Cpu386", Const, 0, ""},
+		{"CpuAmd64", Const, 0, ""},
+		{"CpuArm", Const, 3, ""},
+		{"CpuArm64", Const, 11, ""},
+		{"CpuPpc", Const, 3, ""},
+		{"CpuPpc64", Const, 3, ""},
+		{"Dylib", Type, 0, ""},
+		{"Dylib.CompatVersion", Field, 0, ""},
+		{"Dylib.CurrentVersion", Field, 0, ""},
+		{"Dylib.LoadBytes", Field, 0, ""},
+		{"Dylib.Name", Field, 0, ""},
+		{"Dylib.Time", Field, 0, ""},
+		{"DylibCmd", Type, 0, ""},
+		{"DylibCmd.Cmd", Field, 0, ""},
+		{"DylibCmd.CompatVersion", Field, 0, ""},
+		{"DylibCmd.CurrentVersion", Field, 0, ""},
+		{"DylibCmd.Len", Field, 0, ""},
+		{"DylibCmd.Name", Field, 0, ""},
+		{"DylibCmd.Time", Field, 0, ""},
+		{"Dysymtab", Type, 0, ""},
+		{"Dysymtab.DysymtabCmd", Field, 0, ""},
+		{"Dysymtab.IndirectSyms", Field, 0, ""},
+		{"Dysymtab.LoadBytes", Field, 0, ""},
+		{"DysymtabCmd", Type, 0, ""},
+		{"DysymtabCmd.Cmd", Field, 0, ""},
+		{"DysymtabCmd.Extrefsymoff", Field, 0, ""},
+		{"DysymtabCmd.Extreloff", Field, 0, ""},
+		{"DysymtabCmd.Iextdefsym", Field, 0, ""},
+		{"DysymtabCmd.Ilocalsym", Field, 0, ""},
+		{"DysymtabCmd.Indirectsymoff", Field, 0, ""},
+		{"DysymtabCmd.Iundefsym", Field, 0, ""},
+		{"DysymtabCmd.Len", Field, 0, ""},
+		{"DysymtabCmd.Locreloff", Field, 0, ""},
+		{"DysymtabCmd.Modtaboff", Field, 0, ""},
+		{"DysymtabCmd.Nextdefsym", Field, 0, ""},
+		{"DysymtabCmd.Nextrefsyms", Field, 0, ""},
+		{"DysymtabCmd.Nextrel", Field, 0, ""},
+		{"DysymtabCmd.Nindirectsyms", Field, 0, ""},
+		{"DysymtabCmd.Nlocalsym", Field, 0, ""},
+		{"DysymtabCmd.Nlocrel", Field, 0, ""},
+		{"DysymtabCmd.Nmodtab", Field, 0, ""},
+		{"DysymtabCmd.Ntoc", Field, 0, ""},
+		{"DysymtabCmd.Nundefsym", Field, 0, ""},
+		{"DysymtabCmd.Tocoffset", Field, 0, ""},
+		{"ErrNotFat", Var, 3, ""},
+		{"FatArch", Type, 3, ""},
+		{"FatArch.FatArchHeader", Field, 3, ""},
+		{"FatArch.File", Field, 3, ""},
+		{"FatArchHeader", Type, 3, ""},
+		{"FatArchHeader.Align", Field, 3, ""},
+		{"FatArchHeader.Cpu", Field, 3, ""},
+		{"FatArchHeader.Offset", Field, 3, ""},
+		{"FatArchHeader.Size", Field, 3, ""},
+		{"FatArchHeader.SubCpu", Field, 3, ""},
+		{"FatFile", Type, 3, ""},
+		{"FatFile.Arches", Field, 3, ""},
+		{"FatFile.Magic", Field, 3, ""},
+		{"File", Type, 0, ""},
+		{"File.ByteOrder", Field, 0, ""},
+		{"File.Dysymtab", Field, 0, ""},
+		{"File.FileHeader", Field, 0, ""},
+		{"File.Loads", Field, 0, ""},
+		{"File.Sections", Field, 0, ""},
+		{"File.Symtab", Field, 0, ""},
+		{"FileHeader", Type, 0, ""},
+		{"FileHeader.Cmdsz", Field, 0, ""},
+		{"FileHeader.Cpu", Field, 0, ""},
+		{"FileHeader.Flags", Field, 0, ""},
+		{"FileHeader.Magic", Field, 0, ""},
+		{"FileHeader.Ncmd", Field, 0, ""},
+		{"FileHeader.SubCpu", Field, 0, ""},
+		{"FileHeader.Type", Field, 0, ""},
+		{"FlagAllModsBound", Const, 10, ""},
+		{"FlagAllowStackExecution", Const, 10, ""},
+		{"FlagAppExtensionSafe", Const, 10, ""},
+		{"FlagBindAtLoad", Const, 10, ""},
+		{"FlagBindsToWeak", Const, 10, ""},
+		{"FlagCanonical", Const, 10, ""},
+		{"FlagDeadStrippableDylib", Const, 10, ""},
+		{"FlagDyldLink", Const, 10, ""},
+		{"FlagForceFlat", Const, 10, ""},
+		{"FlagHasTLVDescriptors", Const, 10, ""},
+		{"FlagIncrLink", Const, 10, ""},
+		{"FlagLazyInit", Const, 10, ""},
+		{"FlagNoFixPrebinding", Const, 10, ""},
+		{"FlagNoHeapExecution", Const, 10, ""},
+		{"FlagNoMultiDefs", Const, 10, ""},
+		{"FlagNoReexportedDylibs", Const, 10, ""},
+		{"FlagNoUndefs", Const, 10, ""},
+		{"FlagPIE", Const, 10, ""},
+		{"FlagPrebindable", Const, 10, ""},
+		{"FlagPrebound", Const, 10, ""},
+		{"FlagRootSafe", Const, 10, ""},
+		{"FlagSetuidSafe", Const, 10, ""},
+		{"FlagSplitSegs", Const, 10, ""},
+		{"FlagSubsectionsViaSymbols", Const, 10, ""},
+		{"FlagTwoLevel", Const, 10, ""},
+		{"FlagWeakDefines", Const, 10, ""},
+		{"FormatError", Type, 0, ""},
+		{"GENERIC_RELOC_LOCAL_SECTDIFF", Const, 10, ""},
+		{"GENERIC_RELOC_PAIR", Const, 10, ""},
+		{"GENERIC_RELOC_PB_LA_PTR", Const, 10, ""},
+		{"GENERIC_RELOC_SECTDIFF", Const, 10, ""},
+		{"GENERIC_RELOC_TLV", Const, 10, ""},
+		{"GENERIC_RELOC_VANILLA", Const, 10, ""},
+		{"Load", Type, 0, ""},
+		{"LoadBytes", Type, 0, ""},
+		{"LoadCmd", Type, 0, ""},
+		{"LoadCmdDylib", Const, 0, ""},
+		{"LoadCmdDylinker", Const, 0, ""},
+		{"LoadCmdDysymtab", Const, 0, ""},
+		{"LoadCmdRpath", Const, 10, ""},
+		{"LoadCmdSegment", Const, 0, ""},
+		{"LoadCmdSegment64", Const, 0, ""},
+		{"LoadCmdSymtab", Const, 0, ""},
+		{"LoadCmdThread", Const, 0, ""},
+		{"LoadCmdUnixThread", Const, 0, ""},
+		{"Magic32", Const, 0, ""},
+		{"Magic64", Const, 0, ""},
+		{"MagicFat", Const, 3, ""},
+		{"NewFatFile", Func, 3, "func(r io.ReaderAt) (*FatFile, error)"},
+		{"NewFile", Func, 0, "func(r io.ReaderAt) (*File, error)"},
+		{"Nlist32", Type, 0, ""},
+		{"Nlist32.Desc", Field, 0, ""},
+		{"Nlist32.Name", Field, 0, ""},
+		{"Nlist32.Sect", Field, 0, ""},
+		{"Nlist32.Type", Field, 0, ""},
+		{"Nlist32.Value", Field, 0, ""},
+		{"Nlist64", Type, 0, ""},
+		{"Nlist64.Desc", Field, 0, ""},
+		{"Nlist64.Name", Field, 0, ""},
+		{"Nlist64.Sect", Field, 0, ""},
+		{"Nlist64.Type", Field, 0, ""},
+		{"Nlist64.Value", Field, 0, ""},
+		{"Open", Func, 0, "func(name string) (*File, error)"},
+		{"OpenFat", Func, 3, "func(name string) (*FatFile, error)"},
+		{"Regs386", Type, 0, ""},
+		{"Regs386.AX", Field, 0, ""},
+		{"Regs386.BP", Field, 0, ""},
+		{"Regs386.BX", Field, 0, ""},
+		{"Regs386.CS", Field, 0, ""},
+		{"Regs386.CX", Field, 0, ""},
+		{"Regs386.DI", Field, 0, ""},
+		{"Regs386.DS", Field, 0, ""},
+		{"Regs386.DX", Field, 0, ""},
+		{"Regs386.ES", Field, 0, ""},
+		{"Regs386.FLAGS", Field, 0, ""},
+		{"Regs386.FS", Field, 0, ""},
+		{"Regs386.GS", Field, 0, ""},
+		{"Regs386.IP", Field, 0, ""},
+		{"Regs386.SI", Field, 0, ""},
+		{"Regs386.SP", Field, 0, ""},
+		{"Regs386.SS", Field, 0, ""},
+		{"RegsAMD64", Type, 0, ""},
+		{"RegsAMD64.AX", Field, 0, ""},
+		{"RegsAMD64.BP", Field, 0, ""},
+		{"RegsAMD64.BX", Field, 0, ""},
+		{"RegsAMD64.CS", Field, 0, ""},
+		{"RegsAMD64.CX", Field, 0, ""},
+		{"RegsAMD64.DI", Field, 0, ""},
+		{"RegsAMD64.DX", Field, 0, ""},
+		{"RegsAMD64.FLAGS", Field, 0, ""},
+		{"RegsAMD64.FS", Field, 0, ""},
+		{"RegsAMD64.GS", Field, 0, ""},
+		{"RegsAMD64.IP", Field, 0, ""},
+		{"RegsAMD64.R10", Field, 0, ""},
+		{"RegsAMD64.R11", Field, 0, ""},
+		{"RegsAMD64.R12", Field, 0, ""},
+		{"RegsAMD64.R13", Field, 0, ""},
+		{"RegsAMD64.R14", Field, 0, ""},
+		{"RegsAMD64.R15", Field, 0, ""},
+		{"RegsAMD64.R8", Field, 0, ""},
+		{"RegsAMD64.R9", Field, 0, ""},
+		{"RegsAMD64.SI", Field, 0, ""},
+		{"RegsAMD64.SP", Field, 0, ""},
+		{"Reloc", Type, 10, ""},
+		{"Reloc.Addr", Field, 10, ""},
+		{"Reloc.Extern", Field, 10, ""},
+		{"Reloc.Len", Field, 10, ""},
+		{"Reloc.Pcrel", Field, 10, ""},
+		{"Reloc.Scattered", Field, 10, ""},
+		{"Reloc.Type", Field, 10, ""},
+		{"Reloc.Value", Field, 10, ""},
+		{"RelocTypeARM", Type, 10, ""},
+		{"RelocTypeARM64", Type, 10, ""},
+		{"RelocTypeGeneric", Type, 10, ""},
+		{"RelocTypeX86_64", Type, 10, ""},
+		{"Rpath", Type, 10, ""},
+		{"Rpath.LoadBytes", Field, 10, ""},
+		{"Rpath.Path", Field, 10, ""},
+		{"RpathCmd", Type, 10, ""},
+		{"RpathCmd.Cmd", Field, 10, ""},
+		{"RpathCmd.Len", Field, 10, ""},
+		{"RpathCmd.Path", Field, 10, ""},
+		{"Section", Type, 0, ""},
+		{"Section.ReaderAt", Field, 0, ""},
+		{"Section.Relocs", Field, 10, ""},
+		{"Section.SectionHeader", Field, 0, ""},
+		{"Section32", Type, 0, ""},
+		{"Section32.Addr", Field, 0, ""},
+		{"Section32.Align", Field, 0, ""},
+		{"Section32.Flags", Field, 0, ""},
+		{"Section32.Name", Field, 0, ""},
+		{"Section32.Nreloc", Field, 0, ""},
+		{"Section32.Offset", Field, 0, ""},
+		{"Section32.Reloff", Field, 0, ""},
+		{"Section32.Reserve1", Field, 0, ""},
+		{"Section32.Reserve2", Field, 0, ""},
+		{"Section32.Seg", Field, 0, ""},
+		{"Section32.Size", Field, 0, ""},
+		{"Section64", Type, 0, ""},
+		{"Section64.Addr", Field, 0, ""},
+		{"Section64.Align", Field, 0, ""},
+		{"Section64.Flags", Field, 0, ""},
+		{"Section64.Name", Field, 0, ""},
+		{"Section64.Nreloc", Field, 0, ""},
+		{"Section64.Offset", Field, 0, ""},
+		{"Section64.Reloff", Field, 0, ""},
+		{"Section64.Reserve1", Field, 0, ""},
+		{"Section64.Reserve2", Field, 0, ""},
+		{"Section64.Reserve3", Field, 0, ""},
+		{"Section64.Seg", Field, 0, ""},
+		{"Section64.Size", Field, 0, ""},
+		{"SectionHeader", Type, 0, ""},
+		{"SectionHeader.Addr", Field, 0, ""},
+		{"SectionHeader.Align", Field, 0, ""},
+		{"SectionHeader.Flags", Field, 0, ""},
+		{"SectionHeader.Name", Field, 0, ""},
+		{"SectionHeader.Nreloc", Field, 0, ""},
+		{"SectionHeader.Offset", Field, 0, ""},
+		{"SectionHeader.Reloff", Field, 0, ""},
+		{"SectionHeader.Seg", Field, 0, ""},
+		{"SectionHeader.Size", Field, 0, ""},
+		{"Segment", Type, 0, ""},
+		{"Segment.LoadBytes", Field, 0, ""},
+		{"Segment.ReaderAt", Field, 0, ""},
+		{"Segment.SegmentHeader", Field, 0, ""},
+		{"Segment32", Type, 0, ""},
+		{"Segment32.Addr", Field, 0, ""},
+		{"Segment32.Cmd", Field, 0, ""},
+		{"Segment32.Filesz", Field, 0, ""},
+		{"Segment32.Flag", Field, 0, ""},
+		{"Segment32.Len", Field, 0, ""},
+		{"Segment32.Maxprot", Field, 0, ""},
+		{"Segment32.Memsz", Field, 0, ""},
+		{"Segment32.Name", Field, 0, ""},
+		{"Segment32.Nsect", Field, 0, ""},
+		{"Segment32.Offset", Field, 0, ""},
+		{"Segment32.Prot", Field, 0, ""},
+		{"Segment64", Type, 0, ""},
+		{"Segment64.Addr", Field, 0, ""},
+		{"Segment64.Cmd", Field, 0, ""},
+		{"Segment64.Filesz", Field, 0, ""},
+		{"Segment64.Flag", Field, 0, ""},
+		{"Segment64.Len", Field, 0, ""},
+		{"Segment64.Maxprot", Field, 0, ""},
+		{"Segment64.Memsz", Field, 0, ""},
+		{"Segment64.Name", Field, 0, ""},
+		{"Segment64.Nsect", Field, 0, ""},
+		{"Segment64.Offset", Field, 0, ""},
+		{"Segment64.Prot", Field, 0, ""},
+		{"SegmentHeader", Type, 0, ""},
+		{"SegmentHeader.Addr", Field, 0, ""},
+		{"SegmentHeader.Cmd", Field, 0, ""},
+		{"SegmentHeader.Filesz", Field, 0, ""},
+		{"SegmentHeader.Flag", Field, 0, ""},
+		{"SegmentHeader.Len", Field, 0, ""},
+		{"SegmentHeader.Maxprot", Field, 0, ""},
+		{"SegmentHeader.Memsz", Field, 0, ""},
+		{"SegmentHeader.Name", Field, 0, ""},
+		{"SegmentHeader.Nsect", Field, 0, ""},
+		{"SegmentHeader.Offset", Field, 0, ""},
+		{"SegmentHeader.Prot", Field, 0, ""},
+		{"Symbol", Type, 0, ""},
+		{"Symbol.Desc", Field, 0, ""},
+		{"Symbol.Name", Field, 0, ""},
+		{"Symbol.Sect", Field, 0, ""},
+		{"Symbol.Type", Field, 0, ""},
+		{"Symbol.Value", Field, 0, ""},
+		{"Symtab", Type, 0, ""},
+		{"Symtab.LoadBytes", Field, 0, ""},
+		{"Symtab.Syms", Field, 0, ""},
+		{"Symtab.SymtabCmd", Field, 0, ""},
+		{"SymtabCmd", Type, 0, ""},
+		{"SymtabCmd.Cmd", Field, 0, ""},
+		{"SymtabCmd.Len", Field, 0, ""},
+		{"SymtabCmd.Nsyms", Field, 0, ""},
+		{"SymtabCmd.Stroff", Field, 0, ""},
+		{"SymtabCmd.Strsize", Field, 0, ""},
+		{"SymtabCmd.Symoff", Field, 0, ""},
+		{"Thread", Type, 0, ""},
+		{"Thread.Cmd", Field, 0, ""},
+		{"Thread.Data", Field, 0, ""},
+		{"Thread.Len", Field, 0, ""},
+		{"Thread.Type", Field, 0, ""},
+		{"Type", Type, 0, ""},
+		{"TypeBundle", Const, 3, ""},
+		{"TypeDylib", Const, 3, ""},
+		{"TypeExec", Const, 0, ""},
+		{"TypeObj", Const, 0, ""},
+		{"X86_64_RELOC_BRANCH", Const, 10, ""},
+		{"X86_64_RELOC_GOT", Const, 10, ""},
+		{"X86_64_RELOC_GOT_LOAD", Const, 10, ""},
+		{"X86_64_RELOC_SIGNED", Const, 10, ""},
+		{"X86_64_RELOC_SIGNED_1", Const, 10, ""},
+		{"X86_64_RELOC_SIGNED_2", Const, 10, ""},
+		{"X86_64_RELOC_SIGNED_4", Const, 10, ""},
+		{"X86_64_RELOC_SUBTRACTOR", Const, 10, ""},
+		{"X86_64_RELOC_TLV", Const, 10, ""},
+		{"X86_64_RELOC_UNSIGNED", Const, 10, ""},
+	},
+	"debug/pe": {
+		{"(*COFFSymbol).FullName", Method, 8, ""},
+		{"(*File).COFFSymbolReadSectionDefAux", Method, 19, ""},
+		{"(*File).Close", Method, 0, ""},
+		{"(*File).DWARF", Method, 0, ""},
+		{"(*File).ImportedLibraries", Method, 0, ""},
+		{"(*File).ImportedSymbols", Method, 0, ""},
+		{"(*File).Section", Method, 0, ""},
+		{"(*FormatError).Error", Method, 0, ""},
+		{"(*Section).Data", Method, 0, ""},
+		{"(*Section).Open", Method, 0, ""},
+		{"(Section).ReadAt", Method, 0, ""},
+		{"(StringTable).String", Method, 8, ""},
+		{"COFFSymbol", Type, 1, ""},
+		{"COFFSymbol.Name", Field, 1, ""},
+		{"COFFSymbol.NumberOfAuxSymbols", Field, 1, ""},
+		{"COFFSymbol.SectionNumber", Field, 1, ""},
+		{"COFFSymbol.StorageClass", Field, 1, ""},
+		{"COFFSymbol.Type", Field, 1, ""},
+		{"COFFSymbol.Value", Field, 1, ""},
+		{"COFFSymbolAuxFormat5", Type, 19, ""},
+		{"COFFSymbolAuxFormat5.Checksum", Field, 19, ""},
+		{"COFFSymbolAuxFormat5.NumLineNumbers", Field, 19, ""},
+		{"COFFSymbolAuxFormat5.NumRelocs", Field, 19, ""},
+		{"COFFSymbolAuxFormat5.SecNum", Field, 19, ""},
+		{"COFFSymbolAuxFormat5.Selection", Field, 19, ""},
+		{"COFFSymbolAuxFormat5.Size", Field, 19, ""},
+		{"COFFSymbolSize", Const, 1, ""},
+		{"DataDirectory", Type, 3, ""},
+		{"DataDirectory.Size", Field, 3, ""},
+		{"DataDirectory.VirtualAddress", Field, 3, ""},
+		{"File", Type, 0, ""},
+		{"File.COFFSymbols", Field, 8, ""},
+		{"File.FileHeader", Field, 0, ""},
+		{"File.OptionalHeader", Field, 3, ""},
+		{"File.Sections", Field, 0, ""},
+		{"File.StringTable", Field, 8, ""},
+		{"File.Symbols", Field, 1, ""},
+		{"FileHeader", Type, 0, ""},
+		{"FileHeader.Characteristics", Field, 0, ""},
+		{"FileHeader.Machine", Field, 0, ""},
+		{"FileHeader.NumberOfSections", Field, 0, ""},
+		{"FileHeader.NumberOfSymbols", Field, 0, ""},
+		{"FileHeader.PointerToSymbolTable", Field, 0, ""},
+		{"FileHeader.SizeOfOptionalHeader", Field, 0, ""},
+		{"FileHeader.TimeDateStamp", Field, 0, ""},
+		{"FormatError", Type, 0, ""},
+		{"IMAGE_COMDAT_SELECT_ANY", Const, 19, ""},
+		{"IMAGE_COMDAT_SELECT_ASSOCIATIVE", Const, 19, ""},
+		{"IMAGE_COMDAT_SELECT_EXACT_MATCH", Const, 19, ""},
+		{"IMAGE_COMDAT_SELECT_LARGEST", Const, 19, ""},
+		{"IMAGE_COMDAT_SELECT_NODUPLICATES", Const, 19, ""},
+		{"IMAGE_COMDAT_SELECT_SAME_SIZE", Const, 19, ""},
+		{"IMAGE_DIRECTORY_ENTRY_ARCHITECTURE", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_BASERELOC", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_DEBUG", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_EXCEPTION", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_EXPORT", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_GLOBALPTR", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_IAT", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_IMPORT", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_RESOURCE", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_SECURITY", Const, 11, ""},
+		{"IMAGE_DIRECTORY_ENTRY_TLS", Const, 11, ""},
+		{"IMAGE_DLLCHARACTERISTICS_APPCONTAINER", Const, 15, ""},
+		{"IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE", Const, 15, ""},
+		{"IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY", Const, 15, ""},
+		{"IMAGE_DLLCHARACTERISTICS_GUARD_CF", Const, 15, ""},
+		{"IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA", Const, 15, ""},
+		{"IMAGE_DLLCHARACTERISTICS_NO_BIND", Const, 15, ""},
+		{"IMAGE_DLLCHARACTERISTICS_NO_ISOLATION", Const, 15, ""},
+		{"IMAGE_DLLCHARACTERISTICS_NO_SEH", Const, 15, ""},
+		{"IMAGE_DLLCHARACTERISTICS_NX_COMPAT", Const, 15, ""},
+		{"IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE", Const, 15, ""},
+		{"IMAGE_DLLCHARACTERISTICS_WDM_DRIVER", Const, 15, ""},
+		{"IMAGE_FILE_32BIT_MACHINE", Const, 15, ""},
+		{"IMAGE_FILE_AGGRESIVE_WS_TRIM", Const, 15, ""},
+		{"IMAGE_FILE_BYTES_REVERSED_HI", Const, 15, ""},
+		{"IMAGE_FILE_BYTES_REVERSED_LO", Const, 15, ""},
+		{"IMAGE_FILE_DEBUG_STRIPPED", Const, 15, ""},
+		{"IMAGE_FILE_DLL", Const, 15, ""},
+		{"IMAGE_FILE_EXECUTABLE_IMAGE", Const, 15, ""},
+		{"IMAGE_FILE_LARGE_ADDRESS_AWARE", Const, 15, ""},
+		{"IMAGE_FILE_LINE_NUMS_STRIPPED", Const, 15, ""},
+		{"IMAGE_FILE_LOCAL_SYMS_STRIPPED", Const, 15, ""},
+		{"IMAGE_FILE_MACHINE_AM33", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_AMD64", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_ARM", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_ARM64", Const, 11, ""},
+		{"IMAGE_FILE_MACHINE_ARMNT", Const, 12, ""},
+		{"IMAGE_FILE_MACHINE_EBC", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_I386", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_IA64", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_LOONGARCH32", Const, 19, ""},
+		{"IMAGE_FILE_MACHINE_LOONGARCH64", Const, 19, ""},
+		{"IMAGE_FILE_MACHINE_M32R", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_MIPS16", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_MIPSFPU", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_MIPSFPU16", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_POWERPC", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_POWERPCFP", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_R4000", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_RISCV128", Const, 20, ""},
+		{"IMAGE_FILE_MACHINE_RISCV32", Const, 20, ""},
+		{"IMAGE_FILE_MACHINE_RISCV64", Const, 20, ""},
+		{"IMAGE_FILE_MACHINE_SH3", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_SH3DSP", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_SH4", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_SH5", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_THUMB", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_UNKNOWN", Const, 0, ""},
+		{"IMAGE_FILE_MACHINE_WCEMIPSV2", Const, 0, ""},
+		{"IMAGE_FILE_NET_RUN_FROM_SWAP", Const, 15, ""},
+		{"IMAGE_FILE_RELOCS_STRIPPED", Const, 15, ""},
+		{"IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP", Const, 15, ""},
+		{"IMAGE_FILE_SYSTEM", Const, 15, ""},
+		{"IMAGE_FILE_UP_SYSTEM_ONLY", Const, 15, ""},
+		{"IMAGE_SCN_CNT_CODE", Const, 19, ""},
+		{"IMAGE_SCN_CNT_INITIALIZED_DATA", Const, 19, ""},
+		{"IMAGE_SCN_CNT_UNINITIALIZED_DATA", Const, 19, ""},
+		{"IMAGE_SCN_LNK_COMDAT", Const, 19, ""},
+		{"IMAGE_SCN_MEM_DISCARDABLE", Const, 19, ""},
+		{"IMAGE_SCN_MEM_EXECUTE", Const, 19, ""},
+		{"IMAGE_SCN_MEM_READ", Const, 19, ""},
+		{"IMAGE_SCN_MEM_WRITE", Const, 19, ""},
+		{"IMAGE_SUBSYSTEM_EFI_APPLICATION", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_EFI_ROM", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_NATIVE", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_NATIVE_WINDOWS", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_OS2_CUI", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_POSIX_CUI", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_UNKNOWN", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_WINDOWS_CE_GUI", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_WINDOWS_CUI", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_WINDOWS_GUI", Const, 15, ""},
+		{"IMAGE_SUBSYSTEM_XBOX", Const, 15, ""},
+		{"ImportDirectory", Type, 0, ""},
+		{"ImportDirectory.FirstThunk", Field, 0, ""},
+		{"ImportDirectory.ForwarderChain", Field, 0, ""},
+		{"ImportDirectory.Name", Field, 0, ""},
+		{"ImportDirectory.OriginalFirstThunk", Field, 0, ""},
+		{"ImportDirectory.TimeDateStamp", Field, 0, ""},
+		{"NewFile", Func, 0, "func(r io.ReaderAt) (*File, error)"},
+		{"Open", Func, 0, "func(name string) (*File, error)"},
+		{"OptionalHeader32", Type, 3, ""},
+		{"OptionalHeader32.AddressOfEntryPoint", Field, 3, ""},
+		{"OptionalHeader32.BaseOfCode", Field, 3, ""},
+		{"OptionalHeader32.BaseOfData", Field, 3, ""},
+		{"OptionalHeader32.CheckSum", Field, 3, ""},
+		{"OptionalHeader32.DataDirectory", Field, 3, ""},
+		{"OptionalHeader32.DllCharacteristics", Field, 3, ""},
+		{"OptionalHeader32.FileAlignment", Field, 3, ""},
+		{"OptionalHeader32.ImageBase", Field, 3, ""},
+		{"OptionalHeader32.LoaderFlags", Field, 3, ""},
+		{"OptionalHeader32.Magic", Field, 3, ""},
+		{"OptionalHeader32.MajorImageVersion", Field, 3, ""},
+		{"OptionalHeader32.MajorLinkerVersion", Field, 3, ""},
+		{"OptionalHeader32.MajorOperatingSystemVersion", Field, 3, ""},
+		{"OptionalHeader32.MajorSubsystemVersion", Field, 3, ""},
+		{"OptionalHeader32.MinorImageVersion", Field, 3, ""},
+		{"OptionalHeader32.MinorLinkerVersion", Field, 3, ""},
+		{"OptionalHeader32.MinorOperatingSystemVersion", Field, 3, ""},
+		{"OptionalHeader32.MinorSubsystemVersion", Field, 3, ""},
+		{"OptionalHeader32.NumberOfRvaAndSizes", Field, 3, ""},
+		{"OptionalHeader32.SectionAlignment", Field, 3, ""},
+		{"OptionalHeader32.SizeOfCode", Field, 3, ""},
+		{"OptionalHeader32.SizeOfHeaders", Field, 3, ""},
+		{"OptionalHeader32.SizeOfHeapCommit", Field, 3, ""},
+		{"OptionalHeader32.SizeOfHeapReserve", Field, 3, ""},
+		{"OptionalHeader32.SizeOfImage", Field, 3, ""},
+		{"OptionalHeader32.SizeOfInitializedData", Field, 3, ""},
+		{"OptionalHeader32.SizeOfStackCommit", Field, 3, ""},
+		{"OptionalHeader32.SizeOfStackReserve", Field, 3, ""},
+		{"OptionalHeader32.SizeOfUninitializedData", Field, 3, ""},
+		{"OptionalHeader32.Subsystem", Field, 3, ""},
+		{"OptionalHeader32.Win32VersionValue", Field, 3, ""},
+		{"OptionalHeader64", Type, 3, ""},
+		{"OptionalHeader64.AddressOfEntryPoint", Field, 3, ""},
+		{"OptionalHeader64.BaseOfCode", Field, 3, ""},
+		{"OptionalHeader64.CheckSum", Field, 3, ""},
+		{"OptionalHeader64.DataDirectory", Field, 3, ""},
+		{"OptionalHeader64.DllCharacteristics", Field, 3, ""},
+		{"OptionalHeader64.FileAlignment", Field, 3, ""},
+		{"OptionalHeader64.ImageBase", Field, 3, ""},
+		{"OptionalHeader64.LoaderFlags", Field, 3, ""},
+		{"OptionalHeader64.Magic", Field, 3, ""},
+		{"OptionalHeader64.MajorImageVersion", Field, 3, ""},
+		{"OptionalHeader64.MajorLinkerVersion", Field, 3, ""},
+		{"OptionalHeader64.MajorOperatingSystemVersion", Field, 3, ""},
+		{"OptionalHeader64.MajorSubsystemVersion", Field, 3, ""},
+		{"OptionalHeader64.MinorImageVersion", Field, 3, ""},
+		{"OptionalHeader64.MinorLinkerVersion", Field, 3, ""},
+		{"OptionalHeader64.MinorOperatingSystemVersion", Field, 3, ""},
+		{"OptionalHeader64.MinorSubsystemVersion", Field, 3, ""},
+		{"OptionalHeader64.NumberOfRvaAndSizes", Field, 3, ""},
+		{"OptionalHeader64.SectionAlignment", Field, 3, ""},
+		{"OptionalHeader64.SizeOfCode", Field, 3, ""},
+		{"OptionalHeader64.SizeOfHeaders", Field, 3, ""},
+		{"OptionalHeader64.SizeOfHeapCommit", Field, 3, ""},
+		{"OptionalHeader64.SizeOfHeapReserve", Field, 3, ""},
+		{"OptionalHeader64.SizeOfImage", Field, 3, ""},
+		{"OptionalHeader64.SizeOfInitializedData", Field, 3, ""},
+		{"OptionalHeader64.SizeOfStackCommit", Field, 3, ""},
+		{"OptionalHeader64.SizeOfStackReserve", Field, 3, ""},
+		{"OptionalHeader64.SizeOfUninitializedData", Field, 3, ""},
+		{"OptionalHeader64.Subsystem", Field, 3, ""},
+		{"OptionalHeader64.Win32VersionValue", Field, 3, ""},
+		{"Reloc", Type, 8, ""},
+		{"Reloc.SymbolTableIndex", Field, 8, ""},
+		{"Reloc.Type", Field, 8, ""},
+		{"Reloc.VirtualAddress", Field, 8, ""},
+		{"Section", Type, 0, ""},
+		{"Section.ReaderAt", Field, 0, ""},
+		{"Section.Relocs", Field, 8, ""},
+		{"Section.SectionHeader", Field, 0, ""},
+		{"SectionHeader", Type, 0, ""},
+		{"SectionHeader.Characteristics", Field, 0, ""},
+		{"SectionHeader.Name", Field, 0, ""},
+		{"SectionHeader.NumberOfLineNumbers", Field, 0, ""},
+		{"SectionHeader.NumberOfRelocations", Field, 0, ""},
+		{"SectionHeader.Offset", Field, 0, ""},
+		{"SectionHeader.PointerToLineNumbers", Field, 0, ""},
+		{"SectionHeader.PointerToRelocations", Field, 0, ""},
+		{"SectionHeader.Size", Field, 0, ""},
+		{"SectionHeader.VirtualAddress", Field, 0, ""},
+		{"SectionHeader.VirtualSize", Field, 0, ""},
+		{"SectionHeader32", Type, 0, ""},
+		{"SectionHeader32.Characteristics", Field, 0, ""},
+		{"SectionHeader32.Name", Field, 0, ""},
+		{"SectionHeader32.NumberOfLineNumbers", Field, 0, ""},
+		{"SectionHeader32.NumberOfRelocations", Field, 0, ""},
+		{"SectionHeader32.PointerToLineNumbers", Field, 0, ""},
+		{"SectionHeader32.PointerToRawData", Field, 0, ""},
+		{"SectionHeader32.PointerToRelocations", Field, 0, ""},
+		{"SectionHeader32.SizeOfRawData", Field, 0, ""},
+		{"SectionHeader32.VirtualAddress", Field, 0, ""},
+		{"SectionHeader32.VirtualSize", Field, 0, ""},
+		{"StringTable", Type, 8, ""},
+		{"Symbol", Type, 1, ""},
+		{"Symbol.Name", Field, 1, ""},
+		{"Symbol.SectionNumber", Field, 1, ""},
+		{"Symbol.StorageClass", Field, 1, ""},
+		{"Symbol.Type", Field, 1, ""},
+		{"Symbol.Value", Field, 1, ""},
+	},
+	"debug/plan9obj": {
+		{"(*File).Close", Method, 3, ""},
+		{"(*File).Section", Method, 3, ""},
+		{"(*File).Symbols", Method, 3, ""},
+		{"(*Section).Data", Method, 3, ""},
+		{"(*Section).Open", Method, 3, ""},
+		{"(Section).ReadAt", Method, 3, ""},
+		{"ErrNoSymbols", Var, 18, ""},
+		{"File", Type, 3, ""},
+		{"File.FileHeader", Field, 3, ""},
+		{"File.Sections", Field, 3, ""},
+		{"FileHeader", Type, 3, ""},
+		{"FileHeader.Bss", Field, 3, ""},
+		{"FileHeader.Entry", Field, 3, ""},
+		{"FileHeader.HdrSize", Field, 4, ""},
+		{"FileHeader.LoadAddress", Field, 4, ""},
+		{"FileHeader.Magic", Field, 3, ""},
+		{"FileHeader.PtrSize", Field, 3, ""},
+		{"Magic386", Const, 3, ""},
+		{"Magic64", Const, 3, ""},
+		{"MagicAMD64", Const, 3, ""},
+		{"MagicARM", Const, 3, ""},
+		{"NewFile", Func, 3, "func(r io.ReaderAt) (*File, error)"},
+		{"Open", Func, 3, "func(name string) (*File, error)"},
+		{"Section", Type, 3, ""},
+		{"Section.ReaderAt", Field, 3, ""},
+		{"Section.SectionHeader", Field, 3, ""},
+		{"SectionHeader", Type, 3, ""},
+		{"SectionHeader.Name", Field, 3, ""},
+		{"SectionHeader.Offset", Field, 3, ""},
+		{"SectionHeader.Size", Field, 3, ""},
+		{"Sym", Type, 3, ""},
+		{"Sym.Name", Field, 3, ""},
+		{"Sym.Type", Field, 3, ""},
+		{"Sym.Value", Field, 3, ""},
+	},
+	"embed": {
+		{"(FS).Open", Method, 16, ""},
+		{"(FS).ReadDir", Method, 16, ""},
+		{"(FS).ReadFile", Method, 16, ""},
+		{"FS", Type, 16, ""},
+	},
+	"encoding": {
+		{"(BinaryAppender).AppendBinary", Method, 24, ""},
+		{"(BinaryMarshaler).MarshalBinary", Method, 2, ""},
+		{"(BinaryUnmarshaler).UnmarshalBinary", Method, 2, ""},
+		{"(TextAppender).AppendText", Method, 24, ""},
+		{"(TextMarshaler).MarshalText", Method, 2, ""},
+		{"(TextUnmarshaler).UnmarshalText", Method, 2, ""},
+		{"BinaryAppender", Type, 24, ""},
+		{"BinaryMarshaler", Type, 2, ""},
+		{"BinaryUnmarshaler", Type, 2, ""},
+		{"TextAppender", Type, 24, ""},
+		{"TextMarshaler", Type, 2, ""},
+		{"TextUnmarshaler", Type, 2, ""},
+	},
+	"encoding/ascii85": {
+		{"(CorruptInputError).Error", Method, 0, ""},
+		{"CorruptInputError", Type, 0, ""},
+		{"Decode", Func, 0, "func(dst []byte, src []byte, flush bool) (ndst int, nsrc int, err error)"},
+		{"Encode", Func, 0, "func(dst []byte, src []byte) int"},
+		{"MaxEncodedLen", Func, 0, "func(n int) int"},
+		{"NewDecoder", Func, 0, "func(r io.Reader) io.Reader"},
+		{"NewEncoder", Func, 0, "func(w io.Writer) io.WriteCloser"},
+	},
+	"encoding/asn1": {
+		{"(BitString).At", Method, 0, ""},
+		{"(BitString).RightAlign", Method, 0, ""},
+		{"(ObjectIdentifier).Equal", Method, 0, ""},
+		{"(ObjectIdentifier).String", Method, 3, ""},
+		{"(StructuralError).Error", Method, 0, ""},
+		{"(SyntaxError).Error", Method, 0, ""},
+		{"BitString", Type, 0, ""},
+		{"BitString.BitLength", Field, 0, ""},
+		{"BitString.Bytes", Field, 0, ""},
+		{"ClassApplication", Const, 6, ""},
+		{"ClassContextSpecific", Const, 6, ""},
+		{"ClassPrivate", Const, 6, ""},
+		{"ClassUniversal", Const, 6, ""},
+		{"Enumerated", Type, 0, ""},
+		{"Flag", Type, 0, ""},
+		{"Marshal", Func, 0, "func(val any) ([]byte, error)"},
+		{"MarshalWithParams", Func, 10, "func(val any, params string) ([]byte, error)"},
+		{"NullBytes", Var, 9, ""},
+		{"NullRawValue", Var, 9, ""},
+		{"ObjectIdentifier", Type, 0, ""},
+		{"RawContent", Type, 0, ""},
+		{"RawValue", Type, 0, ""},
+		{"RawValue.Bytes", Field, 0, ""},
+		{"RawValue.Class", Field, 0, ""},
+		{"RawValue.FullBytes", Field, 0, ""},
+		{"RawValue.IsCompound", Field, 0, ""},
+		{"RawValue.Tag", Field, 0, ""},
+		{"StructuralError", Type, 0, ""},
+		{"StructuralError.Msg", Field, 0, ""},
+		{"SyntaxError", Type, 0, ""},
+		{"SyntaxError.Msg", Field, 0, ""},
+		{"TagBMPString", Const, 14, ""},
+		{"TagBitString", Const, 6, ""},
+		{"TagBoolean", Const, 6, ""},
+		{"TagEnum", Const, 6, ""},
+		{"TagGeneralString", Const, 6, ""},
+		{"TagGeneralizedTime", Const, 6, ""},
+		{"TagIA5String", Const, 6, ""},
+		{"TagInteger", Const, 6, ""},
+		{"TagNull", Const, 9, ""},
+		{"TagNumericString", Const, 10, ""},
+		{"TagOID", Const, 6, ""},
+		{"TagOctetString", Const, 6, ""},
+		{"TagPrintableString", Const, 6, ""},
+		{"TagSequence", Const, 6, ""},
+		{"TagSet", Const, 6, ""},
+		{"TagT61String", Const, 6, ""},
+		{"TagUTCTime", Const, 6, ""},
+		{"TagUTF8String", Const, 6, ""},
+		{"Unmarshal", Func, 0, "func(b []byte, val any) (rest []byte, err error)"},
+		{"UnmarshalWithParams", Func, 0, "func(b []byte, val any, params string) (rest []byte, err error)"},
+	},
+	"encoding/base32": {
+		{"(*Encoding).AppendDecode", Method, 22, ""},
+		{"(*Encoding).AppendEncode", Method, 22, ""},
+		{"(*Encoding).Decode", Method, 0, ""},
+		{"(*Encoding).DecodeString", Method, 0, ""},
+		{"(*Encoding).DecodedLen", Method, 0, ""},
+		{"(*Encoding).Encode", Method, 0, ""},
+		{"(*Encoding).EncodeToString", Method, 0, ""},
+		{"(*Encoding).EncodedLen", Method, 0, ""},
+		{"(CorruptInputError).Error", Method, 0, ""},
+		{"(Encoding).WithPadding", Method, 9, ""},
+		{"CorruptInputError", Type, 0, ""},
+		{"Encoding", Type, 0, ""},
+		{"HexEncoding", Var, 0, ""},
+		{"NewDecoder", Func, 0, "func(enc *Encoding, r io.Reader) io.Reader"},
+		{"NewEncoder", Func, 0, "func(enc *Encoding, w io.Writer) io.WriteCloser"},
+		{"NewEncoding", Func, 0, "func(encoder string) *Encoding"},
+		{"NoPadding", Const, 9, ""},
+		{"StdEncoding", Var, 0, ""},
+		{"StdPadding", Const, 9, ""},
+	},
+	"encoding/base64": {
+		{"(*Encoding).AppendDecode", Method, 22, ""},
+		{"(*Encoding).AppendEncode", Method, 22, ""},
+		{"(*Encoding).Decode", Method, 0, ""},
+		{"(*Encoding).DecodeString", Method, 0, ""},
+		{"(*Encoding).DecodedLen", Method, 0, ""},
+		{"(*Encoding).Encode", Method, 0, ""},
+		{"(*Encoding).EncodeToString", Method, 0, ""},
+		{"(*Encoding).EncodedLen", Method, 0, ""},
+		{"(CorruptInputError).Error", Method, 0, ""},
+		{"(Encoding).Strict", Method, 8, ""},
+		{"(Encoding).WithPadding", Method, 5, ""},
+		{"CorruptInputError", Type, 0, ""},
+		{"Encoding", Type, 0, ""},
+		{"NewDecoder", Func, 0, "func(enc *Encoding, r io.Reader) io.Reader"},
+		{"NewEncoder", Func, 0, "func(enc *Encoding, w io.Writer) io.WriteCloser"},
+		{"NewEncoding", Func, 0, "func(encoder string) *Encoding"},
+		{"NoPadding", Const, 5, ""},
+		{"RawStdEncoding", Var, 5, ""},
+		{"RawURLEncoding", Var, 5, ""},
+		{"StdEncoding", Var, 0, ""},
+		{"StdPadding", Const, 5, ""},
+		{"URLEncoding", Var, 0, ""},
+	},
+	"encoding/binary": {
+		{"(AppendByteOrder).AppendUint16", Method, 19, ""},
+		{"(AppendByteOrder).AppendUint32", Method, 19, ""},
+		{"(AppendByteOrder).AppendUint64", Method, 19, ""},
+		{"(AppendByteOrder).String", Method, 19, ""},
+		{"(ByteOrder).PutUint16", Method, 0, ""},
+		{"(ByteOrder).PutUint32", Method, 0, ""},
+		{"(ByteOrder).PutUint64", Method, 0, ""},
+		{"(ByteOrder).String", Method, 0, ""},
+		{"(ByteOrder).Uint16", Method, 0, ""},
+		{"(ByteOrder).Uint32", Method, 0, ""},
+		{"(ByteOrder).Uint64", Method, 0, ""},
+		{"Append", Func, 23, "func(buf []byte, order ByteOrder, data any) ([]byte, error)"},
+		{"AppendByteOrder", Type, 19, ""},
+		{"AppendUvarint", Func, 19, "func(buf []byte, x uint64) []byte"},
+		{"AppendVarint", Func, 19, "func(buf []byte, x int64) []byte"},
+		{"BigEndian", Var, 0, ""},
+		{"ByteOrder", Type, 0, ""},
+		{"Decode", Func, 23, "func(buf []byte, order ByteOrder, data any) (int, error)"},
+		{"Encode", Func, 23, "func(buf []byte, order ByteOrder, data any) (int, error)"},
+		{"LittleEndian", Var, 0, ""},
+		{"MaxVarintLen16", Const, 0, ""},
+		{"MaxVarintLen32", Const, 0, ""},
+		{"MaxVarintLen64", Const, 0, ""},
+		{"NativeEndian", Var, 21, ""},
+		{"PutUvarint", Func, 0, "func(buf []byte, x uint64) int"},
+		{"PutVarint", Func, 0, "func(buf []byte, x int64) int"},
+		{"Read", Func, 0, "func(r io.Reader, order ByteOrder, data any) error"},
+		{"ReadUvarint", Func, 0, "func(r io.ByteReader) (uint64, error)"},
+		{"ReadVarint", Func, 0, "func(r io.ByteReader) (int64, error)"},
+		{"Size", Func, 0, "func(v any) int"},
+		{"Uvarint", Func, 0, "func(buf []byte) (uint64, int)"},
+		{"Varint", Func, 0, "func(buf []byte) (int64, int)"},
+		{"Write", Func, 0, "func(w io.Writer, order ByteOrder, data any) error"},
+	},
+	"encoding/csv": {
+		{"(*ParseError).Error", Method, 0, ""},
+		{"(*ParseError).Unwrap", Method, 13, ""},
+		{"(*Reader).FieldPos", Method, 17, ""},
+		{"(*Reader).InputOffset", Method, 19, ""},
+		{"(*Reader).Read", Method, 0, ""},
+		{"(*Reader).ReadAll", Method, 0, ""},
+		{"(*Writer).Error", Method, 1, ""},
+		{"(*Writer).Flush", Method, 0, ""},
+		{"(*Writer).Write", Method, 0, ""},
+		{"(*Writer).WriteAll", Method, 0, ""},
+		{"ErrBareQuote", Var, 0, ""},
+		{"ErrFieldCount", Var, 0, ""},
+		{"ErrQuote", Var, 0, ""},
+		{"ErrTrailingComma", Var, 0, ""},
+		{"NewReader", Func, 0, "func(r io.Reader) *Reader"},
+		{"NewWriter", Func, 0, "func(w io.Writer) *Writer"},
+		{"ParseError", Type, 0, ""},
+		{"ParseError.Column", Field, 0, ""},
+		{"ParseError.Err", Field, 0, ""},
+		{"ParseError.Line", Field, 0, ""},
+		{"ParseError.StartLine", Field, 10, ""},
+		{"Reader", Type, 0, ""},
+		{"Reader.Comma", Field, 0, ""},
+		{"Reader.Comment", Field, 0, ""},
+		{"Reader.FieldsPerRecord", Field, 0, ""},
+		{"Reader.LazyQuotes", Field, 0, ""},
+		{"Reader.ReuseRecord", Field, 9, ""},
+		{"Reader.TrailingComma", Field, 0, ""},
+		{"Reader.TrimLeadingSpace", Field, 0, ""},
+		{"Writer", Type, 0, ""},
+		{"Writer.Comma", Field, 0, ""},
+		{"Writer.UseCRLF", Field, 0, ""},
+	},
+	"encoding/gob": {
+		{"(*Decoder).Decode", Method, 0, ""},
+		{"(*Decoder).DecodeValue", Method, 0, ""},
+		{"(*Encoder).Encode", Method, 0, ""},
+		{"(*Encoder).EncodeValue", Method, 0, ""},
+		{"(GobDecoder).GobDecode", Method, 0, ""},
+		{"(GobEncoder).GobEncode", Method, 0, ""},
+		{"CommonType", Type, 0, ""},
+		{"CommonType.Id", Field, 0, ""},
+		{"CommonType.Name", Field, 0, ""},
+		{"Decoder", Type, 0, ""},
+		{"Encoder", Type, 0, ""},
+		{"GobDecoder", Type, 0, ""},
+		{"GobEncoder", Type, 0, ""},
+		{"NewDecoder", Func, 0, "func(r io.Reader) *Decoder"},
+		{"NewEncoder", Func, 0, "func(w io.Writer) *Encoder"},
+		{"Register", Func, 0, "func(value any)"},
+		{"RegisterName", Func, 0, "func(name string, value any)"},
+	},
+	"encoding/hex": {
+		{"(InvalidByteError).Error", Method, 0, ""},
+		{"AppendDecode", Func, 22, "func(dst []byte, src []byte) ([]byte, error)"},
+		{"AppendEncode", Func, 22, "func(dst []byte, src []byte) []byte"},
+		{"Decode", Func, 0, "func(dst []byte, src []byte) (int, error)"},
+		{"DecodeString", Func, 0, "func(s string) ([]byte, error)"},
+		{"DecodedLen", Func, 0, "func(x int) int"},
+		{"Dump", Func, 0, "func(data []byte) string"},
+		{"Dumper", Func, 0, "func(w io.Writer) io.WriteCloser"},
+		{"Encode", Func, 0, "func(dst []byte, src []byte) int"},
+		{"EncodeToString", Func, 0, "func(src []byte) string"},
+		{"EncodedLen", Func, 0, "func(n int) int"},
+		{"ErrLength", Var, 0, ""},
+		{"InvalidByteError", Type, 0, ""},
+		{"NewDecoder", Func, 10, "func(r io.Reader) io.Reader"},
+		{"NewEncoder", Func, 10, "func(w io.Writer) io.Writer"},
+	},
+	"encoding/json": {
+		{"(*Decoder).Buffered", Method, 1, ""},
+		{"(*Decoder).Decode", Method, 0, ""},
+		{"(*Decoder).DisallowUnknownFields", Method, 10, ""},
+		{"(*Decoder).InputOffset", Method, 14, ""},
+		{"(*Decoder).More", Method, 5, ""},
+		{"(*Decoder).Token", Method, 5, ""},
+		{"(*Decoder).UseNumber", Method, 1, ""},
+		{"(*Encoder).Encode", Method, 0, ""},
+		{"(*Encoder).SetEscapeHTML", Method, 7, ""},
+		{"(*Encoder).SetIndent", Method, 7, ""},
+		{"(*InvalidUTF8Error).Error", Method, 0, ""},
+		{"(*InvalidUnmarshalError).Error", Method, 0, ""},
+		{"(*MarshalerError).Error", Method, 0, ""},
+		{"(*MarshalerError).Unwrap", Method, 13, ""},
+		{"(*Number).UnmarshalJSONFrom", Method, 27, ""},
+		{"(*RawMessage).MarshalJSON", Method, 0, ""},
+		{"(*RawMessage).UnmarshalJSON", Method, 0, ""},
+		{"(*SyntaxError).Error", Method, 0, ""},
+		{"(*UnmarshalFieldError).Error", Method, 0, ""},
+		{"(*UnmarshalTypeError).Error", Method, 0, ""},
+		{"(*UnmarshalTypeError).Unwrap", Method, 27, ""},
+		{"(*UnsupportedTypeError).Error", Method, 0, ""},
+		{"(*UnsupportedValueError).Error", Method, 0, ""},
+		{"(Delim).String", Method, 5, ""},
+		{"(Marshaler).MarshalJSON", Method, 0, ""},
+		{"(Number).Float64", Method, 1, ""},
+		{"(Number).Int64", Method, 1, ""},
+		{"(Number).MarshalJSONTo", Method, 27, ""},
+		{"(Number).String", Method, 1, ""},
+		{"(RawMessage).MarshalJSON", Method, 8, ""},
+		{"(Unmarshaler).UnmarshalJSON", Method, 0, ""},
+		{"CallMethodsWithLegacySemantics", Func, 27, "func(v bool) Options"},
+		{"Compact", Func, 0, "func(dst *bytes.Buffer, src []byte) error"},
+		{"Decoder", Type, 0, ""},
+		{"DefaultOptionsV1", Func, 27, "func() Options"},
+		{"Delim", Type, 5, ""},
+		{"Encoder", Type, 0, ""},
+		{"FormatByteArrayAsArray", Func, 27, "func(v bool) Options"},
+		{"FormatBytesWithLegacySemantics", Func, 27, "func(v bool) Options"},
+		{"FormatDurationAsNano", Func, 27, "func(v bool) Options"},
+		{"HTMLEscape", Func, 0, "func(dst *bytes.Buffer, src []byte)"},
+		{"Indent", Func, 0, "func(dst *bytes.Buffer, src []byte, prefix string, indent string) error"},
+		{"InvalidUTF8Error", Type, 0, ""},
+		{"InvalidUTF8Error.S", Field, 0, ""},
+		{"InvalidUnmarshalError", Type, 0, ""},
+		{"InvalidUnmarshalError.Type", Field, 0, ""},
+		{"Marshal", Func, 0, "func(v any) ([]byte, error)"},
+		{"MarshalIndent", Func, 0, "func(v any, prefix string, indent string) ([]byte, error)"},
+		{"Marshaler", Type, 0, ""},
+		{"MarshalerError", Type, 0, ""},
+		{"MarshalerError.Err", Field, 0, ""},
+		{"MarshalerError.Type", Field, 0, ""},
+		{"MatchCaseSensitiveDelimiter", Func, 27, "func(v bool) Options"},
+		{"MergeWithLegacySemantics", Func, 27, "func(v bool) Options"},
+		{"NewDecoder", Func, 0, "func(r io.Reader) *Decoder"},
+		{"NewEncoder", Func, 0, "func(w io.Writer) *Encoder"},
+		{"Number", Type, 1, ""},
+		{"OmitEmptyWithLegacySemantics", Func, 27, "func(v bool) Options"},
+		{"Options", Type, 27, ""},
+		{"ParseBytesWithLooseRFC4648", Func, 27, "func(v bool) Options"},
+		{"ParseTimeWithLooseRFC3339", Func, 27, "func(v bool) Options"},
+		{"RawMessage", Type, 0, ""},
+		{"ReportErrorsWithLegacySemantics", Func, 27, "func(v bool) Options"},
+		{"StringifyWithLegacySemantics", Func, 27, "func(v bool) Options"},
+		{"SyntaxError", Type, 0, ""},
+		{"SyntaxError.Offset", Field, 0, ""},
+		{"Token", Type, 5, ""},
+		{"Unmarshal", Func, 0, "func(data []byte, v any) error"},
+		{"UnmarshalArrayFromAnyLength", Func, 27, "func(v bool) Options"},
+		{"UnmarshalFieldError", Type, 0, ""},
+		{"UnmarshalFieldError.Field", Field, 0, ""},
+		{"UnmarshalFieldError.Key", Field, 0, ""},
+		{"UnmarshalFieldError.Type", Field, 0, ""},
+		{"UnmarshalTypeError", Type, 0, ""},
+		{"UnmarshalTypeError.Err", Field, 27, ""},
+		{"UnmarshalTypeError.Field", Field, 8, ""},
+		{"UnmarshalTypeError.Offset", Field, 5, ""},
+		{"UnmarshalTypeError.Struct", Field, 8, ""},
+		{"UnmarshalTypeError.Type", Field, 0, ""},
+		{"UnmarshalTypeError.Value", Field, 0, ""},
+		{"Unmarshaler", Type, 0, ""},
+		{"UnsupportedTypeError", Type, 0, ""},
+		{"UnsupportedTypeError.Type", Field, 0, ""},
+		{"UnsupportedValueError", Type, 0, ""},
+		{"UnsupportedValueError.Str", Field, 0, ""},
+		{"UnsupportedValueError.Value", Field, 0, ""},
+		{"Valid", Func, 9, "func(data []byte) bool"},
+	},
+	"encoding/json/jsontext": {
+		{"(*Decoder).InputOffset", Method, 27, ""},
+		{"(*Decoder).Options", Method, 27, ""},
+		{"(*Decoder).PeekKind", Method, 27, ""},
+		{"(*Decoder).ReadToken", Method, 27, ""},
+		{"(*Decoder).ReadValue", Method, 27, ""},
+		{"(*Decoder).Reset", Method, 27, ""},
+		{"(*Decoder).SkipValue", Method, 27, ""},
+		{"(*Decoder).StackDepth", Method, 27, ""},
+		{"(*Decoder).StackIndex", Method, 27, ""},
+		{"(*Decoder).StackPointer", Method, 27, ""},
+		{"(*Decoder).UnreadBuffer", Method, 27, ""},
+		{"(*Encoder).AvailableBuffer", Method, 27, ""},
+		{"(*Encoder).Options", Method, 27, ""},
+		{"(*Encoder).OutputOffset", Method, 27, ""},
+		{"(*Encoder).Reset", Method, 27, ""},
+		{"(*Encoder).StackDepth", Method, 27, ""},
+		{"(*Encoder).StackIndex", Method, 27, ""},
+		{"(*Encoder).StackPointer", Method, 27, ""},
+		{"(*Encoder).WriteToken", Method, 27, ""},
+		{"(*Encoder).WriteValue", Method, 27, ""},
+		{"(*SyntacticError).Error", Method, 27, ""},
+		{"(*SyntacticError).Unwrap", Method, 27, ""},
+		{"(*Value).Canonicalize", Method, 27, ""},
+		{"(*Value).Compact", Method, 27, ""},
+		{"(*Value).Format", Method, 27, ""},
+		{"(*Value).Indent", Method, 27, ""},
+		{"(*Value).UnmarshalJSON", Method, 27, ""},
+		{"(Kind).String", Method, 27, ""},
+		{"(Pointer).AppendToken", Method, 27, ""},
+		{"(Pointer).Contains", Method, 27, ""},
+		{"(Pointer).IsValid", Method, 27, ""},
+		{"(Pointer).LastToken", Method, 27, ""},
+		{"(Pointer).Parent", Method, 27, ""},
+		{"(Pointer).Tokens", Method, 27, ""},
+		{"(Token).Bool", Method, 27, ""},
+		{"(Token).Clone", Method, 27, ""},
+		{"(Token).Float", Method, 27, ""},
+		{"(Token).Float32", Method, 27, ""},
+		{"(Token).Int", Method, 27, ""},
+		{"(Token).Kind", Method, 27, ""},
+		{"(Token).String", Method, 27, ""},
+		{"(Token).Uint", Method, 27, ""},
+		{"(Value).Clone", Method, 27, ""},
+		{"(Value).IsValid", Method, 27, ""},
+		{"(Value).Kind", Method, 27, ""},
+		{"(Value).MarshalJSON", Method, 27, ""},
+		{"(Value).String", Method, 27, ""},
+		{"AllowDuplicateNames", Func, 27, "func(v bool) Options"},
+		{"AllowInvalidUTF8", Func, 27, "func(v bool) Options"},
+		{"AppendFloat", Func, 27, "func(dst []byte, src float64, bits int) []byte"},
+		{"AppendFormat", Func, 27, "func[Bytes ~[]byte | ~string](dst []byte, src Bytes, opts ...Options) ([]byte, error)"},
+		{"AppendQuote", Func, 27, "func[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error)"},
+		{"AppendUnquote", Func, 27, "func[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error)"},
+		{"BeginArray", Var, 27, ""},
+		{"BeginObject", Var, 27, ""},
+		{"Bool", Func, 27, "func(b bool) Token"},
+		{"CanonicalizeRawFloats", Func, 27, "func(v bool) Options"},
+		{"CanonicalizeRawInts", Func, 27, "func(v bool) Options"},
+		{"Decoder", Type, 27, ""},
+		{"Encoder", Type, 27, ""},
+		{"EndArray", Var, 27, ""},
+		{"EndObject", Var, 27, ""},
+		{"ErrDuplicateName", Var, 27, ""},
+		{"ErrNonStringName", Var, 27, ""},
+		{"EscapeForHTML", Func, 27, "func(v bool) Options"},
+		{"EscapeForJS", Func, 27, "func(v bool) Options"},
+		{"False", Var, 27, ""},
+		{"Float", Func, 27, "func(n float64) Token"},
+		{"Float32", Func, 27, "func(n float32) Token"},
+		{"Int", Func, 27, "func(n int64) Token"},
+		{"Internal", Var, 27, ""},
+		{"Kind", Type, 27, ""},
+		{"KindBeginArray", Const, 27, ""},
+		{"KindBeginObject", Const, 27, ""},
+		{"KindEndArray", Const, 27, ""},
+		{"KindEndObject", Const, 27, ""},
+		{"KindFalse", Const, 27, ""},
+		{"KindInvalid", Const, 27, ""},
+		{"KindNull", Const, 27, ""},
+		{"KindNumber", Const, 27, ""},
+		{"KindString", Const, 27, ""},
+		{"KindTrue", Const, 27, ""},
+		{"Multiline", Func, 27, "func(v bool) Options"},
+		{"NewDecoder", Func, 27, "func(r io.Reader, opts ...Options) *Decoder"},
+		{"NewEncoder", Func, 27, "func(w io.Writer, opts ...Options) *Encoder"},
+		{"Null", Var, 27, ""},
+		{"Options", Type, 27, ""},
+		{"Pointer", Type, 27, ""},
+		{"PreserveRawStrings", Func, 27, "func(v bool) Options"},
+		{"ReorderRawObjects", Func, 27, "func(v bool) Options"},
+		{"SpaceAfterColon", Func, 27, "func(v bool) Options"},
+		{"SpaceAfterComma", Func, 27, "func(v bool) Options"},
+		{"String", Func, 27, "func(s string) Token"},
+		{"SyntacticError", Type, 27, ""},
+		{"SyntacticError.ByteOffset", Field, 27, ""},
+		{"SyntacticError.Err", Field, 27, ""},
+		{"SyntacticError.JSONPointer", Field, 27, ""},
+		{"Token", Type, 27, ""},
+		{"True", Var, 27, ""},
+		{"Uint", Func, 27, "func(n uint64) Token"},
+		{"Value", Type, 27, ""},
+		{"WithIndent", Func, 27, "func(indent string) Options"},
+		{"WithIndentPrefix", Func, 27, "func(prefix string) Options"},
+	},
+	"encoding/json/v2": {
+		{"(*SemanticError).Error", Method, 27, ""},
+		{"(*SemanticError).Unwrap", Method, 27, ""},
+		{"(Marshaler).MarshalJSON", Method, 27, ""},
+		{"(MarshalerTo).MarshalJSONTo", Method, 27, ""},
+		{"(Unmarshaler).UnmarshalJSON", Method, 27, ""},
+		{"(UnmarshalerFrom).UnmarshalJSONFrom", Method, 27, ""},
+		{"DefaultOptionsV2", Func, 27, "func() Options"},
+		{"Deterministic", Func, 27, "func(v bool) Options"},
+		{"ErrUnknownName", Var, 27, ""},
+		{"FormatNilMapAsNull", Func, 27, "func(v bool) Options"},
+		{"FormatNilSliceAsNull", Func, 27, "func(v bool) Options"},
+		{"GetOption", Func, 27, "func[T any](opts Options, setter func(T) Options) (T, bool)"},
+		{"JoinMarshalers", Func, 27, "func(ms ...*Marshalers) *Marshalers"},
+		{"JoinOptions", Func, 27, "func(srcs ...Options) Options"},
+		{"JoinUnmarshalers", Func, 27, "func(us ...*Unmarshalers) *Unmarshalers"},
+		{"Marshal", Func, 27, "func(in any, opts ...Options) (out []byte, err error)"},
+		{"MarshalEncode", Func, 27, "func(out *jsontext.Encoder, in any, opts ...Options) (err error)"},
+		{"MarshalFunc", Func, 27, "func[T any](fn func(T) ([]byte, error)) *Marshalers"},
+		{"MarshalToFunc", Func, 27, "func[T any](fn func(*jsontext.Encoder, T) error) *Marshalers"},
+		{"MarshalWrite", Func, 27, "func(out io.Writer, in any, opts ...Options) (err error)"},
+		{"Marshaler", Type, 27, ""},
+		{"MarshalerTo", Type, 27, ""},
+		{"Marshalers", Type, 27, ""},
+		{"MatchCaseInsensitiveNames", Func, 27, "func(v bool) Options"},
+		{"OmitZeroStructFields", Func, 27, "func(v bool) Options"},
+		{"Options", Type, 27, ""},
+		{"RejectUnknownMembers", Func, 27, "func(v bool) Options"},
+		{"SemanticError", Type, 27, ""},
+		{"SemanticError.ByteOffset", Field, 27, ""},
+		{"SemanticError.Err", Field, 27, ""},
+		{"SemanticError.GoType", Field, 27, ""},
+		{"SemanticError.JSONKind", Field, 27, ""},
+		{"SemanticError.JSONPointer", Field, 27, ""},
+		{"SemanticError.JSONValue", Field, 27, ""},
+		{"StringifyNumbers", Func, 27, "func(v bool) Options"},
+		{"Unmarshal", Func, 27, "func(in []byte, out any, opts ...Options) (err error)"},
+		{"UnmarshalDecode", Func, 27, "func(in *jsontext.Decoder, out any, opts ...Options) (err error)"},
+		{"UnmarshalFromFunc", Func, 27, "func[T any](fn func(*jsontext.Decoder, T) error) *Unmarshalers"},
+		{"UnmarshalFunc", Func, 27, "func[T any](fn func([]byte, T) error) *Unmarshalers"},
+		{"UnmarshalRead", Func, 27, "func(in io.Reader, out any, opts ...Options) (err error)"},
+		{"Unmarshaler", Type, 27, ""},
+		{"UnmarshalerFrom", Type, 27, ""},
+		{"Unmarshalers", Type, 27, ""},
+		{"WithMarshalers", Func, 27, "func(v *Marshalers) Options"},
+		{"WithUnmarshalers", Func, 27, "func(v *Unmarshalers) Options"},
+	},
+	"encoding/pem": {
+		{"Block", Type, 0, ""},
+		{"Block.Bytes", Field, 0, ""},
+		{"Block.Headers", Field, 0, ""},
+		{"Block.Type", Field, 0, ""},
+		{"Decode", Func, 0, "func(data []byte) (p *Block, rest []byte)"},
+		{"Encode", Func, 0, "func(out io.Writer, b *Block) error"},
+		{"EncodeToMemory", Func, 0, "func(b *Block) []byte"},
+	},
+	"encoding/xml": {
+		{"(*Decoder).Decode", Method, 0, ""},
+		{"(*Decoder).DecodeElement", Method, 0, ""},
+		{"(*Decoder).InputOffset", Method, 4, ""},
+		{"(*Decoder).InputPos", Method, 19, ""},
+		{"(*Decoder).RawToken", Method, 0, ""},
+		{"(*Decoder).Skip", Method, 0, ""},
+		{"(*Decoder).Token", Method, 0, ""},
+		{"(*Encoder).Close", Method, 20, ""},
+		{"(*Encoder).Encode", Method, 0, ""},
+		{"(*Encoder).EncodeElement", Method, 2, ""},
+		{"(*Encoder).EncodeToken", Method, 2, ""},
+		{"(*Encoder).Flush", Method, 2, ""},
+		{"(*Encoder).Indent", Method, 1, ""},
+		{"(*SyntaxError).Error", Method, 0, ""},
+		{"(*TagPathError).Error", Method, 0, ""},
+		{"(*UnsupportedTypeError).Error", Method, 0, ""},
+		{"(CharData).Copy", Method, 0, ""},
+		{"(Comment).Copy", Method, 0, ""},
+		{"(Directive).Copy", Method, 0, ""},
+		{"(Marshaler).MarshalXML", Method, 2, ""},
+		{"(MarshalerAttr).MarshalXMLAttr", Method, 2, ""},
+		{"(ProcInst).Copy", Method, 0, ""},
+		{"(StartElement).Copy", Method, 0, ""},
+		{"(StartElement).End", Method, 2, ""},
+		{"(TokenReader).Token", Method, 10, ""},
+		{"(UnmarshalError).Error", Method, 0, ""},
+		{"(Unmarshaler).UnmarshalXML", Method, 2, ""},
+		{"(UnmarshalerAttr).UnmarshalXMLAttr", Method, 2, ""},
+		{"Attr", Type, 0, ""},
+		{"Attr.Name", Field, 0, ""},
+		{"Attr.Value", Field, 0, ""},
+		{"CharData", Type, 0, ""},
+		{"Comment", Type, 0, ""},
+		{"CopyToken", Func, 0, "func(t Token) Token"},
+		{"Decoder", Type, 0, ""},
+		{"Decoder.AutoClose", Field, 0, ""},
+		{"Decoder.CharsetReader", Field, 0, ""},
+		{"Decoder.DefaultSpace", Field, 1, ""},
+		{"Decoder.Entity", Field, 0, ""},
+		{"Decoder.Strict", Field, 0, ""},
+		{"Directive", Type, 0, ""},
+		{"Encoder", Type, 0, ""},
+		{"EndElement", Type, 0, ""},
+		{"EndElement.Name", Field, 0, ""},
+		{"Escape", Func, 0, "func(w io.Writer, s []byte)"},
+		{"EscapeText", Func, 1, "func(w io.Writer, s []byte) error"},
+		{"HTMLAutoClose", Var, 0, ""},
+		{"HTMLEntity", Var, 0, ""},
+		{"Header", Const, 0, ""},
+		{"Marshal", Func, 0, "func(v any) ([]byte, error)"},
+		{"MarshalIndent", Func, 0, "func(v any, prefix string, indent string) ([]byte, error)"},
+		{"Marshaler", Type, 2, ""},
+		{"MarshalerAttr", Type, 2, ""},
+		{"Name", Type, 0, ""},
+		{"Name.Local", Field, 0, ""},
+		{"Name.Space", Field, 0, ""},
+		{"NewDecoder", Func, 0, "func(r io.Reader) *Decoder"},
+		{"NewEncoder", Func, 0, "func(w io.Writer) *Encoder"},
+		{"NewTokenDecoder", Func, 10, "func(t TokenReader) *Decoder"},
+		{"ProcInst", Type, 0, ""},
+		{"ProcInst.Inst", Field, 0, ""},
+		{"ProcInst.Target", Field, 0, ""},
+		{"StartElement", Type, 0, ""},
+		{"StartElement.Attr", Field, 0, ""},
+		{"StartElement.Name", Field, 0, ""},
+		{"SyntaxError", Type, 0, ""},
+		{"SyntaxError.Line", Field, 0, ""},
+		{"SyntaxError.Msg", Field, 0, ""},
+		{"TagPathError", Type, 0, ""},
+		{"TagPathError.Field1", Field, 0, ""},
+		{"TagPathError.Field2", Field, 0, ""},
+		{"TagPathError.Struct", Field, 0, ""},
+		{"TagPathError.Tag1", Field, 0, ""},
+		{"TagPathError.Tag2", Field, 0, ""},
+		{"Token", Type, 0, ""},
+		{"TokenReader", Type, 10, ""},
+		{"Unmarshal", Func, 0, "func(data []byte, v any) error"},
+		{"UnmarshalError", Type, 0, ""},
+		{"Unmarshaler", Type, 2, ""},
+		{"UnmarshalerAttr", Type, 2, ""},
+		{"UnsupportedTypeError", Type, 0, ""},
+		{"UnsupportedTypeError.Type", Field, 0, ""},
+	},
+	"errors": {
+		{"As", Func, 13, "func(err error, target any) bool"},
+		{"AsType", Func, 26, "func[E error](err error) (E, bool)"},
+		{"ErrUnsupported", Var, 21, ""},
+		{"Is", Func, 13, "func(err error, target error) bool"},
+		{"Join", Func, 20, "func(errs ...error) error"},
+		{"New", Func, 0, "func(text string) error"},
+		{"Unwrap", Func, 13, "func(err error) error"},
+	},
+	"expvar": {
+		{"(*Float).Add", Method, 0, ""},
+		{"(*Float).Set", Method, 0, ""},
+		{"(*Float).String", Method, 0, ""},
+		{"(*Float).Value", Method, 8, ""},
+		{"(*Int).Add", Method, 0, ""},
+		{"(*Int).Set", Method, 0, ""},
+		{"(*Int).String", Method, 0, ""},
+		{"(*Int).Value", Method, 8, ""},
+		{"(*Map).Add", Method, 0, ""},
+		{"(*Map).AddFloat", Method, 0, ""},
+		{"(*Map).Delete", Method, 12, ""},
+		{"(*Map).Do", Method, 0, ""},
+		{"(*Map).Get", Method, 0, ""},
+		{"(*Map).Init", Method, 0, ""},
+		{"(*Map).Set", Method, 0, ""},
+		{"(*Map).String", Method, 0, ""},
+		{"(*String).Set", Method, 0, ""},
+		{"(*String).String", Method, 0, ""},
+		{"(*String).Value", Method, 8, ""},
+		{"(Func).String", Method, 0, ""},
+		{"(Func).Value", Method, 8, ""},
+		{"(Var).String", Method, 0, ""},
+		{"Do", Func, 0, "func(f func(KeyValue))"},
+		{"Float", Type, 0, ""},
+		{"Func", Type, 0, ""},
+		{"Get", Func, 0, "func(name string) Var"},
+		{"Handler", Func, 8, "func() http.Handler"},
+		{"Int", Type, 0, ""},
+		{"KeyValue", Type, 0, ""},
+		{"KeyValue.Key", Field, 0, ""},
+		{"KeyValue.Value", Field, 0, ""},
+		{"Map", Type, 0, ""},
+		{"NewFloat", Func, 0, "func(name string) *Float"},
+		{"NewInt", Func, 0, "func(name string) *Int"},
+		{"NewMap", Func, 0, "func(name string) *Map"},
+		{"NewString", Func, 0, "func(name string) *String"},
+		{"Publish", Func, 0, "func(name string, v Var)"},
+		{"String", Type, 0, ""},
+		{"Var", Type, 0, ""},
+	},
+	"flag": {
+		{"(*FlagSet).Arg", Method, 0, ""},
+		{"(*FlagSet).Args", Method, 0, ""},
+		{"(*FlagSet).Bool", Method, 0, ""},
+		{"(*FlagSet).BoolFunc", Method, 21, ""},
+		{"(*FlagSet).BoolVar", Method, 0, ""},
+		{"(*FlagSet).Duration", Method, 0, ""},
+		{"(*FlagSet).DurationVar", Method, 0, ""},
+		{"(*FlagSet).ErrorHandling", Method, 10, ""},
+		{"(*FlagSet).Float64", Method, 0, ""},
+		{"(*FlagSet).Float64Var", Method, 0, ""},
+		{"(*FlagSet).Func", Method, 16, ""},
+		{"(*FlagSet).Init", Method, 0, ""},
+		{"(*FlagSet).Int", Method, 0, ""},
+		{"(*FlagSet).Int64", Method, 0, ""},
+		{"(*FlagSet).Int64Var", Method, 0, ""},
+		{"(*FlagSet).IntVar", Method, 0, ""},
+		{"(*FlagSet).Lookup", Method, 0, ""},
+		{"(*FlagSet).NArg", Method, 0, ""},
+		{"(*FlagSet).NFlag", Method, 0, ""},
+		{"(*FlagSet).Name", Method, 10, ""},
+		{"(*FlagSet).Output", Method, 10, ""},
+		{"(*FlagSet).Parse", Method, 0, ""},
+		{"(*FlagSet).Parsed", Method, 0, ""},
+		{"(*FlagSet).PrintDefaults", Method, 0, ""},
+		{"(*FlagSet).Set", Method, 0, ""},
+		{"(*FlagSet).SetOutput", Method, 0, ""},
+		{"(*FlagSet).String", Method, 0, ""},
+		{"(*FlagSet).StringVar", Method, 0, ""},
+		{"(*FlagSet).TextVar", Method, 19, ""},
+		{"(*FlagSet).Uint", Method, 0, ""},
+		{"(*FlagSet).Uint64", Method, 0, ""},
+		{"(*FlagSet).Uint64Var", Method, 0, ""},
+		{"(*FlagSet).UintVar", Method, 0, ""},
+		{"(*FlagSet).Var", Method, 0, ""},
+		{"(*FlagSet).Visit", Method, 0, ""},
+		{"(*FlagSet).VisitAll", Method, 0, ""},
+		{"(Getter).Get", Method, 2, ""},
+		{"(Getter).Set", Method, 2, ""},
+		{"(Getter).String", Method, 2, ""},
+		{"(Value).Set", Method, 0, ""},
+		{"(Value).String", Method, 0, ""},
+		{"Arg", Func, 0, "func(i int) string"},
+		{"Args", Func, 0, "func() []string"},
+		{"Bool", Func, 0, "func(name string, value bool, usage string) *bool"},
+		{"BoolFunc", Func, 21, "func(name string, usage string, fn func(string) error)"},
+		{"BoolVar", Func, 0, "func(p *bool, name string, value bool, usage string)"},
+		{"CommandLine", Var, 2, ""},
+		{"ContinueOnError", Const, 0, ""},
+		{"Duration", Func, 0, "func(name string, value time.Duration, usage string) *time.Duration"},
+		{"DurationVar", Func, 0, "func(p *time.Duration, name string, value time.Duration, usage string)"},
+		{"ErrHelp", Var, 0, ""},
+		{"ErrorHandling", Type, 0, ""},
+		{"ExitOnError", Const, 0, ""},
+		{"Flag", Type, 0, ""},
+		{"Flag.DefValue", Field, 0, ""},
+		{"Flag.Name", Field, 0, ""},
+		{"Flag.Usage", Field, 0, ""},
+		{"Flag.Value", Field, 0, ""},
+		{"FlagSet", Type, 0, ""},
+		{"FlagSet.Usage", Field, 0, ""},
+		{"Float64", Func, 0, "func(name string, value float64, usage string) *float64"},
+		{"Float64Var", Func, 0, "func(p *float64, name string, value float64, usage string)"},
+		{"Func", Func, 16, "func(name string, usage string, fn func(string) error)"},
+		{"Getter", Type, 2, ""},
+		{"Int", Func, 0, "func(name string, value int, usage string) *int"},
+		{"Int64", Func, 0, "func(name string, value int64, usage string) *int64"},
+		{"Int64Var", Func, 0, "func(p *int64, name string, value int64, usage string)"},
+		{"IntVar", Func, 0, "func(p *int, name string, value int, usage string)"},
+		{"Lookup", Func, 0, "func(name string) *Flag"},
+		{"NArg", Func, 0, "func() int"},
+		{"NFlag", Func, 0, "func() int"},
+		{"NewFlagSet", Func, 0, "func(name string, errorHandling ErrorHandling) *FlagSet"},
+		{"PanicOnError", Const, 0, ""},
+		{"Parse", Func, 0, "func()"},
+		{"Parsed", Func, 0, "func() bool"},
+		{"PrintDefaults", Func, 0, "func()"},
+		{"Set", Func, 0, "func(name string, value string) error"},
+		{"String", Func, 0, "func(name string, value string, usage string) *string"},
+		{"StringVar", Func, 0, "func(p *string, name string, value string, usage string)"},
+		{"TextVar", Func, 19, "func(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string)"},
+		{"Uint", Func, 0, "func(name string, value uint, usage string) *uint"},
+		{"Uint64", Func, 0, "func(name string, value uint64, usage string) *uint64"},
+		{"Uint64Var", Func, 0, "func(p *uint64, name string, value uint64, usage string)"},
+		{"UintVar", Func, 0, "func(p *uint, name string, value uint, usage string)"},
+		{"UnquoteUsage", Func, 5, "func(flag *Flag) (name string, usage string)"},
+		{"Usage", Var, 0, ""},
+		{"Value", Type, 0, ""},
+		{"Var", Func, 0, "func(value Value, name string, usage string)"},
+		{"Visit", Func, 0, "func(fn func(*Flag))"},
+		{"VisitAll", Func, 0, "func(fn func(*Flag))"},
+	},
+	"fmt": {
+		{"(Formatter).Format", Method, 0, ""},
+		{"(GoStringer).GoString", Method, 0, ""},
+		{"(ScanState).Read", Method, 0, ""},
+		{"(ScanState).ReadRune", Method, 0, ""},
+		{"(ScanState).SkipSpace", Method, 0, ""},
+		{"(ScanState).Token", Method, 0, ""},
+		{"(ScanState).UnreadRune", Method, 0, ""},
+		{"(ScanState).Width", Method, 0, ""},
+		{"(Scanner).Scan", Method, 0, ""},
+		{"(State).Flag", Method, 0, ""},
+		{"(State).Precision", Method, 0, ""},
+		{"(State).Width", Method, 0, ""},
+		{"(State).Write", Method, 0, ""},
+		{"(Stringer).String", Method, 0, ""},
+		{"Append", Func, 19, "func(b []byte, a ...any) []byte"},
+		{"Appendf", Func, 19, "func(b []byte, format string, a ...any) []byte"},
+		{"Appendln", Func, 19, "func(b []byte, a ...any) []byte"},
+		{"Errorf", Func, 0, "func(format string, a ...any) (err error)"},
+		{"FormatString", Func, 20, "func(state State, verb rune) string"},
+		{"Formatter", Type, 0, ""},
+		{"Fprint", Func, 0, "func(w io.Writer, a ...any) (n int, err error)"},
+		{"Fprintf", Func, 0, "func(w io.Writer, format string, a ...any) (n int, err error)"},
+		{"Fprintln", Func, 0, "func(w io.Writer, a ...any) (n int, err error)"},
+		{"Fscan", Func, 0, "func(r io.Reader, a ...any) (n int, err error)"},
+		{"Fscanf", Func, 0, "func(r io.Reader, format string, a ...any) (n int, err error)"},
+		{"Fscanln", Func, 0, "func(r io.Reader, a ...any) (n int, err error)"},
+		{"GoStringer", Type, 0, ""},
+		{"Print", Func, 0, "func(a ...any) (n int, err error)"},
+		{"Printf", Func, 0, "func(format string, a ...any) (n int, err error)"},
+		{"Println", Func, 0, "func(a ...any) (n int, err error)"},
+		{"Scan", Func, 0, "func(a ...any) (n int, err error)"},
+		{"ScanState", Type, 0, ""},
+		{"Scanf", Func, 0, "func(format string, a ...any) (n int, err error)"},
+		{"Scanln", Func, 0, "func(a ...any) (n int, err error)"},
+		{"Scanner", Type, 0, ""},
+		{"Sprint", Func, 0, "func(a ...any) string"},
+		{"Sprintf", Func, 0, "func(format string, a ...any) string"},
+		{"Sprintln", Func, 0, "func(a ...any) string"},
+		{"Sscan", Func, 0, "func(str string, a ...any) (n int, err error)"},
+		{"Sscanf", Func, 0, "func(str string, format string, a ...any) (n int, err error)"},
+		{"Sscanln", Func, 0, "func(str string, a ...any) (n int, err error)"},
+		{"State", Type, 0, ""},
+		{"Stringer", Type, 0, ""},
+	},
+	"go/ast": {
+		{"(*ArrayType).End", Method, 0, ""},
+		{"(*ArrayType).Pos", Method, 0, ""},
+		{"(*AssignStmt).End", Method, 0, ""},
+		{"(*AssignStmt).Pos", Method, 0, ""},
+		{"(*BadDecl).End", Method, 0, ""},
+		{"(*BadDecl).Pos", Method, 0, ""},
+		{"(*BadExpr).End", Method, 0, ""},
+		{"(*BadExpr).Pos", Method, 0, ""},
+		{"(*BadStmt).End", Method, 0, ""},
+		{"(*BadStmt).Pos", Method, 0, ""},
+		{"(*BasicLit).End", Method, 0, ""},
+		{"(*BasicLit).Pos", Method, 0, ""},
+		{"(*BinaryExpr).End", Method, 0, ""},
+		{"(*BinaryExpr).Pos", Method, 0, ""},
+		{"(*BlockStmt).End", Method, 0, ""},
+		{"(*BlockStmt).Pos", Method, 0, ""},
+		{"(*BranchStmt).End", Method, 0, ""},
+		{"(*BranchStmt).Pos", Method, 0, ""},
+		{"(*CallExpr).End", Method, 0, ""},
+		{"(*CallExpr).Pos", Method, 0, ""},
+		{"(*CaseClause).End", Method, 0, ""},
+		{"(*CaseClause).Pos", Method, 0, ""},
+		{"(*ChanType).End", Method, 0, ""},
+		{"(*ChanType).Pos", Method, 0, ""},
+		{"(*CommClause).End", Method, 0, ""},
+		{"(*CommClause).Pos", Method, 0, ""},
+		{"(*Comment).End", Method, 0, ""},
+		{"(*Comment).Pos", Method, 0, ""},
+		{"(*CommentGroup).End", Method, 0, ""},
+		{"(*CommentGroup).Pos", Method, 0, ""},
+		{"(*CommentGroup).Text", Method, 0, ""},
+		{"(*CompositeLit).End", Method, 0, ""},
+		{"(*CompositeLit).Pos", Method, 0, ""},
+		{"(*DeclStmt).End", Method, 0, ""},
+		{"(*DeclStmt).Pos", Method, 0, ""},
+		{"(*DeferStmt).End", Method, 0, ""},
+		{"(*DeferStmt).Pos", Method, 0, ""},
+		{"(*Directive).End", Method, 26, ""},
+		{"(*Directive).ParseArgs", Method, 26, ""},
+		{"(*Directive).Pos", Method, 26, ""},
+		{"(*Ellipsis).End", Method, 0, ""},
+		{"(*Ellipsis).Pos", Method, 0, ""},
+		{"(*EmptyStmt).End", Method, 0, ""},
+		{"(*EmptyStmt).Pos", Method, 0, ""},
+		{"(*ExprStmt).End", Method, 0, ""},
+		{"(*ExprStmt).Pos", Method, 0, ""},
+		{"(*Field).End", Method, 0, ""},
+		{"(*Field).Pos", Method, 0, ""},
+		{"(*FieldList).End", Method, 0, ""},
+		{"(*FieldList).NumFields", Method, 0, ""},
+		{"(*FieldList).Pos", Method, 0, ""},
+		{"(*File).End", Method, 0, ""},
+		{"(*File).Pos", Method, 0, ""},
+		{"(*ForStmt).End", Method, 0, ""},
+		{"(*ForStmt).Pos", Method, 0, ""},
+		{"(*FuncDecl).End", Method, 0, ""},
+		{"(*FuncDecl).Pos", Method, 0, ""},
+		{"(*FuncLit).End", Method, 0, ""},
+		{"(*FuncLit).Pos", Method, 0, ""},
+		{"(*FuncType).End", Method, 0, ""},
+		{"(*FuncType).Pos", Method, 0, ""},
+		{"(*GenDecl).End", Method, 0, ""},
+		{"(*GenDecl).Pos", Method, 0, ""},
+		{"(*GoStmt).End", Method, 0, ""},
+		{"(*GoStmt).Pos", Method, 0, ""},
+		{"(*Ident).End", Method, 0, ""},
+		{"(*Ident).IsExported", Method, 0, ""},
+		{"(*Ident).Pos", Method, 0, ""},
+		{"(*Ident).String", Method, 0, ""},
+		{"(*IfStmt).End", Method, 0, ""},
+		{"(*IfStmt).Pos", Method, 0, ""},
+		{"(*ImportSpec).End", Method, 0, ""},
+		{"(*ImportSpec).Pos", Method, 0, ""},
+		{"(*IncDecStmt).End", Method, 0, ""},
+		{"(*IncDecStmt).Pos", Method, 0, ""},
+		{"(*IndexExpr).End", Method, 0, ""},
+		{"(*IndexExpr).Pos", Method, 0, ""},
+		{"(*IndexListExpr).End", Method, 18, ""},
+		{"(*IndexListExpr).Pos", Method, 18, ""},
+		{"(*InterfaceType).End", Method, 0, ""},
+		{"(*InterfaceType).Pos", Method, 0, ""},
+		{"(*KeyValueExpr).End", Method, 0, ""},
+		{"(*KeyValueExpr).Pos", Method, 0, ""},
+		{"(*LabeledStmt).End", Method, 0, ""},
+		{"(*LabeledStmt).Pos", Method, 0, ""},
+		{"(*MapType).End", Method, 0, ""},
+		{"(*MapType).Pos", Method, 0, ""},
+		{"(*Object).Pos", Method, 0, ""},
+		{"(*Package).End", Method, 0, ""},
+		{"(*Package).Pos", Method, 0, ""},
+		{"(*ParenExpr).End", Method, 0, ""},
+		{"(*ParenExpr).Pos", Method, 0, ""},
+		{"(*RangeStmt).End", Method, 0, ""},
+		{"(*RangeStmt).Pos", Method, 0, ""},
+		{"(*ReturnStmt).End", Method, 0, ""},
+		{"(*ReturnStmt).Pos", Method, 0, ""},
+		{"(*Scope).Insert", Method, 0, ""},
+		{"(*Scope).Lookup", Method, 0, ""},
+		{"(*Scope).String", Method, 0, ""},
+		{"(*SelectStmt).End", Method, 0, ""},
+		{"(*SelectStmt).Pos", Method, 0, ""},
+		{"(*SelectorExpr).End", Method, 0, ""},
+		{"(*SelectorExpr).Pos", Method, 0, ""},
+		{"(*SendStmt).End", Method, 0, ""},
+		{"(*SendStmt).Pos", Method, 0, ""},
+		{"(*SliceExpr).End", Method, 0, ""},
+		{"(*SliceExpr).Pos", Method, 0, ""},
+		{"(*StarExpr).End", Method, 0, ""},
+		{"(*StarExpr).Pos", Method, 0, ""},
+		{"(*StructType).End", Method, 0, ""},
+		{"(*StructType).Pos", Method, 0, ""},
+		{"(*SwitchStmt).End", Method, 0, ""},
+		{"(*SwitchStmt).Pos", Method, 0, ""},
+		{"(*TypeAssertExpr).End", Method, 0, ""},
+		{"(*TypeAssertExpr).Pos", Method, 0, ""},
+		{"(*TypeSpec).End", Method, 0, ""},
+		{"(*TypeSpec).Pos", Method, 0, ""},
+		{"(*TypeSwitchStmt).End", Method, 0, ""},
+		{"(*TypeSwitchStmt).Pos", Method, 0, ""},
+		{"(*UnaryExpr).End", Method, 0, ""},
+		{"(*UnaryExpr).Pos", Method, 0, ""},
+		{"(*ValueSpec).End", Method, 0, ""},
+		{"(*ValueSpec).Pos", Method, 0, ""},
+		{"(CommentMap).Comments", Method, 1, ""},
+		{"(CommentMap).Filter", Method, 1, ""},
+		{"(CommentMap).String", Method, 1, ""},
+		{"(CommentMap).Update", Method, 1, ""},
+		{"(Decl).End", Method, 0, ""},
+		{"(Decl).Pos", Method, 0, ""},
+		{"(Expr).End", Method, 0, ""},
+		{"(Expr).Pos", Method, 0, ""},
+		{"(Node).End", Method, 0, ""},
+		{"(Node).Pos", Method, 0, ""},
+		{"(ObjKind).String", Method, 0, ""},
+		{"(Spec).End", Method, 0, ""},
+		{"(Spec).Pos", Method, 0, ""},
+		{"(Stmt).End", Method, 0, ""},
+		{"(Stmt).Pos", Method, 0, ""},
+		{"(Visitor).Visit", Method, 0, ""},
+		{"ArrayType", Type, 0, ""},
+		{"ArrayType.Elt", Field, 0, ""},
+		{"ArrayType.Lbrack", Field, 0, ""},
+		{"ArrayType.Len", Field, 0, ""},
+		{"AssignStmt", Type, 0, ""},
+		{"AssignStmt.Lhs", Field, 0, ""},
+		{"AssignStmt.Rhs", Field, 0, ""},
+		{"AssignStmt.Tok", Field, 0, ""},
+		{"AssignStmt.TokPos", Field, 0, ""},
+		{"Bad", Const, 0, ""},
+		{"BadDecl", Type, 0, ""},
+		{"BadDecl.From", Field, 0, ""},
+		{"BadDecl.To", Field, 0, ""},
+		{"BadExpr", Type, 0, ""},
+		{"BadExpr.From", Field, 0, ""},
+		{"BadExpr.To", Field, 0, ""},
+		{"BadStmt", Type, 0, ""},
+		{"BadStmt.From", Field, 0, ""},
+		{"BadStmt.To", Field, 0, ""},
+		{"BasicLit", Type, 0, ""},
+		{"BasicLit.Kind", Field, 0, ""},
+		{"BasicLit.Value", Field, 0, ""},
+		{"BasicLit.ValueEnd", Field, 26, ""},
+		{"BasicLit.ValuePos", Field, 0, ""},
+		{"BinaryExpr", Type, 0, ""},
+		{"BinaryExpr.Op", Field, 0, ""},
+		{"BinaryExpr.OpPos", Field, 0, ""},
+		{"BinaryExpr.X", Field, 0, ""},
+		{"BinaryExpr.Y", Field, 0, ""},
+		{"BlockStmt", Type, 0, ""},
+		{"BlockStmt.Lbrace", Field, 0, ""},
+		{"BlockStmt.List", Field, 0, ""},
+		{"BlockStmt.Rbrace", Field, 0, ""},
+		{"BranchStmt", Type, 0, ""},
+		{"BranchStmt.Label", Field, 0, ""},
+		{"BranchStmt.Tok", Field, 0, ""},
+		{"BranchStmt.TokPos", Field, 0, ""},
+		{"CallExpr", Type, 0, ""},
+		{"CallExpr.Args", Field, 0, ""},
+		{"CallExpr.Ellipsis", Field, 0, ""},
+		{"CallExpr.Fun", Field, 0, ""},
+		{"CallExpr.Lparen", Field, 0, ""},
+		{"CallExpr.Rparen", Field, 0, ""},
+		{"CaseClause", Type, 0, ""},
+		{"CaseClause.Body", Field, 0, ""},
+		{"CaseClause.Case", Field, 0, ""},
+		{"CaseClause.Colon", Field, 0, ""},
+		{"CaseClause.List", Field, 0, ""},
+		{"ChanDir", Type, 0, ""},
+		{"ChanType", Type, 0, ""},
+		{"ChanType.Arrow", Field, 1, ""},
+		{"ChanType.Begin", Field, 0, ""},
+		{"ChanType.Dir", Field, 0, ""},
+		{"ChanType.Value", Field, 0, ""},
+		{"CommClause", Type, 0, ""},
+		{"CommClause.Body", Field, 0, ""},
+		{"CommClause.Case", Field, 0, ""},
+		{"CommClause.Colon", Field, 0, ""},
+		{"CommClause.Comm", Field, 0, ""},
+		{"Comment", Type, 0, ""},
+		{"Comment.Slash", Field, 0, ""},
+		{"Comment.Text", Field, 0, ""},
+		{"CommentGroup", Type, 0, ""},
+		{"CommentGroup.List", Field, 0, ""},
+		{"CommentMap", Type, 1, ""},
+		{"CompositeLit", Type, 0, ""},
+		{"CompositeLit.Elts", Field, 0, ""},
+		{"CompositeLit.Incomplete", Field, 11, ""},
+		{"CompositeLit.Lbrace", Field, 0, ""},
+		{"CompositeLit.Rbrace", Field, 0, ""},
+		{"CompositeLit.Type", Field, 0, ""},
+		{"Con", Const, 0, ""},
+		{"DeclStmt", Type, 0, ""},
+		{"DeclStmt.Decl", Field, 0, ""},
+		{"DeferStmt", Type, 0, ""},
+		{"DeferStmt.Call", Field, 0, ""},
+		{"DeferStmt.Defer", Field, 0, ""},
+		{"Directive", Type, 26, ""},
+		{"Directive.Args", Field, 26, ""},
+		{"Directive.ArgsPos", Field, 26, ""},
+		{"Directive.Name", Field, 26, ""},
+		{"Directive.Slash", Field, 26, ""},
+		{"Directive.Tool", Field, 26, ""},
+		{"DirectiveArg", Type, 26, ""},
+		{"DirectiveArg.Arg", Field, 26, ""},
+		{"DirectiveArg.Pos", Field, 26, ""},
+		{"Ellipsis", Type, 0, ""},
+		{"Ellipsis.Ellipsis", Field, 0, ""},
+		{"Ellipsis.Elt", Field, 0, ""},
+		{"EmptyStmt", Type, 0, ""},
+		{"EmptyStmt.Implicit", Field, 5, ""},
+		{"EmptyStmt.Semicolon", Field, 0, ""},
+		{"ExprStmt", Type, 0, ""},
+		{"ExprStmt.X", Field, 0, ""},
+		{"Field", Type, 0, ""},
+		{"Field.Comment", Field, 0, ""},
+		{"Field.Doc", Field, 0, ""},
+		{"Field.Names", Field, 0, ""},
+		{"Field.Tag", Field, 0, ""},
+		{"Field.Type", Field, 0, ""},
+		{"FieldFilter", Type, 0, ""},
+		{"FieldList", Type, 0, ""},
+		{"FieldList.Closing", Field, 0, ""},
+		{"FieldList.List", Field, 0, ""},
+		{"FieldList.Opening", Field, 0, ""},
+		{"File", Type, 0, ""},
+		{"File.Comments", Field, 0, ""},
+		{"File.Decls", Field, 0, ""},
+		{"File.Doc", Field, 0, ""},
+		{"File.FileEnd", Field, 20, ""},
+		{"File.FileStart", Field, 20, ""},
+		{"File.GoVersion", Field, 21, ""},
+		{"File.Imports", Field, 0, ""},
+		{"File.Name", Field, 0, ""},
+		{"File.Package", Field, 0, ""},
+		{"File.Scope", Field, 0, ""},
+		{"File.Unresolved", Field, 0, ""},
+		{"FileExports", Func, 0, "func(src *File) bool"},
+		{"Filter", Type, 0, ""},
+		{"FilterDecl", Func, 0, "func(decl Decl, f Filter) bool"},
+		{"FilterFile", Func, 0, "func(src *File, f Filter) bool"},
+		{"FilterFuncDuplicates", Const, 0, ""},
+		{"FilterImportDuplicates", Const, 0, ""},
+		{"FilterPackage", Func, 0, "func(pkg *Package, f Filter) bool"},
+		{"FilterUnassociatedComments", Const, 0, ""},
+		{"ForStmt", Type, 0, ""},
+		{"ForStmt.Body", Field, 0, ""},
+		{"ForStmt.Cond", Field, 0, ""},
+		{"ForStmt.For", Field, 0, ""},
+		{"ForStmt.Init", Field, 0, ""},
+		{"ForStmt.Post", Field, 0, ""},
+		{"Fprint", Func, 0, "func(w io.Writer, fset *token.FileSet, x any, f FieldFilter) error"},
+		{"Fun", Const, 0, ""},
+		{"FuncDecl", Type, 0, ""},
+		{"FuncDecl.Body", Field, 0, ""},
+		{"FuncDecl.Doc", Field, 0, ""},
+		{"FuncDecl.Name", Field, 0, ""},
+		{"FuncDecl.Recv", Field, 0, ""},
+		{"FuncDecl.Type", Field, 0, ""},
+		{"FuncLit", Type, 0, ""},
+		{"FuncLit.Body", Field, 0, ""},
+		{"FuncLit.Type", Field, 0, ""},
+		{"FuncType", Type, 0, ""},
+		{"FuncType.Func", Field, 0, ""},
+		{"FuncType.Params", Field, 0, ""},
+		{"FuncType.Results", Field, 0, ""},
+		{"FuncType.TypeParams", Field, 18, ""},
+		{"GenDecl", Type, 0, ""},
+		{"GenDecl.Doc", Field, 0, ""},
+		{"GenDecl.Lparen", Field, 0, ""},
+		{"GenDecl.Rparen", Field, 0, ""},
+		{"GenDecl.Specs", Field, 0, ""},
+		{"GenDecl.Tok", Field, 0, ""},
+		{"GenDecl.TokPos", Field, 0, ""},
+		{"GoStmt", Type, 0, ""},
+		{"GoStmt.Call", Field, 0, ""},
+		{"GoStmt.Go", Field, 0, ""},
+		{"Ident", Type, 0, ""},
+		{"Ident.Name", Field, 0, ""},
+		{"Ident.NamePos", Field, 0, ""},
+		{"Ident.Obj", Field, 0, ""},
+		{"IfStmt", Type, 0, ""},
+		{"IfStmt.Body", Field, 0, ""},
+		{"IfStmt.Cond", Field, 0, ""},
+		{"IfStmt.Else", Field, 0, ""},
+		{"IfStmt.If", Field, 0, ""},
+		{"IfStmt.Init", Field, 0, ""},
+		{"ImportSpec", Type, 0, ""},
+		{"ImportSpec.Comment", Field, 0, ""},
+		{"ImportSpec.Doc", Field, 0, ""},
+		{"ImportSpec.EndPos", Field, 0, ""},
+		{"ImportSpec.Name", Field, 0, ""},
+		{"ImportSpec.Path", Field, 0, ""},
+		{"Importer", Type, 0, ""},
+		{"IncDecStmt", Type, 0, ""},
+		{"IncDecStmt.Tok", Field, 0, ""},
+		{"IncDecStmt.TokPos", Field, 0, ""},
+		{"IncDecStmt.X", Field, 0, ""},
+		{"IndexExpr", Type, 0, ""},
+		{"IndexExpr.Index", Field, 0, ""},
+		{"IndexExpr.Lbrack", Field, 0, ""},
+		{"IndexExpr.Rbrack", Field, 0, ""},
+		{"IndexExpr.X", Field, 0, ""},
+		{"IndexListExpr", Type, 18, ""},
+		{"IndexListExpr.Indices", Field, 18, ""},
+		{"IndexListExpr.Lbrack", Field, 18, ""},
+		{"IndexListExpr.Rbrack", Field, 18, ""},
+		{"IndexListExpr.X", Field, 18, ""},
+		{"Inspect", Func, 0, "func(node Node, f func(Node) bool)"},
+		{"InterfaceType", Type, 0, ""},
+		{"InterfaceType.Incomplete", Field, 0, ""},
+		{"InterfaceType.Interface", Field, 0, ""},
+		{"InterfaceType.Methods", Field, 0, ""},
+		{"IsExported", Func, 0, "func(name string) bool"},
+		{"IsGenerated", Func, 21, "func(file *File) bool"},
+		{"KeyValueExpr", Type, 0, ""},
+		{"KeyValueExpr.Colon", Field, 0, ""},
+		{"KeyValueExpr.Key", Field, 0, ""},
+		{"KeyValueExpr.Value", Field, 0, ""},
+		{"LabeledStmt", Type, 0, ""},
+		{"LabeledStmt.Colon", Field, 0, ""},
+		{"LabeledStmt.Label", Field, 0, ""},
+		{"LabeledStmt.Stmt", Field, 0, ""},
+		{"Lbl", Const, 0, ""},
+		{"MapType", Type, 0, ""},
+		{"MapType.Key", Field, 0, ""},
+		{"MapType.Map", Field, 0, ""},
+		{"MapType.Value", Field, 0, ""},
+		{"MergeMode", Type, 0, ""},
+		{"MergePackageFiles", Func, 0, "func(pkg *Package, mode MergeMode) *File"},
+		{"NewCommentMap", Func, 1, "func(fset *token.FileSet, node Node, comments []*CommentGroup) CommentMap"},
+		{"NewIdent", Func, 0, "func(name string) *Ident"},
+		{"NewObj", Func, 0, "func(kind ObjKind, name string) *Object"},
+		{"NewPackage", Func, 0, "func(fset *token.FileSet, files map[string]*File, importer Importer, universe *Scope) (*Package, error)"},
+		{"NewScope", Func, 0, "func(outer *Scope) *Scope"},
+		{"Node", Type, 0, ""},
+		{"NotNilFilter", Func, 0, "func(_ string, v reflect.Value) bool"},
+		{"ObjKind", Type, 0, ""},
+		{"Object", Type, 0, ""},
+		{"Object.Data", Field, 0, ""},
+		{"Object.Decl", Field, 0, ""},
+		{"Object.Kind", Field, 0, ""},
+		{"Object.Name", Field, 0, ""},
+		{"Object.Type", Field, 0, ""},
+		{"Package", Type, 0, ""},
+		{"Package.Files", Field, 0, ""},
+		{"Package.Imports", Field, 0, ""},
+		{"Package.Name", Field, 0, ""},
+		{"Package.Scope", Field, 0, ""},
+		{"PackageExports", Func, 0, "func(pkg *Package) bool"},
+		{"ParenExpr", Type, 0, ""},
+		{"ParenExpr.Lparen", Field, 0, ""},
+		{"ParenExpr.Rparen", Field, 0, ""},
+		{"ParenExpr.X", Field, 0, ""},
+		{"ParseDirective", Func, 26, "func(pos token.Pos, c string) (Directive, bool)"},
+		{"Pkg", Const, 0, ""},
+		{"Preorder", Func, 23, "func(root Node) iter.Seq[Node]"},
+		{"PreorderStack", Func, 25, "func(root Node, stack []Node, f func(n Node, stack []Node) bool)"},
+		{"Print", Func, 0, "func(fset *token.FileSet, x any) error"},
+		{"RECV", Const, 0, ""},
+		{"RangeStmt", Type, 0, ""},
+		{"RangeStmt.Body", Field, 0, ""},
+		{"RangeStmt.For", Field, 0, ""},
+		{"RangeStmt.Key", Field, 0, ""},
+		{"RangeStmt.Range", Field, 20, ""},
+		{"RangeStmt.Tok", Field, 0, ""},
+		{"RangeStmt.TokPos", Field, 0, ""},
+		{"RangeStmt.Value", Field, 0, ""},
+		{"RangeStmt.X", Field, 0, ""},
+		{"ReturnStmt", Type, 0, ""},
+		{"ReturnStmt.Results", Field, 0, ""},
+		{"ReturnStmt.Return", Field, 0, ""},
+		{"SEND", Const, 0, ""},
+		{"Scope", Type, 0, ""},
+		{"Scope.Objects", Field, 0, ""},
+		{"Scope.Outer", Field, 0, ""},
+		{"SelectStmt", Type, 0, ""},
+		{"SelectStmt.Body", Field, 0, ""},
+		{"SelectStmt.Select", Field, 0, ""},
+		{"SelectorExpr", Type, 0, ""},
+		{"SelectorExpr.Sel", Field, 0, ""},
+		{"SelectorExpr.X", Field, 0, ""},
+		{"SendStmt", Type, 0, ""},
+		{"SendStmt.Arrow", Field, 0, ""},
+		{"SendStmt.Chan", Field, 0, ""},
+		{"SendStmt.Value", Field, 0, ""},
+		{"SliceExpr", Type, 0, ""},
+		{"SliceExpr.High", Field, 0, ""},
+		{"SliceExpr.Lbrack", Field, 0, ""},
+		{"SliceExpr.Low", Field, 0, ""},
+		{"SliceExpr.Max", Field, 2, ""},
+		{"SliceExpr.Rbrack", Field, 0, ""},
+		{"SliceExpr.Slice3", Field, 2, ""},
+		{"SliceExpr.X", Field, 0, ""},
+		{"SortImports", Func, 0, "func(fset *token.FileSet, f *File)"},
+		{"StarExpr", Type, 0, ""},
+		{"StarExpr.Star", Field, 0, ""},
+		{"StarExpr.X", Field, 0, ""},
+		{"StructType", Type, 0, ""},
+		{"StructType.Fields", Field, 0, ""},
+		{"StructType.Incomplete", Field, 0, ""},
+		{"StructType.Struct", Field, 0, ""},
+		{"SwitchStmt", Type, 0, ""},
+		{"SwitchStmt.Body", Field, 0, ""},
+		{"SwitchStmt.Init", Field, 0, ""},
+		{"SwitchStmt.Switch", Field, 0, ""},
+		{"SwitchStmt.Tag", Field, 0, ""},
+		{"Typ", Const, 0, ""},
+		{"TypeAssertExpr", Type, 0, ""},
+		{"TypeAssertExpr.Lparen", Field, 2, ""},
+		{"TypeAssertExpr.Rparen", Field, 2, ""},
+		{"TypeAssertExpr.Type", Field, 0, ""},
+		{"TypeAssertExpr.X", Field, 0, ""},
+		{"TypeSpec", Type, 0, ""},
+		{"TypeSpec.Assign", Field, 9, ""},
+		{"TypeSpec.Comment", Field, 0, ""},
+		{"TypeSpec.Doc", Field, 0, ""},
+		{"TypeSpec.Name", Field, 0, ""},
+		{"TypeSpec.Type", Field, 0, ""},
+		{"TypeSpec.TypeParams", Field, 18, ""},
+		{"TypeSwitchStmt", Type, 0, ""},
+		{"TypeSwitchStmt.Assign", Field, 0, ""},
+		{"TypeSwitchStmt.Body", Field, 0, ""},
+		{"TypeSwitchStmt.Init", Field, 0, ""},
+		{"TypeSwitchStmt.Switch", Field, 0, ""},
+		{"UnaryExpr", Type, 0, ""},
+		{"UnaryExpr.Op", Field, 0, ""},
+		{"UnaryExpr.OpPos", Field, 0, ""},
+		{"UnaryExpr.X", Field, 0, ""},
+		{"Unparen", Func, 22, "func(e Expr) Expr"},
+		{"ValueSpec", Type, 0, ""},
+		{"ValueSpec.Comment", Field, 0, ""},
+		{"ValueSpec.Doc", Field, 0, ""},
+		{"ValueSpec.Names", Field, 0, ""},
+		{"ValueSpec.Type", Field, 0, ""},
+		{"ValueSpec.Values", Field, 0, ""},
+		{"Var", Const, 0, ""},
+		{"Visitor", Type, 0, ""},
+		{"Walk", Func, 0, "func(v Visitor, node Node)"},
+	},
+	"go/build": {
+		{"(*Context).Import", Method, 0, ""},
+		{"(*Context).ImportDir", Method, 0, ""},
+		{"(*Context).MatchFile", Method, 2, ""},
+		{"(*Context).SrcDirs", Method, 0, ""},
+		{"(*MultiplePackageError).Error", Method, 4, ""},
+		{"(*NoGoError).Error", Method, 0, ""},
+		{"(*Package).IsCommand", Method, 0, ""},
+		{"AllowBinary", Const, 0, ""},
+		{"ArchChar", Func, 0, "func(goarch string) (string, error)"},
+		{"Context", Type, 0, ""},
+		{"Context.BuildTags", Field, 0, ""},
+		{"Context.CgoEnabled", Field, 0, ""},
+		{"Context.Compiler", Field, 0, ""},
+		{"Context.Dir", Field, 14, ""},
+		{"Context.GOARCH", Field, 0, ""},
+		{"Context.GOOS", Field, 0, ""},
+		{"Context.GOPATH", Field, 0, ""},
+		{"Context.GOROOT", Field, 0, ""},
+		{"Context.HasSubdir", Field, 0, ""},
+		{"Context.InstallSuffix", Field, 1, ""},
+		{"Context.IsAbsPath", Field, 0, ""},
+		{"Context.IsDir", Field, 0, ""},
+		{"Context.JoinPath", Field, 0, ""},
+		{"Context.OpenFile", Field, 0, ""},
+		{"Context.ReadDir", Field, 0, ""},
+		{"Context.ReleaseTags", Field, 1, ""},
+		{"Context.SplitPathList", Field, 0, ""},
+		{"Context.ToolTags", Field, 17, ""},
+		{"Context.UseAllFiles", Field, 0, ""},
+		{"Default", Var, 0, ""},
+		{"Directive", Type, 21, ""},
+		{"Directive.Pos", Field, 21, ""},
+		{"Directive.Text", Field, 21, ""},
+		{"FindOnly", Const, 0, ""},
+		{"IgnoreVendor", Const, 6, ""},
+		{"Import", Func, 0, "func(path string, srcDir string, mode ImportMode) (*Package, error)"},
+		{"ImportComment", Const, 4, ""},
+		{"ImportDir", Func, 0, "func(dir string, mode ImportMode) (*Package, error)"},
+		{"ImportMode", Type, 0, ""},
+		{"IsLocalImport", Func, 0, "func(path string) bool"},
+		{"MultiplePackageError", Type, 4, ""},
+		{"MultiplePackageError.Dir", Field, 4, ""},
+		{"MultiplePackageError.Files", Field, 4, ""},
+		{"MultiplePackageError.Packages", Field, 4, ""},
+		{"NoGoError", Type, 0, ""},
+		{"NoGoError.Dir", Field, 0, ""},
+		{"Package", Type, 0, ""},
+		{"Package.AllTags", Field, 2, ""},
+		{"Package.BinDir", Field, 0, ""},
+		{"Package.BinaryOnly", Field, 7, ""},
+		{"Package.CFiles", Field, 0, ""},
+		{"Package.CXXFiles", Field, 2, ""},
+		{"Package.CgoCFLAGS", Field, 0, ""},
+		{"Package.CgoCPPFLAGS", Field, 2, ""},
+		{"Package.CgoCXXFLAGS", Field, 2, ""},
+		{"Package.CgoFFLAGS", Field, 7, ""},
+		{"Package.CgoFiles", Field, 0, ""},
+		{"Package.CgoLDFLAGS", Field, 0, ""},
+		{"Package.CgoPkgConfig", Field, 0, ""},
+		{"Package.ConflictDir", Field, 2, ""},
+		{"Package.Dir", Field, 0, ""},
+		{"Package.Directives", Field, 21, ""},
+		{"Package.Doc", Field, 0, ""},
+		{"Package.EmbedPatternPos", Field, 16, ""},
+		{"Package.EmbedPatterns", Field, 16, ""},
+		{"Package.FFiles", Field, 7, ""},
+		{"Package.GoFiles", Field, 0, ""},
+		{"Package.Goroot", Field, 0, ""},
+		{"Package.HFiles", Field, 0, ""},
+		{"Package.IgnoredGoFiles", Field, 1, ""},
+		{"Package.IgnoredOtherFiles", Field, 16, ""},
+		{"Package.ImportComment", Field, 4, ""},
+		{"Package.ImportPath", Field, 0, ""},
+		{"Package.ImportPos", Field, 0, ""},
+		{"Package.Imports", Field, 0, ""},
+		{"Package.InvalidGoFiles", Field, 6, ""},
+		{"Package.MFiles", Field, 3, ""},
+		{"Package.Name", Field, 0, ""},
+		{"Package.PkgObj", Field, 0, ""},
+		{"Package.PkgRoot", Field, 0, ""},
+		{"Package.PkgTargetRoot", Field, 5, ""},
+		{"Package.Root", Field, 0, ""},
+		{"Package.SFiles", Field, 0, ""},
+		{"Package.SrcRoot", Field, 0, ""},
+		{"Package.SwigCXXFiles", Field, 1, ""},
+		{"Package.SwigFiles", Field, 1, ""},
+		{"Package.SysoFiles", Field, 0, ""},
+		{"Package.TestDirectives", Field, 21, ""},
+		{"Package.TestEmbedPatternPos", Field, 16, ""},
+		{"Package.TestEmbedPatterns", Field, 16, ""},
+		{"Package.TestGoFiles", Field, 0, ""},
+		{"Package.TestImportPos", Field, 0, ""},
+		{"Package.TestImports", Field, 0, ""},
+		{"Package.XTestDirectives", Field, 21, ""},
+		{"Package.XTestEmbedPatternPos", Field, 16, ""},
+		{"Package.XTestEmbedPatterns", Field, 16, ""},
+		{"Package.XTestGoFiles", Field, 0, ""},
+		{"Package.XTestImportPos", Field, 0, ""},
+		{"Package.XTestImports", Field, 0, ""},
+		{"ToolDir", Var, 0, ""},
+	},
+	"go/build/constraint": {
+		{"(*AndExpr).Eval", Method, 16, ""},
+		{"(*AndExpr).String", Method, 16, ""},
+		{"(*NotExpr).Eval", Method, 16, ""},
+		{"(*NotExpr).String", Method, 16, ""},
+		{"(*OrExpr).Eval", Method, 16, ""},
+		{"(*OrExpr).String", Method, 16, ""},
+		{"(*SyntaxError).Error", Method, 16, ""},
+		{"(*TagExpr).Eval", Method, 16, ""},
+		{"(*TagExpr).String", Method, 16, ""},
+		{"(Expr).Eval", Method, 16, ""},
+		{"(Expr).String", Method, 16, ""},
+		{"AndExpr", Type, 16, ""},
+		{"AndExpr.X", Field, 16, ""},
+		{"AndExpr.Y", Field, 16, ""},
+		{"GoVersion", Func, 21, "func(x Expr) string"},
+		{"IsGoBuild", Func, 16, "func(line string) bool"},
+		{"IsPlusBuild", Func, 16, "func(line string) bool"},
+		{"NotExpr", Type, 16, ""},
+		{"NotExpr.X", Field, 16, ""},
+		{"OrExpr", Type, 16, ""},
+		{"OrExpr.X", Field, 16, ""},
+		{"OrExpr.Y", Field, 16, ""},
+		{"Parse", Func, 16, "func(line string) (Expr, error)"},
+		{"PlusBuildLines", Func, 16, "func(x Expr) ([]string, error)"},
+		{"SyntaxError", Type, 16, ""},
+		{"SyntaxError.Err", Field, 16, ""},
+		{"SyntaxError.Offset", Field, 16, ""},
+		{"TagExpr", Type, 16, ""},
+		{"TagExpr.Tag", Field, 16, ""},
+	},
+	"go/constant": {
+		{"(Kind).String", Method, 18, ""},
+		{"(Value).ExactString", Method, 6, ""},
+		{"(Value).Kind", Method, 5, ""},
+		{"(Value).String", Method, 5, ""},
+		{"BinaryOp", Func, 5, "func(x_ Value, op token.Token, y_ Value) Value"},
+		{"BitLen", Func, 5, "func(x Value) int"},
+		{"Bool", Const, 5, ""},
+		{"BoolVal", Func, 5, "func(x Value) bool"},
+		{"Bytes", Func, 5, "func(x Value) []byte"},
+		{"Compare", Func, 5, "func(x_ Value, op token.Token, y_ Value) bool"},
+		{"Complex", Const, 5, ""},
+		{"Denom", Func, 5, "func(x Value) Value"},
+		{"Float", Const, 5, ""},
+		{"Float32Val", Func, 5, "func(x Value) (float32, bool)"},
+		{"Float64Val", Func, 5, "func(x Value) (float64, bool)"},
+		{"Imag", Func, 5, "func(x Value) Value"},
+		{"Int", Const, 5, ""},
+		{"Int64Val", Func, 5, "func(x Value) (int64, bool)"},
+		{"Kind", Type, 5, ""},
+		{"Make", Func, 13, "func(x any) Value"},
+		{"MakeBool", Func, 5, "func(b bool) Value"},
+		{"MakeFloat64", Func, 5, "func(x float64) Value"},
+		{"MakeFromBytes", Func, 5, "func(bytes []byte) Value"},
+		{"MakeFromLiteral", Func, 5, "func(lit string, tok token.Token, zero uint) Value"},
+		{"MakeImag", Func, 5, "func(x Value) Value"},
+		{"MakeInt64", Func, 5, "func(x int64) Value"},
+		{"MakeString", Func, 5, "func(s string) Value"},
+		{"MakeUint64", Func, 5, "func(x uint64) Value"},
+		{"MakeUnknown", Func, 5, "func() Value"},
+		{"Num", Func, 5, "func(x Value) Value"},
+		{"Real", Func, 5, "func(x Value) Value"},
+		{"Shift", Func, 5, "func(x Value, op token.Token, s uint) Value"},
+		{"Sign", Func, 5, "func(x Value) int"},
+		{"String", Const, 5, ""},
+		{"StringLen", Func, 27, "func(x Value) int64"},
+		{"StringVal", Func, 5, "func(x Value) string"},
+		{"ToComplex", Func, 6, "func(x Value) Value"},
+		{"ToFloat", Func, 6, "func(x Value) Value"},
+		{"ToInt", Func, 6, "func(x Value) Value"},
+		{"Uint64Val", Func, 5, "func(x Value) (uint64, bool)"},
+		{"UnaryOp", Func, 5, "func(op token.Token, y Value, prec uint) Value"},
+		{"Unknown", Const, 5, ""},
+		{"Val", Func, 13, "func(x Value) any"},
+	},
+	"go/doc": {
+		{"(*Package).Filter", Method, 0, ""},
+		{"(*Package).HTML", Method, 19, ""},
+		{"(*Package).Markdown", Method, 19, ""},
+		{"(*Package).Parser", Method, 19, ""},
+		{"(*Package).Printer", Method, 19, ""},
+		{"(*Package).Synopsis", Method, 19, ""},
+		{"(*Package).Text", Method, 19, ""},
+		{"AllDecls", Const, 0, ""},
+		{"AllMethods", Const, 0, ""},
+		{"Example", Type, 0, ""},
+		{"Example.Code", Field, 0, ""},
+		{"Example.Comments", Field, 0, ""},
+		{"Example.Doc", Field, 0, ""},
+		{"Example.EmptyOutput", Field, 1, ""},
+		{"Example.Name", Field, 0, ""},
+		{"Example.Order", Field, 1, ""},
+		{"Example.Output", Field, 0, ""},
+		{"Example.Play", Field, 1, ""},
+		{"Example.Suffix", Field, 14, ""},
+		{"Example.Unordered", Field, 7, ""},
+		{"Examples", Func, 0, "func(testFiles ...*ast.File) []*Example"},
+		{"Filter", Type, 0, ""},
+		{"Func", Type, 0, ""},
+		{"Func.Decl", Field, 0, ""},
+		{"Func.Doc", Field, 0, ""},
+		{"Func.Examples", Field, 14, ""},
+		{"Func.Level", Field, 0, ""},
+		{"Func.Name", Field, 0, ""},
+		{"Func.Orig", Field, 0, ""},
+		{"Func.Recv", Field, 0, ""},
+		{"IllegalPrefixes", Var, 1, ""},
+		{"IsPredeclared", Func, 8, "func(s string) bool"},
+		{"Mode", Type, 0, ""},
+		{"New", Func, 0, "func(pkg *ast.Package, importPath string, mode Mode) *Package"},
+		{"NewFromFiles", Func, 14, "func(fset *token.FileSet, files []*ast.File, importPath string, opts ...any) (*Package, error)"},
+		{"Note", Type, 1, ""},
+		{"Note.Body", Field, 1, ""},
+		{"Note.End", Field, 1, ""},
+		{"Note.Pos", Field, 1, ""},
+		{"Note.UID", Field, 1, ""},
+		{"Package", Type, 0, ""},
+		{"Package.Bugs", Field, 0, ""},
+		{"Package.Consts", Field, 0, ""},
+		{"Package.Doc", Field, 0, ""},
+		{"Package.Examples", Field, 14, ""},
+		{"Package.Filenames", Field, 0, ""},
+		{"Package.Funcs", Field, 0, ""},
+		{"Package.ImportPath", Field, 0, ""},
+		{"Package.Imports", Field, 0, ""},
+		{"Package.Name", Field, 0, ""},
+		{"Package.Notes", Field, 1, ""},
+		{"Package.Types", Field, 0, ""},
+		{"Package.Vars", Field, 0, ""},
+		{"PreserveAST", Const, 12, ""},
+		{"Synopsis", Func, 0, "func(text string) string"},
+		{"ToHTML", Func, 0, "func(w io.Writer, text string, words map[string]string)"},
+		{"ToText", Func, 0, "func(w io.Writer, text string, prefix string, codePrefix string, width int)"},
+		{"Type", Type, 0, ""},
+		{"Type.Consts", Field, 0, ""},
+		{"Type.Decl", Field, 0, ""},
+		{"Type.Doc", Field, 0, ""},
+		{"Type.Examples", Field, 14, ""},
+		{"Type.Funcs", Field, 0, ""},
+		{"Type.Methods", Field, 0, ""},
+		{"Type.Name", Field, 0, ""},
+		{"Type.Vars", Field, 0, ""},
+		{"Value", Type, 0, ""},
+		{"Value.Decl", Field, 0, ""},
+		{"Value.Doc", Field, 0, ""},
+		{"Value.Names", Field, 0, ""},
+	},
+	"go/doc/comment": {
+		{"(*DocLink).DefaultURL", Method, 19, ""},
+		{"(*Heading).DefaultID", Method, 19, ""},
+		{"(*List).BlankBefore", Method, 19, ""},
+		{"(*List).BlankBetween", Method, 19, ""},
+		{"(*Parser).Parse", Method, 19, ""},
+		{"(*Printer).Comment", Method, 19, ""},
+		{"(*Printer).HTML", Method, 19, ""},
+		{"(*Printer).Markdown", Method, 19, ""},
+		{"(*Printer).Text", Method, 19, ""},
+		{"Code", Type, 19, ""},
+		{"Code.Text", Field, 19, ""},
+		{"DefaultLookupPackage", Func, 19, "func(name string) (importPath string, ok bool)"},
+		{"Doc", Type, 19, ""},
+		{"Doc.Content", Field, 19, ""},
+		{"Doc.Links", Field, 19, ""},
+		{"DocLink", Type, 19, ""},
+		{"DocLink.ImportPath", Field, 19, ""},
+		{"DocLink.Name", Field, 19, ""},
+		{"DocLink.Recv", Field, 19, ""},
+		{"DocLink.Text", Field, 19, ""},
+		{"Heading", Type, 19, ""},
+		{"Heading.Text", Field, 19, ""},
+		{"Italic", Type, 19, ""},
+		{"Link", Type, 19, ""},
+		{"Link.Auto", Field, 19, ""},
+		{"Link.Text", Field, 19, ""},
+		{"Link.URL", Field, 19, ""},
+		{"LinkDef", Type, 19, ""},
+		{"LinkDef.Text", Field, 19, ""},
+		{"LinkDef.URL", Field, 19, ""},
+		{"LinkDef.Used", Field, 19, ""},
+		{"List", Type, 19, ""},
+		{"List.ForceBlankBefore", Field, 19, ""},
+		{"List.ForceBlankBetween", Field, 19, ""},
+		{"List.Items", Field, 19, ""},
+		{"ListItem", Type, 19, ""},
+		{"ListItem.Content", Field, 19, ""},
+		{"ListItem.Number", Field, 19, ""},
+		{"Paragraph", Type, 19, ""},
+		{"Paragraph.Text", Field, 19, ""},
+		{"Parser", Type, 19, ""},
+		{"Parser.LookupPackage", Field, 19, ""},
+		{"Parser.LookupSym", Field, 19, ""},
+		{"Parser.Words", Field, 19, ""},
+		{"Plain", Type, 19, ""},
+		{"Printer", Type, 19, ""},
+		{"Printer.DocLinkBaseURL", Field, 19, ""},
+		{"Printer.DocLinkURL", Field, 19, ""},
+		{"Printer.HeadingID", Field, 19, ""},
+		{"Printer.HeadingLevel", Field, 19, ""},
+		{"Printer.TextCodePrefix", Field, 19, ""},
+		{"Printer.TextPrefix", Field, 19, ""},
+		{"Printer.TextWidth", Field, 19, ""},
+	},
+	"go/format": {
+		{"Node", Func, 1, "func(dst io.Writer, fset *token.FileSet, node any) error"},
+		{"Source", Func, 1, "func(src []byte) ([]byte, error)"},
+	},
+	"go/importer": {
+		{"Default", Func, 5, "func() types.Importer"},
+		{"For", Func, 5, "func(compiler string, lookup Lookup) types.Importer"},
+		{"ForCompiler", Func, 12, "func(fset *token.FileSet, compiler string, lookup Lookup) types.Importer"},
+		{"Lookup", Type, 5, ""},
+	},
+	"go/parser": {
+		{"AllErrors", Const, 1, ""},
+		{"DeclarationErrors", Const, 0, ""},
+		{"ImportsOnly", Const, 0, ""},
+		{"Mode", Type, 0, ""},
+		{"PackageClauseOnly", Const, 0, ""},
+		{"ParseComments", Const, 0, ""},
+		{"ParseDir", Func, 0, "func(fset *token.FileSet, path string, filter func(fs.FileInfo) bool, mode Mode) (pkgs map[string]*ast.Package, first error)"},
+		{"ParseExpr", Func, 0, "func(x string) (ast.Expr, error)"},
+		{"ParseExprFrom", Func, 5, "func(fset *token.FileSet, filename string, src any, mode Mode) (expr ast.Expr, err error)"},
+		{"ParseFile", Func, 0, "func(fset *token.FileSet, filename string, src any, mode Mode) (f *ast.File, err error)"},
+		{"SkipObjectResolution", Const, 17, ""},
+		{"SpuriousErrors", Const, 0, ""},
+		{"Trace", Const, 0, ""},
+	},
+	"go/printer": {
+		{"(*Config).Fprint", Method, 0, ""},
+		{"CommentedNode", Type, 0, ""},
+		{"CommentedNode.Comments", Field, 0, ""},
+		{"CommentedNode.Node", Field, 0, ""},
+		{"Config", Type, 0, ""},
+		{"Config.Indent", Field, 1, ""},
+		{"Config.Mode", Field, 0, ""},
+		{"Config.Tabwidth", Field, 0, ""},
+		{"Fprint", Func, 0, "func(output io.Writer, fset *token.FileSet, node any) error"},
+		{"Mode", Type, 0, ""},
+		{"RawFormat", Const, 0, ""},
+		{"SourcePos", Const, 0, ""},
+		{"TabIndent", Const, 0, ""},
+		{"UseSpaces", Const, 0, ""},
+	},
+	"go/scanner": {
+		{"(*ErrorList).Add", Method, 0, ""},
+		{"(*ErrorList).RemoveMultiples", Method, 0, ""},
+		{"(*ErrorList).Reset", Method, 0, ""},
+		{"(*Scanner).End", Method, 27, ""},
+		{"(*Scanner).Init", Method, 0, ""},
+		{"(*Scanner).Scan", Method, 0, ""},
+		{"(Error).Error", Method, 0, ""},
+		{"(ErrorList).Err", Method, 0, ""},
+		{"(ErrorList).Error", Method, 0, ""},
+		{"(ErrorList).Len", Method, 0, ""},
+		{"(ErrorList).Less", Method, 0, ""},
+		{"(ErrorList).Sort", Method, 0, ""},
+		{"(ErrorList).Swap", Method, 0, ""},
+		{"Error", Type, 0, ""},
+		{"Error.Msg", Field, 0, ""},
+		{"Error.Pos", Field, 0, ""},
+		{"ErrorHandler", Type, 0, ""},
+		{"ErrorList", Type, 0, ""},
+		{"Mode", Type, 0, ""},
+		{"PrintError", Func, 0, "func(w io.Writer, err error)"},
+		{"ScanComments", Const, 0, ""},
+		{"Scanner", Type, 0, ""},
+		{"Scanner.ErrorCount", Field, 0, ""},
+	},
+	"go/token": {
+		{"(*File).AddLine", Method, 0, ""},
+		{"(*File).AddLineColumnInfo", Method, 11, ""},
+		{"(*File).AddLineInfo", Method, 0, ""},
+		{"(*File).Base", Method, 0, ""},
+		{"(*File).End", Method, 26, ""},
+		{"(*File).Line", Method, 0, ""},
+		{"(*File).LineCount", Method, 0, ""},
+		{"(*File).LineStart", Method, 12, ""},
+		{"(*File).Lines", Method, 21, ""},
+		{"(*File).MergeLine", Method, 2, ""},
+		{"(*File).Name", Method, 0, ""},
+		{"(*File).Offset", Method, 0, ""},
+		{"(*File).Pos", Method, 0, ""},
+		{"(*File).Position", Method, 0, ""},
+		{"(*File).PositionFor", Method, 4, ""},
+		{"(*File).SetLines", Method, 0, ""},
+		{"(*File).SetLinesForContent", Method, 0, ""},
+		{"(*File).Size", Method, 0, ""},
+		{"(*File).String", Method, 27, ""},
+		{"(*FileSet).AddExistingFiles", Method, 25, ""},
+		{"(*FileSet).AddFile", Method, 0, ""},
+		{"(*FileSet).Base", Method, 0, ""},
+		{"(*FileSet).File", Method, 0, ""},
+		{"(*FileSet).Iterate", Method, 0, ""},
+		{"(*FileSet).Position", Method, 0, ""},
+		{"(*FileSet).PositionFor", Method, 4, ""},
+		{"(*FileSet).Read", Method, 0, ""},
+		{"(*FileSet).RemoveFile", Method, 20, ""},
+		{"(*FileSet).Write", Method, 0, ""},
+		{"(*Position).IsValid", Method, 0, ""},
+		{"(Pos).IsValid", Method, 0, ""},
+		{"(Position).String", Method, 0, ""},
+		{"(Token).IsKeyword", Method, 0, ""},
+		{"(Token).IsLiteral", Method, 0, ""},
+		{"(Token).IsOperator", Method, 0, ""},
+		{"(Token).Precedence", Method, 0, ""},
+		{"(Token).String", Method, 0, ""},
+		{"ADD", Const, 0, ""},
+		{"ADD_ASSIGN", Const, 0, ""},
+		{"AND", Const, 0, ""},
+		{"AND_ASSIGN", Const, 0, ""},
+		{"AND_NOT", Const, 0, ""},
+		{"AND_NOT_ASSIGN", Const, 0, ""},
+		{"ARROW", Const, 0, ""},
+		{"ASSIGN", Const, 0, ""},
+		{"BREAK", Const, 0, ""},
+		{"CASE", Const, 0, ""},
+		{"CHAN", Const, 0, ""},
+		{"CHAR", Const, 0, ""},
+		{"COLON", Const, 0, ""},
+		{"COMMA", Const, 0, ""},
+		{"COMMENT", Const, 0, ""},
+		{"CONST", Const, 0, ""},
+		{"CONTINUE", Const, 0, ""},
+		{"DEC", Const, 0, ""},
+		{"DEFAULT", Const, 0, ""},
+		{"DEFER", Const, 0, ""},
+		{"DEFINE", Const, 0, ""},
+		{"ELLIPSIS", Const, 0, ""},
+		{"ELSE", Const, 0, ""},
+		{"EOF", Const, 0, ""},
+		{"EQL", Const, 0, ""},
+		{"FALLTHROUGH", Const, 0, ""},
+		{"FLOAT", Const, 0, ""},
+		{"FOR", Const, 0, ""},
+		{"FUNC", Const, 0, ""},
+		{"File", Type, 0, ""},
+		{"FileSet", Type, 0, ""},
+		{"GEQ", Const, 0, ""},
+		{"GO", Const, 0, ""},
+		{"GOTO", Const, 0, ""},
+		{"GTR", Const, 0, ""},
+		{"HighestPrec", Const, 0, ""},
+		{"IDENT", Const, 0, ""},
+		{"IF", Const, 0, ""},
+		{"ILLEGAL", Const, 0, ""},
+		{"IMAG", Const, 0, ""},
+		{"IMPORT", Const, 0, ""},
+		{"INC", Const, 0, ""},
+		{"INT", Const, 0, ""},
+		{"INTERFACE", Const, 0, ""},
+		{"IsExported", Func, 13, "func(name string) bool"},
+		{"IsIdentifier", Func, 13, "func(name string) bool"},
+		{"IsKeyword", Func, 13, "func(name string) bool"},
+		{"LAND", Const, 0, ""},
+		{"LBRACE", Const, 0, ""},
+		{"LBRACK", Const, 0, ""},
+		{"LEQ", Const, 0, ""},
+		{"LOR", Const, 0, ""},
+		{"LPAREN", Const, 0, ""},
+		{"LSS", Const, 0, ""},
+		{"Lookup", Func, 0, "func(ident string) Token"},
+		{"LowestPrec", Const, 0, ""},
+		{"MAP", Const, 0, ""},
+		{"MUL", Const, 0, ""},
+		{"MUL_ASSIGN", Const, 0, ""},
+		{"NEQ", Const, 0, ""},
+		{"NOT", Const, 0, ""},
+		{"NewFileSet", Func, 0, "func() *FileSet"},
+		{"NoPos", Const, 0, ""},
+		{"OR", Const, 0, ""},
+		{"OR_ASSIGN", Const, 0, ""},
+		{"PACKAGE", Const, 0, ""},
+		{"PERIOD", Const, 0, ""},
+		{"Pos", Type, 0, ""},
+		{"Position", Type, 0, ""},
+		{"Position.Column", Field, 0, ""},
+		{"Position.Filename", Field, 0, ""},
+		{"Position.Line", Field, 0, ""},
+		{"Position.Offset", Field, 0, ""},
+		{"QUO", Const, 0, ""},
+		{"QUO_ASSIGN", Const, 0, ""},
+		{"RANGE", Const, 0, ""},
+		{"RBRACE", Const, 0, ""},
+		{"RBRACK", Const, 0, ""},
+		{"REM", Const, 0, ""},
+		{"REM_ASSIGN", Const, 0, ""},
+		{"RETURN", Const, 0, ""},
+		{"RPAREN", Const, 0, ""},
+		{"SELECT", Const, 0, ""},
+		{"SEMICOLON", Const, 0, ""},
+		{"SHL", Const, 0, ""},
+		{"SHL_ASSIGN", Const, 0, ""},
+		{"SHR", Const, 0, ""},
+		{"SHR_ASSIGN", Const, 0, ""},
+		{"STRING", Const, 0, ""},
+		{"STRUCT", Const, 0, ""},
+		{"SUB", Const, 0, ""},
+		{"SUB_ASSIGN", Const, 0, ""},
+		{"SWITCH", Const, 0, ""},
+		{"TILDE", Const, 18, ""},
+		{"TYPE", Const, 0, ""},
+		{"Token", Type, 0, ""},
+		{"UnaryPrec", Const, 0, ""},
+		{"VAR", Const, 0, ""},
+		{"XOR", Const, 0, ""},
+		{"XOR_ASSIGN", Const, 0, ""},
+	},
+	"go/types": {
+		{"(*Alias).Obj", Method, 22, ""},
+		{"(*Alias).Origin", Method, 23, ""},
+		{"(*Alias).Rhs", Method, 23, ""},
+		{"(*Alias).SetTypeParams", Method, 23, ""},
+		{"(*Alias).String", Method, 22, ""},
+		{"(*Alias).TypeArgs", Method, 23, ""},
+		{"(*Alias).TypeParams", Method, 23, ""},
+		{"(*Alias).Underlying", Method, 22, ""},
+		{"(*ArgumentError).Error", Method, 18, ""},
+		{"(*ArgumentError).Unwrap", Method, 18, ""},
+		{"(*Array).Elem", Method, 5, ""},
+		{"(*Array).Len", Method, 5, ""},
+		{"(*Array).String", Method, 5, ""},
+		{"(*Array).Underlying", Method, 5, ""},
+		{"(*Basic).Info", Method, 5, ""},
+		{"(*Basic).Kind", Method, 5, ""},
+		{"(*Basic).Name", Method, 5, ""},
+		{"(*Basic).String", Method, 5, ""},
+		{"(*Basic).Underlying", Method, 5, ""},
+		{"(*Builtin).Exported", Method, 5, ""},
+		{"(*Builtin).Id", Method, 5, ""},
+		{"(*Builtin).Name", Method, 5, ""},
+		{"(*Builtin).Parent", Method, 5, ""},
+		{"(*Builtin).Pkg", Method, 5, ""},
+		{"(*Builtin).Pos", Method, 5, ""},
+		{"(*Builtin).String", Method, 5, ""},
+		{"(*Builtin).Type", Method, 5, ""},
+		{"(*Chan).Dir", Method, 5, ""},
+		{"(*Chan).Elem", Method, 5, ""},
+		{"(*Chan).String", Method, 5, ""},
+		{"(*Chan).Underlying", Method, 5, ""},
+		{"(*Checker).Files", Method, 5, ""},
+		{"(*Config).Check", Method, 5, ""},
+		{"(*Const).Exported", Method, 5, ""},
+		{"(*Const).Id", Method, 5, ""},
+		{"(*Const).Name", Method, 5, ""},
+		{"(*Const).Parent", Method, 5, ""},
+		{"(*Const).Pkg", Method, 5, ""},
+		{"(*Const).Pos", Method, 5, ""},
+		{"(*Const).String", Method, 5, ""},
+		{"(*Const).Type", Method, 5, ""},
+		{"(*Const).Val", Method, 5, ""},
+		{"(*Func).Exported", Method, 5, ""},
+		{"(*Func).FullName", Method, 5, ""},
+		{"(*Func).Id", Method, 5, ""},
+		{"(*Func).Name", Method, 5, ""},
+		{"(*Func).Origin", Method, 19, ""},
+		{"(*Func).Parent", Method, 5, ""},
+		{"(*Func).Pkg", Method, 5, ""},
+		{"(*Func).Pos", Method, 5, ""},
+		{"(*Func).Scope", Method, 5, ""},
+		{"(*Func).Signature", Method, 23, ""},
+		{"(*Func).String", Method, 5, ""},
+		{"(*Func).Type", Method, 5, ""},
+		{"(*Info).ObjectOf", Method, 5, ""},
+		{"(*Info).PkgNameOf", Method, 22, ""},
+		{"(*Info).TypeOf", Method, 5, ""},
+		{"(*Initializer).String", Method, 5, ""},
+		{"(*Interface).Complete", Method, 5, ""},
+		{"(*Interface).Embedded", Method, 5, ""},
+		{"(*Interface).EmbeddedType", Method, 11, ""},
+		{"(*Interface).EmbeddedTypes", Method, 24, ""},
+		{"(*Interface).Empty", Method, 5, ""},
+		{"(*Interface).ExplicitMethod", Method, 5, ""},
+		{"(*Interface).ExplicitMethods", Method, 24, ""},
+		{"(*Interface).IsComparable", Method, 18, ""},
+		{"(*Interface).IsImplicit", Method, 18, ""},
+		{"(*Interface).IsMethodSet", Method, 18, ""},
+		{"(*Interface).MarkImplicit", Method, 18, ""},
+		{"(*Interface).Method", Method, 5, ""},
+		{"(*Interface).Methods", Method, 24, ""},
+		{"(*Interface).NumEmbeddeds", Method, 5, ""},
+		{"(*Interface).NumExplicitMethods", Method, 5, ""},
+		{"(*Interface).NumMethods", Method, 5, ""},
+		{"(*Interface).String", Method, 5, ""},
+		{"(*Interface).Underlying", Method, 5, ""},
+		{"(*Label).Exported", Method, 5, ""},
+		{"(*Label).Id", Method, 5, ""},
+		{"(*Label).Name", Method, 5, ""},
+		{"(*Label).Parent", Method, 5, ""},
+		{"(*Label).Pkg", Method, 5, ""},
+		{"(*Label).Pos", Method, 5, ""},
+		{"(*Label).String", Method, 5, ""},
+		{"(*Label).Type", Method, 5, ""},
+		{"(*Map).Elem", Method, 5, ""},
+		{"(*Map).Key", Method, 5, ""},
+		{"(*Map).String", Method, 5, ""},
+		{"(*Map).Underlying", Method, 5, ""},
+		{"(*MethodSet).At", Method, 5, ""},
+		{"(*MethodSet).Len", Method, 5, ""},
+		{"(*MethodSet).Lookup", Method, 5, ""},
+		{"(*MethodSet).Methods", Method, 24, ""},
+		{"(*MethodSet).String", Method, 5, ""},
+		{"(*Named).AddMethod", Method, 5, ""},
+		{"(*Named).Method", Method, 5, ""},
+		{"(*Named).Methods", Method, 24, ""},
+		{"(*Named).NumMethods", Method, 5, ""},
+		{"(*Named).Obj", Method, 5, ""},
+		{"(*Named).Origin", Method, 18, ""},
+		{"(*Named).SetTypeParams", Method, 18, ""},
+		{"(*Named).SetUnderlying", Method, 5, ""},
+		{"(*Named).String", Method, 5, ""},
+		{"(*Named).TypeArgs", Method, 18, ""},
+		{"(*Named).TypeParams", Method, 18, ""},
+		{"(*Named).Underlying", Method, 5, ""},
+		{"(*Nil).Exported", Method, 5, ""},
+		{"(*Nil).Id", Method, 5, ""},
+		{"(*Nil).Name", Method, 5, ""},
+		{"(*Nil).Parent", Method, 5, ""},
+		{"(*Nil).Pkg", Method, 5, ""},
+		{"(*Nil).Pos", Method, 5, ""},
+		{"(*Nil).String", Method, 5, ""},
+		{"(*Nil).Type", Method, 5, ""},
+		{"(*Package).Complete", Method, 5, ""},
+		{"(*Package).GoVersion", Method, 21, ""},
+		{"(*Package).Imports", Method, 5, ""},
+		{"(*Package).MarkComplete", Method, 5, ""},
+		{"(*Package).Name", Method, 5, ""},
+		{"(*Package).Path", Method, 5, ""},
+		{"(*Package).Scope", Method, 5, ""},
+		{"(*Package).SetImports", Method, 5, ""},
+		{"(*Package).SetName", Method, 6, ""},
+		{"(*Package).String", Method, 5, ""},
+		{"(*PkgName).Exported", Method, 5, ""},
+		{"(*PkgName).Id", Method, 5, ""},
+		{"(*PkgName).Imported", Method, 5, ""},
+		{"(*PkgName).Name", Method, 5, ""},
+		{"(*PkgName).Parent", Method, 5, ""},
+		{"(*PkgName).Pkg", Method, 5, ""},
+		{"(*PkgName).Pos", Method, 5, ""},
+		{"(*PkgName).String", Method, 5, ""},
+		{"(*PkgName).Type", Method, 5, ""},
+		{"(*Pointer).Elem", Method, 5, ""},
+		{"(*Pointer).String", Method, 5, ""},
+		{"(*Pointer).Underlying", Method, 5, ""},
+		{"(*Scope).Child", Method, 5, ""},
+		{"(*Scope).Children", Method, 24, ""},
+		{"(*Scope).Contains", Method, 5, ""},
+		{"(*Scope).End", Method, 5, ""},
+		{"(*Scope).Innermost", Method, 5, ""},
+		{"(*Scope).Insert", Method, 5, ""},
+		{"(*Scope).Len", Method, 5, ""},
+		{"(*Scope).Lookup", Method, 5, ""},
+		{"(*Scope).LookupParent", Method, 5, ""},
+		{"(*Scope).Names", Method, 5, ""},
+		{"(*Scope).NumChildren", Method, 5, ""},
+		{"(*Scope).Parent", Method, 5, ""},
+		{"(*Scope).Pos", Method, 5, ""},
+		{"(*Scope).String", Method, 5, ""},
+		{"(*Scope).WriteTo", Method, 5, ""},
+		{"(*Selection).Index", Method, 5, ""},
+		{"(*Selection).Indirect", Method, 5, ""},
+		{"(*Selection).Kind", Method, 5, ""},
+		{"(*Selection).Obj", Method, 5, ""},
+		{"(*Selection).Recv", Method, 5, ""},
+		{"(*Selection).String", Method, 5, ""},
+		{"(*Selection).Type", Method, 5, ""},
+		{"(*Signature).Params", Method, 5, ""},
+		{"(*Signature).Recv", Method, 5, ""},
+		{"(*Signature).RecvTypeParams", Method, 18, ""},
+		{"(*Signature).Results", Method, 5, ""},
+		{"(*Signature).String", Method, 5, ""},
+		{"(*Signature).TypeParams", Method, 18, ""},
+		{"(*Signature).Underlying", Method, 5, ""},
+		{"(*Signature).Variadic", Method, 5, ""},
+		{"(*Slice).Elem", Method, 5, ""},
+		{"(*Slice).String", Method, 5, ""},
+		{"(*Slice).Underlying", Method, 5, ""},
+		{"(*StdSizes).Alignof", Method, 5, ""},
+		{"(*StdSizes).Offsetsof", Method, 5, ""},
+		{"(*StdSizes).Sizeof", Method, 5, ""},
+		{"(*Struct).Field", Method, 5, ""},
+		{"(*Struct).Fields", Method, 24, ""},
+		{"(*Struct).NumFields", Method, 5, ""},
+		{"(*Struct).String", Method, 5, ""},
+		{"(*Struct).Tag", Method, 5, ""},
+		{"(*Struct).Underlying", Method, 5, ""},
+		{"(*Term).String", Method, 18, ""},
+		{"(*Term).Tilde", Method, 18, ""},
+		{"(*Term).Type", Method, 18, ""},
+		{"(*Tuple).At", Method, 5, ""},
+		{"(*Tuple).Len", Method, 5, ""},
+		{"(*Tuple).String", Method, 5, ""},
+		{"(*Tuple).Underlying", Method, 5, ""},
+		{"(*Tuple).Variables", Method, 24, ""},
+		{"(*TypeList).At", Method, 18, ""},
+		{"(*TypeList).Len", Method, 18, ""},
+		{"(*TypeList).String", Method, 27, ""},
+		{"(*TypeList).Types", Method, 24, ""},
+		{"(*TypeName).Exported", Method, 5, ""},
+		{"(*TypeName).Id", Method, 5, ""},
+		{"(*TypeName).IsAlias", Method, 9, ""},
+		{"(*TypeName).Name", Method, 5, ""},
+		{"(*TypeName).Parent", Method, 5, ""},
+		{"(*TypeName).Pkg", Method, 5, ""},
+		{"(*TypeName).Pos", Method, 5, ""},
+		{"(*TypeName).String", Method, 5, ""},
+		{"(*TypeName).Type", Method, 5, ""},
+		{"(*TypeParam).Constraint", Method, 18, ""},
+		{"(*TypeParam).Index", Method, 18, ""},
+		{"(*TypeParam).Obj", Method, 18, ""},
+		{"(*TypeParam).SetConstraint", Method, 18, ""},
+		{"(*TypeParam).String", Method, 18, ""},
+		{"(*TypeParam).Underlying", Method, 18, ""},
+		{"(*TypeParamList).At", Method, 18, ""},
+		{"(*TypeParamList).Len", Method, 18, ""},
+		{"(*TypeParamList).String", Method, 27, ""},
+		{"(*TypeParamList).TypeParams", Method, 24, ""},
+		{"(*Union).Len", Method, 18, ""},
+		{"(*Union).String", Method, 18, ""},
+		{"(*Union).Term", Method, 18, ""},
+		{"(*Union).Terms", Method, 24, ""},
+		{"(*Union).Underlying", Method, 18, ""},
+		{"(*Var).Anonymous", Method, 5, ""},
+		{"(*Var).Embedded", Method, 11, ""},
+		{"(*Var).Exported", Method, 5, ""},
+		{"(*Var).Id", Method, 5, ""},
+		{"(*Var).IsField", Method, 5, ""},
+		{"(*Var).Kind", Method, 25, ""},
+		{"(*Var).Name", Method, 5, ""},
+		{"(*Var).Origin", Method, 19, ""},
+		{"(*Var).Parent", Method, 5, ""},
+		{"(*Var).Pkg", Method, 5, ""},
+		{"(*Var).Pos", Method, 5, ""},
+		{"(*Var).SetKind", Method, 25, ""},
+		{"(*Var).String", Method, 5, ""},
+		{"(*Var).Type", Method, 5, ""},
+		{"(Checker).ObjectOf", Method, 5, ""},
+		{"(Checker).PkgNameOf", Method, 22, ""},
+		{"(Checker).TypeOf", Method, 5, ""},
+		{"(Error).Error", Method, 5, ""},
+		{"(Hasher).Equal", Method, 27, ""},
+		{"(Hasher).Hash", Method, 27, ""},
+		{"(HasherIgnoreTags).Equal", Method, 27, ""},
+		{"(HasherIgnoreTags).Hash", Method, 27, ""},
+		{"(Importer).Import", Method, 5, ""},
+		{"(ImporterFrom).Import", Method, 6, ""},
+		{"(ImporterFrom).ImportFrom", Method, 6, ""},
+		{"(Instance).String", Method, 27, ""},
+		{"(Object).Exported", Method, 5, ""},
+		{"(Object).Id", Method, 5, ""},
+		{"(Object).Name", Method, 5, ""},
+		{"(Object).Parent", Method, 5, ""},
+		{"(Object).Pkg", Method, 5, ""},
+		{"(Object).Pos", Method, 5, ""},
+		{"(Object).String", Method, 5, ""},
+		{"(Object).Type", Method, 5, ""},
+		{"(Sizes).Alignof", Method, 5, ""},
+		{"(Sizes).Offsetsof", Method, 5, ""},
+		{"(Sizes).Sizeof", Method, 5, ""},
+		{"(Type).String", Method, 5, ""},
+		{"(Type).Underlying", Method, 5, ""},
+		{"(TypeAndValue).Addressable", Method, 5, ""},
+		{"(TypeAndValue).Assignable", Method, 5, ""},
+		{"(TypeAndValue).HasOk", Method, 5, ""},
+		{"(TypeAndValue).IsBuiltin", Method, 5, ""},
+		{"(TypeAndValue).IsNil", Method, 5, ""},
+		{"(TypeAndValue).IsType", Method, 5, ""},
+		{"(TypeAndValue).IsValue", Method, 5, ""},
+		{"(TypeAndValue).IsVoid", Method, 5, ""},
+		{"(VarKind).String", Method, 25, ""},
+		{"Alias", Type, 22, ""},
+		{"ArgumentError", Type, 18, ""},
+		{"ArgumentError.Err", Field, 18, ""},
+		{"ArgumentError.Index", Field, 18, ""},
+		{"Array", Type, 5, ""},
+		{"AssertableTo", Func, 5, "func(V *Interface, T Type) bool"},
+		{"AssignableTo", Func, 5, "func(V Type, T Type) bool"},
+		{"Basic", Type, 5, ""},
+		{"BasicInfo", Type, 5, ""},
+		{"BasicKind", Type, 5, ""},
+		{"Bool", Const, 5, ""},
+		{"Builtin", Type, 5, ""},
+		{"Byte", Const, 5, ""},
+		{"Chan", Type, 5, ""},
+		{"ChanDir", Type, 5, ""},
+		{"CheckExpr", Func, 13, "func(fset *token.FileSet, pkg *Package, pos token.Pos, expr ast.Expr, info *Info) (err error)"},
+		{"Checker", Type, 5, ""},
+		{"Checker.Info", Field, 5, ""},
+		{"Comparable", Func, 5, "func(T Type) bool"},
+		{"Complex128", Const, 5, ""},
+		{"Complex64", Const, 5, ""},
+		{"Config", Type, 5, ""},
+		{"Config.Context", Field, 18, ""},
+		{"Config.DisableUnusedImportCheck", Field, 5, ""},
+		{"Config.Error", Field, 5, ""},
+		{"Config.FakeImportC", Field, 5, ""},
+		{"Config.GoVersion", Field, 18, ""},
+		{"Config.IgnoreFuncBodies", Field, 5, ""},
+		{"Config.Importer", Field, 5, ""},
+		{"Config.Sizes", Field, 5, ""},
+		{"Const", Type, 5, ""},
+		{"Context", Type, 18, ""},
+		{"ConvertibleTo", Func, 5, "func(V Type, T Type) bool"},
+		{"DefPredeclaredTestFuncs", Func, 5, "func()"},
+		{"Default", Func, 8, "func(t Type) Type"},
+		{"Error", Type, 5, ""},
+		{"Error.Fset", Field, 5, ""},
+		{"Error.Msg", Field, 5, ""},
+		{"Error.Pos", Field, 5, ""},
+		{"Error.Soft", Field, 5, ""},
+		{"Eval", Func, 5, "func(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (_ TypeAndValue, err error)"},
+		{"ExprString", Func, 5, "func(x ast.Expr) string"},
+		{"FieldVal", Const, 5, ""},
+		{"FieldVar", Const, 25, ""},
+		{"Float32", Const, 5, ""},
+		{"Float64", Const, 5, ""},
+		{"Func", Type, 5, ""},
+		{"Hasher", Type, 27, ""},
+		{"HasherIgnoreTags", Type, 27, ""},
+		{"Id", Func, 5, "func(pkg *Package, name string) string"},
+		{"Identical", Func, 5, "func(x Type, y Type) bool"},
+		{"IdenticalIgnoreTags", Func, 8, "func(x Type, y Type) bool"},
+		{"Implements", Func, 5, "func(V Type, T *Interface) bool"},
+		{"ImportMode", Type, 6, ""},
+		{"Importer", Type, 5, ""},
+		{"ImporterFrom", Type, 6, ""},
+		{"Info", Type, 5, ""},
+		{"Info.Defs", Field, 5, ""},
+		{"Info.FileVersions", Field, 22, ""},
+		{"Info.Implicits", Field, 5, ""},
+		{"Info.InitOrder", Field, 5, ""},
+		{"Info.Instances", Field, 18, ""},
+		{"Info.Scopes", Field, 5, ""},
+		{"Info.Selections", Field, 5, ""},
+		{"Info.Types", Field, 5, ""},
+		{"Info.Uses", Field, 5, ""},
+		{"Initializer", Type, 5, ""},
+		{"Initializer.Lhs", Field, 5, ""},
+		{"Initializer.Rhs", Field, 5, ""},
+		{"Instance", Type, 18, ""},
+		{"Instance.Type", Field, 18, ""},
+		{"Instance.TypeArgs", Field, 18, ""},
+		{"Instantiate", Func, 18, "func(ctxt *Context, orig Type, targs []Type, validate bool) (Type, error)"},
+		{"Int", Const, 5, ""},
+		{"Int16", Const, 5, ""},
+		{"Int32", Const, 5, ""},
+		{"Int64", Const, 5, ""},
+		{"Int8", Const, 5, ""},
+		{"Interface", Type, 5, ""},
+		{"Invalid", Const, 5, ""},
+		{"IsBoolean", Const, 5, ""},
+		{"IsComplex", Const, 5, ""},
+		{"IsConstType", Const, 5, ""},
+		{"IsFloat", Const, 5, ""},
+		{"IsInteger", Const, 5, ""},
+		{"IsInterface", Func, 5, "func(t Type) bool"},
+		{"IsNumeric", Const, 5, ""},
+		{"IsOrdered", Const, 5, ""},
+		{"IsString", Const, 5, ""},
+		{"IsUnsigned", Const, 5, ""},
+		{"IsUntyped", Const, 5, ""},
+		{"Label", Type, 5, ""},
+		{"LocalVar", Const, 25, ""},
+		{"LookupFieldOrMethod", Func, 5, "func(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool)"},
+		{"LookupSelection", Func, 25, "func(T Type, addressable bool, pkg *Package, name string) (Selection, bool)"},
+		{"Map", Type, 5, ""},
+		{"MethodExpr", Const, 5, ""},
+		{"MethodSet", Type, 5, ""},
+		{"MethodVal", Const, 5, ""},
+		{"MissingMethod", Func, 5, "func(V Type, T *Interface, static bool) (method *Func, wrongType bool)"},
+		{"Named", Type, 5, ""},
+		{"NewAlias", Func, 22, "func(obj *TypeName, rhs Type) *Alias"},
+		{"NewArray", Func, 5, "func(elem Type, len int64) *Array"},
+		{"NewChan", Func, 5, "func(dir ChanDir, elem Type) *Chan"},
+		{"NewChecker", Func, 5, "func(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Checker"},
+		{"NewConst", Func, 5, "func(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const"},
+		{"NewContext", Func, 18, "func() *Context"},
+		{"NewField", Func, 5, "func(pos token.Pos, pkg *Package, name string, typ Type, embedded bool) *Var"},
+		{"NewFunc", Func, 5, "func(pos token.Pos, pkg *Package, name string, sig *Signature) *Func"},
+		{"NewInterface", Func, 5, "func(methods []*Func, embeddeds []*Named) *Interface"},
+		{"NewInterfaceType", Func, 11, "func(methods []*Func, embeddeds []Type) *Interface"},
+		{"NewLabel", Func, 5, "func(pos token.Pos, pkg *Package, name string) *Label"},
+		{"NewMap", Func, 5, "func(key Type, elem Type) *Map"},
+		{"NewMethodSet", Func, 5, "func(T Type) *MethodSet"},
+		{"NewNamed", Func, 5, "func(obj *TypeName, underlying Type, methods []*Func) *Named"},
+		{"NewPackage", Func, 5, "func(path string, name string) *Package"},
+		{"NewParam", Func, 5, "func(pos token.Pos, pkg *Package, name string, typ Type) *Var"},
+		{"NewPkgName", Func, 5, "func(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName"},
+		{"NewPointer", Func, 5, "func(elem Type) *Pointer"},
+		{"NewScope", Func, 5, "func(parent *Scope, pos token.Pos, end token.Pos, comment string) *Scope"},
+		{"NewSignature", Func, 5, "func(recv *Var, params *Tuple, results *Tuple, variadic bool) *Signature"},
+		{"NewSignatureType", Func, 18, "func(recv *Var, recvTypeParams []*TypeParam, typeParams []*TypeParam, params *Tuple, results *Tuple, variadic bool) *Signature"},
+		{"NewSlice", Func, 5, "func(elem Type) *Slice"},
+		{"NewStruct", Func, 5, "func(fields []*Var, tags []string) *Struct"},
+		{"NewTerm", Func, 18, "func(tilde bool, typ Type) *Term"},
+		{"NewTuple", Func, 5, "func(x ...*Var) *Tuple"},
+		{"NewTypeName", Func, 5, "func(pos token.Pos, pkg *Package, name string, typ Type) *TypeName"},
+		{"NewTypeParam", Func, 18, "func(obj *TypeName, constraint Type) *TypeParam"},
+		{"NewUnion", Func, 18, "func(terms []*Term) *Union"},
+		{"NewVar", Func, 5, "func(pos token.Pos, pkg *Package, name string, typ Type) *Var"},
+		{"Nil", Type, 5, ""},
+		{"ObjectString", Func, 5, "func(obj Object, qf Qualifier) string"},
+		{"Package", Type, 5, ""},
+		{"PackageVar", Const, 25, ""},
+		{"ParamVar", Const, 25, ""},
+		{"PkgName", Type, 5, ""},
+		{"Pointer", Type, 5, ""},
+		{"Qualifier", Type, 5, ""},
+		{"RecvOnly", Const, 5, ""},
+		{"RecvVar", Const, 25, ""},
+		{"RelativeTo", Func, 5, "func(pkg *Package) Qualifier"},
+		{"ResultVar", Const, 25, ""},
+		{"Rune", Const, 5, ""},
+		{"Satisfies", Func, 20, "func(V Type, T *Interface) bool"},
+		{"Scope", Type, 5, ""},
+		{"Selection", Type, 5, ""},
+		{"SelectionKind", Type, 5, ""},
+		{"SelectionString", Func, 5, "func(s *Selection, qf Qualifier) string"},
+		{"SendOnly", Const, 5, ""},
+		{"SendRecv", Const, 5, ""},
+		{"Signature", Type, 5, ""},
+		{"Sizes", Type, 5, ""},
+		{"SizesFor", Func, 9, "func(compiler string, arch string) Sizes"},
+		{"Slice", Type, 5, ""},
+		{"StdSizes", Type, 5, ""},
+		{"StdSizes.MaxAlign", Field, 5, ""},
+		{"StdSizes.WordSize", Field, 5, ""},
+		{"String", Const, 5, ""},
+		{"Struct", Type, 5, ""},
+		{"Term", Type, 18, ""},
+		{"Tuple", Type, 5, ""},
+		{"Typ", Var, 5, ""},
+		{"Type", Type, 5, ""},
+		{"TypeAndValue", Type, 5, ""},
+		{"TypeAndValue.Type", Field, 5, ""},
+		{"TypeAndValue.Value", Field, 5, ""},
+		{"TypeList", Type, 18, ""},
+		{"TypeName", Type, 5, ""},
+		{"TypeParam", Type, 18, ""},
+		{"TypeParamList", Type, 18, ""},
+		{"TypeString", Func, 5, "func(typ Type, qf Qualifier) string"},
+		{"Uint", Const, 5, ""},
+		{"Uint16", Const, 5, ""},
+		{"Uint32", Const, 5, ""},
+		{"Uint64", Const, 5, ""},
+		{"Uint8", Const, 5, ""},
+		{"Uintptr", Const, 5, ""},
+		{"Unalias", Func, 22, "func(t Type) Type"},
+		{"Union", Type, 18, ""},
+		{"Universe", Var, 5, ""},
+		{"Unsafe", Var, 5, ""},
+		{"UnsafePointer", Const, 5, ""},
+		{"UntypedBool", Const, 5, ""},
+		{"UntypedComplex", Const, 5, ""},
+		{"UntypedFloat", Const, 5, ""},
+		{"UntypedInt", Const, 5, ""},
+		{"UntypedNil", Const, 5, ""},
+		{"UntypedRune", Const, 5, ""},
+		{"UntypedString", Const, 5, ""},
+		{"Var", Type, 5, ""},
+		{"VarKind", Type, 25, ""},
+		{"WriteExpr", Func, 5, "func(buf *bytes.Buffer, x ast.Expr)"},
+		{"WriteSignature", Func, 5, "func(buf *bytes.Buffer, sig *Signature, qf Qualifier)"},
+		{"WriteType", Func, 5, "func(buf *bytes.Buffer, typ Type, qf Qualifier)"},
+	},
+	"go/version": {
+		{"Compare", Func, 22, "func(x string, y string) int"},
+		{"IsValid", Func, 22, "func(x string) bool"},
+		{"Lang", Func, 22, "func(x string) string"},
+	},
+	"hash": {
+		{"(Cloner).BlockSize", Method, 25, ""},
+		{"(Cloner).Clone", Method, 25, ""},
+		{"(Cloner).Reset", Method, 25, ""},
+		{"(Cloner).Size", Method, 25, ""},
+		{"(Cloner).Sum", Method, 25, ""},
+		{"(Cloner).Write", Method, 25, ""},
+		{"(Hash).BlockSize", Method, 0, ""},
+		{"(Hash).Reset", Method, 0, ""},
+		{"(Hash).Size", Method, 0, ""},
+		{"(Hash).Sum", Method, 0, ""},
+		{"(Hash).Write", Method, 0, ""},
+		{"(Hash32).BlockSize", Method, 0, ""},
+		{"(Hash32).Reset", Method, 0, ""},
+		{"(Hash32).Size", Method, 0, ""},
+		{"(Hash32).Sum", Method, 0, ""},
+		{"(Hash32).Sum32", Method, 0, ""},
+		{"(Hash32).Write", Method, 0, ""},
+		{"(Hash64).BlockSize", Method, 0, ""},
+		{"(Hash64).Reset", Method, 0, ""},
+		{"(Hash64).Size", Method, 0, ""},
+		{"(Hash64).Sum", Method, 0, ""},
+		{"(Hash64).Sum64", Method, 0, ""},
+		{"(Hash64).Write", Method, 0, ""},
+		{"(XOF).BlockSize", Method, 25, ""},
+		{"(XOF).Read", Method, 25, ""},
+		{"(XOF).Reset", Method, 25, ""},
+		{"(XOF).Write", Method, 25, ""},
+		{"Cloner", Type, 25, ""},
+		{"Hash", Type, 0, ""},
+		{"Hash32", Type, 0, ""},
+		{"Hash64", Type, 0, ""},
+		{"XOF", Type, 25, ""},
+	},
+	"hash/adler32": {
+		{"Checksum", Func, 0, "func(data []byte) uint32"},
+		{"New", Func, 0, "func() hash.Hash32"},
+		{"Size", Const, 0, ""},
+	},
+	"hash/crc32": {
+		{"Castagnoli", Const, 0, ""},
+		{"Checksum", Func, 0, "func(data []byte, tab *Table) uint32"},
+		{"ChecksumIEEE", Func, 0, "func(data []byte) uint32"},
+		{"IEEE", Const, 0, ""},
+		{"IEEETable", Var, 0, ""},
+		{"Koopman", Const, 0, ""},
+		{"MakeTable", Func, 0, "func(poly uint32) *Table"},
+		{"New", Func, 0, "func(tab *Table) hash.Hash32"},
+		{"NewIEEE", Func, 0, "func() hash.Hash32"},
+		{"Size", Const, 0, ""},
+		{"Table", Type, 0, ""},
+		{"Update", Func, 0, "func(crc uint32, tab *Table, p []byte) uint32"},
+	},
+	"hash/crc64": {
+		{"Checksum", Func, 0, "func(data []byte, tab *Table) uint64"},
+		{"ECMA", Const, 0, ""},
+		{"ISO", Const, 0, ""},
+		{"MakeTable", Func, 0, "func(poly uint64) *Table"},
+		{"New", Func, 0, "func(tab *Table) hash.Hash64"},
+		{"Size", Const, 0, ""},
+		{"Table", Type, 0, ""},
+		{"Update", Func, 0, "func(crc uint64, tab *Table, p []byte) uint64"},
+	},
+	"hash/fnv": {
+		{"New128", Func, 9, "func() hash.Hash"},
+		{"New128a", Func, 9, "func() hash.Hash"},
+		{"New32", Func, 0, "func() hash.Hash32"},
+		{"New32a", Func, 0, "func() hash.Hash32"},
+		{"New64", Func, 0, "func() hash.Hash64"},
+		{"New64a", Func, 0, "func() hash.Hash64"},
+	},
+	"hash/maphash": {
+		{"(*Hash).BlockSize", Method, 14, ""},
+		{"(*Hash).Clone", Method, 25, ""},
+		{"(*Hash).Reset", Method, 14, ""},
+		{"(*Hash).Seed", Method, 14, ""},
+		{"(*Hash).SetSeed", Method, 14, ""},
+		{"(*Hash).Size", Method, 14, ""},
+		{"(*Hash).Sum", Method, 14, ""},
+		{"(*Hash).Sum64", Method, 14, ""},
+		{"(*Hash).Write", Method, 14, ""},
+		{"(*Hash).WriteByte", Method, 14, ""},
+		{"(*Hash).WriteString", Method, 14, ""},
+		{"(ComparableHasher).Equal", Method, 27, ""},
+		{"(ComparableHasher).Hash", Method, 27, ""},
+		{"Bytes", Func, 19, "func(seed Seed, b []byte) uint64"},
+		{"Comparable", Func, 24, "func[T comparable](seed Seed, v T) uint64"},
+		{"ComparableHasher", Type, 27, ""},
+		{"Hash", Type, 14, ""},
+		{"Hasher", Type, 27, ""},
+		{"MakeSeed", Func, 14, "func() Seed"},
+		{"Seed", Type, 14, ""},
+		{"String", Func, 19, "func(seed Seed, s string) uint64"},
+		{"WriteComparable", Func, 24, "func[T comparable](h *Hash, x T)"},
+	},
+	"html": {
+		{"EscapeString", Func, 0, "func(s string) string"},
+		{"UnescapeString", Func, 0, "func(s string) string"},
+	},
+	"html/template": {
+		{"(*Error).Error", Method, 0, ""},
+		{"(*Template).AddParseTree", Method, 0, ""},
+		{"(*Template).Clone", Method, 0, ""},
+		{"(*Template).DefinedTemplates", Method, 6, ""},
+		{"(*Template).Delims", Method, 0, ""},
+		{"(*Template).Execute", Method, 0, ""},
+		{"(*Template).ExecuteTemplate", Method, 0, ""},
+		{"(*Template).Funcs", Method, 0, ""},
+		{"(*Template).Lookup", Method, 0, ""},
+		{"(*Template).Name", Method, 0, ""},
+		{"(*Template).New", Method, 0, ""},
+		{"(*Template).Option", Method, 5, ""},
+		{"(*Template).Parse", Method, 0, ""},
+		{"(*Template).ParseFS", Method, 16, ""},
+		{"(*Template).ParseFiles", Method, 0, ""},
+		{"(*Template).ParseGlob", Method, 0, ""},
+		{"(*Template).Templates", Method, 0, ""},
+		{"CSS", Type, 0, ""},
+		{"ErrAmbigContext", Const, 0, ""},
+		{"ErrBadHTML", Const, 0, ""},
+		{"ErrBranchEnd", Const, 0, ""},
+		{"ErrEndContext", Const, 0, ""},
+		{"ErrJSTemplate", Const, 21, ""},
+		{"ErrNoSuchTemplate", Const, 0, ""},
+		{"ErrOutputContext", Const, 0, ""},
+		{"ErrPartialCharset", Const, 0, ""},
+		{"ErrPartialEscape", Const, 0, ""},
+		{"ErrPredefinedEscaper", Const, 9, ""},
+		{"ErrRangeLoopReentry", Const, 0, ""},
+		{"ErrSlashAmbig", Const, 0, ""},
+		{"Error", Type, 0, ""},
+		{"Error.Description", Field, 0, ""},
+		{"Error.ErrorCode", Field, 0, ""},
+		{"Error.Line", Field, 0, ""},
+		{"Error.Name", Field, 0, ""},
+		{"Error.Node", Field, 4, ""},
+		{"ErrorCode", Type, 0, ""},
+		{"FuncMap", Type, 0, ""},
+		{"HTML", Type, 0, ""},
+		{"HTMLAttr", Type, 0, ""},
+		{"HTMLEscape", Func, 0, "func(w io.Writer, b []byte)"},
+		{"HTMLEscapeString", Func, 0, "func(s string) string"},
+		{"HTMLEscaper", Func, 0, "func(args ...any) string"},
+		{"IsTrue", Func, 6, "func(val any) (truth bool, ok bool)"},
+		{"JS", Type, 0, ""},
+		{"JSEscape", Func, 0, "func(w io.Writer, b []byte)"},
+		{"JSEscapeString", Func, 0, "func(s string) string"},
+		{"JSEscaper", Func, 0, "func(args ...any) string"},
+		{"JSStr", Type, 0, ""},
+		{"Must", Func, 0, "func(t *Template, err error) *Template"},
+		{"New", Func, 0, "func(name string) *Template"},
+		{"OK", Const, 0, ""},
+		{"ParseFS", Func, 16, "func(fs fs.FS, patterns ...string) (*Template, error)"},
+		{"ParseFiles", Func, 0, "func(filenames ...string) (*Template, error)"},
+		{"ParseGlob", Func, 0, "func(pattern string) (*Template, error)"},
+		{"Srcset", Type, 10, ""},
+		{"Template", Type, 0, ""},
+		{"Template.Tree", Field, 2, ""},
+		{"URL", Type, 0, ""},
+		{"URLQueryEscaper", Func, 0, "func(args ...any) string"},
+	},
+	"image": {
+		{"(*Alpha).AlphaAt", Method, 4, ""},
+		{"(*Alpha).At", Method, 0, ""},
+		{"(*Alpha).Bounds", Method, 0, ""},
+		{"(*Alpha).ColorModel", Method, 0, ""},
+		{"(*Alpha).Opaque", Method, 0, ""},
+		{"(*Alpha).PixOffset", Method, 0, ""},
+		{"(*Alpha).RGBA64At", Method, 17, ""},
+		{"(*Alpha).Set", Method, 0, ""},
+		{"(*Alpha).SetAlpha", Method, 0, ""},
+		{"(*Alpha).SetRGBA64", Method, 17, ""},
+		{"(*Alpha).SubImage", Method, 0, ""},
+		{"(*Alpha16).Alpha16At", Method, 4, ""},
+		{"(*Alpha16).At", Method, 0, ""},
+		{"(*Alpha16).Bounds", Method, 0, ""},
+		{"(*Alpha16).ColorModel", Method, 0, ""},
+		{"(*Alpha16).Opaque", Method, 0, ""},
+		{"(*Alpha16).PixOffset", Method, 0, ""},
+		{"(*Alpha16).RGBA64At", Method, 17, ""},
+		{"(*Alpha16).Set", Method, 0, ""},
+		{"(*Alpha16).SetAlpha16", Method, 0, ""},
+		{"(*Alpha16).SetRGBA64", Method, 17, ""},
+		{"(*Alpha16).SubImage", Method, 0, ""},
+		{"(*CMYK).At", Method, 5, ""},
+		{"(*CMYK).Bounds", Method, 5, ""},
+		{"(*CMYK).CMYKAt", Method, 5, ""},
+		{"(*CMYK).ColorModel", Method, 5, ""},
+		{"(*CMYK).Opaque", Method, 5, ""},
+		{"(*CMYK).PixOffset", Method, 5, ""},
+		{"(*CMYK).RGBA64At", Method, 17, ""},
+		{"(*CMYK).Set", Method, 5, ""},
+		{"(*CMYK).SetCMYK", Method, 5, ""},
+		{"(*CMYK).SetRGBA64", Method, 17, ""},
+		{"(*CMYK).SubImage", Method, 5, ""},
+		{"(*Gray).At", Method, 0, ""},
+		{"(*Gray).Bounds", Method, 0, ""},
+		{"(*Gray).ColorModel", Method, 0, ""},
+		{"(*Gray).GrayAt", Method, 4, ""},
+		{"(*Gray).Opaque", Method, 0, ""},
+		{"(*Gray).PixOffset", Method, 0, ""},
+		{"(*Gray).RGBA64At", Method, 17, ""},
+		{"(*Gray).Set", Method, 0, ""},
+		{"(*Gray).SetGray", Method, 0, ""},
+		{"(*Gray).SetRGBA64", Method, 17, ""},
+		{"(*Gray).SubImage", Method, 0, ""},
+		{"(*Gray16).At", Method, 0, ""},
+		{"(*Gray16).Bounds", Method, 0, ""},
+		{"(*Gray16).ColorModel", Method, 0, ""},
+		{"(*Gray16).Gray16At", Method, 4, ""},
+		{"(*Gray16).Opaque", Method, 0, ""},
+		{"(*Gray16).PixOffset", Method, 0, ""},
+		{"(*Gray16).RGBA64At", Method, 17, ""},
+		{"(*Gray16).Set", Method, 0, ""},
+		{"(*Gray16).SetGray16", Method, 0, ""},
+		{"(*Gray16).SetRGBA64", Method, 17, ""},
+		{"(*Gray16).SubImage", Method, 0, ""},
+		{"(*NRGBA).At", Method, 0, ""},
+		{"(*NRGBA).Bounds", Method, 0, ""},
+		{"(*NRGBA).ColorModel", Method, 0, ""},
+		{"(*NRGBA).NRGBAAt", Method, 4, ""},
+		{"(*NRGBA).Opaque", Method, 0, ""},
+		{"(*NRGBA).PixOffset", Method, 0, ""},
+		{"(*NRGBA).RGBA64At", Method, 17, ""},
+		{"(*NRGBA).Set", Method, 0, ""},
+		{"(*NRGBA).SetNRGBA", Method, 0, ""},
+		{"(*NRGBA).SetRGBA64", Method, 17, ""},
+		{"(*NRGBA).SubImage", Method, 0, ""},
+		{"(*NRGBA64).At", Method, 0, ""},
+		{"(*NRGBA64).Bounds", Method, 0, ""},
+		{"(*NRGBA64).ColorModel", Method, 0, ""},
+		{"(*NRGBA64).NRGBA64At", Method, 4, ""},
+		{"(*NRGBA64).Opaque", Method, 0, ""},
+		{"(*NRGBA64).PixOffset", Method, 0, ""},
+		{"(*NRGBA64).RGBA64At", Method, 17, ""},
+		{"(*NRGBA64).Set", Method, 0, ""},
+		{"(*NRGBA64).SetNRGBA64", Method, 0, ""},
+		{"(*NRGBA64).SetRGBA64", Method, 17, ""},
+		{"(*NRGBA64).SubImage", Method, 0, ""},
+		{"(*NYCbCrA).AOffset", Method, 6, ""},
+		{"(*NYCbCrA).At", Method, 6, ""},
+		{"(*NYCbCrA).Bounds", Method, 6, ""},
+		{"(*NYCbCrA).COffset", Method, 6, ""},
+		{"(*NYCbCrA).ColorModel", Method, 6, ""},
+		{"(*NYCbCrA).NYCbCrAAt", Method, 6, ""},
+		{"(*NYCbCrA).Opaque", Method, 6, ""},
+		{"(*NYCbCrA).RGBA64At", Method, 17, ""},
+		{"(*NYCbCrA).SubImage", Method, 6, ""},
+		{"(*NYCbCrA).YCbCrAt", Method, 6, ""},
+		{"(*NYCbCrA).YOffset", Method, 6, ""},
+		{"(*Paletted).At", Method, 0, ""},
+		{"(*Paletted).Bounds", Method, 0, ""},
+		{"(*Paletted).ColorIndexAt", Method, 0, ""},
+		{"(*Paletted).ColorModel", Method, 0, ""},
+		{"(*Paletted).Opaque", Method, 0, ""},
+		{"(*Paletted).PixOffset", Method, 0, ""},
+		{"(*Paletted).RGBA64At", Method, 17, ""},
+		{"(*Paletted).Set", Method, 0, ""},
+		{"(*Paletted).SetColorIndex", Method, 0, ""},
+		{"(*Paletted).SetRGBA64", Method, 17, ""},
+		{"(*Paletted).SubImage", Method, 0, ""},
+		{"(*RGBA).At", Method, 0, ""},
+		{"(*RGBA).Bounds", Method, 0, ""},
+		{"(*RGBA).ColorModel", Method, 0, ""},
+		{"(*RGBA).Opaque", Method, 0, ""},
+		{"(*RGBA).PixOffset", Method, 0, ""},
+		{"(*RGBA).RGBA64At", Method, 17, ""},
+		{"(*RGBA).RGBAAt", Method, 4, ""},
+		{"(*RGBA).Set", Method, 0, ""},
+		{"(*RGBA).SetRGBA", Method, 0, ""},
+		{"(*RGBA).SetRGBA64", Method, 17, ""},
+		{"(*RGBA).SubImage", Method, 0, ""},
+		{"(*RGBA64).At", Method, 0, ""},
+		{"(*RGBA64).Bounds", Method, 0, ""},
+		{"(*RGBA64).ColorModel", Method, 0, ""},
+		{"(*RGBA64).Opaque", Method, 0, ""},
+		{"(*RGBA64).PixOffset", Method, 0, ""},
+		{"(*RGBA64).RGBA64At", Method, 4, ""},
+		{"(*RGBA64).Set", Method, 0, ""},
+		{"(*RGBA64).SetRGBA64", Method, 0, ""},
+		{"(*RGBA64).SubImage", Method, 0, ""},
+		{"(*Uniform).At", Method, 0, ""},
+		{"(*Uniform).Bounds", Method, 0, ""},
+		{"(*Uniform).ColorModel", Method, 0, ""},
+		{"(*Uniform).Convert", Method, 0, ""},
+		{"(*Uniform).Opaque", Method, 0, ""},
+		{"(*Uniform).RGBA", Method, 0, ""},
+		{"(*Uniform).RGBA64At", Method, 17, ""},
+		{"(*YCbCr).At", Method, 0, ""},
+		{"(*YCbCr).Bounds", Method, 0, ""},
+		{"(*YCbCr).COffset", Method, 0, ""},
+		{"(*YCbCr).ColorModel", Method, 0, ""},
+		{"(*YCbCr).Opaque", Method, 0, ""},
+		{"(*YCbCr).RGBA64At", Method, 17, ""},
+		{"(*YCbCr).SubImage", Method, 0, ""},
+		{"(*YCbCr).YCbCrAt", Method, 4, ""},
+		{"(*YCbCr).YOffset", Method, 0, ""},
+		{"(Image).At", Method, 0, ""},
+		{"(Image).Bounds", Method, 0, ""},
+		{"(Image).ColorModel", Method, 0, ""},
+		{"(PalettedImage).At", Method, 0, ""},
+		{"(PalettedImage).Bounds", Method, 0, ""},
+		{"(PalettedImage).ColorIndexAt", Method, 0, ""},
+		{"(PalettedImage).ColorModel", Method, 0, ""},
+		{"(Point).Add", Method, 0, ""},
+		{"(Point).Div", Method, 0, ""},
+		{"(Point).Eq", Method, 0, ""},
+		{"(Point).In", Method, 0, ""},
+		{"(Point).Mod", Method, 0, ""},
+		{"(Point).Mul", Method, 0, ""},
+		{"(Point).String", Method, 0, ""},
+		{"(Point).Sub", Method, 0, ""},
+		{"(RGBA64Image).At", Method, 17, ""},
+		{"(RGBA64Image).Bounds", Method, 17, ""},
+		{"(RGBA64Image).ColorModel", Method, 17, ""},
+		{"(RGBA64Image).RGBA64At", Method, 17, ""},
+		{"(Rectangle).Add", Method, 0, ""},
+		{"(Rectangle).At", Method, 5, ""},
+		{"(Rectangle).Bounds", Method, 5, ""},
+		{"(Rectangle).Canon", Method, 0, ""},
+		{"(Rectangle).ColorModel", Method, 5, ""},
+		{"(Rectangle).Dx", Method, 0, ""},
+		{"(Rectangle).Dy", Method, 0, ""},
+		{"(Rectangle).Empty", Method, 0, ""},
+		{"(Rectangle).Eq", Method, 0, ""},
+		{"(Rectangle).In", Method, 0, ""},
+		{"(Rectangle).Inset", Method, 0, ""},
+		{"(Rectangle).Intersect", Method, 0, ""},
+		{"(Rectangle).Overlaps", Method, 0, ""},
+		{"(Rectangle).RGBA64At", Method, 17, ""},
+		{"(Rectangle).Size", Method, 0, ""},
+		{"(Rectangle).String", Method, 0, ""},
+		{"(Rectangle).Sub", Method, 0, ""},
+		{"(Rectangle).Union", Method, 0, ""},
+		{"(YCbCrSubsampleRatio).String", Method, 0, ""},
+		{"Alpha", Type, 0, ""},
+		{"Alpha.Pix", Field, 0, ""},
+		{"Alpha.Rect", Field, 0, ""},
+		{"Alpha.Stride", Field, 0, ""},
+		{"Alpha16", Type, 0, ""},
+		{"Alpha16.Pix", Field, 0, ""},
+		{"Alpha16.Rect", Field, 0, ""},
+		{"Alpha16.Stride", Field, 0, ""},
+		{"Black", Var, 0, ""},
+		{"CMYK", Type, 5, ""},
+		{"CMYK.Pix", Field, 5, ""},
+		{"CMYK.Rect", Field, 5, ""},
+		{"CMYK.Stride", Field, 5, ""},
+		{"Config", Type, 0, ""},
+		{"Config.ColorModel", Field, 0, ""},
+		{"Config.Height", Field, 0, ""},
+		{"Config.Width", Field, 0, ""},
+		{"Decode", Func, 0, "func(r io.Reader) (Image, string, error)"},
+		{"DecodeConfig", Func, 0, "func(r io.Reader) (Config, string, error)"},
+		{"ErrFormat", Var, 0, ""},
+		{"Gray", Type, 0, ""},
+		{"Gray.Pix", Field, 0, ""},
+		{"Gray.Rect", Field, 0, ""},
+		{"Gray.Stride", Field, 0, ""},
+		{"Gray16", Type, 0, ""},
+		{"Gray16.Pix", Field, 0, ""},
+		{"Gray16.Rect", Field, 0, ""},
+		{"Gray16.Stride", Field, 0, ""},
+		{"Image", Type, 0, ""},
+		{"NRGBA", Type, 0, ""},
+		{"NRGBA.Pix", Field, 0, ""},
+		{"NRGBA.Rect", Field, 0, ""},
+		{"NRGBA.Stride", Field, 0, ""},
+		{"NRGBA64", Type, 0, ""},
+		{"NRGBA64.Pix", Field, 0, ""},
+		{"NRGBA64.Rect", Field, 0, ""},
+		{"NRGBA64.Stride", Field, 0, ""},
+		{"NYCbCrA", Type, 6, ""},
+		{"NYCbCrA.A", Field, 6, ""},
+		{"NYCbCrA.AStride", Field, 6, ""},
+		{"NYCbCrA.YCbCr", Field, 6, ""},
+		{"NewAlpha", Func, 0, "func(r Rectangle) *Alpha"},
+		{"NewAlpha16", Func, 0, "func(r Rectangle) *Alpha16"},
+		{"NewCMYK", Func, 5, "func(r Rectangle) *CMYK"},
+		{"NewGray", Func, 0, "func(r Rectangle) *Gray"},
+		{"NewGray16", Func, 0, "func(r Rectangle) *Gray16"},
+		{"NewNRGBA", Func, 0, "func(r Rectangle) *NRGBA"},
+		{"NewNRGBA64", Func, 0, "func(r Rectangle) *NRGBA64"},
+		{"NewNYCbCrA", Func, 6, "func(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *NYCbCrA"},
+		{"NewPaletted", Func, 0, "func(r Rectangle, p color.Palette) *Paletted"},
+		{"NewRGBA", Func, 0, "func(r Rectangle) *RGBA"},
+		{"NewRGBA64", Func, 0, "func(r Rectangle) *RGBA64"},
+		{"NewUniform", Func, 0, "func(c color.Color) *Uniform"},
+		{"NewYCbCr", Func, 0, "func(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *YCbCr"},
+		{"Opaque", Var, 0, ""},
+		{"Paletted", Type, 0, ""},
+		{"Paletted.Palette", Field, 0, ""},
+		{"Paletted.Pix", Field, 0, ""},
+		{"Paletted.Rect", Field, 0, ""},
+		{"Paletted.Stride", Field, 0, ""},
+		{"PalettedImage", Type, 0, ""},
+		{"Point", Type, 0, ""},
+		{"Point.X", Field, 0, ""},
+		{"Point.Y", Field, 0, ""},
+		{"Pt", Func, 0, "func(X int, Y int) Point"},
+		{"RGBA", Type, 0, ""},
+		{"RGBA.Pix", Field, 0, ""},
+		{"RGBA.Rect", Field, 0, ""},
+		{"RGBA.Stride", Field, 0, ""},
+		{"RGBA64", Type, 0, ""},
+		{"RGBA64.Pix", Field, 0, ""},
+		{"RGBA64.Rect", Field, 0, ""},
+		{"RGBA64.Stride", Field, 0, ""},
+		{"RGBA64Image", Type, 17, ""},
+		{"Rect", Func, 0, "func(x0 int, y0 int, x1 int, y1 int) Rectangle"},
+		{"Rectangle", Type, 0, ""},
+		{"Rectangle.Max", Field, 0, ""},
+		{"Rectangle.Min", Field, 0, ""},
+		{"RegisterFormat", Func, 0, "func(name string, magic string, decode func(io.Reader) (Image, error), decodeConfig func(io.Reader) (Config, error))"},
+		{"Transparent", Var, 0, ""},
+		{"Uniform", Type, 0, ""},
+		{"Uniform.C", Field, 0, ""},
+		{"White", Var, 0, ""},
+		{"YCbCr", Type, 0, ""},
+		{"YCbCr.CStride", Field, 0, ""},
+		{"YCbCr.Cb", Field, 0, ""},
+		{"YCbCr.Cr", Field, 0, ""},
+		{"YCbCr.Rect", Field, 0, ""},
+		{"YCbCr.SubsampleRatio", Field, 0, ""},
+		{"YCbCr.Y", Field, 0, ""},
+		{"YCbCr.YStride", Field, 0, ""},
+		{"YCbCrSubsampleRatio", Type, 0, ""},
+		{"YCbCrSubsampleRatio410", Const, 5, ""},
+		{"YCbCrSubsampleRatio411", Const, 5, ""},
+		{"YCbCrSubsampleRatio420", Const, 0, ""},
+		{"YCbCrSubsampleRatio422", Const, 0, ""},
+		{"YCbCrSubsampleRatio440", Const, 1, ""},
+		{"YCbCrSubsampleRatio444", Const, 0, ""},
+		{"ZP", Var, 0, ""},
+		{"ZR", Var, 0, ""},
+	},
+	"image/color": {
+		{"(Alpha).RGBA", Method, 0, ""},
+		{"(Alpha16).RGBA", Method, 0, ""},
+		{"(CMYK).RGBA", Method, 5, ""},
+		{"(Color).RGBA", Method, 0, ""},
+		{"(Gray).RGBA", Method, 0, ""},
+		{"(Gray16).RGBA", Method, 0, ""},
+		{"(Model).Convert", Method, 0, ""},
+		{"(NRGBA).RGBA", Method, 0, ""},
+		{"(NRGBA64).RGBA", Method, 0, ""},
+		{"(NYCbCrA).RGBA", Method, 6, ""},
+		{"(Palette).Convert", Method, 0, ""},
+		{"(Palette).Index", Method, 0, ""},
+		{"(RGBA).RGBA", Method, 0, ""},
+		{"(RGBA64).RGBA", Method, 0, ""},
+		{"(YCbCr).RGBA", Method, 0, ""},
+		{"Alpha", Type, 0, ""},
+		{"Alpha.A", Field, 0, ""},
+		{"Alpha16", Type, 0, ""},
+		{"Alpha16.A", Field, 0, ""},
+		{"Alpha16Model", Var, 0, ""},
+		{"AlphaModel", Var, 0, ""},
+		{"Black", Var, 0, ""},
+		{"CMYK", Type, 5, ""},
+		{"CMYK.C", Field, 5, ""},
+		{"CMYK.K", Field, 5, ""},
+		{"CMYK.M", Field, 5, ""},
+		{"CMYK.Y", Field, 5, ""},
+		{"CMYKModel", Var, 5, ""},
+		{"CMYKToRGB", Func, 5, "func(c uint8, m uint8, y uint8, k uint8) (uint8, uint8, uint8)"},
+		{"Color", Type, 0, ""},
+		{"Gray", Type, 0, ""},
+		{"Gray.Y", Field, 0, ""},
+		{"Gray16", Type, 0, ""},
+		{"Gray16.Y", Field, 0, ""},
+		{"Gray16Model", Var, 0, ""},
+		{"GrayModel", Var, 0, ""},
+		{"Model", Type, 0, ""},
+		{"ModelFunc", Func, 0, "func(f func(Color) Color) Model"},
+		{"NRGBA", Type, 0, ""},
+		{"NRGBA.A", Field, 0, ""},
+		{"NRGBA.B", Field, 0, ""},
+		{"NRGBA.G", Field, 0, ""},
+		{"NRGBA.R", Field, 0, ""},
+		{"NRGBA64", Type, 0, ""},
+		{"NRGBA64.A", Field, 0, ""},
+		{"NRGBA64.B", Field, 0, ""},
+		{"NRGBA64.G", Field, 0, ""},
+		{"NRGBA64.R", Field, 0, ""},
+		{"NRGBA64Model", Var, 0, ""},
+		{"NRGBAModel", Var, 0, ""},
+		{"NYCbCrA", Type, 6, ""},
+		{"NYCbCrA.A", Field, 6, ""},
+		{"NYCbCrA.YCbCr", Field, 6, ""},
+		{"NYCbCrAModel", Var, 6, ""},
+		{"Opaque", Var, 0, ""},
+		{"Palette", Type, 0, ""},
+		{"RGBA", Type, 0, ""},
+		{"RGBA.A", Field, 0, ""},
+		{"RGBA.B", Field, 0, ""},
+		{"RGBA.G", Field, 0, ""},
+		{"RGBA.R", Field, 0, ""},
+		{"RGBA64", Type, 0, ""},
+		{"RGBA64.A", Field, 0, ""},
+		{"RGBA64.B", Field, 0, ""},
+		{"RGBA64.G", Field, 0, ""},
+		{"RGBA64.R", Field, 0, ""},
+		{"RGBA64Model", Var, 0, ""},
+		{"RGBAModel", Var, 0, ""},
+		{"RGBToCMYK", Func, 5, "func(r uint8, g uint8, b uint8) (uint8, uint8, uint8, uint8)"},
+		{"RGBToYCbCr", Func, 0, "func(r uint8, g uint8, b uint8) (uint8, uint8, uint8)"},
+		{"Transparent", Var, 0, ""},
+		{"White", Var, 0, ""},
+		{"YCbCr", Type, 0, ""},
+		{"YCbCr.Cb", Field, 0, ""},
+		{"YCbCr.Cr", Field, 0, ""},
+		{"YCbCr.Y", Field, 0, ""},
+		{"YCbCrModel", Var, 0, ""},
+		{"YCbCrToRGB", Func, 0, "func(y uint8, cb uint8, cr uint8) (uint8, uint8, uint8)"},
+	},
+	"image/color/palette": {
+		{"Plan9", Var, 2, ""},
+		{"WebSafe", Var, 2, ""},
+	},
+	"image/draw": {
+		{"(Drawer).Draw", Method, 2, ""},
+		{"(Image).At", Method, 0, ""},
+		{"(Image).Bounds", Method, 0, ""},
+		{"(Image).ColorModel", Method, 0, ""},
+		{"(Image).Set", Method, 0, ""},
+		{"(Op).Draw", Method, 2, ""},
+		{"(Quantizer).Quantize", Method, 2, ""},
+		{"(RGBA64Image).At", Method, 17, ""},
+		{"(RGBA64Image).Bounds", Method, 17, ""},
+		{"(RGBA64Image).ColorModel", Method, 17, ""},
+		{"(RGBA64Image).RGBA64At", Method, 17, ""},
+		{"(RGBA64Image).Set", Method, 17, ""},
+		{"(RGBA64Image).SetRGBA64", Method, 17, ""},
+		{"Draw", Func, 0, "func(dst Image, r image.Rectangle, src image.Image, sp image.Point, op Op)"},
+		{"DrawMask", Func, 0, "func(dst Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op)"},
+		{"Drawer", Type, 2, ""},
+		{"FloydSteinberg", Var, 2, ""},
+		{"Image", Type, 0, ""},
+		{"Op", Type, 0, ""},
+		{"Over", Const, 0, ""},
+		{"Quantizer", Type, 2, ""},
+		{"RGBA64Image", Type, 17, ""},
+		{"Src", Const, 0, ""},
+	},
+	"image/gif": {
+		{"Decode", Func, 0, "func(r io.Reader) (image.Image, error)"},
+		{"DecodeAll", Func, 0, "func(r io.Reader) (*GIF, error)"},
+		{"DecodeConfig", Func, 0, "func(r io.Reader) (image.Config, error)"},
+		{"DisposalBackground", Const, 5, ""},
+		{"DisposalNone", Const, 5, ""},
+		{"DisposalPrevious", Const, 5, ""},
+		{"Encode", Func, 2, "func(w io.Writer, m image.Image, o *Options) error"},
+		{"EncodeAll", Func, 2, "func(w io.Writer, g *GIF) error"},
+		{"GIF", Type, 0, ""},
+		{"GIF.BackgroundIndex", Field, 5, ""},
+		{"GIF.Config", Field, 5, ""},
+		{"GIF.Delay", Field, 0, ""},
+		{"GIF.Disposal", Field, 5, ""},
+		{"GIF.Image", Field, 0, ""},
+		{"GIF.LoopCount", Field, 0, ""},
+		{"Options", Type, 2, ""},
+		{"Options.Drawer", Field, 2, ""},
+		{"Options.NumColors", Field, 2, ""},
+		{"Options.Quantizer", Field, 2, ""},
+	},
+	"image/jpeg": {
+		{"(FormatError).Error", Method, 0, ""},
+		{"(Reader).Read", Method, 0, ""},
+		{"(Reader).ReadByte", Method, 0, ""},
+		{"(UnsupportedError).Error", Method, 0, ""},
+		{"Decode", Func, 0, "func(r io.Reader) (image.Image, error)"},
+		{"DecodeConfig", Func, 0, "func(r io.Reader) (image.Config, error)"},
+		{"DefaultQuality", Const, 0, ""},
+		{"Encode", Func, 0, "func(w io.Writer, m image.Image, o *Options) error"},
+		{"FormatError", Type, 0, ""},
+		{"Options", Type, 0, ""},
+		{"Options.Quality", Field, 0, ""},
+		{"Reader", Type, 0, ""},
+		{"UnsupportedError", Type, 0, ""},
+	},
+	"image/png": {
+		{"(*Encoder).Encode", Method, 4, ""},
+		{"(EncoderBufferPool).Get", Method, 9, ""},
+		{"(EncoderBufferPool).Put", Method, 9, ""},
+		{"(FormatError).Error", Method, 0, ""},
+		{"(UnsupportedError).Error", Method, 0, ""},
+		{"BestCompression", Const, 4, ""},
+		{"BestSpeed", Const, 4, ""},
+		{"CompressionLevel", Type, 4, ""},
+		{"Decode", Func, 0, "func(r io.Reader) (image.Image, error)"},
+		{"DecodeConfig", Func, 0, "func(r io.Reader) (image.Config, error)"},
+		{"DefaultCompression", Const, 4, ""},
+		{"Encode", Func, 0, "func(w io.Writer, m image.Image) error"},
+		{"Encoder", Type, 4, ""},
+		{"Encoder.BufferPool", Field, 9, ""},
+		{"Encoder.CompressionLevel", Field, 4, ""},
+		{"EncoderBuffer", Type, 9, ""},
+		{"EncoderBufferPool", Type, 9, ""},
+		{"FormatError", Type, 0, ""},
+		{"NoCompression", Const, 4, ""},
+		{"UnsupportedError", Type, 0, ""},
+	},
+	"index/suffixarray": {
+		{"(*Index).Bytes", Method, 0, ""},
+		{"(*Index).FindAllIndex", Method, 0, ""},
+		{"(*Index).Lookup", Method, 0, ""},
+		{"(*Index).Read", Method, 0, ""},
+		{"(*Index).Write", Method, 0, ""},
+		{"Index", Type, 0, ""},
+		{"New", Func, 0, "func(data []byte) *Index"},
+	},
+	"io": {
+		{"(*LimitedReader).Read", Method, 0, ""},
+		{"(*OffsetWriter).Seek", Method, 20, ""},
+		{"(*OffsetWriter).Write", Method, 20, ""},
+		{"(*OffsetWriter).WriteAt", Method, 20, ""},
+		{"(*PipeReader).Close", Method, 0, ""},
+		{"(*PipeReader).CloseWithError", Method, 0, ""},
+		{"(*PipeReader).Read", Method, 0, ""},
+		{"(*PipeWriter).Close", Method, 0, ""},
+		{"(*PipeWriter).CloseWithError", Method, 0, ""},
+		{"(*PipeWriter).Write", Method, 0, ""},
+		{"(*SectionReader).Outer", Method, 22, ""},
+		{"(*SectionReader).Read", Method, 0, ""},
+		{"(*SectionReader).ReadAt", Method, 0, ""},
+		{"(*SectionReader).Seek", Method, 0, ""},
+		{"(*SectionReader).Size", Method, 0, ""},
+		{"(ByteReader).ReadByte", Method, 0, ""},
+		{"(ByteScanner).ReadByte", Method, 0, ""},
+		{"(ByteScanner).UnreadByte", Method, 0, ""},
+		{"(ByteWriter).WriteByte", Method, 1, ""},
+		{"(Closer).Close", Method, 0, ""},
+		{"(ReadCloser).Close", Method, 0, ""},
+		{"(ReadCloser).Read", Method, 0, ""},
+		{"(ReadSeekCloser).Close", Method, 16, ""},
+		{"(ReadSeekCloser).Read", Method, 16, ""},
+		{"(ReadSeekCloser).Seek", Method, 16, ""},
+		{"(ReadSeeker).Read", Method, 0, ""},
+		{"(ReadSeeker).Seek", Method, 0, ""},
+		{"(ReadWriteCloser).Close", Method, 0, ""},
+		{"(ReadWriteCloser).Read", Method, 0, ""},
+		{"(ReadWriteCloser).Write", Method, 0, ""},
+		{"(ReadWriteSeeker).Read", Method, 0, ""},
+		{"(ReadWriteSeeker).Seek", Method, 0, ""},
+		{"(ReadWriteSeeker).Write", Method, 0, ""},
+		{"(ReadWriter).Read", Method, 0, ""},
+		{"(ReadWriter).Write", Method, 0, ""},
+		{"(Reader).Read", Method, 0, ""},
+		{"(ReaderAt).ReadAt", Method, 0, ""},
+		{"(ReaderFrom).ReadFrom", Method, 0, ""},
+		{"(RuneReader).ReadRune", Method, 0, ""},
+		{"(RuneScanner).ReadRune", Method, 0, ""},
+		{"(RuneScanner).UnreadRune", Method, 0, ""},
+		{"(Seeker).Seek", Method, 0, ""},
+		{"(StringWriter).WriteString", Method, 12, ""},
+		{"(WriteCloser).Close", Method, 0, ""},
+		{"(WriteCloser).Write", Method, 0, ""},
+		{"(WriteSeeker).Seek", Method, 0, ""},
+		{"(WriteSeeker).Write", Method, 0, ""},
+		{"(Writer).Write", Method, 0, ""},
+		{"(WriterAt).WriteAt", Method, 0, ""},
+		{"(WriterTo).WriteTo", Method, 0, ""},
+		{"ByteReader", Type, 0, ""},
+		{"ByteScanner", Type, 0, ""},
+		{"ByteWriter", Type, 1, ""},
+		{"Closer", Type, 0, ""},
+		{"Copy", Func, 0, "func(dst Writer, src Reader) (written int64, err error)"},
+		{"CopyBuffer", Func, 5, "func(dst Writer, src Reader, buf []byte) (written int64, err error)"},
+		{"CopyN", Func, 0, "func(dst Writer, src Reader, n int64) (written int64, err error)"},
+		{"Discard", Var, 16, ""},
+		{"EOF", Var, 0, ""},
+		{"ErrClosedPipe", Var, 0, ""},
+		{"ErrNoProgress", Var, 1, ""},
+		{"ErrShortBuffer", Var, 0, ""},
+		{"ErrShortWrite", Var, 0, ""},
+		{"ErrUnexpectedEOF", Var, 0, ""},
+		{"LimitReader", Func, 0, "func(r Reader, n int64) Reader"},
+		{"LimitedReader", Type, 0, ""},
+		{"LimitedReader.N", Field, 0, ""},
+		{"LimitedReader.R", Field, 0, ""},
+		{"MultiReader", Func, 0, "func(readers ...Reader) Reader"},
+		{"MultiWriter", Func, 0, "func(writers ...Writer) Writer"},
+		{"NewOffsetWriter", Func, 20, "func(w WriterAt, off int64) *OffsetWriter"},
+		{"NewSectionReader", Func, 0, "func(r ReaderAt, off int64, n int64) *SectionReader"},
+		{"NopCloser", Func, 16, "func(r Reader) ReadCloser"},
+		{"OffsetWriter", Type, 20, ""},
+		{"Pipe", Func, 0, "func() (*PipeReader, *PipeWriter)"},
+		{"PipeReader", Type, 0, ""},
+		{"PipeWriter", Type, 0, ""},
+		{"ReadAll", Func, 16, "func(r Reader) ([]byte, error)"},
+		{"ReadAtLeast", Func, 0, "func(r Reader, buf []byte, min int) (n int, err error)"},
+		{"ReadCloser", Type, 0, ""},
+		{"ReadFull", Func, 0, "func(r Reader, buf []byte) (n int, err error)"},
+		{"ReadSeekCloser", Type, 16, ""},
+		{"ReadSeeker", Type, 0, ""},
+		{"ReadWriteCloser", Type, 0, ""},
+		{"ReadWriteSeeker", Type, 0, ""},
+		{"ReadWriter", Type, 0, ""},
+		{"Reader", Type, 0, ""},
+		{"ReaderAt", Type, 0, ""},
+		{"ReaderFrom", Type, 0, ""},
+		{"RuneReader", Type, 0, ""},
+		{"RuneScanner", Type, 0, ""},
+		{"SectionReader", Type, 0, ""},
+		{"SeekCurrent", Const, 7, ""},
+		{"SeekEnd", Const, 7, ""},
+		{"SeekStart", Const, 7, ""},
+		{"Seeker", Type, 0, ""},
+		{"StringWriter", Type, 12, ""},
+		{"TeeReader", Func, 0, "func(r Reader, w Writer) Reader"},
+		{"WriteCloser", Type, 0, ""},
+		{"WriteSeeker", Type, 0, ""},
+		{"WriteString", Func, 0, "func(w Writer, s string) (n int, err error)"},
+		{"Writer", Type, 0, ""},
+		{"WriterAt", Type, 0, ""},
+		{"WriterTo", Type, 0, ""},
+	},
+	"io/fs": {
+		{"(*PathError).Error", Method, 16, ""},
+		{"(*PathError).Timeout", Method, 16, ""},
+		{"(*PathError).Unwrap", Method, 16, ""},
+		{"(DirEntry).Info", Method, 16, ""},
+		{"(DirEntry).IsDir", Method, 16, ""},
+		{"(DirEntry).Name", Method, 16, ""},
+		{"(DirEntry).Type", Method, 16, ""},
+		{"(FS).Open", Method, 16, ""},
+		{"(File).Close", Method, 16, ""},
+		{"(File).Read", Method, 16, ""},
+		{"(File).Stat", Method, 16, ""},
+		{"(FileInfo).IsDir", Method, 16, ""},
+		{"(FileInfo).ModTime", Method, 16, ""},
+		{"(FileInfo).Mode", Method, 16, ""},
+		{"(FileInfo).Name", Method, 16, ""},
+		{"(FileInfo).Size", Method, 16, ""},
+		{"(FileInfo).Sys", Method, 16, ""},
+		{"(FileMode).IsDir", Method, 16, ""},
+		{"(FileMode).IsRegular", Method, 16, ""},
+		{"(FileMode).Perm", Method, 16, ""},
+		{"(FileMode).String", Method, 16, ""},
+		{"(FileMode).Type", Method, 16, ""},
+		{"(GlobFS).Glob", Method, 16, ""},
+		{"(GlobFS).Open", Method, 16, ""},
+		{"(ReadDirFS).Open", Method, 16, ""},
+		{"(ReadDirFS).ReadDir", Method, 16, ""},
+		{"(ReadDirFile).Close", Method, 16, ""},
+		{"(ReadDirFile).Read", Method, 16, ""},
+		{"(ReadDirFile).ReadDir", Method, 16, ""},
+		{"(ReadDirFile).Stat", Method, 16, ""},
+		{"(ReadFileFS).Open", Method, 16, ""},
+		{"(ReadFileFS).ReadFile", Method, 16, ""},
+		{"(ReadLinkFS).Lstat", Method, 25, ""},
+		{"(ReadLinkFS).Open", Method, 25, ""},
+		{"(ReadLinkFS).ReadLink", Method, 25, ""},
+		{"(StatFS).Open", Method, 16, ""},
+		{"(StatFS).Stat", Method, 16, ""},
+		{"(SubFS).Open", Method, 16, ""},
+		{"(SubFS).Sub", Method, 16, ""},
+		{"DirEntry", Type, 16, ""},
+		{"ErrClosed", Var, 16, ""},
+		{"ErrExist", Var, 16, ""},
+		{"ErrInvalid", Var, 16, ""},
+		{"ErrNotExist", Var, 16, ""},
+		{"ErrPermission", Var, 16, ""},
+		{"FS", Type, 16, ""},
+		{"File", Type, 16, ""},
+		{"FileInfo", Type, 16, ""},
+		{"FileInfoToDirEntry", Func, 17, "func(info FileInfo) DirEntry"},
+		{"FileMode", Type, 16, ""},
+		{"FormatDirEntry", Func, 21, "func(dir DirEntry) string"},
+		{"FormatFileInfo", Func, 21, "func(info FileInfo) string"},
+		{"Glob", Func, 16, "func(fsys FS, pattern string) (matches []string, err error)"},
+		{"GlobFS", Type, 16, ""},
+		{"Lstat", Func, 25, "func(fsys FS, name string) (FileInfo, error)"},
+		{"ModeAppend", Const, 16, ""},
+		{"ModeCharDevice", Const, 16, ""},
+		{"ModeDevice", Const, 16, ""},
+		{"ModeDir", Const, 16, ""},
+		{"ModeExclusive", Const, 16, ""},
+		{"ModeIrregular", Const, 16, ""},
+		{"ModeNamedPipe", Const, 16, ""},
+		{"ModePerm", Const, 16, ""},
+		{"ModeSetgid", Const, 16, ""},
+		{"ModeSetuid", Const, 16, ""},
+		{"ModeSocket", Const, 16, ""},
+		{"ModeSticky", Const, 16, ""},
+		{"ModeSymlink", Const, 16, ""},
+		{"ModeTemporary", Const, 16, ""},
+		{"ModeType", Const, 16, ""},
+		{"PathError", Type, 16, ""},
+		{"PathError.Err", Field, 16, ""},
+		{"PathError.Op", Field, 16, ""},
+		{"PathError.Path", Field, 16, ""},
+		{"ReadDir", Func, 16, "func(fsys FS, name string) ([]DirEntry, error)"},
+		{"ReadDirFS", Type, 16, ""},
+		{"ReadDirFile", Type, 16, ""},
+		{"ReadFile", Func, 16, "func(fsys FS, name string) ([]byte, error)"},
+		{"ReadFileFS", Type, 16, ""},
+		{"ReadLink", Func, 25, "func(fsys FS, name string) (string, error)"},
+		{"ReadLinkFS", Type, 25, ""},
+		{"SkipAll", Var, 20, ""},
+		{"SkipDir", Var, 16, ""},
+		{"Stat", Func, 16, "func(fsys FS, name string) (FileInfo, error)"},
+		{"StatFS", Type, 16, ""},
+		{"Sub", Func, 16, "func(fsys FS, dir string) (FS, error)"},
+		{"SubFS", Type, 16, ""},
+		{"ValidPath", Func, 16, "func(name string) bool"},
+		{"WalkDir", Func, 16, "func(fsys FS, root string, fn WalkDirFunc) error"},
+		{"WalkDirFunc", Type, 16, ""},
+	},
+	"io/ioutil": {
+		{"Discard", Var, 0, ""},
+		{"NopCloser", Func, 0, "func(r io.Reader) io.ReadCloser"},
+		{"ReadAll", Func, 0, "func(r io.Reader) ([]byte, error)"},
+		{"ReadDir", Func, 0, "func(dirname string) ([]fs.FileInfo, error)"},
+		{"ReadFile", Func, 0, "func(filename string) ([]byte, error)"},
+		{"TempDir", Func, 0, "func(dir string, pattern string) (name string, err error)"},
+		{"TempFile", Func, 0, "func(dir string, pattern string) (f *os.File, err error)"},
+		{"WriteFile", Func, 0, "func(filename string, data []byte, perm fs.FileMode) error"},
+	},
+	"iter": {
+		{"Pull", Func, 23, "func[V any](seq Seq[V]) (next func() (V, bool), stop func())"},
+		{"Pull2", Func, 23, "func[K, V any](seq Seq2[K, V]) (next func() (K, V, bool), stop func())"},
+		{"Seq", Type, 23, ""},
+		{"Seq2", Type, 23, ""},
+	},
+	"log": {
+		{"(*Logger).Fatal", Method, 0, ""},
+		{"(*Logger).Fatalf", Method, 0, ""},
+		{"(*Logger).Fatalln", Method, 0, ""},
+		{"(*Logger).Flags", Method, 0, ""},
+		{"(*Logger).Output", Method, 0, ""},
+		{"(*Logger).Panic", Method, 0, ""},
+		{"(*Logger).Panicf", Method, 0, ""},
+		{"(*Logger).Panicln", Method, 0, ""},
+		{"(*Logger).Prefix", Method, 0, ""},
+		{"(*Logger).Print", Method, 0, ""},
+		{"(*Logger).Printf", Method, 0, ""},
+		{"(*Logger).Println", Method, 0, ""},
+		{"(*Logger).SetFlags", Method, 0, ""},
+		{"(*Logger).SetOutput", Method, 5, ""},
+		{"(*Logger).SetPrefix", Method, 0, ""},
+		{"(*Logger).Writer", Method, 12, ""},
+		{"Default", Func, 16, "func() *Logger"},
+		{"Fatal", Func, 0, "func(v ...any)"},
+		{"Fatalf", Func, 0, "func(format string, v ...any)"},
+		{"Fatalln", Func, 0, "func(v ...any)"},
+		{"Flags", Func, 0, "func() int"},
+		{"LUTC", Const, 5, ""},
+		{"Ldate", Const, 0, ""},
+		{"Llongfile", Const, 0, ""},
+		{"Lmicroseconds", Const, 0, ""},
+		{"Lmsgprefix", Const, 14, ""},
+		{"Logger", Type, 0, ""},
+		{"Lshortfile", Const, 0, ""},
+		{"LstdFlags", Const, 0, ""},
+		{"Ltime", Const, 0, ""},
+		{"New", Func, 0, "func(out io.Writer, prefix string, flag int) *Logger"},
+		{"Output", Func, 5, "func(calldepth int, s string) error"},
+		{"Panic", Func, 0, "func(v ...any)"},
+		{"Panicf", Func, 0, "func(format string, v ...any)"},
+		{"Panicln", Func, 0, "func(v ...any)"},
+		{"Prefix", Func, 0, "func() string"},
+		{"Print", Func, 0, "func(v ...any)"},
+		{"Printf", Func, 0, "func(format string, v ...any)"},
+		{"Println", Func, 0, "func(v ...any)"},
+		{"SetFlags", Func, 0, "func(flag int)"},
+		{"SetOutput", Func, 0, "func(w io.Writer)"},
+		{"SetPrefix", Func, 0, "func(prefix string)"},
+		{"Writer", Func, 13, "func() io.Writer"},
+	},
+	"log/slog": {
+		{"(*JSONHandler).Enabled", Method, 21, ""},
+		{"(*JSONHandler).Handle", Method, 21, ""},
+		{"(*JSONHandler).WithAttrs", Method, 21, ""},
+		{"(*JSONHandler).WithGroup", Method, 21, ""},
+		{"(*Level).UnmarshalJSON", Method, 21, ""},
+		{"(*Level).UnmarshalText", Method, 21, ""},
+		{"(*LevelVar).AppendText", Method, 24, ""},
+		{"(*LevelVar).Level", Method, 21, ""},
+		{"(*LevelVar).MarshalText", Method, 21, ""},
+		{"(*LevelVar).Set", Method, 21, ""},
+		{"(*LevelVar).String", Method, 21, ""},
+		{"(*LevelVar).UnmarshalText", Method, 21, ""},
+		{"(*Logger).Debug", Method, 21, ""},
+		{"(*Logger).DebugContext", Method, 21, ""},
+		{"(*Logger).Enabled", Method, 21, ""},
+		{"(*Logger).Error", Method, 21, ""},
+		{"(*Logger).ErrorContext", Method, 21, ""},
+		{"(*Logger).Handler", Method, 21, ""},
+		{"(*Logger).Info", Method, 21, ""},
+		{"(*Logger).InfoContext", Method, 21, ""},
+		{"(*Logger).Log", Method, 21, ""},
+		{"(*Logger).LogAttrs", Method, 21, ""},
+		{"(*Logger).Warn", Method, 21, ""},
+		{"(*Logger).WarnContext", Method, 21, ""},
+		{"(*Logger).With", Method, 21, ""},
+		{"(*Logger).WithGroup", Method, 21, ""},
+		{"(*MultiHandler).Enabled", Method, 26, ""},
+		{"(*MultiHandler).Handle", Method, 26, ""},
+		{"(*MultiHandler).WithAttrs", Method, 26, ""},
+		{"(*MultiHandler).WithGroup", Method, 26, ""},
+		{"(*Record).Add", Method, 21, ""},
+		{"(*Record).AddAttrs", Method, 21, ""},
+		{"(*TextHandler).Enabled", Method, 21, ""},
+		{"(*TextHandler).Handle", Method, 21, ""},
+		{"(*TextHandler).WithAttrs", Method, 21, ""},
+		{"(*TextHandler).WithGroup", Method, 21, ""},
+		{"(Attr).Equal", Method, 21, ""},
+		{"(Attr).String", Method, 21, ""},
+		{"(Handler).Enabled", Method, 21, ""},
+		{"(Handler).Handle", Method, 21, ""},
+		{"(Handler).WithAttrs", Method, 21, ""},
+		{"(Handler).WithGroup", Method, 21, ""},
+		{"(Kind).String", Method, 21, ""},
+		{"(Level).AppendText", Method, 24, ""},
+		{"(Level).Level", Method, 21, ""},
+		{"(Level).MarshalJSON", Method, 21, ""},
+		{"(Level).MarshalText", Method, 21, ""},
+		{"(Level).String", Method, 21, ""},
+		{"(Leveler).Level", Method, 21, ""},
+		{"(LogValuer).LogValue", Method, 21, ""},
+		{"(Record).Attrs", Method, 21, ""},
+		{"(Record).Clone", Method, 21, ""},
+		{"(Record).NumAttrs", Method, 21, ""},
+		{"(Record).Source", Method, 25, ""},
+		{"(Value).Any", Method, 21, ""},
+		{"(Value).Bool", Method, 21, ""},
+		{"(Value).Duration", Method, 21, ""},
+		{"(Value).Equal", Method, 21, ""},
+		{"(Value).Float64", Method, 21, ""},
+		{"(Value).Group", Method, 21, ""},
+		{"(Value).Int64", Method, 21, ""},
+		{"(Value).Kind", Method, 21, ""},
+		{"(Value).LogValuer", Method, 21, ""},
+		{"(Value).Resolve", Method, 21, ""},
+		{"(Value).String", Method, 21, ""},
+		{"(Value).Time", Method, 21, ""},
+		{"(Value).Uint64", Method, 21, ""},
+		{"Any", Func, 21, "func(key string, value any) Attr"},
+		{"AnyValue", Func, 21, "func(v any) Value"},
+		{"Attr", Type, 21, ""},
+		{"Attr.Key", Field, 21, ""},
+		{"Attr.Value", Field, 21, ""},
+		{"Bool", Func, 21, "func(key string, v bool) Attr"},
+		{"BoolValue", Func, 21, "func(v bool) Value"},
+		{"Debug", Func, 21, "func(msg string, args ...any)"},
+		{"DebugContext", Func, 21, "func(ctx context.Context, msg string, args ...any)"},
+		{"Default", Func, 21, "func() *Logger"},
+		{"DiscardHandler", Var, 24, ""},
+		{"Duration", Func, 21, "func(key string, v time.Duration) Attr"},
+		{"DurationValue", Func, 21, "func(v time.Duration) Value"},
+		{"Error", Func, 21, "func(msg string, args ...any)"},
+		{"ErrorContext", Func, 21, "func(ctx context.Context, msg string, args ...any)"},
+		{"Float64", Func, 21, "func(key string, v float64) Attr"},
+		{"Float64Value", Func, 21, "func(v float64) Value"},
+		{"Group", Func, 21, "func(key string, args ...any) Attr"},
+		{"GroupAttrs", Func, 25, "func(key string, attrs ...Attr) Attr"},
+		{"GroupValue", Func, 21, "func(as ...Attr) Value"},
+		{"Handler", Type, 21, ""},
+		{"HandlerOptions", Type, 21, ""},
+		{"HandlerOptions.AddSource", Field, 21, ""},
+		{"HandlerOptions.Level", Field, 21, ""},
+		{"HandlerOptions.ReplaceAttr", Field, 21, ""},
+		{"Info", Func, 21, "func(msg string, args ...any)"},
+		{"InfoContext", Func, 21, "func(ctx context.Context, msg string, args ...any)"},
+		{"Int", Func, 21, "func(key string, value int) Attr"},
+		{"Int64", Func, 21, "func(key string, value int64) Attr"},
+		{"Int64Value", Func, 21, "func(v int64) Value"},
+		{"IntValue", Func, 21, "func(v int) Value"},
+		{"JSONHandler", Type, 21, ""},
+		{"Kind", Type, 21, ""},
+		{"KindAny", Const, 21, ""},
+		{"KindBool", Const, 21, ""},
+		{"KindDuration", Const, 21, ""},
+		{"KindFloat64", Const, 21, ""},
+		{"KindGroup", Const, 21, ""},
+		{"KindInt64", Const, 21, ""},
+		{"KindLogValuer", Const, 21, ""},
+		{"KindString", Const, 21, ""},
+		{"KindTime", Const, 21, ""},
+		{"KindUint64", Const, 21, ""},
+		{"Level", Type, 21, ""},
+		{"LevelDebug", Const, 21, ""},
+		{"LevelError", Const, 21, ""},
+		{"LevelInfo", Const, 21, ""},
+		{"LevelKey", Const, 21, ""},
+		{"LevelVar", Type, 21, ""},
+		{"LevelWarn", Const, 21, ""},
+		{"Leveler", Type, 21, ""},
+		{"Log", Func, 21, "func(ctx context.Context, level Level, msg string, args ...any)"},
+		{"LogAttrs", Func, 21, "func(ctx context.Context, level Level, msg string, attrs ...Attr)"},
+		{"LogValuer", Type, 21, ""},
+		{"Logger", Type, 21, ""},
+		{"MessageKey", Const, 21, ""},
+		{"MultiHandler", Type, 26, ""},
+		{"New", Func, 21, "func(h Handler) *Logger"},
+		{"NewJSONHandler", Func, 21, "func(w io.Writer, opts *HandlerOptions) *JSONHandler"},
+		{"NewLogLogger", Func, 21, "func(h Handler, level Level) *log.Logger"},
+		{"NewMultiHandler", Func, 26, "func(handlers ...Handler) *MultiHandler"},
+		{"NewRecord", Func, 21, "func(t time.Time, level Level, msg string, pc uintptr) Record"},
+		{"NewTextHandler", Func, 21, "func(w io.Writer, opts *HandlerOptions) *TextHandler"},
+		{"Record", Type, 21, ""},
+		{"Record.Level", Field, 21, ""},
+		{"Record.Message", Field, 21, ""},
+		{"Record.PC", Field, 21, ""},
+		{"Record.Time", Field, 21, ""},
+		{"SetDefault", Func, 21, "func(l *Logger)"},
+		{"SetLogLoggerLevel", Func, 22, "func(level Level) (oldLevel Level)"},
+		{"Source", Type, 21, ""},
+		{"Source.File", Field, 21, ""},
+		{"Source.Function", Field, 21, ""},
+		{"Source.Line", Field, 21, ""},
+		{"SourceKey", Const, 21, ""},
+		{"String", Func, 21, "func(key string, value string) Attr"},
+		{"StringValue", Func, 21, "func(value string) Value"},
+		{"TextHandler", Type, 21, ""},
+		{"Time", Func, 21, "func(key string, v time.Time) Attr"},
+		{"TimeKey", Const, 21, ""},
+		{"TimeValue", Func, 21, "func(v time.Time) Value"},
+		{"Uint64", Func, 21, "func(key string, v uint64) Attr"},
+		{"Uint64Value", Func, 21, "func(v uint64) Value"},
+		{"Value", Type, 21, ""},
+		{"Warn", Func, 21, "func(msg string, args ...any)"},
+		{"WarnContext", Func, 21, "func(ctx context.Context, msg string, args ...any)"},
+		{"With", Func, 21, "func(args ...any) *Logger"},
+	},
+	"log/syslog": {
+		{"(*Writer).Alert", Method, 0, ""},
+		{"(*Writer).Close", Method, 0, ""},
+		{"(*Writer).Crit", Method, 0, ""},
+		{"(*Writer).Debug", Method, 0, ""},
+		{"(*Writer).Emerg", Method, 0, ""},
+		{"(*Writer).Err", Method, 0, ""},
+		{"(*Writer).Info", Method, 0, ""},
+		{"(*Writer).Notice", Method, 0, ""},
+		{"(*Writer).Warning", Method, 0, ""},
+		{"(*Writer).Write", Method, 0, ""},
+		{"Dial", Func, 0, "func(network string, raddr string, priority Priority, tag string) (*Writer, error)"},
+		{"LOG_ALERT", Const, 0, ""},
+		{"LOG_AUTH", Const, 1, ""},
+		{"LOG_AUTHPRIV", Const, 1, ""},
+		{"LOG_CRIT", Const, 0, ""},
+		{"LOG_CRON", Const, 1, ""},
+		{"LOG_DAEMON", Const, 1, ""},
+		{"LOG_DEBUG", Const, 0, ""},
+		{"LOG_EMERG", Const, 0, ""},
+		{"LOG_ERR", Const, 0, ""},
+		{"LOG_FTP", Const, 1, ""},
+		{"LOG_INFO", Const, 0, ""},
+		{"LOG_KERN", Const, 1, ""},
+		{"LOG_LOCAL0", Const, 1, ""},
+		{"LOG_LOCAL1", Const, 1, ""},
+		{"LOG_LOCAL2", Const, 1, ""},
+		{"LOG_LOCAL3", Const, 1, ""},
+		{"LOG_LOCAL4", Const, 1, ""},
+		{"LOG_LOCAL5", Const, 1, ""},
+		{"LOG_LOCAL6", Const, 1, ""},
+		{"LOG_LOCAL7", Const, 1, ""},
+		{"LOG_LPR", Const, 1, ""},
+		{"LOG_MAIL", Const, 1, ""},
+		{"LOG_NEWS", Const, 1, ""},
+		{"LOG_NOTICE", Const, 0, ""},
+		{"LOG_SYSLOG", Const, 1, ""},
+		{"LOG_USER", Const, 1, ""},
+		{"LOG_UUCP", Const, 1, ""},
+		{"LOG_WARNING", Const, 0, ""},
+		{"New", Func, 0, "func(priority Priority, tag string) (*Writer, error)"},
+		{"NewLogger", Func, 0, "func(p Priority, logFlag int) (*log.Logger, error)"},
+		{"Priority", Type, 0, ""},
+		{"Writer", Type, 0, ""},
+	},
+	"maps": {
+		{"All", Func, 23, "func[Map ~map[K]V, K comparable, V any](m Map) iter.Seq2[K, V]"},
+		{"Clone", Func, 21, "func[M ~map[K]V, K comparable, V any](m M) M"},
+		{"Collect", Func, 23, "func[K comparable, V any](seq iter.Seq2[K, V]) map[K]V"},
+		{"Copy", Func, 21, "func[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2)"},
+		{"DeleteFunc", Func, 21, "func[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool)"},
+		{"Equal", Func, 21, "func[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool"},
+		{"EqualFunc", Func, 21, "func[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool"},
+		{"Insert", Func, 23, "func[Map ~map[K]V, K comparable, V any](m Map, seq iter.Seq2[K, V])"},
+		{"Keys", Func, 23, "func[Map ~map[K]V, K comparable, V any](m Map) iter.Seq[K]"},
+		{"Values", Func, 23, "func[Map ~map[K]V, K comparable, V any](m Map) iter.Seq[V]"},
+	},
+	"math": {
+		{"Abs", Func, 0, "func(x float64) float64"},
+		{"Acos", Func, 0, "func(x float64) float64"},
+		{"Acosh", Func, 0, "func(x float64) float64"},
+		{"Asin", Func, 0, "func(x float64) float64"},
+		{"Asinh", Func, 0, "func(x float64) float64"},
+		{"Atan", Func, 0, "func(x float64) float64"},
+		{"Atan2", Func, 0, "func(y float64, x float64) float64"},
+		{"Atanh", Func, 0, "func(x float64) float64"},
+		{"Cbrt", Func, 0, "func(x float64) float64"},
+		{"Ceil", Func, 0, "func(x float64) float64"},
+		{"Copysign", Func, 0, "func(f float64, sign float64) float64"},
+		{"Cos", Func, 0, "func(x float64) float64"},
+		{"Cosh", Func, 0, "func(x float64) float64"},
+		{"Dim", Func, 0, "func(x float64, y float64) float64"},
+		{"E", Const, 0, ""},
+		{"Erf", Func, 0, "func(x float64) float64"},
+		{"Erfc", Func, 0, "func(x float64) float64"},
+		{"Erfcinv", Func, 10, "func(x float64) float64"},
+		{"Erfinv", Func, 10, "func(x float64) float64"},
+		{"Exp", Func, 0, "func(x float64) float64"},
+		{"Exp2", Func, 0, "func(x float64) float64"},
+		{"Expm1", Func, 0, "func(x float64) float64"},
+		{"FMA", Func, 14, "func(x float64, y float64, z float64) float64"},
+		{"Float32bits", Func, 0, "func(f float32) uint32"},
+		{"Float32frombits", Func, 0, "func(b uint32) float32"},
+		{"Float64bits", Func, 0, "func(f float64) uint64"},
+		{"Float64frombits", Func, 0, "func(b uint64) float64"},
+		{"Floor", Func, 0, "func(x float64) float64"},
+		{"Frexp", Func, 0, "func(f float64) (frac float64, exp int)"},
+		{"Gamma", Func, 0, "func(x float64) float64"},
+		{"Hypot", Func, 0, "func(p float64, q float64) float64"},
+		{"Ilogb", Func, 0, "func(x float64) int"},
+		{"Inf", Func, 0, "func(sign int) float64"},
+		{"IsInf", Func, 0, "func(f float64, sign int) bool"},
+		{"IsNaN", Func, 0, "func(f float64) (is bool)"},
+		{"J0", Func, 0, "func(x float64) float64"},
+		{"J1", Func, 0, "func(x float64) float64"},
+		{"Jn", Func, 0, "func(n int, x float64) float64"},
+		{"Ldexp", Func, 0, "func(frac float64, exp int) float64"},
+		{"Lgamma", Func, 0, "func(x float64) (lgamma float64, sign int)"},
+		{"Ln10", Const, 0, ""},
+		{"Ln2", Const, 0, ""},
+		{"Log", Func, 0, "func(x float64) float64"},
+		{"Log10", Func, 0, "func(x float64) float64"},
+		{"Log10E", Const, 0, ""},
+		{"Log1p", Func, 0, "func(x float64) float64"},
+		{"Log2", Func, 0, "func(x float64) float64"},
+		{"Log2E", Const, 0, ""},
+		{"Logb", Func, 0, "func(x float64) float64"},
+		{"Max", Func, 0, "func(x float64, y float64) float64"},
+		{"MaxFloat32", Const, 0, ""},
+		{"MaxFloat64", Const, 0, ""},
+		{"MaxInt", Const, 17, ""},
+		{"MaxInt16", Const, 0, ""},
+		{"MaxInt32", Const, 0, ""},
+		{"MaxInt64", Const, 0, ""},
+		{"MaxInt8", Const, 0, ""},
+		{"MaxUint", Const, 17, ""},
+		{"MaxUint16", Const, 0, ""},
+		{"MaxUint32", Const, 0, ""},
+		{"MaxUint64", Const, 0, ""},
+		{"MaxUint8", Const, 0, ""},
+		{"Min", Func, 0, "func(x float64, y float64) float64"},
+		{"MinInt", Const, 17, ""},
+		{"MinInt16", Const, 0, ""},
+		{"MinInt32", Const, 0, ""},
+		{"MinInt64", Const, 0, ""},
+		{"MinInt8", Const, 0, ""},
+		{"Mod", Func, 0, "func(x float64, y float64) float64"},
+		{"Modf", Func, 0, "func(f float64) (integer float64, fractional float64)"},
+		{"NaN", Func, 0, "func() float64"},
+		{"Nextafter", Func, 0, "func(x float64, y float64) (r float64)"},
+		{"Nextafter32", Func, 4, "func(x float32, y float32) (r float32)"},
+		{"Phi", Const, 0, ""},
+		{"Pi", Const, 0, ""},
+		{"Pow", Func, 0, "func(x float64, y float64) float64"},
+		{"Pow10", Func, 0, "func(n int) float64"},
+		{"Remainder", Func, 0, "func(x float64, y float64) float64"},
+		{"Round", Func, 10, "func(x float64) float64"},
+		{"RoundToEven", Func, 10, "func(x float64) float64"},
+		{"Signbit", Func, 0, "func(x float64) bool"},
+		{"Sin", Func, 0, "func(x float64) float64"},
+		{"Sincos", Func, 0, "func(x float64) (sin float64, cos float64)"},
+		{"Sinh", Func, 0, "func(x float64) float64"},
+		{"SmallestNonzeroFloat32", Const, 0, ""},
+		{"SmallestNonzeroFloat64", Const, 0, ""},
+		{"Sqrt", Func, 0, "func(x float64) float64"},
+		{"Sqrt2", Const, 0, ""},
+		{"SqrtE", Const, 0, ""},
+		{"SqrtPhi", Const, 0, ""},
+		{"SqrtPi", Const, 0, ""},
+		{"Tan", Func, 0, "func(x float64) float64"},
+		{"Tanh", Func, 0, "func(x float64) float64"},
+		{"Trunc", Func, 0, "func(x float64) float64"},
+		{"Y0", Func, 0, "func(x float64) float64"},
+		{"Y1", Func, 0, "func(x float64) float64"},
+		{"Yn", Func, 0, "func(n int, x float64) float64"},
+	},
+	"math/big": {
+		{"(*Float).Abs", Method, 5, ""},
+		{"(*Float).Acc", Method, 5, ""},
+		{"(*Float).Add", Method, 5, ""},
+		{"(*Float).Append", Method, 5, ""},
+		{"(*Float).AppendText", Method, 24, ""},
+		{"(*Float).Cmp", Method, 5, ""},
+		{"(*Float).Copy", Method, 5, ""},
+		{"(*Float).Float32", Method, 5, ""},
+		{"(*Float).Float64", Method, 5, ""},
+		{"(*Float).Format", Method, 5, ""},
+		{"(*Float).GobDecode", Method, 7, ""},
+		{"(*Float).GobEncode", Method, 7, ""},
+		{"(*Float).Int", Method, 5, ""},
+		{"(*Float).Int64", Method, 5, ""},
+		{"(*Float).IsInf", Method, 5, ""},
+		{"(*Float).IsInt", Method, 5, ""},
+		{"(*Float).MantExp", Method, 5, ""},
+		{"(*Float).MarshalText", Method, 6, ""},
+		{"(*Float).MinPrec", Method, 5, ""},
+		{"(*Float).Mode", Method, 5, ""},
+		{"(*Float).Mul", Method, 5, ""},
+		{"(*Float).Neg", Method, 5, ""},
+		{"(*Float).Parse", Method, 5, ""},
+		{"(*Float).Prec", Method, 5, ""},
+		{"(*Float).Quo", Method, 5, ""},
+		{"(*Float).Rat", Method, 5, ""},
+		{"(*Float).Scan", Method, 8, ""},
+		{"(*Float).Set", Method, 5, ""},
+		{"(*Float).SetFloat64", Method, 5, ""},
+		{"(*Float).SetInf", Method, 5, ""},
+		{"(*Float).SetInt", Method, 5, ""},
+		{"(*Float).SetInt64", Method, 5, ""},
+		{"(*Float).SetMantExp", Method, 5, ""},
+		{"(*Float).SetMode", Method, 5, ""},
+		{"(*Float).SetPrec", Method, 5, ""},
+		{"(*Float).SetRat", Method, 5, ""},
+		{"(*Float).SetString", Method, 5, ""},
+		{"(*Float).SetUint64", Method, 5, ""},
+		{"(*Float).Sign", Method, 5, ""},
+		{"(*Float).Signbit", Method, 5, ""},
+		{"(*Float).Sqrt", Method, 10, ""},
+		{"(*Float).String", Method, 5, ""},
+		{"(*Float).Sub", Method, 5, ""},
+		{"(*Float).Text", Method, 5, ""},
+		{"(*Float).Uint64", Method, 5, ""},
+		{"(*Float).UnmarshalText", Method, 6, ""},
+		{"(*Int).Abs", Method, 0, ""},
+		{"(*Int).Add", Method, 0, ""},
+		{"(*Int).And", Method, 0, ""},
+		{"(*Int).AndNot", Method, 0, ""},
+		{"(*Int).Append", Method, 6, ""},
+		{"(*Int).AppendText", Method, 24, ""},
+		{"(*Int).Binomial", Method, 0, ""},
+		{"(*Int).Bit", Method, 0, ""},
+		{"(*Int).BitLen", Method, 0, ""},
+		{"(*Int).Bits", Method, 0, ""},
+		{"(*Int).Bytes", Method, 0, ""},
+		{"(*Int).Cmp", Method, 0, ""},
+		{"(*Int).CmpAbs", Method, 10, ""},
+		{"(*Int).Div", Method, 0, ""},
+		{"(*Int).DivMod", Method, 0, ""},
+		{"(*Int).Divide", Method, 27, ""},
+		{"(*Int).Exp", Method, 0, ""},
+		{"(*Int).FillBytes", Method, 15, ""},
+		{"(*Int).Float64", Method, 21, ""},
+		{"(*Int).Format", Method, 0, ""},
+		{"(*Int).GCD", Method, 0, ""},
+		{"(*Int).GobDecode", Method, 0, ""},
+		{"(*Int).GobEncode", Method, 0, ""},
+		{"(*Int).Int64", Method, 0, ""},
+		{"(*Int).IsInt64", Method, 9, ""},
+		{"(*Int).IsUint64", Method, 9, ""},
+		{"(*Int).Lsh", Method, 0, ""},
+		{"(*Int).MarshalJSON", Method, 1, ""},
+		{"(*Int).MarshalText", Method, 3, ""},
+		{"(*Int).Mod", Method, 0, ""},
+		{"(*Int).ModInverse", Method, 0, ""},
+		{"(*Int).ModSqrt", Method, 5, ""},
+		{"(*Int).Mul", Method, 0, ""},
+		{"(*Int).MulRange", Method, 0, ""},
+		{"(*Int).Neg", Method, 0, ""},
+		{"(*Int).Not", Method, 0, ""},
+		{"(*Int).Or", Method, 0, ""},
+		{"(*Int).ProbablyPrime", Method, 0, ""},
+		{"(*Int).Quo", Method, 0, ""},
+		{"(*Int).QuoRem", Method, 0, ""},
+		{"(*Int).Rand", Method, 0, ""},
+		{"(*Int).Rem", Method, 0, ""},
+		{"(*Int).Rsh", Method, 0, ""},
+		{"(*Int).Scan", Method, 0, ""},
+		{"(*Int).Set", Method, 0, ""},
+		{"(*Int).SetBit", Method, 0, ""},
+		{"(*Int).SetBits", Method, 0, ""},
+		{"(*Int).SetBytes", Method, 0, ""},
+		{"(*Int).SetInt64", Method, 0, ""},
+		{"(*Int).SetString", Method, 0, ""},
+		{"(*Int).SetUint64", Method, 1, ""},
+		{"(*Int).Sign", Method, 0, ""},
+		{"(*Int).Sqrt", Method, 8, ""},
+		{"(*Int).String", Method, 0, ""},
+		{"(*Int).Sub", Method, 0, ""},
+		{"(*Int).Text", Method, 6, ""},
+		{"(*Int).TrailingZeroBits", Method, 13, ""},
+		{"(*Int).Uint64", Method, 1, ""},
+		{"(*Int).UnmarshalJSON", Method, 1, ""},
+		{"(*Int).UnmarshalText", Method, 3, ""},
+		{"(*Int).Xor", Method, 0, ""},
+		{"(*Rat).Abs", Method, 0, ""},
+		{"(*Rat).Add", Method, 0, ""},
+		{"(*Rat).AppendText", Method, 24, ""},
+		{"(*Rat).Cmp", Method, 0, ""},
+		{"(*Rat).Denom", Method, 0, ""},
+		{"(*Rat).Float32", Method, 4, ""},
+		{"(*Rat).Float64", Method, 1, ""},
+		{"(*Rat).FloatPrec", Method, 22, ""},
+		{"(*Rat).FloatString", Method, 0, ""},
+		{"(*Rat).GobDecode", Method, 0, ""},
+		{"(*Rat).GobEncode", Method, 0, ""},
+		{"(*Rat).Inv", Method, 0, ""},
+		{"(*Rat).IsInt", Method, 0, ""},
+		{"(*Rat).MarshalText", Method, 3, ""},
+		{"(*Rat).Mul", Method, 0, ""},
+		{"(*Rat).Neg", Method, 0, ""},
+		{"(*Rat).Num", Method, 0, ""},
+		{"(*Rat).Quo", Method, 0, ""},
+		{"(*Rat).RatString", Method, 0, ""},
+		{"(*Rat).Scan", Method, 0, ""},
+		{"(*Rat).Set", Method, 0, ""},
+		{"(*Rat).SetFloat64", Method, 1, ""},
+		{"(*Rat).SetFrac", Method, 0, ""},
+		{"(*Rat).SetFrac64", Method, 0, ""},
+		{"(*Rat).SetInt", Method, 0, ""},
+		{"(*Rat).SetInt64", Method, 0, ""},
+		{"(*Rat).SetString", Method, 0, ""},
+		{"(*Rat).SetUint64", Method, 13, ""},
+		{"(*Rat).Sign", Method, 0, ""},
+		{"(*Rat).String", Method, 0, ""},
+		{"(*Rat).Sub", Method, 0, ""},
+		{"(*Rat).UnmarshalText", Method, 3, ""},
+		{"(Accuracy).String", Method, 5, ""},
+		{"(ErrNaN).Error", Method, 5, ""},
+		{"(RoundingMode).String", Method, 5, ""},
+		{"Above", Const, 5, ""},
+		{"Accuracy", Type, 5, ""},
+		{"AwayFromZero", Const, 5, ""},
+		{"Below", Const, 5, ""},
+		{"Ceil", Const, 27, ""},
+		{"ErrNaN", Type, 5, ""},
+		{"Exact", Const, 5, ""},
+		{"Float", Type, 5, ""},
+		{"Floor", Const, 27, ""},
+		{"Int", Type, 0, ""},
+		{"Jacobi", Func, 5, "func(x *Int, y *Int) int"},
+		{"MaxBase", Const, 0, ""},
+		{"MaxExp", Const, 5, ""},
+		{"MaxPrec", Const, 5, ""},
+		{"MinExp", Const, 5, ""},
+		{"NewFloat", Func, 5, "func(x float64) *Float"},
+		{"NewInt", Func, 0, "func(x int64) *Int"},
+		{"NewRat", Func, 0, "func(a int64, b int64) *Rat"},
+		{"ParseFloat", Func, 5, "func(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error)"},
+		{"Rat", Type, 0, ""},
+		{"Round", Const, 27, ""},
+		{"RoundingMode", Type, 5, ""},
+		{"ToNearestAway", Const, 5, ""},
+		{"ToNearestEven", Const, 5, ""},
+		{"ToNegativeInf", Const, 5, ""},
+		{"ToPositiveInf", Const, 5, ""},
+		{"ToZero", Const, 5, ""},
+		{"Trunc", Const, 27, ""},
+		{"Word", Type, 0, ""},
+	},
+	"math/bits": {
+		{"Add", Func, 12, "func(x uint, y uint, carry uint) (sum uint, carryOut uint)"},
+		{"Add32", Func, 12, "func(x uint32, y uint32, carry uint32) (sum uint32, carryOut uint32)"},
+		{"Add64", Func, 12, "func(x uint64, y uint64, carry uint64) (sum uint64, carryOut uint64)"},
+		{"Div", Func, 12, "func(hi uint, lo uint, y uint) (quo uint, rem uint)"},
+		{"Div32", Func, 12, "func(hi uint32, lo uint32, y uint32) (quo uint32, rem uint32)"},
+		{"Div64", Func, 12, "func(hi uint64, lo uint64, y uint64) (quo uint64, rem uint64)"},
+		{"LeadingZeros", Func, 9, "func(x uint) int"},
+		{"LeadingZeros16", Func, 9, "func(x uint16) int"},
+		{"LeadingZeros32", Func, 9, "func(x uint32) int"},
+		{"LeadingZeros64", Func, 9, "func(x uint64) int"},
+		{"LeadingZeros8", Func, 9, "func(x uint8) int"},
+		{"Len", Func, 9, "func(x uint) int"},
+		{"Len16", Func, 9, "func(x uint16) (n int)"},
+		{"Len32", Func, 9, "func(x uint32) (n int)"},
+		{"Len64", Func, 9, "func(x uint64) (n int)"},
+		{"Len8", Func, 9, "func(x uint8) int"},
+		{"Mul", Func, 12, "func(x uint, y uint) (hi uint, lo uint)"},
+		{"Mul32", Func, 12, "func(x uint32, y uint32) (hi uint32, lo uint32)"},
+		{"Mul64", Func, 12, "func(x uint64, y uint64) (hi uint64, lo uint64)"},
+		{"OnesCount", Func, 9, "func(x uint) int"},
+		{"OnesCount16", Func, 9, "func(x uint16) int"},
+		{"OnesCount32", Func, 9, "func(x uint32) int"},
+		{"OnesCount64", Func, 9, "func(x uint64) int"},
+		{"OnesCount8", Func, 9, "func(x uint8) int"},
+		{"Rem", Func, 14, "func(hi uint, lo uint, y uint) uint"},
+		{"Rem32", Func, 14, "func(hi uint32, lo uint32, y uint32) uint32"},
+		{"Rem64", Func, 14, "func(hi uint64, lo uint64, y uint64) uint64"},
+		{"Reverse", Func, 9, "func(x uint) uint"},
+		{"Reverse16", Func, 9, "func(x uint16) uint16"},
+		{"Reverse32", Func, 9, "func(x uint32) uint32"},
+		{"Reverse64", Func, 9, "func(x uint64) uint64"},
+		{"Reverse8", Func, 9, "func(x uint8) uint8"},
+		{"ReverseBytes", Func, 9, "func(x uint) uint"},
+		{"ReverseBytes16", Func, 9, "func(x uint16) uint16"},
+		{"ReverseBytes32", Func, 9, "func(x uint32) uint32"},
+		{"ReverseBytes64", Func, 9, "func(x uint64) uint64"},
+		{"RotateLeft", Func, 9, "func(x uint, k int) uint"},
+		{"RotateLeft16", Func, 9, "func(x uint16, k int) uint16"},
+		{"RotateLeft32", Func, 9, "func(x uint32, k int) uint32"},
+		{"RotateLeft64", Func, 9, "func(x uint64, k int) uint64"},
+		{"RotateLeft8", Func, 9, "func(x uint8, k int) uint8"},
+		{"Sub", Func, 12, "func(x uint, y uint, borrow uint) (diff uint, borrowOut uint)"},
+		{"Sub32", Func, 12, "func(x uint32, y uint32, borrow uint32) (diff uint32, borrowOut uint32)"},
+		{"Sub64", Func, 12, "func(x uint64, y uint64, borrow uint64) (diff uint64, borrowOut uint64)"},
+		{"TrailingZeros", Func, 9, "func(x uint) int"},
+		{"TrailingZeros16", Func, 9, "func(x uint16) int"},
+		{"TrailingZeros32", Func, 9, "func(x uint32) int"},
+		{"TrailingZeros64", Func, 9, "func(x uint64) int"},
+		{"TrailingZeros8", Func, 9, "func(x uint8) int"},
+		{"UintSize", Const, 9, ""},
+	},
+	"math/cmplx": {
+		{"Abs", Func, 0, "func(x complex128) float64"},
+		{"Acos", Func, 0, "func(x complex128) complex128"},
+		{"Acosh", Func, 0, "func(x complex128) complex128"},
+		{"Asin", Func, 0, "func(x complex128) complex128"},
+		{"Asinh", Func, 0, "func(x complex128) complex128"},
+		{"Atan", Func, 0, "func(x complex128) complex128"},
+		{"Atanh", Func, 0, "func(x complex128) complex128"},
+		{"Conj", Func, 0, "func(x complex128) complex128"},
+		{"Cos", Func, 0, "func(x complex128) complex128"},
+		{"Cosh", Func, 0, "func(x complex128) complex128"},
+		{"Cot", Func, 0, "func(x complex128) complex128"},
+		{"Exp", Func, 0, "func(x complex128) complex128"},
+		{"Inf", Func, 0, "func() complex128"},
+		{"IsInf", Func, 0, "func(x complex128) bool"},
+		{"IsNaN", Func, 0, "func(x complex128) bool"},
+		{"Log", Func, 0, "func(x complex128) complex128"},
+		{"Log10", Func, 0, "func(x complex128) complex128"},
+		{"NaN", Func, 0, "func() complex128"},
+		{"Phase", Func, 0, "func(x complex128) float64"},
+		{"Polar", Func, 0, "func(x complex128) (r float64, θ float64)"},
+		{"Pow", Func, 0, "func(x complex128, y complex128) complex128"},
+		{"Rect", Func, 0, "func(r float64, θ float64) complex128"},
+		{"Sin", Func, 0, "func(x complex128) complex128"},
+		{"Sinh", Func, 0, "func(x complex128) complex128"},
+		{"Sqrt", Func, 0, "func(x complex128) complex128"},
+		{"Tan", Func, 0, "func(x complex128) complex128"},
+		{"Tanh", Func, 0, "func(x complex128) complex128"},
+	},
+	"math/rand": {
+		{"(*Rand).ExpFloat64", Method, 0, ""},
+		{"(*Rand).Float32", Method, 0, ""},
+		{"(*Rand).Float64", Method, 0, ""},
+		{"(*Rand).Int", Method, 0, ""},
+		{"(*Rand).Int31", Method, 0, ""},
+		{"(*Rand).Int31n", Method, 0, ""},
+		{"(*Rand).Int63", Method, 0, ""},
+		{"(*Rand).Int63n", Method, 0, ""},
+		{"(*Rand).Intn", Method, 0, ""},
+		{"(*Rand).NormFloat64", Method, 0, ""},
+		{"(*Rand).Perm", Method, 0, ""},
+		{"(*Rand).Read", Method, 6, ""},
+		{"(*Rand).Seed", Method, 0, ""},
+		{"(*Rand).Shuffle", Method, 10, ""},
+		{"(*Rand).Uint32", Method, 0, ""},
+		{"(*Rand).Uint64", Method, 8, ""},
+		{"(*Zipf).Uint64", Method, 0, ""},
+		{"(Source).Int63", Method, 0, ""},
+		{"(Source).Seed", Method, 0, ""},
+		{"(Source64).Int63", Method, 8, ""},
+		{"(Source64).Seed", Method, 8, ""},
+		{"(Source64).Uint64", Method, 8, ""},
+		{"ExpFloat64", Func, 0, "func() float64"},
+		{"Float32", Func, 0, "func() float32"},
+		{"Float64", Func, 0, "func() float64"},
+		{"Int", Func, 0, "func() int"},
+		{"Int31", Func, 0, "func() int32"},
+		{"Int31n", Func, 0, "func(n int32) int32"},
+		{"Int63", Func, 0, "func() int64"},
+		{"Int63n", Func, 0, "func(n int64) int64"},
+		{"Intn", Func, 0, "func(n int) int"},
+		{"New", Func, 0, "func(src Source) *Rand"},
+		{"NewSource", Func, 0, "func(seed int64) Source"},
+		{"NewZipf", Func, 0, "func(r *Rand, s float64, v float64, imax uint64) *Zipf"},
+		{"NormFloat64", Func, 0, "func() float64"},
+		{"Perm", Func, 0, "func(n int) []int"},
+		{"Rand", Type, 0, ""},
+		{"Read", Func, 6, "func(p []byte) (n int, err error)"},
+		{"Seed", Func, 0, "func(seed int64)"},
+		{"Shuffle", Func, 10, "func(n int, swap func(i int, j int))"},
+		{"Source", Type, 0, ""},
+		{"Source64", Type, 8, ""},
+		{"Uint32", Func, 0, "func() uint32"},
+		{"Uint64", Func, 8, "func() uint64"},
+		{"Zipf", Type, 0, ""},
+	},
+	"math/rand/v2": {
+		{"(*ChaCha8).AppendBinary", Method, 24, ""},
+		{"(*ChaCha8).MarshalBinary", Method, 22, ""},
+		{"(*ChaCha8).Read", Method, 23, ""},
+		{"(*ChaCha8).Seed", Method, 22, ""},
+		{"(*ChaCha8).Uint64", Method, 22, ""},
+		{"(*ChaCha8).UnmarshalBinary", Method, 22, ""},
+		{"(*PCG).AppendBinary", Method, 24, ""},
+		{"(*PCG).MarshalBinary", Method, 22, ""},
+		{"(*PCG).Seed", Method, 22, ""},
+		{"(*PCG).Uint64", Method, 22, ""},
+		{"(*PCG).UnmarshalBinary", Method, 22, ""},
+		{"(*Rand).ExpFloat64", Method, 22, ""},
+		{"(*Rand).Float32", Method, 22, ""},
+		{"(*Rand).Float64", Method, 22, ""},
+		{"(*Rand).Int", Method, 22, ""},
+		{"(*Rand).Int32", Method, 22, ""},
+		{"(*Rand).Int32N", Method, 22, ""},
+		{"(*Rand).Int64", Method, 22, ""},
+		{"(*Rand).Int64N", Method, 22, ""},
+		{"(*Rand).IntN", Method, 22, ""},
+		{"(*Rand).N", Method, 27, ""},
+		{"(*Rand).NormFloat64", Method, 22, ""},
+		{"(*Rand).Perm", Method, 22, ""},
+		{"(*Rand).Shuffle", Method, 22, ""},
+		{"(*Rand).Uint", Method, 23, ""},
+		{"(*Rand).Uint32", Method, 22, ""},
+		{"(*Rand).Uint32N", Method, 22, ""},
+		{"(*Rand).Uint64", Method, 22, ""},
+		{"(*Rand).Uint64N", Method, 22, ""},
+		{"(*Rand).UintN", Method, 22, ""},
+		{"(*Zipf).Uint64", Method, 22, ""},
+		{"(Source).Uint64", Method, 22, ""},
+		{"ChaCha8", Type, 22, ""},
+		{"ExpFloat64", Func, 22, "func() float64"},
+		{"Float32", Func, 22, "func() float32"},
+		{"Float64", Func, 22, "func() float64"},
+		{"Int", Func, 22, "func() int"},
+		{"Int32", Func, 22, "func() int32"},
+		{"Int32N", Func, 22, "func(n int32) int32"},
+		{"Int64", Func, 22, "func() int64"},
+		{"Int64N", Func, 22, "func(n int64) int64"},
+		{"IntN", Func, 22, "func(n int) int"},
+		{"N", Func, 22, "func[Int intType](n Int) Int"},
+		{"New", Func, 22, "func(src Source) *Rand"},
+		{"NewChaCha8", Func, 22, "func(seed [32]byte) *ChaCha8"},
+		{"NewPCG", Func, 22, "func(seed1 uint64, seed2 uint64) *PCG"},
+		{"NewZipf", Func, 22, "func(r *Rand, s float64, v float64, imax uint64) *Zipf"},
+		{"NormFloat64", Func, 22, "func() float64"},
+		{"PCG", Type, 22, ""},
+		{"Perm", Func, 22, "func(n int) []int"},
+		{"Rand", Type, 22, ""},
+		{"Shuffle", Func, 22, "func(n int, swap func(i int, j int))"},
+		{"Source", Type, 22, ""},
+		{"Uint", Func, 23, "func() uint"},
+		{"Uint32", Func, 22, "func() uint32"},
+		{"Uint32N", Func, 22, "func(n uint32) uint32"},
+		{"Uint64", Func, 22, "func() uint64"},
+		{"Uint64N", Func, 22, "func(n uint64) uint64"},
+		{"UintN", Func, 22, "func(n uint) uint"},
+		{"Zipf", Type, 22, ""},
+	},
+	"mime": {
+		{"(*WordDecoder).Decode", Method, 5, ""},
+		{"(*WordDecoder).DecodeHeader", Method, 5, ""},
+		{"(WordEncoder).Encode", Method, 5, ""},
+		{"AddExtensionType", Func, 0, "func(ext string, typ string) error"},
+		{"BEncoding", Const, 5, ""},
+		{"ErrInvalidMediaParameter", Var, 9, ""},
+		{"ExtensionsByType", Func, 5, "func(typ string) ([]string, error)"},
+		{"FormatMediaType", Func, 0, "func(t string, param map[string]string) string"},
+		{"ParseMediaType", Func, 0, "func(v string) (mediatype string, params map[string]string, err error)"},
+		{"QEncoding", Const, 5, ""},
+		{"TypeByExtension", Func, 0, "func(ext string) string"},
+		{"WordDecoder", Type, 5, ""},
+		{"WordDecoder.CharsetReader", Field, 5, ""},
+		{"WordEncoder", Type, 5, ""},
+	},
+	"mime/multipart": {
+		{"(*FileHeader).Open", Method, 0, ""},
+		{"(*Form).RemoveAll", Method, 0, ""},
+		{"(*Part).Close", Method, 0, ""},
+		{"(*Part).FileName", Method, 0, ""},
+		{"(*Part).FormName", Method, 0, ""},
+		{"(*Part).Read", Method, 0, ""},
+		{"(*Reader).NextPart", Method, 0, ""},
+		{"(*Reader).NextRawPart", Method, 14, ""},
+		{"(*Reader).ReadForm", Method, 0, ""},
+		{"(*Writer).Boundary", Method, 0, ""},
+		{"(*Writer).Close", Method, 0, ""},
+		{"(*Writer).CreateFormField", Method, 0, ""},
+		{"(*Writer).CreateFormFile", Method, 0, ""},
+		{"(*Writer).CreatePart", Method, 0, ""},
+		{"(*Writer).FormDataContentType", Method, 0, ""},
+		{"(*Writer).SetBoundary", Method, 1, ""},
+		{"(*Writer).WriteField", Method, 0, ""},
+		{"(File).Close", Method, 0, ""},
+		{"(File).Read", Method, 0, ""},
+		{"(File).ReadAt", Method, 0, ""},
+		{"(File).Seek", Method, 0, ""},
+		{"ErrMessageTooLarge", Var, 9, ""},
+		{"File", Type, 0, ""},
+		{"FileContentDisposition", Func, 25, "func(fieldname string, filename string) string"},
+		{"FileHeader", Type, 0, ""},
+		{"FileHeader.Filename", Field, 0, ""},
+		{"FileHeader.Header", Field, 0, ""},
+		{"FileHeader.Size", Field, 9, ""},
+		{"Form", Type, 0, ""},
+		{"Form.File", Field, 0, ""},
+		{"Form.Value", Field, 0, ""},
+		{"NewReader", Func, 0, "func(r io.Reader, boundary string) *Reader"},
+		{"NewWriter", Func, 0, "func(w io.Writer) *Writer"},
+		{"Part", Type, 0, ""},
+		{"Part.Header", Field, 0, ""},
+		{"Reader", Type, 0, ""},
+		{"Writer", Type, 0, ""},
+	},
+	"mime/quotedprintable": {
+		{"(*Reader).Read", Method, 5, ""},
+		{"(*Writer).Close", Method, 5, ""},
+		{"(*Writer).Write", Method, 5, ""},
+		{"NewReader", Func, 5, "func(r io.Reader) *Reader"},
+		{"NewWriter", Func, 5, "func(w io.Writer) *Writer"},
+		{"Reader", Type, 5, ""},
+		{"Writer", Type, 5, ""},
+		{"Writer.Binary", Field, 5, ""},
+	},
+	"net": {
+		{"(*AddrError).Error", Method, 0, ""},
+		{"(*AddrError).Temporary", Method, 0, ""},
+		{"(*AddrError).Timeout", Method, 0, ""},
+		{"(*Buffers).Read", Method, 8, ""},
+		{"(*Buffers).WriteTo", Method, 8, ""},
+		{"(*DNSConfigError).Error", Method, 0, ""},
+		{"(*DNSConfigError).Temporary", Method, 0, ""},
+		{"(*DNSConfigError).Timeout", Method, 0, ""},
+		{"(*DNSConfigError).Unwrap", Method, 13, ""},
+		{"(*DNSError).Error", Method, 0, ""},
+		{"(*DNSError).Temporary", Method, 0, ""},
+		{"(*DNSError).Timeout", Method, 0, ""},
+		{"(*DNSError).Unwrap", Method, 23, ""},
+		{"(*Dialer).Dial", Method, 1, ""},
+		{"(*Dialer).DialContext", Method, 7, ""},
+		{"(*Dialer).DialIP", Method, 26, ""},
+		{"(*Dialer).DialTCP", Method, 26, ""},
+		{"(*Dialer).DialUDP", Method, 26, ""},
+		{"(*Dialer).DialUnix", Method, 26, ""},
+		{"(*Dialer).MultipathTCP", Method, 21, ""},
+		{"(*Dialer).SetMultipathTCP", Method, 21, ""},
+		{"(*IP).UnmarshalText", Method, 2, ""},
+		{"(*IPAddr).Network", Method, 0, ""},
+		{"(*IPAddr).String", Method, 0, ""},
+		{"(*IPConn).Close", Method, 0, ""},
+		{"(*IPConn).File", Method, 0, ""},
+		{"(*IPConn).LocalAddr", Method, 0, ""},
+		{"(*IPConn).Read", Method, 0, ""},
+		{"(*IPConn).ReadFrom", Method, 0, ""},
+		{"(*IPConn).ReadFromIP", Method, 0, ""},
+		{"(*IPConn).ReadMsgIP", Method, 1, ""},
+		{"(*IPConn).RemoteAddr", Method, 0, ""},
+		{"(*IPConn).SetDeadline", Method, 0, ""},
+		{"(*IPConn).SetReadBuffer", Method, 0, ""},
+		{"(*IPConn).SetReadDeadline", Method, 0, ""},
+		{"(*IPConn).SetWriteBuffer", Method, 0, ""},
+		{"(*IPConn).SetWriteDeadline", Method, 0, ""},
+		{"(*IPConn).SyscallConn", Method, 9, ""},
+		{"(*IPConn).Write", Method, 0, ""},
+		{"(*IPConn).WriteMsgIP", Method, 1, ""},
+		{"(*IPConn).WriteTo", Method, 0, ""},
+		{"(*IPConn).WriteToIP", Method, 0, ""},
+		{"(*IPNet).Contains", Method, 0, ""},
+		{"(*IPNet).Network", Method, 0, ""},
+		{"(*IPNet).String", Method, 0, ""},
+		{"(*Interface).Addrs", Method, 0, ""},
+		{"(*Interface).MulticastAddrs", Method, 0, ""},
+		{"(*ListenConfig).Listen", Method, 11, ""},
+		{"(*ListenConfig).ListenPacket", Method, 11, ""},
+		{"(*ListenConfig).MultipathTCP", Method, 21, ""},
+		{"(*ListenConfig).SetMultipathTCP", Method, 21, ""},
+		{"(*OpError).Error", Method, 0, ""},
+		{"(*OpError).Temporary", Method, 0, ""},
+		{"(*OpError).Timeout", Method, 0, ""},
+		{"(*OpError).Unwrap", Method, 13, ""},
+		{"(*ParseError).Error", Method, 0, ""},
+		{"(*ParseError).Temporary", Method, 17, ""},
+		{"(*ParseError).Timeout", Method, 17, ""},
+		{"(*Resolver).LookupAddr", Method, 8, ""},
+		{"(*Resolver).LookupCNAME", Method, 8, ""},
+		{"(*Resolver).LookupHost", Method, 8, ""},
+		{"(*Resolver).LookupIP", Method, 15, ""},
+		{"(*Resolver).LookupIPAddr", Method, 8, ""},
+		{"(*Resolver).LookupMX", Method, 8, ""},
+		{"(*Resolver).LookupNS", Method, 8, ""},
+		{"(*Resolver).LookupNetIP", Method, 18, ""},
+		{"(*Resolver).LookupPort", Method, 8, ""},
+		{"(*Resolver).LookupSRV", Method, 8, ""},
+		{"(*Resolver).LookupTXT", Method, 8, ""},
+		{"(*TCPAddr).AddrPort", Method, 18, ""},
+		{"(*TCPAddr).Network", Method, 0, ""},
+		{"(*TCPAddr).String", Method, 0, ""},
+		{"(*TCPConn).Close", Method, 0, ""},
+		{"(*TCPConn).CloseRead", Method, 0, ""},
+		{"(*TCPConn).CloseWrite", Method, 0, ""},
+		{"(*TCPConn).File", Method, 0, ""},
+		{"(*TCPConn).LocalAddr", Method, 0, ""},
+		{"(*TCPConn).MultipathTCP", Method, 21, ""},
+		{"(*TCPConn).Read", Method, 0, ""},
+		{"(*TCPConn).ReadFrom", Method, 0, ""},
+		{"(*TCPConn).RemoteAddr", Method, 0, ""},
+		{"(*TCPConn).SetDeadline", Method, 0, ""},
+		{"(*TCPConn).SetKeepAlive", Method, 0, ""},
+		{"(*TCPConn).SetKeepAliveConfig", Method, 23, ""},
+		{"(*TCPConn).SetKeepAlivePeriod", Method, 2, ""},
+		{"(*TCPConn).SetLinger", Method, 0, ""},
+		{"(*TCPConn).SetNoDelay", Method, 0, ""},
+		{"(*TCPConn).SetReadBuffer", Method, 0, ""},
+		{"(*TCPConn).SetReadDeadline", Method, 0, ""},
+		{"(*TCPConn).SetWriteBuffer", Method, 0, ""},
+		{"(*TCPConn).SetWriteDeadline", Method, 0, ""},
+		{"(*TCPConn).SyscallConn", Method, 9, ""},
+		{"(*TCPConn).Write", Method, 0, ""},
+		{"(*TCPConn).WriteTo", Method, 22, ""},
+		{"(*TCPListener).Accept", Method, 0, ""},
+		{"(*TCPListener).AcceptTCP", Method, 0, ""},
+		{"(*TCPListener).Addr", Method, 0, ""},
+		{"(*TCPListener).Close", Method, 0, ""},
+		{"(*TCPListener).File", Method, 0, ""},
+		{"(*TCPListener).SetDeadline", Method, 0, ""},
+		{"(*TCPListener).SyscallConn", Method, 10, ""},
+		{"(*UDPAddr).AddrPort", Method, 18, ""},
+		{"(*UDPAddr).Network", Method, 0, ""},
+		{"(*UDPAddr).String", Method, 0, ""},
+		{"(*UDPConn).Close", Method, 0, ""},
+		{"(*UDPConn).File", Method, 0, ""},
+		{"(*UDPConn).LocalAddr", Method, 0, ""},
+		{"(*UDPConn).Read", Method, 0, ""},
+		{"(*UDPConn).ReadFrom", Method, 0, ""},
+		{"(*UDPConn).ReadFromUDP", Method, 0, ""},
+		{"(*UDPConn).ReadFromUDPAddrPort", Method, 18, ""},
+		{"(*UDPConn).ReadMsgUDP", Method, 1, ""},
+		{"(*UDPConn).ReadMsgUDPAddrPort", Method, 18, ""},
+		{"(*UDPConn).RemoteAddr", Method, 0, ""},
+		{"(*UDPConn).SetDeadline", Method, 0, ""},
+		{"(*UDPConn).SetReadBuffer", Method, 0, ""},
+		{"(*UDPConn).SetReadDeadline", Method, 0, ""},
+		{"(*UDPConn).SetWriteBuffer", Method, 0, ""},
+		{"(*UDPConn).SetWriteDeadline", Method, 0, ""},
+		{"(*UDPConn).SyscallConn", Method, 9, ""},
+		{"(*UDPConn).Write", Method, 0, ""},
+		{"(*UDPConn).WriteMsgUDP", Method, 1, ""},
+		{"(*UDPConn).WriteMsgUDPAddrPort", Method, 18, ""},
+		{"(*UDPConn).WriteTo", Method, 0, ""},
+		{"(*UDPConn).WriteToUDP", Method, 0, ""},
+		{"(*UDPConn).WriteToUDPAddrPort", Method, 18, ""},
+		{"(*UnixAddr).Network", Method, 0, ""},
+		{"(*UnixAddr).String", Method, 0, ""},
+		{"(*UnixConn).Close", Method, 0, ""},
+		{"(*UnixConn).CloseRead", Method, 1, ""},
+		{"(*UnixConn).CloseWrite", Method, 1, ""},
+		{"(*UnixConn).File", Method, 0, ""},
+		{"(*UnixConn).LocalAddr", Method, 0, ""},
+		{"(*UnixConn).Read", Method, 0, ""},
+		{"(*UnixConn).ReadFrom", Method, 0, ""},
+		{"(*UnixConn).ReadFromUnix", Method, 0, ""},
+		{"(*UnixConn).ReadMsgUnix", Method, 0, ""},
+		{"(*UnixConn).RemoteAddr", Method, 0, ""},
+		{"(*UnixConn).SetDeadline", Method, 0, ""},
+		{"(*UnixConn).SetReadBuffer", Method, 0, ""},
+		{"(*UnixConn).SetReadDeadline", Method, 0, ""},
+		{"(*UnixConn).SetWriteBuffer", Method, 0, ""},
+		{"(*UnixConn).SetWriteDeadline", Method, 0, ""},
+		{"(*UnixConn).SyscallConn", Method, 9, ""},
+		{"(*UnixConn).Write", Method, 0, ""},
+		{"(*UnixConn).WriteMsgUnix", Method, 0, ""},
+		{"(*UnixConn).WriteTo", Method, 0, ""},
+		{"(*UnixConn).WriteToUnix", Method, 0, ""},
+		{"(*UnixListener).Accept", Method, 0, ""},
+		{"(*UnixListener).AcceptUnix", Method, 0, ""},
+		{"(*UnixListener).Addr", Method, 0, ""},
+		{"(*UnixListener).Close", Method, 0, ""},
+		{"(*UnixListener).File", Method, 0, ""},
+		{"(*UnixListener).SetDeadline", Method, 0, ""},
+		{"(*UnixListener).SetUnlinkOnClose", Method, 8, ""},
+		{"(*UnixListener).SyscallConn", Method, 10, ""},
+		{"(Addr).Network", Method, 0, ""},
+		{"(Addr).String", Method, 0, ""},
+		{"(Conn).Close", Method, 0, ""},
+		{"(Conn).LocalAddr", Method, 0, ""},
+		{"(Conn).Read", Method, 0, ""},
+		{"(Conn).RemoteAddr", Method, 0, ""},
+		{"(Conn).SetDeadline", Method, 0, ""},
+		{"(Conn).SetReadDeadline", Method, 0, ""},
+		{"(Conn).SetWriteDeadline", Method, 0, ""},
+		{"(Conn).Write", Method, 0, ""},
+		{"(Error).Error", Method, 0, ""},
+		{"(Error).Temporary", Method, 0, ""},
+		{"(Error).Timeout", Method, 0, ""},
+		{"(Flags).String", Method, 0, ""},
+		{"(HardwareAddr).String", Method, 0, ""},
+		{"(IP).AppendText", Method, 24, ""},
+		{"(IP).DefaultMask", Method, 0, ""},
+		{"(IP).Equal", Method, 0, ""},
+		{"(IP).IsGlobalUnicast", Method, 0, ""},
+		{"(IP).IsInterfaceLocalMulticast", Method, 0, ""},
+		{"(IP).IsLinkLocalMulticast", Method, 0, ""},
+		{"(IP).IsLinkLocalUnicast", Method, 0, ""},
+		{"(IP).IsLoopback", Method, 0, ""},
+		{"(IP).IsMulticast", Method, 0, ""},
+		{"(IP).IsPrivate", Method, 17, ""},
+		{"(IP).IsUnspecified", Method, 0, ""},
+		{"(IP).MarshalText", Method, 2, ""},
+		{"(IP).Mask", Method, 0, ""},
+		{"(IP).String", Method, 0, ""},
+		{"(IP).To16", Method, 0, ""},
+		{"(IP).To4", Method, 0, ""},
+		{"(IPMask).Size", Method, 0, ""},
+		{"(IPMask).String", Method, 0, ""},
+		{"(InvalidAddrError).Error", Method, 0, ""},
+		{"(InvalidAddrError).Temporary", Method, 0, ""},
+		{"(InvalidAddrError).Timeout", Method, 0, ""},
+		{"(Listener).Accept", Method, 0, ""},
+		{"(Listener).Addr", Method, 0, ""},
+		{"(Listener).Close", Method, 0, ""},
+		{"(PacketConn).Close", Method, 0, ""},
+		{"(PacketConn).LocalAddr", Method, 0, ""},
+		{"(PacketConn).ReadFrom", Method, 0, ""},
+		{"(PacketConn).SetDeadline", Method, 0, ""},
+		{"(PacketConn).SetReadDeadline", Method, 0, ""},
+		{"(PacketConn).SetWriteDeadline", Method, 0, ""},
+		{"(PacketConn).WriteTo", Method, 0, ""},
+		{"(UnknownNetworkError).Error", Method, 0, ""},
+		{"(UnknownNetworkError).Temporary", Method, 0, ""},
+		{"(UnknownNetworkError).Timeout", Method, 0, ""},
+		{"Addr", Type, 0, ""},
+		{"AddrError", Type, 0, ""},
+		{"AddrError.Addr", Field, 0, ""},
+		{"AddrError.Err", Field, 0, ""},
+		{"Buffers", Type, 8, ""},
+		{"CIDRMask", Func, 0, "func(ones int, bits int) IPMask"},
+		{"Conn", Type, 0, ""},
+		{"DNSConfigError", Type, 0, ""},
+		{"DNSConfigError.Err", Field, 0, ""},
+		{"DNSError", Type, 0, ""},
+		{"DNSError.Err", Field, 0, ""},
+		{"DNSError.IsNotFound", Field, 13, ""},
+		{"DNSError.IsTemporary", Field, 6, ""},
+		{"DNSError.IsTimeout", Field, 0, ""},
+		{"DNSError.Name", Field, 0, ""},
+		{"DNSError.Server", Field, 0, ""},
+		{"DNSError.UnwrapErr", Field, 23, ""},
+		{"DefaultResolver", Var, 8, ""},
+		{"Dial", Func, 0, "func(network string, address string) (Conn, error)"},
+		{"DialIP", Func, 0, "func(network string, laddr *IPAddr, raddr *IPAddr) (*IPConn, error)"},
+		{"DialTCP", Func, 0, "func(network string, laddr *TCPAddr, raddr *TCPAddr) (*TCPConn, error)"},
+		{"DialTimeout", Func, 0, "func(network string, address string, timeout time.Duration) (Conn, error)"},
+		{"DialUDP", Func, 0, "func(network string, laddr *UDPAddr, raddr *UDPAddr) (*UDPConn, error)"},
+		{"DialUnix", Func, 0, "func(network string, laddr *UnixAddr, raddr *UnixAddr) (*UnixConn, error)"},
+		{"Dialer", Type, 1, ""},
+		{"Dialer.Cancel", Field, 6, ""},
+		{"Dialer.Control", Field, 11, ""},
+		{"Dialer.ControlContext", Field, 20, ""},
+		{"Dialer.Deadline", Field, 1, ""},
+		{"Dialer.DualStack", Field, 2, ""},
+		{"Dialer.FallbackDelay", Field, 5, ""},
+		{"Dialer.KeepAlive", Field, 3, ""},
+		{"Dialer.KeepAliveConfig", Field, 23, ""},
+		{"Dialer.LocalAddr", Field, 1, ""},
+		{"Dialer.Resolver", Field, 8, ""},
+		{"Dialer.Timeout", Field, 1, ""},
+		{"ErrClosed", Var, 16, ""},
+		{"ErrWriteToConnected", Var, 0, ""},
+		{"Error", Type, 0, ""},
+		{"FileConn", Func, 0, "func(f *os.File) (c Conn, err error)"},
+		{"FileListener", Func, 0, "func(f *os.File) (ln Listener, err error)"},
+		{"FilePacketConn", Func, 0, "func(f *os.File) (c PacketConn, err error)"},
+		{"FlagBroadcast", Const, 0, ""},
+		{"FlagLoopback", Const, 0, ""},
+		{"FlagMulticast", Const, 0, ""},
+		{"FlagPointToPoint", Const, 0, ""},
+		{"FlagRunning", Const, 20, ""},
+		{"FlagUp", Const, 0, ""},
+		{"Flags", Type, 0, ""},
+		{"HardwareAddr", Type, 0, ""},
+		{"IP", Type, 0, ""},
+		{"IPAddr", Type, 0, ""},
+		{"IPAddr.IP", Field, 0, ""},
+		{"IPAddr.Zone", Field, 1, ""},
+		{"IPConn", Type, 0, ""},
+		{"IPMask", Type, 0, ""},
+		{"IPNet", Type, 0, ""},
+		{"IPNet.IP", Field, 0, ""},
+		{"IPNet.Mask", Field, 0, ""},
+		{"IPv4", Func, 0, "func(a byte, b byte, c byte, d byte) IP"},
+		{"IPv4Mask", Func, 0, "func(a byte, b byte, c byte, d byte) IPMask"},
+		{"IPv4allrouter", Var, 0, ""},
+		{"IPv4allsys", Var, 0, ""},
+		{"IPv4bcast", Var, 0, ""},
+		{"IPv4len", Const, 0, ""},
+		{"IPv4zero", Var, 0, ""},
+		{"IPv6interfacelocalallnodes", Var, 0, ""},
+		{"IPv6len", Const, 0, ""},
+		{"IPv6linklocalallnodes", Var, 0, ""},
+		{"IPv6linklocalallrouters", Var, 0, ""},
+		{"IPv6loopback", Var, 0, ""},
+		{"IPv6unspecified", Var, 0, ""},
+		{"IPv6zero", Var, 0, ""},
+		{"Interface", Type, 0, ""},
+		{"Interface.Flags", Field, 0, ""},
+		{"Interface.HardwareAddr", Field, 0, ""},
+		{"Interface.Index", Field, 0, ""},
+		{"Interface.MTU", Field, 0, ""},
+		{"Interface.Name", Field, 0, ""},
+		{"InterfaceAddrs", Func, 0, "func() ([]Addr, error)"},
+		{"InterfaceByIndex", Func, 0, "func(index int) (*Interface, error)"},
+		{"InterfaceByName", Func, 0, "func(name string) (*Interface, error)"},
+		{"Interfaces", Func, 0, "func() ([]Interface, error)"},
+		{"InvalidAddrError", Type, 0, ""},
+		{"JoinHostPort", Func, 0, "func(host string, port string) string"},
+		{"KeepAliveConfig", Type, 23, ""},
+		{"KeepAliveConfig.Count", Field, 23, ""},
+		{"KeepAliveConfig.Enable", Field, 23, ""},
+		{"KeepAliveConfig.Idle", Field, 23, ""},
+		{"KeepAliveConfig.Interval", Field, 23, ""},
+		{"Listen", Func, 0, "func(network string, address string) (Listener, error)"},
+		{"ListenConfig", Type, 11, ""},
+		{"ListenConfig.Control", Field, 11, ""},
+		{"ListenConfig.KeepAlive", Field, 13, ""},
+		{"ListenConfig.KeepAliveConfig", Field, 23, ""},
+		{"ListenIP", Func, 0, "func(network string, laddr *IPAddr) (*IPConn, error)"},
+		{"ListenMulticastUDP", Func, 0, "func(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error)"},
+		{"ListenPacket", Func, 0, "func(network string, address string) (PacketConn, error)"},
+		{"ListenTCP", Func, 0, "func(network string, laddr *TCPAddr) (*TCPListener, error)"},
+		{"ListenUDP", Func, 0, "func(network string, laddr *UDPAddr) (*UDPConn, error)"},
+		{"ListenUnix", Func, 0, "func(network string, laddr *UnixAddr) (*UnixListener, error)"},
+		{"ListenUnixgram", Func, 0, "func(network string, laddr *UnixAddr) (*UnixConn, error)"},
+		{"Listener", Type, 0, ""},
+		{"LookupAddr", Func, 0, "func(addr string) (names []string, err error)"},
+		{"LookupCNAME", Func, 0, "func(host string) (cname string, err error)"},
+		{"LookupHost", Func, 0, "func(host string) (addrs []string, err error)"},
+		{"LookupIP", Func, 0, "func(host string) ([]IP, error)"},
+		{"LookupMX", Func, 0, "func(name string) ([]*MX, error)"},
+		{"LookupNS", Func, 1, "func(name string) ([]*NS, error)"},
+		{"LookupPort", Func, 0, "func(network string, service string) (port int, err error)"},
+		{"LookupSRV", Func, 0, "func(service string, proto string, name string) (cname string, addrs []*SRV, err error)"},
+		{"LookupTXT", Func, 0, "func(name string) ([]string, error)"},
+		{"MX", Type, 0, ""},
+		{"MX.Host", Field, 0, ""},
+		{"MX.Pref", Field, 0, ""},
+		{"NS", Type, 1, ""},
+		{"NS.Host", Field, 1, ""},
+		{"OpError", Type, 0, ""},
+		{"OpError.Addr", Field, 0, ""},
+		{"OpError.Err", Field, 0, ""},
+		{"OpError.Net", Field, 0, ""},
+		{"OpError.Op", Field, 0, ""},
+		{"OpError.Source", Field, 5, ""},
+		{"PacketConn", Type, 0, ""},
+		{"ParseCIDR", Func, 0, "func(s string) (IP, *IPNet, error)"},
+		{"ParseError", Type, 0, ""},
+		{"ParseError.Text", Field, 0, ""},
+		{"ParseError.Type", Field, 0, ""},
+		{"ParseIP", Func, 0, "func(s string) IP"},
+		{"ParseMAC", Func, 0, "func(s string) (hw HardwareAddr, err error)"},
+		{"Pipe", Func, 0, "func() (Conn, Conn)"},
+		{"ResolveIPAddr", Func, 0, "func(network string, address string) (*IPAddr, error)"},
+		{"ResolveTCPAddr", Func, 0, "func(network string, address string) (*TCPAddr, error)"},
+		{"ResolveUDPAddr", Func, 0, "func(network string, address string) (*UDPAddr, error)"},
+		{"ResolveUnixAddr", Func, 0, "func(network string, address string) (*UnixAddr, error)"},
+		{"Resolver", Type, 8, ""},
+		{"Resolver.Dial", Field, 9, ""},
+		{"Resolver.PreferGo", Field, 8, ""},
+		{"Resolver.StrictErrors", Field, 9, ""},
+		{"SRV", Type, 0, ""},
+		{"SRV.Port", Field, 0, ""},
+		{"SRV.Priority", Field, 0, ""},
+		{"SRV.Target", Field, 0, ""},
+		{"SRV.Weight", Field, 0, ""},
+		{"SplitHostPort", Func, 0, "func(hostport string) (host string, port string, err error)"},
+		{"TCPAddr", Type, 0, ""},
+		{"TCPAddr.IP", Field, 0, ""},
+		{"TCPAddr.Port", Field, 0, ""},
+		{"TCPAddr.Zone", Field, 1, ""},
+		{"TCPAddrFromAddrPort", Func, 18, "func(addr netip.AddrPort) *TCPAddr"},
+		{"TCPConn", Type, 0, ""},
+		{"TCPListener", Type, 0, ""},
+		{"UDPAddr", Type, 0, ""},
+		{"UDPAddr.IP", Field, 0, ""},
+		{"UDPAddr.Port", Field, 0, ""},
+		{"UDPAddr.Zone", Field, 1, ""},
+		{"UDPAddrFromAddrPort", Func, 18, "func(addr netip.AddrPort) *UDPAddr"},
+		{"UDPConn", Type, 0, ""},
+		{"UnixAddr", Type, 0, ""},
+		{"UnixAddr.Name", Field, 0, ""},
+		{"UnixAddr.Net", Field, 0, ""},
+		{"UnixConn", Type, 0, ""},
+		{"UnixListener", Type, 0, ""},
+		{"UnknownNetworkError", Type, 0, ""},
+	},
+	"net/http": {
+		{"(*Client).CloseIdleConnections", Method, 12, ""},
+		{"(*Client).Do", Method, 0, ""},
+		{"(*Client).Get", Method, 0, ""},
+		{"(*Client).Head", Method, 0, ""},
+		{"(*Client).Post", Method, 0, ""},
+		{"(*Client).PostForm", Method, 0, ""},
+		{"(*ClientConn).Available", Method, 26, ""},
+		{"(*ClientConn).Close", Method, 26, ""},
+		{"(*ClientConn).Err", Method, 26, ""},
+		{"(*ClientConn).InFlight", Method, 26, ""},
+		{"(*ClientConn).Release", Method, 26, ""},
+		{"(*ClientConn).Reserve", Method, 26, ""},
+		{"(*ClientConn).RoundTrip", Method, 26, ""},
+		{"(*ClientConn).SetStateHook", Method, 26, ""},
+		{"(*Cookie).String", Method, 0, ""},
+		{"(*Cookie).Valid", Method, 18, ""},
+		{"(*CrossOriginProtection).AddInsecureBypassPattern", Method, 25, ""},
+		{"(*CrossOriginProtection).AddTrustedOrigin", Method, 25, ""},
+		{"(*CrossOriginProtection).Check", Method, 25, ""},
+		{"(*CrossOriginProtection).Handler", Method, 25, ""},
+		{"(*CrossOriginProtection).SetDenyHandler", Method, 25, ""},
+		{"(*MaxBytesError).Error", Method, 19, ""},
+		{"(*ProtocolError).Error", Method, 0, ""},
+		{"(*ProtocolError).Is", Method, 21, ""},
+		{"(*Protocols).SetHTTP1", Method, 24, ""},
+		{"(*Protocols).SetHTTP2", Method, 24, ""},
+		{"(*Protocols).SetUnencryptedHTTP2", Method, 24, ""},
+		{"(*Request).AddCookie", Method, 0, ""},
+		{"(*Request).BasicAuth", Method, 4, ""},
+		{"(*Request).Clone", Method, 13, ""},
+		{"(*Request).Context", Method, 7, ""},
+		{"(*Request).Cookie", Method, 0, ""},
+		{"(*Request).Cookies", Method, 0, ""},
+		{"(*Request).CookiesNamed", Method, 23, ""},
+		{"(*Request).FormFile", Method, 0, ""},
+		{"(*Request).FormValue", Method, 0, ""},
+		{"(*Request).MultipartReader", Method, 0, ""},
+		{"(*Request).ParseForm", Method, 0, ""},
+		{"(*Request).ParseMultipartForm", Method, 0, ""},
+		{"(*Request).PathValue", Method, 22, ""},
+		{"(*Request).PostFormValue", Method, 1, ""},
+		{"(*Request).ProtoAtLeast", Method, 0, ""},
+		{"(*Request).Referer", Method, 0, ""},
+		{"(*Request).SetBasicAuth", Method, 0, ""},
+		{"(*Request).SetPathValue", Method, 22, ""},
+		{"(*Request).UserAgent", Method, 0, ""},
+		{"(*Request).WithContext", Method, 7, ""},
+		{"(*Request).Write", Method, 0, ""},
+		{"(*Request).WriteProxy", Method, 0, ""},
+		{"(*Response).Cookies", Method, 0, ""},
+		{"(*Response).Location", Method, 0, ""},
+		{"(*Response).ProtoAtLeast", Method, 0, ""},
+		{"(*Response).Write", Method, 0, ""},
+		{"(*ResponseController).EnableFullDuplex", Method, 21, ""},
+		{"(*ResponseController).Flush", Method, 20, ""},
+		{"(*ResponseController).Hijack", Method, 20, ""},
+		{"(*ResponseController).SetReadDeadline", Method, 20, ""},
+		{"(*ResponseController).SetWriteDeadline", Method, 20, ""},
+		{"(*ServeMux).Handle", Method, 0, ""},
+		{"(*ServeMux).HandleFunc", Method, 0, ""},
+		{"(*ServeMux).Handler", Method, 1, ""},
+		{"(*ServeMux).ServeHTTP", Method, 0, ""},
+		{"(*Server).Close", Method, 8, ""},
+		{"(*Server).ListenAndServe", Method, 0, ""},
+		{"(*Server).ListenAndServeTLS", Method, 0, ""},
+		{"(*Server).RegisterOnShutdown", Method, 9, ""},
+		{"(*Server).Serve", Method, 0, ""},
+		{"(*Server).ServeTLS", Method, 9, ""},
+		{"(*Server).SetKeepAlivesEnabled", Method, 3, ""},
+		{"(*Server).Shutdown", Method, 8, ""},
+		{"(*Transport).CancelRequest", Method, 1, ""},
+		{"(*Transport).Clone", Method, 13, ""},
+		{"(*Transport).CloseIdleConnections", Method, 0, ""},
+		{"(*Transport).NewClientConn", Method, 26, ""},
+		{"(*Transport).RegisterProtocol", Method, 0, ""},
+		{"(*Transport).RoundTrip", Method, 0, ""},
+		{"(CloseNotifier).CloseNotify", Method, 1, ""},
+		{"(ConnState).String", Method, 3, ""},
+		{"(CookieJar).Cookies", Method, 0, ""},
+		{"(CookieJar).SetCookies", Method, 0, ""},
+		{"(Dir).Open", Method, 0, ""},
+		{"(File).Close", Method, 0, ""},
+		{"(File).Read", Method, 0, ""},
+		{"(File).Readdir", Method, 0, ""},
+		{"(File).Seek", Method, 0, ""},
+		{"(File).Stat", Method, 0, ""},
+		{"(FileSystem).Open", Method, 0, ""},
+		{"(Flusher).Flush", Method, 0, ""},
+		{"(Handler).ServeHTTP", Method, 0, ""},
+		{"(HandlerFunc).ServeHTTP", Method, 0, ""},
+		{"(Header).Add", Method, 0, ""},
+		{"(Header).Clone", Method, 13, ""},
+		{"(Header).Del", Method, 0, ""},
+		{"(Header).Get", Method, 0, ""},
+		{"(Header).Set", Method, 0, ""},
+		{"(Header).Values", Method, 14, ""},
+		{"(Header).Write", Method, 0, ""},
+		{"(Header).WriteSubset", Method, 0, ""},
+		{"(Hijacker).Hijack", Method, 0, ""},
+		{"(Protocols).HTTP1", Method, 24, ""},
+		{"(Protocols).HTTP2", Method, 24, ""},
+		{"(Protocols).String", Method, 24, ""},
+		{"(Protocols).UnencryptedHTTP2", Method, 24, ""},
+		{"(Pusher).Push", Method, 8, ""},
+		{"(ResponseWriter).Header", Method, 0, ""},
+		{"(ResponseWriter).Write", Method, 0, ""},
+		{"(ResponseWriter).WriteHeader", Method, 0, ""},
+		{"(RoundTripper).RoundTrip", Method, 0, ""},
+		{"AllowQuerySemicolons", Func, 17, "func(h Handler) Handler"},
+		{"CanonicalHeaderKey", Func, 0, "func(s string) string"},
+		{"Client", Type, 0, ""},
+		{"Client.CheckRedirect", Field, 0, ""},
+		{"Client.Jar", Field, 0, ""},
+		{"Client.Timeout", Field, 3, ""},
+		{"Client.Transport", Field, 0, ""},
+		{"ClientConn", Type, 26, ""},
+		{"CloseNotifier", Type, 1, ""},
+		{"ConnState", Type, 3, ""},
+		{"Cookie", Type, 0, ""},
+		{"Cookie.Domain", Field, 0, ""},
+		{"Cookie.Expires", Field, 0, ""},
+		{"Cookie.HttpOnly", Field, 0, ""},
+		{"Cookie.MaxAge", Field, 0, ""},
+		{"Cookie.Name", Field, 0, ""},
+		{"Cookie.Partitioned", Field, 23, ""},
+		{"Cookie.Path", Field, 0, ""},
+		{"Cookie.Quoted", Field, 23, ""},
+		{"Cookie.Raw", Field, 0, ""},
+		{"Cookie.RawExpires", Field, 0, ""},
+		{"Cookie.SameSite", Field, 11, ""},
+		{"Cookie.Secure", Field, 0, ""},
+		{"Cookie.Unparsed", Field, 0, ""},
+		{"Cookie.Value", Field, 0, ""},
+		{"CookieJar", Type, 0, ""},
+		{"CrossOriginProtection", Type, 25, ""},
+		{"DefaultClient", Var, 0, ""},
+		{"DefaultMaxHeaderBytes", Const, 0, ""},
+		{"DefaultMaxHeaderValueCount", Const, 27, ""},
+		{"DefaultMaxIdleConnsPerHost", Const, 0, ""},
+		{"DefaultServeMux", Var, 0, ""},
+		{"DefaultTransport", Var, 0, ""},
+		{"DetectContentType", Func, 0, "func(data []byte) string"},
+		{"Dir", Type, 0, ""},
+		{"ErrAbortHandler", Var, 8, ""},
+		{"ErrBodyNotAllowed", Var, 0, ""},
+		{"ErrBodyReadAfterClose", Var, 0, ""},
+		{"ErrContentLength", Var, 0, ""},
+		{"ErrHandlerTimeout", Var, 0, ""},
+		{"ErrHeaderTooLong", Var, 0, ""},
+		{"ErrHijacked", Var, 0, ""},
+		{"ErrLineTooLong", Var, 0, ""},
+		{"ErrMissingBoundary", Var, 0, ""},
+		{"ErrMissingContentLength", Var, 0, ""},
+		{"ErrMissingFile", Var, 0, ""},
+		{"ErrNoCookie", Var, 0, ""},
+		{"ErrNoLocation", Var, 0, ""},
+		{"ErrNotMultipart", Var, 0, ""},
+		{"ErrNotSupported", Var, 0, ""},
+		{"ErrSchemeMismatch", Var, 21, ""},
+		{"ErrServerClosed", Var, 8, ""},
+		{"ErrShortBody", Var, 0, ""},
+		{"ErrSkipAltProtocol", Var, 6, ""},
+		{"ErrUnexpectedTrailer", Var, 0, ""},
+		{"ErrUseLastResponse", Var, 7, ""},
+		{"ErrWriteAfterFlush", Var, 0, ""},
+		{"Error", Func, 0, "func(w ResponseWriter, error string, code int)"},
+		{"FS", Func, 16, "func(fsys fs.FS) FileSystem"},
+		{"File", Type, 0, ""},
+		{"FileServer", Func, 0, "func(root FileSystem) Handler"},
+		{"FileServerFS", Func, 22, "func(root fs.FS) Handler"},
+		{"FileSystem", Type, 0, ""},
+		{"Flusher", Type, 0, ""},
+		{"Get", Func, 0, "func(url string) (resp *Response, err error)"},
+		{"HTTP2Config", Type, 24, ""},
+		{"HTTP2Config.CountError", Field, 24, ""},
+		{"HTTP2Config.MaxConcurrentStreams", Field, 24, ""},
+		{"HTTP2Config.MaxDecoderHeaderTableSize", Field, 24, ""},
+		{"HTTP2Config.MaxEncoderHeaderTableSize", Field, 24, ""},
+		{"HTTP2Config.MaxReadFrameSize", Field, 24, ""},
+		{"HTTP2Config.MaxReceiveBufferPerConnection", Field, 24, ""},
+		{"HTTP2Config.MaxReceiveBufferPerStream", Field, 24, ""},
+		{"HTTP2Config.PermitProhibitedCipherSuites", Field, 24, ""},
+		{"HTTP2Config.PingTimeout", Field, 24, ""},
+		{"HTTP2Config.SendPingTimeout", Field, 24, ""},
+		{"HTTP2Config.StrictMaxConcurrentRequests", Field, 26, ""},
+		{"HTTP2Config.WriteByteTimeout", Field, 24, ""},
+		{"Handle", Func, 0, "func(pattern string, handler Handler)"},
+		{"HandleFunc", Func, 0, "func(pattern string, handler func(ResponseWriter, *Request))"},
+		{"Handler", Type, 0, ""},
+		{"HandlerFunc", Type, 0, ""},
+		{"Head", Func, 0, "func(url string) (resp *Response, err error)"},
+		{"Header", Type, 0, ""},
+		{"Hijacker", Type, 0, ""},
+		{"ListenAndServe", Func, 0, "func(addr string, handler Handler) error"},
+		{"ListenAndServeTLS", Func, 0, "func(addr string, certFile string, keyFile string, handler Handler) error"},
+		{"LocalAddrContextKey", Var, 7, ""},
+		{"MaxBytesError", Type, 19, ""},
+		{"MaxBytesError.Limit", Field, 19, ""},
+		{"MaxBytesHandler", Func, 18, "func(h Handler, n int64) Handler"},
+		{"MaxBytesReader", Func, 0, "func(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser"},
+		{"MethodConnect", Const, 6, ""},
+		{"MethodDelete", Const, 6, ""},
+		{"MethodGet", Const, 6, ""},
+		{"MethodHead", Const, 6, ""},
+		{"MethodOptions", Const, 6, ""},
+		{"MethodPatch", Const, 6, ""},
+		{"MethodPost", Const, 6, ""},
+		{"MethodPut", Const, 6, ""},
+		{"MethodTrace", Const, 6, ""},
+		{"NewCrossOriginProtection", Func, 25, "func() *CrossOriginProtection"},
+		{"NewFileTransport", Func, 0, "func(fs FileSystem) RoundTripper"},
+		{"NewFileTransportFS", Func, 22, "func(fsys fs.FS) RoundTripper"},
+		{"NewRequest", Func, 0, "func(method string, url string, body io.Reader) (*Request, error)"},
+		{"NewRequestWithContext", Func, 13, "func(ctx context.Context, method string, url string, body io.Reader) (*Request, error)"},
+		{"NewResponseController", Func, 20, "func(rw ResponseWriter) *ResponseController"},
+		{"NewServeMux", Func, 0, "func() *ServeMux"},
+		{"NoBody", Var, 8, ""},
+		{"NotFound", Func, 0, "func(w ResponseWriter, r *Request)"},
+		{"NotFoundHandler", Func, 0, "func() Handler"},
+		{"ParseCookie", Func, 23, "func(line string) (#rv1 []*Cookie, #rv2 error)"},
+		{"ParseHTTPVersion", Func, 0, "func(vers string) (major int, minor int, ok bool)"},
+		{"ParseSetCookie", Func, 23, "func(line string) (*Cookie, error)"},
+		{"ParseTime", Func, 1, "func(text string) (t time.Time, err error)"},
+		{"Post", Func, 0, "func(url string, contentType string, body io.Reader) (resp *Response, err error)"},
+		{"PostForm", Func, 0, "func(url string, data url.Values) (resp *Response, err error)"},
+		{"ProtocolError", Type, 0, ""},
+		{"ProtocolError.ErrorString", Field, 0, ""},
+		{"Protocols", Type, 24, ""},
+		{"ProxyFromEnvironment", Func, 0, "func(req *Request) (*url.URL, error)"},
+		{"ProxyURL", Func, 0, "func(fixedURL *url.URL) func(*Request) (*url.URL, error)"},
+		{"PushOptions", Type, 8, ""},
+		{"PushOptions.Header", Field, 8, ""},
+		{"PushOptions.Method", Field, 8, ""},
+		{"Pusher", Type, 8, ""},
+		{"ReadRequest", Func, 0, "func(b *bufio.Reader) (*Request, error)"},
+		{"ReadResponse", Func, 0, "func(r *bufio.Reader, req *Request) (*Response, error)"},
+		{"Redirect", Func, 0, "func(w ResponseWriter, r *Request, url string, code int)"},
+		{"RedirectHandler", Func, 0, "func(url string, code int) Handler"},
+		{"Request", Type, 0, ""},
+		{"Request.Body", Field, 0, ""},
+		{"Request.Cancel", Field, 5, ""},
+		{"Request.Close", Field, 0, ""},
+		{"Request.ContentLength", Field, 0, ""},
+		{"Request.Form", Field, 0, ""},
+		{"Request.GetBody", Field, 8, ""},
+		{"Request.Header", Field, 0, ""},
+		{"Request.Host", Field, 0, ""},
+		{"Request.Method", Field, 0, ""},
+		{"Request.MultipartForm", Field, 0, ""},
+		{"Request.Pattern", Field, 23, ""},
+		{"Request.PostForm", Field, 1, ""},
+		{"Request.Proto", Field, 0, ""},
+		{"Request.ProtoMajor", Field, 0, ""},
+		{"Request.ProtoMinor", Field, 0, ""},
+		{"Request.RemoteAddr", Field, 0, ""},
+		{"Request.RequestURI", Field, 0, ""},
+		{"Request.Response", Field, 7, ""},
+		{"Request.TLS", Field, 0, ""},
+		{"Request.Trailer", Field, 0, ""},
+		{"Request.TransferEncoding", Field, 0, ""},
+		{"Request.URL", Field, 0, ""},
+		{"Response", Type, 0, ""},
+		{"Response.Body", Field, 0, ""},
+		{"Response.Close", Field, 0, ""},
+		{"Response.ContentLength", Field, 0, ""},
+		{"Response.Header", Field, 0, ""},
+		{"Response.Proto", Field, 0, ""},
+		{"Response.ProtoMajor", Field, 0, ""},
+		{"Response.ProtoMinor", Field, 0, ""},
+		{"Response.Request", Field, 0, ""},
+		{"Response.Status", Field, 0, ""},
+		{"Response.StatusCode", Field, 0, ""},
+		{"Response.TLS", Field, 3, ""},
+		{"Response.Trailer", Field, 0, ""},
+		{"Response.TransferEncoding", Field, 0, ""},
+		{"Response.Uncompressed", Field, 7, ""},
+		{"ResponseController", Type, 20, ""},
+		{"ResponseWriter", Type, 0, ""},
+		{"RoundTripper", Type, 0, ""},
+		{"SameSite", Type, 11, ""},
+		{"SameSiteDefaultMode", Const, 11, ""},
+		{"SameSiteLaxMode", Const, 11, ""},
+		{"SameSiteNoneMode", Const, 13, ""},
+		{"SameSiteStrictMode", Const, 11, ""},
+		{"Serve", Func, 0, "func(l net.Listener, handler Handler) error"},
+		{"ServeContent", Func, 0, "func(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker)"},
+		{"ServeFile", Func, 0, "func(w ResponseWriter, r *Request, name string)"},
+		{"ServeFileFS", Func, 22, "func(w ResponseWriter, r *Request, fsys fs.FS, name string)"},
+		{"ServeMux", Type, 0, ""},
+		{"ServeTLS", Func, 9, "func(l net.Listener, handler Handler, certFile string, keyFile string) error"},
+		{"Server", Type, 0, ""},
+		{"Server.Addr", Field, 0, ""},
+		{"Server.BaseContext", Field, 13, ""},
+		{"Server.ConnContext", Field, 13, ""},
+		{"Server.ConnState", Field, 3, ""},
+		{"Server.DisableClientPriority", Field, 27, ""},
+		{"Server.DisableGeneralOptionsHandler", Field, 20, ""},
+		{"Server.ErrorLog", Field, 3, ""},
+		{"Server.HTTP2", Field, 24, ""},
+		{"Server.Handler", Field, 0, ""},
+		{"Server.IdleTimeout", Field, 8, ""},
+		{"Server.MaxHeaderBytes", Field, 0, ""},
+		{"Server.MaxHeaderValueCount", Field, 27, ""},
+		{"Server.Protocols", Field, 24, ""},
+		{"Server.ReadHeaderTimeout", Field, 8, ""},
+		{"Server.ReadTimeout", Field, 0, ""},
+		{"Server.TLSConfig", Field, 0, ""},
+		{"Server.TLSNextProto", Field, 1, ""},
+		{"Server.WriteTimeout", Field, 0, ""},
+		{"ServerContextKey", Var, 7, ""},
+		{"SetCookie", Func, 0, "func(w ResponseWriter, cookie *Cookie)"},
+		{"StateActive", Const, 3, ""},
+		{"StateClosed", Const, 3, ""},
+		{"StateHijacked", Const, 3, ""},
+		{"StateIdle", Const, 3, ""},
+		{"StateNew", Const, 3, ""},
+		{"StatusAccepted", Const, 0, ""},
+		{"StatusAlreadyReported", Const, 7, ""},
+		{"StatusBadGateway", Const, 0, ""},
+		{"StatusBadRequest", Const, 0, ""},
+		{"StatusConflict", Const, 0, ""},
+		{"StatusContinue", Const, 0, ""},
+		{"StatusCreated", Const, 0, ""},
+		{"StatusEarlyHints", Const, 13, ""},
+		{"StatusExpectationFailed", Const, 0, ""},
+		{"StatusFailedDependency", Const, 7, ""},
+		{"StatusForbidden", Const, 0, ""},
+		{"StatusFound", Const, 0, ""},
+		{"StatusGatewayTimeout", Const, 0, ""},
+		{"StatusGone", Const, 0, ""},
+		{"StatusHTTPVersionNotSupported", Const, 0, ""},
+		{"StatusIMUsed", Const, 7, ""},
+		{"StatusInsufficientStorage", Const, 7, ""},
+		{"StatusInternalServerError", Const, 0, ""},
+		{"StatusLengthRequired", Const, 0, ""},
+		{"StatusLocked", Const, 7, ""},
+		{"StatusLoopDetected", Const, 7, ""},
+		{"StatusMethodNotAllowed", Const, 0, ""},
+		{"StatusMisdirectedRequest", Const, 11, ""},
+		{"StatusMovedPermanently", Const, 0, ""},
+		{"StatusMultiStatus", Const, 7, ""},
+		{"StatusMultipleChoices", Const, 0, ""},
+		{"StatusNetworkAuthenticationRequired", Const, 6, ""},
+		{"StatusNoContent", Const, 0, ""},
+		{"StatusNonAuthoritativeInfo", Const, 0, ""},
+		{"StatusNotAcceptable", Const, 0, ""},
+		{"StatusNotExtended", Const, 7, ""},
+		{"StatusNotFound", Const, 0, ""},
+		{"StatusNotImplemented", Const, 0, ""},
+		{"StatusNotModified", Const, 0, ""},
+		{"StatusOK", Const, 0, ""},
+		{"StatusPartialContent", Const, 0, ""},
+		{"StatusPaymentRequired", Const, 0, ""},
+		{"StatusPermanentRedirect", Const, 7, ""},
+		{"StatusPreconditionFailed", Const, 0, ""},
+		{"StatusPreconditionRequired", Const, 6, ""},
+		{"StatusProcessing", Const, 7, ""},
+		{"StatusProxyAuthRequired", Const, 0, ""},
+		{"StatusRequestEntityTooLarge", Const, 0, ""},
+		{"StatusRequestHeaderFieldsTooLarge", Const, 6, ""},
+		{"StatusRequestTimeout", Const, 0, ""},
+		{"StatusRequestURITooLong", Const, 0, ""},
+		{"StatusRequestedRangeNotSatisfiable", Const, 0, ""},
+		{"StatusResetContent", Const, 0, ""},
+		{"StatusSeeOther", Const, 0, ""},
+		{"StatusServiceUnavailable", Const, 0, ""},
+		{"StatusSwitchingProtocols", Const, 0, ""},
+		{"StatusTeapot", Const, 0, ""},
+		{"StatusTemporaryRedirect", Const, 0, ""},
+		{"StatusText", Func, 0, "func(code int) string"},
+		{"StatusTooEarly", Const, 12, ""},
+		{"StatusTooManyRequests", Const, 6, ""},
+		{"StatusUnauthorized", Const, 0, ""},
+		{"StatusUnavailableForLegalReasons", Const, 6, ""},
+		{"StatusUnprocessableEntity", Const, 7, ""},
+		{"StatusUnsupportedMediaType", Const, 0, ""},
+		{"StatusUpgradeRequired", Const, 7, ""},
+		{"StatusUseProxy", Const, 0, ""},
+		{"StatusVariantAlsoNegotiates", Const, 7, ""},
+		{"StripPrefix", Func, 0, "func(prefix string, h Handler) Handler"},
+		{"TimeFormat", Const, 0, ""},
+		{"TimeoutHandler", Func, 0, "func(h Handler, dt time.Duration, msg string) Handler"},
+		{"TrailerPrefix", Const, 8, ""},
+		{"Transport", Type, 0, ""},
+		{"Transport.Dial", Field, 0, ""},
+		{"Transport.DialContext", Field, 7, ""},
+		{"Transport.DialTLS", Field, 4, ""},
+		{"Transport.DialTLSContext", Field, 14, ""},
+		{"Transport.DisableCompression", Field, 0, ""},
+		{"Transport.DisableKeepAlives", Field, 0, ""},
+		{"Transport.ExpectContinueTimeout", Field, 6, ""},
+		{"Transport.ForceAttemptHTTP2", Field, 13, ""},
+		{"Transport.GetProxyConnectHeader", Field, 16, ""},
+		{"Transport.HTTP2", Field, 24, ""},
+		{"Transport.IdleConnTimeout", Field, 7, ""},
+		{"Transport.MaxConnsPerHost", Field, 11, ""},
+		{"Transport.MaxIdleConns", Field, 7, ""},
+		{"Transport.MaxIdleConnsPerHost", Field, 0, ""},
+		{"Transport.MaxResponseHeaderBytes", Field, 7, ""},
+		{"Transport.OnProxyConnectResponse", Field, 20, ""},
+		{"Transport.Protocols", Field, 24, ""},
+		{"Transport.Proxy", Field, 0, ""},
+		{"Transport.ProxyConnectHeader", Field, 8, ""},
+		{"Transport.ReadBufferSize", Field, 13, ""},
+		{"Transport.ResponseHeaderTimeout", Field, 1, ""},
+		{"Transport.TLSClientConfig", Field, 0, ""},
+		{"Transport.TLSHandshakeTimeout", Field, 3, ""},
+		{"Transport.TLSNextProto", Field, 6, ""},
+		{"Transport.WriteBufferSize", Field, 13, ""},
+	},
+	"net/http/cgi": {
+		{"(*Handler).ServeHTTP", Method, 0, ""},
+		{"Handler", Type, 0, ""},
+		{"Handler.Args", Field, 0, ""},
+		{"Handler.Dir", Field, 0, ""},
+		{"Handler.Env", Field, 0, ""},
+		{"Handler.InheritEnv", Field, 0, ""},
+		{"Handler.Logger", Field, 0, ""},
+		{"Handler.Path", Field, 0, ""},
+		{"Handler.PathLocationHandler", Field, 0, ""},
+		{"Handler.Root", Field, 0, ""},
+		{"Handler.Stderr", Field, 7, ""},
+		{"Request", Func, 0, "func() (*http.Request, error)"},
+		{"RequestFromMap", Func, 0, "func(params map[string]string) (*http.Request, error)"},
+		{"Serve", Func, 0, "func(handler http.Handler) error"},
+	},
+	"net/http/cookiejar": {
+		{"(*Jar).Cookies", Method, 1, ""},
+		{"(*Jar).SetCookies", Method, 1, ""},
+		{"(PublicSuffixList).PublicSuffix", Method, 1, ""},
+		{"(PublicSuffixList).String", Method, 1, ""},
+		{"Jar", Type, 1, ""},
+		{"New", Func, 1, "func(o *Options) (*Jar, error)"},
+		{"Options", Type, 1, ""},
+		{"Options.PublicSuffixList", Field, 1, ""},
+		{"PublicSuffixList", Type, 1, ""},
+	},
+	"net/http/fcgi": {
+		{"ErrConnClosed", Var, 5, ""},
+		{"ErrRequestAborted", Var, 5, ""},
+		{"ProcessEnv", Func, 9, "func(r *http.Request) map[string]string"},
+		{"Serve", Func, 0, "func(l net.Listener, handler http.Handler) error"},
+	},
+	"net/http/httptest": {
+		{"(*ResponseRecorder).Flush", Method, 0, ""},
+		{"(*ResponseRecorder).Header", Method, 0, ""},
+		{"(*ResponseRecorder).Result", Method, 7, ""},
+		{"(*ResponseRecorder).Write", Method, 0, ""},
+		{"(*ResponseRecorder).WriteHeader", Method, 0, ""},
+		{"(*ResponseRecorder).WriteString", Method, 6, ""},
+		{"(*Server).Certificate", Method, 9, ""},
+		{"(*Server).Client", Method, 9, ""},
+		{"(*Server).Close", Method, 0, ""},
+		{"(*Server).CloseClientConnections", Method, 0, ""},
+		{"(*Server).Start", Method, 0, ""},
+		{"(*Server).StartTLS", Method, 0, ""},
+		{"DefaultRemoteAddr", Const, 0, ""},
+		{"NewRecorder", Func, 0, "func() *ResponseRecorder"},
+		{"NewRequest", Func, 7, "func(method string, target string, body io.Reader) *http.Request"},
+		{"NewRequestWithContext", Func, 23, "func(ctx context.Context, method string, target string, body io.Reader) *http.Request"},
+		{"NewServer", Func, 0, "func(handler http.Handler) *Server"},
+		{"NewTLSServer", Func, 0, "func(handler http.Handler) *Server"},
+		{"NewTestServer", Func, 27, "func(t testing.TB, handler http.Handler) *Server"},
+		{"NewUnstartedServer", Func, 0, "func(handler http.Handler) *Server"},
+		{"ResponseRecorder", Type, 0, ""},
+		{"ResponseRecorder.Body", Field, 0, ""},
+		{"ResponseRecorder.Code", Field, 0, ""},
+		{"ResponseRecorder.Flushed", Field, 0, ""},
+		{"ResponseRecorder.HeaderMap", Field, 0, ""},
+		{"Server", Type, 0, ""},
+		{"Server.Config", Field, 0, ""},
+		{"Server.EnableHTTP2", Field, 14, ""},
+		{"Server.Listener", Field, 0, ""},
+		{"Server.TLS", Field, 0, ""},
+		{"Server.URL", Field, 0, ""},
+	},
+	"net/http/httptrace": {
+		{"ClientTrace", Type, 7, ""},
+		{"ClientTrace.ConnectDone", Field, 7, ""},
+		{"ClientTrace.ConnectStart", Field, 7, ""},
+		{"ClientTrace.DNSDone", Field, 7, ""},
+		{"ClientTrace.DNSStart", Field, 7, ""},
+		{"ClientTrace.GetConn", Field, 7, ""},
+		{"ClientTrace.Got100Continue", Field, 7, ""},
+		{"ClientTrace.Got1xxResponse", Field, 11, ""},
+		{"ClientTrace.GotConn", Field, 7, ""},
+		{"ClientTrace.GotFirstResponseByte", Field, 7, ""},
+		{"ClientTrace.PutIdleConn", Field, 7, ""},
+		{"ClientTrace.TLSHandshakeDone", Field, 8, ""},
+		{"ClientTrace.TLSHandshakeStart", Field, 8, ""},
+		{"ClientTrace.Wait100Continue", Field, 7, ""},
+		{"ClientTrace.WroteHeaderField", Field, 11, ""},
+		{"ClientTrace.WroteHeaders", Field, 7, ""},
+		{"ClientTrace.WroteRequest", Field, 7, ""},
+		{"ContextClientTrace", Func, 7, "func(ctx context.Context) *ClientTrace"},
+		{"DNSDoneInfo", Type, 7, ""},
+		{"DNSDoneInfo.Addrs", Field, 7, ""},
+		{"DNSDoneInfo.Coalesced", Field, 7, ""},
+		{"DNSDoneInfo.Err", Field, 7, ""},
+		{"DNSStartInfo", Type, 7, ""},
+		{"DNSStartInfo.Host", Field, 7, ""},
+		{"GotConnInfo", Type, 7, ""},
+		{"GotConnInfo.Conn", Field, 7, ""},
+		{"GotConnInfo.IdleTime", Field, 7, ""},
+		{"GotConnInfo.Reused", Field, 7, ""},
+		{"GotConnInfo.WasIdle", Field, 7, ""},
+		{"WithClientTrace", Func, 7, "func(ctx context.Context, trace *ClientTrace) context.Context"},
+		{"WroteRequestInfo", Type, 7, ""},
+		{"WroteRequestInfo.Err", Field, 7, ""},
+	},
+	"net/http/httputil": {
+		{"(*ClientConn).Close", Method, 0, ""},
+		{"(*ClientConn).Do", Method, 0, ""},
+		{"(*ClientConn).Hijack", Method, 0, ""},
+		{"(*ClientConn).Pending", Method, 0, ""},
+		{"(*ClientConn).Read", Method, 0, ""},
+		{"(*ClientConn).Write", Method, 0, ""},
+		{"(*ProxyRequest).SetURL", Method, 20, ""},
+		{"(*ProxyRequest).SetXForwarded", Method, 20, ""},
+		{"(*ReverseProxy).ServeHTTP", Method, 0, ""},
+		{"(*ServerConn).Close", Method, 0, ""},
+		{"(*ServerConn).Hijack", Method, 0, ""},
+		{"(*ServerConn).Pending", Method, 0, ""},
+		{"(*ServerConn).Read", Method, 0, ""},
+		{"(*ServerConn).Write", Method, 0, ""},
+		{"(BufferPool).Get", Method, 6, ""},
+		{"(BufferPool).Put", Method, 6, ""},
+		{"BufferPool", Type, 6, ""},
+		{"ClientConn", Type, 0, ""},
+		{"DumpRequest", Func, 0, "func(req *http.Request, body bool) ([]byte, error)"},
+		{"DumpRequestOut", Func, 0, "func(req *http.Request, body bool) ([]byte, error)"},
+		{"DumpResponse", Func, 0, "func(resp *http.Response, body bool) ([]byte, error)"},
+		{"ErrClosed", Var, 0, ""},
+		{"ErrLineTooLong", Var, 0, ""},
+		{"ErrPersistEOF", Var, 0, ""},
+		{"ErrPipeline", Var, 0, ""},
+		{"NewChunkedReader", Func, 0, "func(r io.Reader) io.Reader"},
+		{"NewChunkedWriter", Func, 0, "func(w io.Writer) io.WriteCloser"},
+		{"NewClientConn", Func, 0, "func(c net.Conn, r *bufio.Reader) *ClientConn"},
+		{"NewProxyClientConn", Func, 0, "func(c net.Conn, r *bufio.Reader) *ClientConn"},
+		{"NewServerConn", Func, 0, "func(c net.Conn, r *bufio.Reader) *ServerConn"},
+		{"NewSingleHostReverseProxy", Func, 0, "func(target *url.URL) *ReverseProxy"},
+		{"ProxyRequest", Type, 20, ""},
+		{"ProxyRequest.In", Field, 20, ""},
+		{"ProxyRequest.Out", Field, 20, ""},
+		{"ReverseProxy", Type, 0, ""},
+		{"ReverseProxy.BufferPool", Field, 6, ""},
+		{"ReverseProxy.Director", Field, 0, ""},
+		{"ReverseProxy.ErrorHandler", Field, 11, ""},
+		{"ReverseProxy.ErrorLog", Field, 4, ""},
+		{"ReverseProxy.FlushInterval", Field, 0, ""},
+		{"ReverseProxy.ModifyResponse", Field, 8, ""},
+		{"ReverseProxy.Rewrite", Field, 20, ""},
+		{"ReverseProxy.Transport", Field, 0, ""},
+		{"ServerConn", Type, 0, ""},
+	},
+	"net/http/pprof": {
+		{"Cmdline", Func, 0, "func(w http.ResponseWriter, r *http.Request)"},
+		{"Handler", Func, 0, "func(name string) http.Handler"},
+		{"Index", Func, 0, "func(w http.ResponseWriter, r *http.Request)"},
+		{"Profile", Func, 0, "func(w http.ResponseWriter, r *http.Request)"},
+		{"Symbol", Func, 0, "func(w http.ResponseWriter, r *http.Request)"},
+		{"Trace", Func, 5, "func(w http.ResponseWriter, r *http.Request)"},
+	},
+	"net/mail": {
+		{"(*Address).String", Method, 0, ""},
+		{"(*AddressParser).Parse", Method, 5, ""},
+		{"(*AddressParser).ParseList", Method, 5, ""},
+		{"(Header).AddressList", Method, 0, ""},
+		{"(Header).Date", Method, 0, ""},
+		{"(Header).Get", Method, 0, ""},
+		{"Address", Type, 0, ""},
+		{"Address.Address", Field, 0, ""},
+		{"Address.Name", Field, 0, ""},
+		{"AddressParser", Type, 5, ""},
+		{"AddressParser.WordDecoder", Field, 5, ""},
+		{"ErrHeaderNotPresent", Var, 0, ""},
+		{"Header", Type, 0, ""},
+		{"Message", Type, 0, ""},
+		{"Message.Body", Field, 0, ""},
+		{"Message.Header", Field, 0, ""},
+		{"ParseAddress", Func, 1, "func(address string) (*Address, error)"},
+		{"ParseAddressList", Func, 1, "func(list string) ([]*Address, error)"},
+		{"ParseDate", Func, 8, "func(date string) (time.Time, error)"},
+		{"ReadMessage", Func, 0, "func(r io.Reader) (msg *Message, err error)"},
+	},
+	"net/netip": {
+		{"(*Addr).UnmarshalBinary", Method, 18, ""},
+		{"(*Addr).UnmarshalText", Method, 18, ""},
+		{"(*AddrPort).UnmarshalBinary", Method, 18, ""},
+		{"(*AddrPort).UnmarshalText", Method, 18, ""},
+		{"(*Prefix).UnmarshalBinary", Method, 18, ""},
+		{"(*Prefix).UnmarshalText", Method, 18, ""},
+		{"(Addr).AppendBinary", Method, 24, ""},
+		{"(Addr).AppendText", Method, 24, ""},
+		{"(Addr).AppendTo", Method, 18, ""},
+		{"(Addr).As16", Method, 18, ""},
+		{"(Addr).As4", Method, 18, ""},
+		{"(Addr).AsSlice", Method, 18, ""},
+		{"(Addr).BitLen", Method, 18, ""},
+		{"(Addr).Compare", Method, 18, ""},
+		{"(Addr).Is4", Method, 18, ""},
+		{"(Addr).Is4In6", Method, 18, ""},
+		{"(Addr).Is6", Method, 18, ""},
+		{"(Addr).IsGlobalUnicast", Method, 18, ""},
+		{"(Addr).IsInterfaceLocalMulticast", Method, 18, ""},
+		{"(Addr).IsLinkLocalMulticast", Method, 18, ""},
+		{"(Addr).IsLinkLocalUnicast", Method, 18, ""},
+		{"(Addr).IsLoopback", Method, 18, ""},
+		{"(Addr).IsMulticast", Method, 18, ""},
+		{"(Addr).IsPrivate", Method, 18, ""},
+		{"(Addr).IsUnspecified", Method, 18, ""},
+		{"(Addr).IsValid", Method, 18, ""},
+		{"(Addr).Less", Method, 18, ""},
+		{"(Addr).MarshalBinary", Method, 18, ""},
+		{"(Addr).MarshalText", Method, 18, ""},
+		{"(Addr).Next", Method, 18, ""},
+		{"(Addr).Prefix", Method, 18, ""},
+		{"(Addr).Prev", Method, 18, ""},
+		{"(Addr).String", Method, 18, ""},
+		{"(Addr).StringExpanded", Method, 18, ""},
+		{"(Addr).Unmap", Method, 18, ""},
+		{"(Addr).WithZone", Method, 18, ""},
+		{"(Addr).Zone", Method, 18, ""},
+		{"(AddrPort).Addr", Method, 18, ""},
+		{"(AddrPort).AppendBinary", Method, 24, ""},
+		{"(AddrPort).AppendText", Method, 24, ""},
+		{"(AddrPort).AppendTo", Method, 18, ""},
+		{"(AddrPort).Compare", Method, 22, ""},
+		{"(AddrPort).IsValid", Method, 18, ""},
+		{"(AddrPort).MarshalBinary", Method, 18, ""},
+		{"(AddrPort).MarshalText", Method, 18, ""},
+		{"(AddrPort).Port", Method, 18, ""},
+		{"(AddrPort).String", Method, 18, ""},
+		{"(Prefix).Addr", Method, 18, ""},
+		{"(Prefix).AppendBinary", Method, 24, ""},
+		{"(Prefix).AppendText", Method, 24, ""},
+		{"(Prefix).AppendTo", Method, 18, ""},
+		{"(Prefix).Bits", Method, 18, ""},
+		{"(Prefix).Compare", Method, 26, ""},
+		{"(Prefix).Contains", Method, 18, ""},
+		{"(Prefix).IsSingleIP", Method, 18, ""},
+		{"(Prefix).IsValid", Method, 18, ""},
+		{"(Prefix).MarshalBinary", Method, 18, ""},
+		{"(Prefix).MarshalText", Method, 18, ""},
+		{"(Prefix).Masked", Method, 18, ""},
+		{"(Prefix).Overlaps", Method, 18, ""},
+		{"(Prefix).String", Method, 18, ""},
+		{"Addr", Type, 18, ""},
+		{"AddrFrom16", Func, 18, "func(addr [16]byte) Addr"},
+		{"AddrFrom4", Func, 18, "func(addr [4]byte) Addr"},
+		{"AddrFromSlice", Func, 18, "func(slice []byte) (ip Addr, ok bool)"},
+		{"AddrPort", Type, 18, ""},
+		{"AddrPortFrom", Func, 18, "func(ip Addr, port uint16) AddrPort"},
+		{"IPv4Unspecified", Func, 18, "func() Addr"},
+		{"IPv6LinkLocalAllNodes", Func, 18, "func() Addr"},
+		{"IPv6LinkLocalAllRouters", Func, 20, "func() Addr"},
+		{"IPv6Loopback", Func, 20, "func() Addr"},
+		{"IPv6Unspecified", Func, 18, "func() Addr"},
+		{"MustParseAddr", Func, 18, "func(s string) Addr"},
+		{"MustParseAddrPort", Func, 18, "func(s string) AddrPort"},
+		{"MustParsePrefix", Func, 18, "func(s string) Prefix"},
+		{"ParseAddr", Func, 18, "func(s string) (Addr, error)"},
+		{"ParseAddrPort", Func, 18, "func(s string) (AddrPort, error)"},
+		{"ParsePrefix", Func, 18, "func(s string) (Prefix, error)"},
+		{"Prefix", Type, 18, ""},
+		{"PrefixFrom", Func, 18, "func(ip Addr, bits int) Prefix"},
+	},
+	"net/rpc": {
+		{"(*Client).Call", Method, 0, ""},
+		{"(*Client).Close", Method, 0, ""},
+		{"(*Client).Go", Method, 0, ""},
+		{"(*Server).Accept", Method, 0, ""},
+		{"(*Server).HandleHTTP", Method, 0, ""},
+		{"(*Server).Register", Method, 0, ""},
+		{"(*Server).RegisterName", Method, 0, ""},
+		{"(*Server).ServeCodec", Method, 0, ""},
+		{"(*Server).ServeConn", Method, 0, ""},
+		{"(*Server).ServeHTTP", Method, 0, ""},
+		{"(*Server).ServeRequest", Method, 0, ""},
+		{"(ClientCodec).Close", Method, 0, ""},
+		{"(ClientCodec).ReadResponseBody", Method, 0, ""},
+		{"(ClientCodec).ReadResponseHeader", Method, 0, ""},
+		{"(ClientCodec).WriteRequest", Method, 0, ""},
+		{"(ServerCodec).Close", Method, 0, ""},
+		{"(ServerCodec).ReadRequestBody", Method, 0, ""},
+		{"(ServerCodec).ReadRequestHeader", Method, 0, ""},
+		{"(ServerCodec).WriteResponse", Method, 0, ""},
+		{"(ServerError).Error", Method, 0, ""},
+		{"Accept", Func, 0, "func(lis net.Listener)"},
+		{"Call", Type, 0, ""},
+		{"Call.Args", Field, 0, ""},
+		{"Call.Done", Field, 0, ""},
+		{"Call.Error", Field, 0, ""},
+		{"Call.Reply", Field, 0, ""},
+		{"Call.ServiceMethod", Field, 0, ""},
+		{"Client", Type, 0, ""},
+		{"ClientCodec", Type, 0, ""},
+		{"DefaultDebugPath", Const, 0, ""},
+		{"DefaultRPCPath", Const, 0, ""},
+		{"DefaultServer", Var, 0, ""},
+		{"Dial", Func, 0, "func(network string, address string) (*Client, error)"},
+		{"DialHTTP", Func, 0, "func(network string, address string) (*Client, error)"},
+		{"DialHTTPPath", Func, 0, "func(network string, address string, path string) (*Client, error)"},
+		{"ErrShutdown", Var, 0, ""},
+		{"HandleHTTP", Func, 0, "func()"},
+		{"NewClient", Func, 0, "func(conn io.ReadWriteCloser) *Client"},
+		{"NewClientWithCodec", Func, 0, "func(codec ClientCodec) *Client"},
+		{"NewServer", Func, 0, "func() *Server"},
+		{"Register", Func, 0, "func(rcvr any) error"},
+		{"RegisterName", Func, 0, "func(name string, rcvr any) error"},
+		{"Request", Type, 0, ""},
+		{"Request.Seq", Field, 0, ""},
+		{"Request.ServiceMethod", Field, 0, ""},
+		{"Response", Type, 0, ""},
+		{"Response.Error", Field, 0, ""},
+		{"Response.Seq", Field, 0, ""},
+		{"Response.ServiceMethod", Field, 0, ""},
+		{"ServeCodec", Func, 0, "func(codec ServerCodec)"},
+		{"ServeConn", Func, 0, "func(conn io.ReadWriteCloser)"},
+		{"ServeRequest", Func, 0, "func(codec ServerCodec) error"},
+		{"Server", Type, 0, ""},
+		{"ServerCodec", Type, 0, ""},
+		{"ServerError", Type, 0, ""},
+	},
+	"net/rpc/jsonrpc": {
+		{"Dial", Func, 0, "func(network string, address string) (*rpc.Client, error)"},
+		{"NewClient", Func, 0, "func(conn io.ReadWriteCloser) *rpc.Client"},
+		{"NewClientCodec", Func, 0, "func(conn io.ReadWriteCloser) rpc.ClientCodec"},
+		{"NewServerCodec", Func, 0, "func(conn io.ReadWriteCloser) rpc.ServerCodec"},
+		{"ServeConn", Func, 0, "func(conn io.ReadWriteCloser)"},
+	},
+	"net/smtp": {
+		{"(*Client).Auth", Method, 0, ""},
+		{"(*Client).Close", Method, 2, ""},
+		{"(*Client).Data", Method, 0, ""},
+		{"(*Client).Extension", Method, 0, ""},
+		{"(*Client).Hello", Method, 1, ""},
+		{"(*Client).Mail", Method, 0, ""},
+		{"(*Client).Noop", Method, 10, ""},
+		{"(*Client).Quit", Method, 0, ""},
+		{"(*Client).Rcpt", Method, 0, ""},
+		{"(*Client).Reset", Method, 0, ""},
+		{"(*Client).StartTLS", Method, 0, ""},
+		{"(*Client).TLSConnectionState", Method, 5, ""},
+		{"(*Client).Verify", Method, 0, ""},
+		{"(Auth).Next", Method, 0, ""},
+		{"(Auth).Start", Method, 0, ""},
+		{"Auth", Type, 0, ""},
+		{"CRAMMD5Auth", Func, 0, "func(username string, secret string) Auth"},
+		{"Client", Type, 0, ""},
+		{"Client.Text", Field, 0, ""},
+		{"Dial", Func, 0, "func(addr string) (*Client, error)"},
+		{"NewClient", Func, 0, "func(conn net.Conn, host string) (*Client, error)"},
+		{"PlainAuth", Func, 0, "func(identity string, username string, password string, host string) Auth"},
+		{"SendMail", Func, 0, "func(addr string, a Auth, from string, to []string, msg []byte) error"},
+		{"ServerInfo", Type, 0, ""},
+		{"ServerInfo.Auth", Field, 0, ""},
+		{"ServerInfo.Name", Field, 0, ""},
+		{"ServerInfo.TLS", Field, 0, ""},
+	},
+	"net/textproto": {
+		{"(*Conn).Close", Method, 0, ""},
+		{"(*Conn).Cmd", Method, 0, ""},
+		{"(*Conn).DotReader", Method, 0, ""},
+		{"(*Conn).DotWriter", Method, 0, ""},
+		{"(*Conn).EndRequest", Method, 0, ""},
+		{"(*Conn).EndResponse", Method, 0, ""},
+		{"(*Conn).Next", Method, 0, ""},
+		{"(*Conn).PrintfLine", Method, 0, ""},
+		{"(*Conn).ReadCodeLine", Method, 0, ""},
+		{"(*Conn).ReadContinuedLine", Method, 0, ""},
+		{"(*Conn).ReadContinuedLineBytes", Method, 0, ""},
+		{"(*Conn).ReadDotBytes", Method, 0, ""},
+		{"(*Conn).ReadDotLines", Method, 0, ""},
+		{"(*Conn).ReadLine", Method, 0, ""},
+		{"(*Conn).ReadLineBytes", Method, 0, ""},
+		{"(*Conn).ReadMIMEHeader", Method, 0, ""},
+		{"(*Conn).ReadResponse", Method, 0, ""},
+		{"(*Conn).StartRequest", Method, 0, ""},
+		{"(*Conn).StartResponse", Method, 0, ""},
+		{"(*Error).Error", Method, 0, ""},
+		{"(*Pipeline).EndRequest", Method, 0, ""},
+		{"(*Pipeline).EndResponse", Method, 0, ""},
+		{"(*Pipeline).Next", Method, 0, ""},
+		{"(*Pipeline).StartRequest", Method, 0, ""},
+		{"(*Pipeline).StartResponse", Method, 0, ""},
+		{"(*Reader).DotReader", Method, 0, ""},
+		{"(*Reader).ReadCodeLine", Method, 0, ""},
+		{"(*Reader).ReadContinuedLine", Method, 0, ""},
+		{"(*Reader).ReadContinuedLineBytes", Method, 0, ""},
+		{"(*Reader).ReadDotBytes", Method, 0, ""},
+		{"(*Reader).ReadDotLines", Method, 0, ""},
+		{"(*Reader).ReadLine", Method, 0, ""},
+		{"(*Reader).ReadLineBytes", Method, 0, ""},
+		{"(*Reader).ReadMIMEHeader", Method, 0, ""},
+		{"(*Reader).ReadResponse", Method, 0, ""},
+		{"(*Writer).DotWriter", Method, 0, ""},
+		{"(*Writer).PrintfLine", Method, 0, ""},
+		{"(MIMEHeader).Add", Method, 0, ""},
+		{"(MIMEHeader).Del", Method, 0, ""},
+		{"(MIMEHeader).Get", Method, 0, ""},
+		{"(MIMEHeader).Set", Method, 0, ""},
+		{"(MIMEHeader).Values", Method, 14, ""},
+		{"(ProtocolError).Error", Method, 0, ""},
+		{"CanonicalMIMEHeaderKey", Func, 0, "func(s string) string"},
+		{"Conn", Type, 0, ""},
+		{"Conn.Pipeline", Field, 0, ""},
+		{"Conn.Reader", Field, 0, ""},
+		{"Conn.Writer", Field, 0, ""},
+		{"Dial", Func, 0, "func(network string, addr string) (*Conn, error)"},
+		{"Error", Type, 0, ""},
+		{"Error.Code", Field, 0, ""},
+		{"Error.Msg", Field, 0, ""},
+		{"MIMEHeader", Type, 0, ""},
+		{"NewConn", Func, 0, "func(conn io.ReadWriteCloser) *Conn"},
+		{"NewReader", Func, 0, "func(r *bufio.Reader) *Reader"},
+		{"NewWriter", Func, 0, "func(w *bufio.Writer) *Writer"},
+		{"Pipeline", Type, 0, ""},
+		{"ProtocolError", Type, 0, ""},
+		{"Reader", Type, 0, ""},
+		{"Reader.R", Field, 0, ""},
+		{"TrimBytes", Func, 1, "func(b []byte) []byte"},
+		{"TrimString", Func, 1, "func(s string) string"},
+		{"Writer", Type, 0, ""},
+		{"Writer.W", Field, 0, ""},
+	},
+	"net/url": {
+		{"(*Error).Error", Method, 0, ""},
+		{"(*Error).Temporary", Method, 6, ""},
+		{"(*Error).Timeout", Method, 6, ""},
+		{"(*Error).Unwrap", Method, 13, ""},
+		{"(*URL).AppendBinary", Method, 24, ""},
+		{"(*URL).Clone", Method, 27, ""},
+		{"(*URL).EscapedFragment", Method, 15, ""},
+		{"(*URL).EscapedPath", Method, 5, ""},
+		{"(*URL).Hostname", Method, 8, ""},
+		{"(*URL).IsAbs", Method, 0, ""},
+		{"(*URL).JoinPath", Method, 19, ""},
+		{"(*URL).MarshalBinary", Method, 8, ""},
+		{"(*URL).Parse", Method, 0, ""},
+		{"(*URL).Port", Method, 8, ""},
+		{"(*URL).Query", Method, 0, ""},
+		{"(*URL).Redacted", Method, 15, ""},
+		{"(*URL).RequestURI", Method, 0, ""},
+		{"(*URL).ResolveReference", Method, 0, ""},
+		{"(*URL).String", Method, 0, ""},
+		{"(*URL).UnmarshalBinary", Method, 8, ""},
+		{"(*Userinfo).Password", Method, 0, ""},
+		{"(*Userinfo).String", Method, 0, ""},
+		{"(*Userinfo).Username", Method, 0, ""},
+		{"(EscapeError).Error", Method, 0, ""},
+		{"(InvalidHostError).Error", Method, 6, ""},
+		{"(Values).Add", Method, 0, ""},
+		{"(Values).Clone", Method, 27, ""},
+		{"(Values).Del", Method, 0, ""},
+		{"(Values).Encode", Method, 0, ""},
+		{"(Values).Get", Method, 0, ""},
+		{"(Values).Has", Method, 17, ""},
+		{"(Values).Set", Method, 0, ""},
+		{"Error", Type, 0, ""},
+		{"Error.Err", Field, 0, ""},
+		{"Error.Op", Field, 0, ""},
+		{"Error.URL", Field, 0, ""},
+		{"EscapeError", Type, 0, ""},
+		{"InvalidHostError", Type, 6, ""},
+		{"JoinPath", Func, 19, "func(base string, elem ...string) (result string, err error)"},
+		{"Parse", Func, 0, "func(rawURL string) (*URL, error)"},
+		{"ParseQuery", Func, 0, "func(query string) (Values, error)"},
+		{"ParseRequestURI", Func, 0, "func(rawURL string) (*URL, error)"},
+		{"PathEscape", Func, 8, "func(s string) string"},
+		{"PathUnescape", Func, 8, "func(s string) (string, error)"},
+		{"QueryEscape", Func, 0, "func(s string) string"},
+		{"QueryUnescape", Func, 0, "func(s string) (string, error)"},
+		{"URL", Type, 0, ""},
+		{"URL.ForceQuery", Field, 7, ""},
+		{"URL.Fragment", Field, 0, ""},
+		{"URL.Host", Field, 0, ""},
+		{"URL.OmitHost", Field, 19, ""},
+		{"URL.Opaque", Field, 0, ""},
+		{"URL.Path", Field, 0, ""},
+		{"URL.RawFragment", Field, 15, ""},
+		{"URL.RawPath", Field, 5, ""},
+		{"URL.RawQuery", Field, 0, ""},
+		{"URL.Scheme", Field, 0, ""},
+		{"URL.User", Field, 0, ""},
+		{"User", Func, 0, "func(username string) *Userinfo"},
+		{"UserPassword", Func, 0, "func(username string, password string) *Userinfo"},
+		{"Userinfo", Type, 0, ""},
+		{"Values", Type, 0, ""},
+	},
+	"os": {
+		{"(*File).Chdir", Method, 0, ""},
+		{"(*File).Chmod", Method, 0, ""},
+		{"(*File).Chown", Method, 0, ""},
+		{"(*File).Close", Method, 0, ""},
+		{"(*File).Fd", Method, 0, ""},
+		{"(*File).Name", Method, 0, ""},
+		{"(*File).Read", Method, 0, ""},
+		{"(*File).ReadAt", Method, 0, ""},
+		{"(*File).ReadDir", Method, 16, ""},
+		{"(*File).ReadFrom", Method, 15, ""},
+		{"(*File).Readdir", Method, 0, ""},
+		{"(*File).Readdirnames", Method, 0, ""},
+		{"(*File).Seek", Method, 0, ""},
+		{"(*File).SetDeadline", Method, 10, ""},
+		{"(*File).SetReadDeadline", Method, 10, ""},
+		{"(*File).SetWriteDeadline", Method, 10, ""},
+		{"(*File).Stat", Method, 0, ""},
+		{"(*File).Sync", Method, 0, ""},
+		{"(*File).SyscallConn", Method, 12, ""},
+		{"(*File).Truncate", Method, 0, ""},
+		{"(*File).Write", Method, 0, ""},
+		{"(*File).WriteAt", Method, 0, ""},
+		{"(*File).WriteString", Method, 0, ""},
+		{"(*File).WriteTo", Method, 22, ""},
+		{"(*LinkError).Error", Method, 0, ""},
+		{"(*LinkError).Unwrap", Method, 13, ""},
+		{"(*PathError).Error", Method, 0, ""},
+		{"(*PathError).Timeout", Method, 10, ""},
+		{"(*PathError).Unwrap", Method, 13, ""},
+		{"(*Process).Kill", Method, 0, ""},
+		{"(*Process).Release", Method, 0, ""},
+		{"(*Process).Signal", Method, 0, ""},
+		{"(*Process).Wait", Method, 0, ""},
+		{"(*Process).WithHandle", Method, 26, ""},
+		{"(*ProcessState).ExitCode", Method, 12, ""},
+		{"(*ProcessState).Exited", Method, 0, ""},
+		{"(*ProcessState).Pid", Method, 0, ""},
+		{"(*ProcessState).String", Method, 0, ""},
+		{"(*ProcessState).Success", Method, 0, ""},
+		{"(*ProcessState).Sys", Method, 0, ""},
+		{"(*ProcessState).SysUsage", Method, 0, ""},
+		{"(*ProcessState).SystemTime", Method, 0, ""},
+		{"(*ProcessState).UserTime", Method, 0, ""},
+		{"(*Root).Chmod", Method, 25, ""},
+		{"(*Root).Chown", Method, 25, ""},
+		{"(*Root).Chtimes", Method, 25, ""},
+		{"(*Root).Close", Method, 24, ""},
+		{"(*Root).Create", Method, 24, ""},
+		{"(*Root).FS", Method, 24, ""},
+		{"(*Root).Lchown", Method, 25, ""},
+		{"(*Root).Link", Method, 25, ""},
+		{"(*Root).Lstat", Method, 24, ""},
+		{"(*Root).Mkdir", Method, 24, ""},
+		{"(*Root).MkdirAll", Method, 25, ""},
+		{"(*Root).Name", Method, 24, ""},
+		{"(*Root).Open", Method, 24, ""},
+		{"(*Root).OpenFile", Method, 24, ""},
+		{"(*Root).OpenRoot", Method, 24, ""},
+		{"(*Root).ReadFile", Method, 25, ""},
+		{"(*Root).Readlink", Method, 25, ""},
+		{"(*Root).Remove", Method, 24, ""},
+		{"(*Root).RemoveAll", Method, 25, ""},
+		{"(*Root).Rename", Method, 25, ""},
+		{"(*Root).Stat", Method, 24, ""},
+		{"(*Root).Symlink", Method, 25, ""},
+		{"(*Root).WriteFile", Method, 25, ""},
+		{"(*SyscallError).Error", Method, 0, ""},
+		{"(*SyscallError).Timeout", Method, 10, ""},
+		{"(*SyscallError).Unwrap", Method, 13, ""},
+		{"(FileInfo).IsDir", Method, 0, ""},
+		{"(FileInfo).ModTime", Method, 0, ""},
+		{"(FileInfo).Mode", Method, 0, ""},
+		{"(FileInfo).Name", Method, 0, ""},
+		{"(FileInfo).Size", Method, 0, ""},
+		{"(FileInfo).Sys", Method, 0, ""},
+		{"(FileMode).IsDir", Method, 0, ""},
+		{"(FileMode).IsRegular", Method, 1, ""},
+		{"(FileMode).Perm", Method, 0, ""},
+		{"(FileMode).String", Method, 0, ""},
+		{"(Signal).Signal", Method, 0, ""},
+		{"(Signal).String", Method, 0, ""},
+		{"Args", Var, 0, ""},
+		{"Chdir", Func, 0, "func(dir string) error"},
+		{"Chmod", Func, 0, "func(name string, mode FileMode) error"},
+		{"Chown", Func, 0, "func(name string, uid int, gid int) error"},
+		{"Chtimes", Func, 0, "func(name string, atime time.Time, mtime time.Time) error"},
+		{"Clearenv", Func, 0, "func()"},
+		{"CopyFS", Func, 23, "func(dir string, fsys fs.FS) error"},
+		{"Create", Func, 0, "func(name string) (*File, error)"},
+		{"CreateTemp", Func, 16, "func(dir string, pattern string) (*File, error)"},
+		{"DevNull", Const, 0, ""},
+		{"DirEntry", Type, 16, ""},
+		{"DirFS", Func, 16, "func(dir string) fs.FS"},
+		{"Environ", Func, 0, "func() []string"},
+		{"ErrClosed", Var, 8, ""},
+		{"ErrDeadlineExceeded", Var, 15, ""},
+		{"ErrExist", Var, 0, ""},
+		{"ErrInvalid", Var, 0, ""},
+		{"ErrNoDeadline", Var, 10, ""},
+		{"ErrNoHandle", Var, 26, ""},
+		{"ErrNotExist", Var, 0, ""},
+		{"ErrPermission", Var, 0, ""},
+		{"ErrProcessDone", Var, 16, ""},
+		{"Executable", Func, 8, "func() (string, error)"},
+		{"Exit", Func, 0, "func(code int)"},
+		{"Expand", Func, 0, "func(s string, mapping func(string) string) string"},
+		{"ExpandEnv", Func, 0, "func(s string) string"},
+		{"File", Type, 0, ""},
+		{"FileInfo", Type, 0, ""},
+		{"FileMode", Type, 0, ""},
+		{"FindProcess", Func, 0, "func(pid int) (*Process, error)"},
+		{"Getegid", Func, 0, "func() int"},
+		{"Getenv", Func, 0, "func(key string) string"},
+		{"Geteuid", Func, 0, "func() int"},
+		{"Getgid", Func, 0, "func() int"},
+		{"Getgroups", Func, 0, "func() ([]int, error)"},
+		{"Getpagesize", Func, 0, "func() int"},
+		{"Getpid", Func, 0, "func() int"},
+		{"Getppid", Func, 0, "func() int"},
+		{"Getuid", Func, 0, "func() int"},
+		{"Getwd", Func, 0, "func() (dir string, err error)"},
+		{"Hostname", Func, 0, "func() (name string, err error)"},
+		{"Interrupt", Var, 0, ""},
+		{"IsExist", Func, 0, "func(err error) bool"},
+		{"IsNotExist", Func, 0, "func(err error) bool"},
+		{"IsPathSeparator", Func, 0, "func(c uint8) bool"},
+		{"IsPermission", Func, 0, "func(err error) bool"},
+		{"IsTimeout", Func, 10, "func(err error) bool"},
+		{"Kill", Var, 0, ""},
+		{"Lchown", Func, 0, "func(name string, uid int, gid int) error"},
+		{"Link", Func, 0, "func(oldname string, newname string) error"},
+		{"LinkError", Type, 0, ""},
+		{"LinkError.Err", Field, 0, ""},
+		{"LinkError.New", Field, 0, ""},
+		{"LinkError.Old", Field, 0, ""},
+		{"LinkError.Op", Field, 0, ""},
+		{"LookupEnv", Func, 5, "func(key string) (string, bool)"},
+		{"Lstat", Func, 0, "func(name string) (FileInfo, error)"},
+		{"Mkdir", Func, 0, "func(name string, perm FileMode) error"},
+		{"MkdirAll", Func, 0, "func(path string, perm FileMode) error"},
+		{"MkdirTemp", Func, 16, "func(dir string, pattern string) (string, error)"},
+		{"ModeAppend", Const, 0, ""},
+		{"ModeCharDevice", Const, 0, ""},
+		{"ModeDevice", Const, 0, ""},
+		{"ModeDir", Const, 0, ""},
+		{"ModeExclusive", Const, 0, ""},
+		{"ModeIrregular", Const, 11, ""},
+		{"ModeNamedPipe", Const, 0, ""},
+		{"ModePerm", Const, 0, ""},
+		{"ModeSetgid", Const, 0, ""},
+		{"ModeSetuid", Const, 0, ""},
+		{"ModeSocket", Const, 0, ""},
+		{"ModeSticky", Const, 0, ""},
+		{"ModeSymlink", Const, 0, ""},
+		{"ModeTemporary", Const, 0, ""},
+		{"ModeType", Const, 0, ""},
+		{"NewFile", Func, 0, "func(fd uintptr, name string) *File"},
+		{"NewSyscallError", Func, 0, "func(syscall string, err error) error"},
+		{"O_APPEND", Const, 0, ""},
+		{"O_CREATE", Const, 0, ""},
+		{"O_EXCL", Const, 0, ""},
+		{"O_RDONLY", Const, 0, ""},
+		{"O_RDWR", Const, 0, ""},
+		{"O_SYNC", Const, 0, ""},
+		{"O_TRUNC", Const, 0, ""},
+		{"O_WRONLY", Const, 0, ""},
+		{"Open", Func, 0, "func(name string) (*File, error)"},
+		{"OpenFile", Func, 0, "func(name string, flag int, perm FileMode) (*File, error)"},
+		{"OpenInRoot", Func, 24, "func(dir string, name string) (*File, error)"},
+		{"OpenRoot", Func, 24, "func(name string) (*Root, error)"},
+		{"PathError", Type, 0, ""},
+		{"PathError.Err", Field, 0, ""},
+		{"PathError.Op", Field, 0, ""},
+		{"PathError.Path", Field, 0, ""},
+		{"PathListSeparator", Const, 0, ""},
+		{"PathSeparator", Const, 0, ""},
+		{"Pipe", Func, 0, "func() (r *File, w *File, err error)"},
+		{"ProcAttr", Type, 0, ""},
+		{"ProcAttr.Dir", Field, 0, ""},
+		{"ProcAttr.Env", Field, 0, ""},
+		{"ProcAttr.Files", Field, 0, ""},
+		{"ProcAttr.Sys", Field, 0, ""},
+		{"Process", Type, 0, ""},
+		{"Process.Pid", Field, 0, ""},
+		{"ProcessState", Type, 0, ""},
+		{"ReadDir", Func, 16, "func(name string) ([]DirEntry, error)"},
+		{"ReadFile", Func, 16, "func(name string) ([]byte, error)"},
+		{"Readlink", Func, 0, "func(name string) (string, error)"},
+		{"Remove", Func, 0, "func(name string) error"},
+		{"RemoveAll", Func, 0, "func(path string) error"},
+		{"Rename", Func, 0, "func(oldpath string, newpath string) error"},
+		{"Root", Type, 24, ""},
+		{"SEEK_CUR", Const, 0, ""},
+		{"SEEK_END", Const, 0, ""},
+		{"SEEK_SET", Const, 0, ""},
+		{"SameFile", Func, 0, "func(fi1 FileInfo, fi2 FileInfo) bool"},
+		{"Setenv", Func, 0, "func(key string, value string) error"},
+		{"Signal", Type, 0, ""},
+		{"StartProcess", Func, 0, "func(name string, argv []string, attr *ProcAttr) (*Process, error)"},
+		{"Stat", Func, 0, "func(name string) (FileInfo, error)"},
+		{"Stderr", Var, 0, ""},
+		{"Stdin", Var, 0, ""},
+		{"Stdout", Var, 0, ""},
+		{"Symlink", Func, 0, "func(oldname string, newname string) error"},
+		{"SyscallError", Type, 0, ""},
+		{"SyscallError.Err", Field, 0, ""},
+		{"SyscallError.Syscall", Field, 0, ""},
+		{"TempDir", Func, 0, "func() string"},
+		{"Truncate", Func, 0, "func(name string, size int64) error"},
+		{"Unsetenv", Func, 4, "func(key string) error"},
+		{"UserCacheDir", Func, 11, "func() (string, error)"},
+		{"UserConfigDir", Func, 13, "func() (string, error)"},
+		{"UserHomeDir", Func, 12, "func() (string, error)"},
+		{"WriteFile", Func, 16, "func(name string, data []byte, perm FileMode) error"},
+	},
+	"os/exec": {
+		{"(*Cmd).CombinedOutput", Method, 0, ""},
+		{"(*Cmd).Environ", Method, 19, ""},
+		{"(*Cmd).Output", Method, 0, ""},
+		{"(*Cmd).Run", Method, 0, ""},
+		{"(*Cmd).Start", Method, 0, ""},
+		{"(*Cmd).StderrPipe", Method, 0, ""},
+		{"(*Cmd).StdinPipe", Method, 0, ""},
+		{"(*Cmd).StdoutPipe", Method, 0, ""},
+		{"(*Cmd).String", Method, 13, ""},
+		{"(*Cmd).Wait", Method, 0, ""},
+		{"(*Error).Error", Method, 0, ""},
+		{"(*Error).Unwrap", Method, 13, ""},
+		{"(*ExitError).Error", Method, 0, ""},
+		{"(ExitError).ExitCode", Method, 12, ""},
+		{"(ExitError).Exited", Method, 0, ""},
+		{"(ExitError).Pid", Method, 0, ""},
+		{"(ExitError).String", Method, 0, ""},
+		{"(ExitError).Success", Method, 0, ""},
+		{"(ExitError).Sys", Method, 0, ""},
+		{"(ExitError).SysUsage", Method, 0, ""},
+		{"(ExitError).SystemTime", Method, 0, ""},
+		{"(ExitError).UserTime", Method, 0, ""},
+		{"Cmd", Type, 0, ""},
+		{"Cmd.Args", Field, 0, ""},
+		{"Cmd.Cancel", Field, 20, ""},
+		{"Cmd.Dir", Field, 0, ""},
+		{"Cmd.Env", Field, 0, ""},
+		{"Cmd.Err", Field, 19, ""},
+		{"Cmd.ExtraFiles", Field, 0, ""},
+		{"Cmd.Path", Field, 0, ""},
+		{"Cmd.Process", Field, 0, ""},
+		{"Cmd.ProcessState", Field, 0, ""},
+		{"Cmd.Stderr", Field, 0, ""},
+		{"Cmd.Stdin", Field, 0, ""},
+		{"Cmd.Stdout", Field, 0, ""},
+		{"Cmd.SysProcAttr", Field, 0, ""},
+		{"Cmd.WaitDelay", Field, 20, ""},
+		{"Command", Func, 0, "func(name string, arg ...string) *Cmd"},
+		{"CommandContext", Func, 7, "func(ctx context.Context, name string, arg ...string) *Cmd"},
+		{"ErrDot", Var, 19, ""},
+		{"ErrNotFound", Var, 0, ""},
+		{"ErrWaitDelay", Var, 20, ""},
+		{"Error", Type, 0, ""},
+		{"Error.Err", Field, 0, ""},
+		{"Error.Name", Field, 0, ""},
+		{"ExitError", Type, 0, ""},
+		{"ExitError.ProcessState", Field, 0, ""},
+		{"ExitError.Stderr", Field, 6, ""},
+		{"LookPath", Func, 0, "func(file string) (string, error)"},
+	},
+	"os/signal": {
+		{"Ignore", Func, 5, "func(sig ...os.Signal)"},
+		{"Ignored", Func, 11, "func(sig os.Signal) bool"},
+		{"Notify", Func, 0, "func(c chan<- os.Signal, sig ...os.Signal)"},
+		{"NotifyContext", Func, 16, "func(parent context.Context, signals ...os.Signal) (ctx context.Context, stop context.CancelFunc)"},
+		{"Reset", Func, 5, "func(sig ...os.Signal)"},
+		{"Stop", Func, 1, "func(c chan<- os.Signal)"},
+	},
+	"os/user": {
+		{"(*User).GroupIds", Method, 7, ""},
+		{"(UnknownGroupError).Error", Method, 7, ""},
+		{"(UnknownGroupIdError).Error", Method, 7, ""},
+		{"(UnknownUserError).Error", Method, 0, ""},
+		{"(UnknownUserIdError).Error", Method, 0, ""},
+		{"Current", Func, 0, "func() (*User, error)"},
+		{"Group", Type, 7, ""},
+		{"Group.Gid", Field, 7, ""},
+		{"Group.Name", Field, 7, ""},
+		{"Lookup", Func, 0, "func(username string) (*User, error)"},
+		{"LookupGroup", Func, 7, "func(name string) (*Group, error)"},
+		{"LookupGroupId", Func, 7, "func(gid string) (*Group, error)"},
+		{"LookupId", Func, 0, "func(uid string) (*User, error)"},
+		{"UnknownGroupError", Type, 7, ""},
+		{"UnknownGroupIdError", Type, 7, ""},
+		{"UnknownUserError", Type, 0, ""},
+		{"UnknownUserIdError", Type, 0, ""},
+		{"User", Type, 0, ""},
+		{"User.Gid", Field, 0, ""},
+		{"User.HomeDir", Field, 0, ""},
+		{"User.Name", Field, 0, ""},
+		{"User.Uid", Field, 0, ""},
+		{"User.Username", Field, 0, ""},
+	},
+	"path": {
+		{"Base", Func, 0, "func(path string) string"},
+		{"Clean", Func, 0, "func(path string) string"},
+		{"Dir", Func, 0, "func(path string) string"},
+		{"ErrBadPattern", Var, 0, ""},
+		{"Ext", Func, 0, "func(path string) string"},
+		{"IsAbs", Func, 0, "func(path string) bool"},
+		{"Join", Func, 0, "func(elem ...string) string"},
+		{"Match", Func, 0, "func(pattern string, name string) (matched bool, err error)"},
+		{"Split", Func, 0, "func(path string) (dir string, file string)"},
+	},
+	"path/filepath": {
+		{"Abs", Func, 0, "func(path string) (string, error)"},
+		{"Base", Func, 0, "func(path string) string"},
+		{"Clean", Func, 0, "func(path string) string"},
+		{"Dir", Func, 0, "func(path string) string"},
+		{"ErrBadPattern", Var, 0, ""},
+		{"EvalSymlinks", Func, 0, "func(path string) (string, error)"},
+		{"Ext", Func, 0, "func(path string) string"},
+		{"FromSlash", Func, 0, "func(path string) string"},
+		{"Glob", Func, 0, "func(pattern string) (matches []string, err error)"},
+		{"HasPrefix", Func, 0, "func(p string, prefix string) bool"},
+		{"IsAbs", Func, 0, "func(path string) bool"},
+		{"IsLocal", Func, 20, "func(path string) bool"},
+		{"Join", Func, 0, "func(elem ...string) string"},
+		{"ListSeparator", Const, 0, ""},
+		{"Localize", Func, 23, "func(path string) (string, error)"},
+		{"Match", Func, 0, "func(pattern string, name string) (matched bool, err error)"},
+		{"Rel", Func, 0, "func(basePath string, targPath string) (string, error)"},
+		{"Separator", Const, 0, ""},
+		{"SkipAll", Var, 20, ""},
+		{"SkipDir", Var, 0, ""},
+		{"Split", Func, 0, "func(path string) (dir string, file string)"},
+		{"SplitList", Func, 0, "func(path string) []string"},
+		{"ToSlash", Func, 0, "func(path string) string"},
+		{"VolumeName", Func, 0, "func(path string) string"},
+		{"Walk", Func, 0, "func(root string, fn WalkFunc) error"},
+		{"WalkDir", Func, 16, "func(root string, fn fs.WalkDirFunc) error"},
+		{"WalkFunc", Type, 0, ""},
+	},
+	"plugin": {
+		{"(*Plugin).Lookup", Method, 8, ""},
+		{"Open", Func, 8, "func(path string) (*Plugin, error)"},
+		{"Plugin", Type, 8, ""},
+		{"Symbol", Type, 8, ""},
+	},
+	"reflect": {
+		{"(*MapIter).Key", Method, 12, ""},
+		{"(*MapIter).Next", Method, 12, ""},
+		{"(*MapIter).Reset", Method, 18, ""},
+		{"(*MapIter).Value", Method, 12, ""},
+		{"(*ValueError).Error", Method, 0, ""},
+		{"(ChanDir).String", Method, 0, ""},
+		{"(Kind).String", Method, 0, ""},
+		{"(Method).IsExported", Method, 17, ""},
+		{"(StructField).IsExported", Method, 17, ""},
+		{"(StructTag).Get", Method, 0, ""},
+		{"(StructTag).Lookup", Method, 7, ""},
+		{"(Type).Align", Method, 0, ""},
+		{"(Type).AssignableTo", Method, 0, ""},
+		{"(Type).Bits", Method, 0, ""},
+		{"(Type).CanSeq", Method, 23, ""},
+		{"(Type).CanSeq2", Method, 23, ""},
+		{"(Type).ChanDir", Method, 0, ""},
+		{"(Type).Comparable", Method, 4, ""},
+		{"(Type).ConvertibleTo", Method, 1, ""},
+		{"(Type).Elem", Method, 0, ""},
+		{"(Type).Field", Method, 0, ""},
+		{"(Type).FieldAlign", Method, 0, ""},
+		{"(Type).FieldByIndex", Method, 0, ""},
+		{"(Type).FieldByName", Method, 0, ""},
+		{"(Type).FieldByNameFunc", Method, 0, ""},
+		{"(Type).Fields", Method, 26, ""},
+		{"(Type).Implements", Method, 0, ""},
+		{"(Type).In", Method, 0, ""},
+		{"(Type).Ins", Method, 26, ""},
+		{"(Type).IsVariadic", Method, 0, ""},
+		{"(Type).Key", Method, 0, ""},
+		{"(Type).Kind", Method, 0, ""},
+		{"(Type).Len", Method, 0, ""},
+		{"(Type).Method", Method, 0, ""},
+		{"(Type).MethodByName", Method, 0, ""},
+		{"(Type).Methods", Method, 26, ""},
+		{"(Type).Name", Method, 0, ""},
+		{"(Type).NumField", Method, 0, ""},
+		{"(Type).NumIn", Method, 0, ""},
+		{"(Type).NumMethod", Method, 0, ""},
+		{"(Type).NumOut", Method, 0, ""},
+		{"(Type).Out", Method, 0, ""},
+		{"(Type).Outs", Method, 26, ""},
+		{"(Type).OverflowComplex", Method, 23, ""},
+		{"(Type).OverflowFloat", Method, 23, ""},
+		{"(Type).OverflowInt", Method, 23, ""},
+		{"(Type).OverflowUint", Method, 23, ""},
+		{"(Type).PkgPath", Method, 0, ""},
+		{"(Type).Size", Method, 0, ""},
+		{"(Type).String", Method, 0, ""},
+		{"(Value).Addr", Method, 0, ""},
+		{"(Value).Bool", Method, 0, ""},
+		{"(Value).Bytes", Method, 0, ""},
+		{"(Value).Call", Method, 0, ""},
+		{"(Value).CallSlice", Method, 0, ""},
+		{"(Value).CanAddr", Method, 0, ""},
+		{"(Value).CanComplex", Method, 18, ""},
+		{"(Value).CanConvert", Method, 17, ""},
+		{"(Value).CanFloat", Method, 18, ""},
+		{"(Value).CanInt", Method, 18, ""},
+		{"(Value).CanInterface", Method, 0, ""},
+		{"(Value).CanSet", Method, 0, ""},
+		{"(Value).CanUint", Method, 18, ""},
+		{"(Value).Cap", Method, 0, ""},
+		{"(Value).Clear", Method, 21, ""},
+		{"(Value).Close", Method, 0, ""},
+		{"(Value).Comparable", Method, 20, ""},
+		{"(Value).Complex", Method, 0, ""},
+		{"(Value).Convert", Method, 1, ""},
+		{"(Value).Elem", Method, 0, ""},
+		{"(Value).Equal", Method, 20, ""},
+		{"(Value).Field", Method, 0, ""},
+		{"(Value).FieldByIndex", Method, 0, ""},
+		{"(Value).FieldByIndexErr", Method, 18, ""},
+		{"(Value).FieldByName", Method, 0, ""},
+		{"(Value).FieldByNameFunc", Method, 0, ""},
+		{"(Value).Fields", Method, 26, ""},
+		{"(Value).Float", Method, 0, ""},
+		{"(Value).Grow", Method, 20, ""},
+		{"(Value).Index", Method, 0, ""},
+		{"(Value).Int", Method, 0, ""},
+		{"(Value).Interface", Method, 0, ""},
+		{"(Value).InterfaceData", Method, 0, ""},
+		{"(Value).IsNil", Method, 0, ""},
+		{"(Value).IsValid", Method, 0, ""},
+		{"(Value).IsZero", Method, 13, ""},
+		{"(Value).Kind", Method, 0, ""},
+		{"(Value).Len", Method, 0, ""},
+		{"(Value).MapIndex", Method, 0, ""},
+		{"(Value).MapKeys", Method, 0, ""},
+		{"(Value).MapRange", Method, 12, ""},
+		{"(Value).Method", Method, 0, ""},
+		{"(Value).MethodByName", Method, 0, ""},
+		{"(Value).Methods", Method, 26, ""},
+		{"(Value).NumField", Method, 0, ""},
+		{"(Value).NumMethod", Method, 0, ""},
+		{"(Value).OverflowComplex", Method, 0, ""},
+		{"(Value).OverflowFloat", Method, 0, ""},
+		{"(Value).OverflowInt", Method, 0, ""},
+		{"(Value).OverflowUint", Method, 0, ""},
+		{"(Value).Pointer", Method, 0, ""},
+		{"(Value).Recv", Method, 0, ""},
+		{"(Value).Send", Method, 0, ""},
+		{"(Value).Seq", Method, 23, ""},
+		{"(Value).Seq2", Method, 23, ""},
+		{"(Value).Set", Method, 0, ""},
+		{"(Value).SetBool", Method, 0, ""},
+		{"(Value).SetBytes", Method, 0, ""},
+		{"(Value).SetCap", Method, 2, ""},
+		{"(Value).SetComplex", Method, 0, ""},
+		{"(Value).SetFloat", Method, 0, ""},
+		{"(Value).SetInt", Method, 0, ""},
+		{"(Value).SetIterKey", Method, 18, ""},
+		{"(Value).SetIterValue", Method, 18, ""},
+		{"(Value).SetLen", Method, 0, ""},
+		{"(Value).SetMapIndex", Method, 0, ""},
+		{"(Value).SetPointer", Method, 0, ""},
+		{"(Value).SetString", Method, 0, ""},
+		{"(Value).SetUint", Method, 0, ""},
+		{"(Value).SetZero", Method, 20, ""},
+		{"(Value).Slice", Method, 0, ""},
+		{"(Value).Slice3", Method, 2, ""},
+		{"(Value).String", Method, 0, ""},
+		{"(Value).TryRecv", Method, 0, ""},
+		{"(Value).TrySend", Method, 0, ""},
+		{"(Value).Type", Method, 0, ""},
+		{"(Value).Uint", Method, 0, ""},
+		{"(Value).UnsafeAddr", Method, 0, ""},
+		{"(Value).UnsafePointer", Method, 18, ""},
+		{"Append", Func, 0, "func(s Value, x ...Value) Value"},
+		{"AppendSlice", Func, 0, "func(s Value, t Value) Value"},
+		{"Array", Const, 0, ""},
+		{"ArrayOf", Func, 5, "func(length int, elem Type) Type"},
+		{"Bool", Const, 0, ""},
+		{"BothDir", Const, 0, ""},
+		{"Chan", Const, 0, ""},
+		{"ChanDir", Type, 0, ""},
+		{"ChanOf", Func, 1, "func(dir ChanDir, t Type) Type"},
+		{"Complex128", Const, 0, ""},
+		{"Complex64", Const, 0, ""},
+		{"Copy", Func, 0, "func(dst Value, src Value) int"},
+		{"DeepEqual", Func, 0, "func(x any, y any) bool"},
+		{"Float32", Const, 0, ""},
+		{"Float64", Const, 0, ""},
+		{"Func", Const, 0, ""},
+		{"FuncOf", Func, 5, "func(in []Type, out []Type, variadic bool) Type"},
+		{"Indirect", Func, 0, "func(v Value) Value"},
+		{"Int", Const, 0, ""},
+		{"Int16", Const, 0, ""},
+		{"Int32", Const, 0, ""},
+		{"Int64", Const, 0, ""},
+		{"Int8", Const, 0, ""},
+		{"Interface", Const, 0, ""},
+		{"Invalid", Const, 0, ""},
+		{"Kind", Type, 0, ""},
+		{"MakeChan", Func, 0, "func(typ Type, buffer int) Value"},
+		{"MakeFunc", Func, 1, "func(typ Type, fn func(args []Value) (results []Value)) Value"},
+		{"MakeMap", Func, 0, "func(typ Type) Value"},
+		{"MakeMapWithSize", Func, 9, "func(typ Type, n int) Value"},
+		{"MakeSlice", Func, 0, "func(typ Type, len int, cap int) Value"},
+		{"Map", Const, 0, ""},
+		{"MapIter", Type, 12, ""},
+		{"MapOf", Func, 1, "func(key Type, elem Type) Type"},
+		{"Method", Type, 0, ""},
+		{"Method.Func", Field, 0, ""},
+		{"Method.Index", Field, 0, ""},
+		{"Method.Name", Field, 0, ""},
+		{"Method.PkgPath", Field, 0, ""},
+		{"Method.Type", Field, 0, ""},
+		{"New", Func, 0, "func(typ Type) Value"},
+		{"NewAt", Func, 0, "func(typ Type, p unsafe.Pointer) Value"},
+		{"Pointer", Const, 18, ""},
+		{"PointerTo", Func, 18, "func(t Type) Type"},
+		{"Ptr", Const, 0, ""},
+		{"PtrTo", Func, 0, "func(t Type) Type"},
+		{"RecvDir", Const, 0, ""},
+		{"Select", Func, 1, "func(cases []SelectCase) (chosen int, recv Value, recvOK bool)"},
+		{"SelectCase", Type, 1, ""},
+		{"SelectCase.Chan", Field, 1, ""},
+		{"SelectCase.Dir", Field, 1, ""},
+		{"SelectCase.Send", Field, 1, ""},
+		{"SelectDefault", Const, 1, ""},
+		{"SelectDir", Type, 1, ""},
+		{"SelectRecv", Const, 1, ""},
+		{"SelectSend", Const, 1, ""},
+		{"SendDir", Const, 0, ""},
+		{"Slice", Const, 0, ""},
+		{"SliceAt", Func, 23, "func(typ Type, p unsafe.Pointer, n int) Value"},
+		{"SliceHeader", Type, 0, ""},
+		{"SliceHeader.Cap", Field, 0, ""},
+		{"SliceHeader.Data", Field, 0, ""},
+		{"SliceHeader.Len", Field, 0, ""},
+		{"SliceOf", Func, 1, "func(t Type) Type"},
+		{"String", Const, 0, ""},
+		{"StringHeader", Type, 0, ""},
+		{"StringHeader.Data", Field, 0, ""},
+		{"StringHeader.Len", Field, 0, ""},
+		{"Struct", Const, 0, ""},
+		{"StructField", Type, 0, ""},
+		{"StructField.Anonymous", Field, 0, ""},
+		{"StructField.Index", Field, 0, ""},
+		{"StructField.Name", Field, 0, ""},
+		{"StructField.Offset", Field, 0, ""},
+		{"StructField.PkgPath", Field, 0, ""},
+		{"StructField.Tag", Field, 0, ""},
+		{"StructField.Type", Field, 0, ""},
+		{"StructOf", Func, 7, "func(fields []StructField) Type"},
+		{"StructTag", Type, 0, ""},
+		{"Swapper", Func, 8, "func(slice any) func(i int, j int)"},
+		{"TypeAssert", Func, 25, "func[T any](v Value) (T, bool)"},
+		{"TypeFor", Func, 22, "func[T any]() Type"},
+		{"TypeOf", Func, 0, "func(i any) Type"},
+		{"Uint", Const, 0, ""},
+		{"Uint16", Const, 0, ""},
+		{"Uint32", Const, 0, ""},
+		{"Uint64", Const, 0, ""},
+		{"Uint8", Const, 0, ""},
+		{"Uintptr", Const, 0, ""},
+		{"UnsafePointer", Const, 0, ""},
+		{"Value", Type, 0, ""},
+		{"ValueError", Type, 0, ""},
+		{"ValueError.Kind", Field, 0, ""},
+		{"ValueError.Method", Field, 0, ""},
+		{"ValueOf", Func, 0, "func(i any) Value"},
+		{"VisibleFields", Func, 17, "func(t Type) []StructField"},
+		{"Zero", Func, 0, "func(typ Type) Value"},
+	},
+	"regexp": {
+		{"(*Regexp).AppendText", Method, 24, ""},
+		{"(*Regexp).Copy", Method, 6, ""},
+		{"(*Regexp).Expand", Method, 0, ""},
+		{"(*Regexp).ExpandString", Method, 0, ""},
+		{"(*Regexp).Find", Method, 0, ""},
+		{"(*Regexp).FindAll", Method, 0, ""},
+		{"(*Regexp).FindAllIndex", Method, 0, ""},
+		{"(*Regexp).FindAllString", Method, 0, ""},
+		{"(*Regexp).FindAllStringIndex", Method, 0, ""},
+		{"(*Regexp).FindAllStringSubmatch", Method, 0, ""},
+		{"(*Regexp).FindAllStringSubmatchIndex", Method, 0, ""},
+		{"(*Regexp).FindAllSubmatch", Method, 0, ""},
+		{"(*Regexp).FindAllSubmatchIndex", Method, 0, ""},
+		{"(*Regexp).FindIndex", Method, 0, ""},
+		{"(*Regexp).FindReaderIndex", Method, 0, ""},
+		{"(*Regexp).FindReaderSubmatchIndex", Method, 0, ""},
+		{"(*Regexp).FindString", Method, 0, ""},
+		{"(*Regexp).FindStringIndex", Method, 0, ""},
+		{"(*Regexp).FindStringSubmatch", Method, 0, ""},
+		{"(*Regexp).FindStringSubmatchIndex", Method, 0, ""},
+		{"(*Regexp).FindSubmatch", Method, 0, ""},
+		{"(*Regexp).FindSubmatchIndex", Method, 0, ""},
+		{"(*Regexp).LiteralPrefix", Method, 0, ""},
+		{"(*Regexp).Longest", Method, 1, ""},
+		{"(*Regexp).MarshalText", Method, 21, ""},
+		{"(*Regexp).Match", Method, 0, ""},
+		{"(*Regexp).MatchReader", Method, 0, ""},
+		{"(*Regexp).MatchString", Method, 0, ""},
+		{"(*Regexp).NumSubexp", Method, 0, ""},
+		{"(*Regexp).ReplaceAll", Method, 0, ""},
+		{"(*Regexp).ReplaceAllFunc", Method, 0, ""},
+		{"(*Regexp).ReplaceAllLiteral", Method, 0, ""},
+		{"(*Regexp).ReplaceAllLiteralString", Method, 0, ""},
+		{"(*Regexp).ReplaceAllString", Method, 0, ""},
+		{"(*Regexp).ReplaceAllStringFunc", Method, 0, ""},
+		{"(*Regexp).Split", Method, 1, ""},
+		{"(*Regexp).String", Method, 0, ""},
+		{"(*Regexp).SubexpIndex", Method, 15, ""},
+		{"(*Regexp).SubexpNames", Method, 0, ""},
+		{"(*Regexp).UnmarshalText", Method, 21, ""},
+		{"Compile", Func, 0, "func(expr string) (*Regexp, error)"},
+		{"CompilePOSIX", Func, 0, "func(expr string) (*Regexp, error)"},
+		{"Match", Func, 0, "func(pattern string, b []byte) (matched bool, err error)"},
+		{"MatchReader", Func, 0, "func(pattern string, r io.RuneReader) (matched bool, err error)"},
+		{"MatchString", Func, 0, "func(pattern string, s string) (matched bool, err error)"},
+		{"MustCompile", Func, 0, "func(str string) *Regexp"},
+		{"MustCompilePOSIX", Func, 0, "func(str string) *Regexp"},
+		{"QuoteMeta", Func, 0, "func(s string) string"},
+		{"Regexp", Type, 0, ""},
+	},
+	"regexp/syntax": {
+		{"(*Error).Error", Method, 0, ""},
+		{"(*Inst).MatchEmptyWidth", Method, 0, ""},
+		{"(*Inst).MatchRune", Method, 0, ""},
+		{"(*Inst).MatchRunePos", Method, 3, ""},
+		{"(*Inst).String", Method, 0, ""},
+		{"(*Prog).Prefix", Method, 0, ""},
+		{"(*Prog).StartCond", Method, 0, ""},
+		{"(*Prog).String", Method, 0, ""},
+		{"(*Regexp).CapNames", Method, 0, ""},
+		{"(*Regexp).Equal", Method, 0, ""},
+		{"(*Regexp).MaxCap", Method, 0, ""},
+		{"(*Regexp).Simplify", Method, 0, ""},
+		{"(*Regexp).String", Method, 0, ""},
+		{"(ErrorCode).String", Method, 0, ""},
+		{"(InstOp).String", Method, 3, ""},
+		{"(Op).String", Method, 11, ""},
+		{"ClassNL", Const, 0, ""},
+		{"Compile", Func, 0, "func(re *Regexp) (*Prog, error)"},
+		{"DotNL", Const, 0, ""},
+		{"EmptyBeginLine", Const, 0, ""},
+		{"EmptyBeginText", Const, 0, ""},
+		{"EmptyEndLine", Const, 0, ""},
+		{"EmptyEndText", Const, 0, ""},
+		{"EmptyNoWordBoundary", Const, 0, ""},
+		{"EmptyOp", Type, 0, ""},
+		{"EmptyOpContext", Func, 0, "func(r1 rune, r2 rune) EmptyOp"},
+		{"EmptyWordBoundary", Const, 0, ""},
+		{"ErrInternalError", Const, 0, ""},
+		{"ErrInvalidCharClass", Const, 0, ""},
+		{"ErrInvalidCharRange", Const, 0, ""},
+		{"ErrInvalidEscape", Const, 0, ""},
+		{"ErrInvalidNamedCapture", Const, 0, ""},
+		{"ErrInvalidPerlOp", Const, 0, ""},
+		{"ErrInvalidRepeatOp", Const, 0, ""},
+		{"ErrInvalidRepeatSize", Const, 0, ""},
+		{"ErrInvalidUTF8", Const, 0, ""},
+		{"ErrLarge", Const, 20, ""},
+		{"ErrMissingBracket", Const, 0, ""},
+		{"ErrMissingParen", Const, 0, ""},
+		{"ErrMissingRepeatArgument", Const, 0, ""},
+		{"ErrNestingDepth", Const, 19, ""},
+		{"ErrTrailingBackslash", Const, 0, ""},
+		{"ErrUnexpectedParen", Const, 1, ""},
+		{"Error", Type, 0, ""},
+		{"Error.Code", Field, 0, ""},
+		{"Error.Expr", Field, 0, ""},
+		{"ErrorCode", Type, 0, ""},
+		{"Flags", Type, 0, ""},
+		{"FoldCase", Const, 0, ""},
+		{"Inst", Type, 0, ""},
+		{"Inst.Arg", Field, 0, ""},
+		{"Inst.Op", Field, 0, ""},
+		{"Inst.Out", Field, 0, ""},
+		{"Inst.Rune", Field, 0, ""},
+		{"InstAlt", Const, 0, ""},
+		{"InstAltMatch", Const, 0, ""},
+		{"InstCapture", Const, 0, ""},
+		{"InstEmptyWidth", Const, 0, ""},
+		{"InstFail", Const, 0, ""},
+		{"InstMatch", Const, 0, ""},
+		{"InstNop", Const, 0, ""},
+		{"InstOp", Type, 0, ""},
+		{"InstRune", Const, 0, ""},
+		{"InstRune1", Const, 0, ""},
+		{"InstRuneAny", Const, 0, ""},
+		{"InstRuneAnyNotNL", Const, 0, ""},
+		{"IsWordChar", Func, 0, "func(r rune) bool"},
+		{"Literal", Const, 0, ""},
+		{"MatchNL", Const, 0, ""},
+		{"NonGreedy", Const, 0, ""},
+		{"OneLine", Const, 0, ""},
+		{"Op", Type, 0, ""},
+		{"OpAlternate", Const, 0, ""},
+		{"OpAnyChar", Const, 0, ""},
+		{"OpAnyCharNotNL", Const, 0, ""},
+		{"OpBeginLine", Const, 0, ""},
+		{"OpBeginText", Const, 0, ""},
+		{"OpCapture", Const, 0, ""},
+		{"OpCharClass", Const, 0, ""},
+		{"OpConcat", Const, 0, ""},
+		{"OpEmptyMatch", Const, 0, ""},
+		{"OpEndLine", Const, 0, ""},
+		{"OpEndText", Const, 0, ""},
+		{"OpLiteral", Const, 0, ""},
+		{"OpNoMatch", Const, 0, ""},
+		{"OpNoWordBoundary", Const, 0, ""},
+		{"OpPlus", Const, 0, ""},
+		{"OpQuest", Const, 0, ""},
+		{"OpRepeat", Const, 0, ""},
+		{"OpStar", Const, 0, ""},
+		{"OpWordBoundary", Const, 0, ""},
+		{"POSIX", Const, 0, ""},
+		{"Parse", Func, 0, "func(s string, flags Flags) (*Regexp, error)"},
+		{"Perl", Const, 0, ""},
+		{"PerlX", Const, 0, ""},
+		{"Prog", Type, 0, ""},
+		{"Prog.Inst", Field, 0, ""},
+		{"Prog.NumCap", Field, 0, ""},
+		{"Prog.Start", Field, 0, ""},
+		{"Regexp", Type, 0, ""},
+		{"Regexp.Cap", Field, 0, ""},
+		{"Regexp.Flags", Field, 0, ""},
+		{"Regexp.Max", Field, 0, ""},
+		{"Regexp.Min", Field, 0, ""},
+		{"Regexp.Name", Field, 0, ""},
+		{"Regexp.Op", Field, 0, ""},
+		{"Regexp.Rune", Field, 0, ""},
+		{"Regexp.Rune0", Field, 0, ""},
+		{"Regexp.Sub", Field, 0, ""},
+		{"Regexp.Sub0", Field, 0, ""},
+		{"Simple", Const, 0, ""},
+		{"UnicodeGroups", Const, 0, ""},
+		{"WasDollar", Const, 0, ""},
+	},
+	"runtime": {
+		{"(*BlockProfileRecord).Stack", Method, 1, ""},
+		{"(*Frames).Next", Method, 7, ""},
+		{"(*Func).Entry", Method, 0, ""},
+		{"(*Func).FileLine", Method, 0, ""},
+		{"(*Func).Name", Method, 0, ""},
+		{"(*MemProfileRecord).InUseBytes", Method, 0, ""},
+		{"(*MemProfileRecord).InUseObjects", Method, 0, ""},
+		{"(*MemProfileRecord).Stack", Method, 0, ""},
+		{"(*PanicNilError).Error", Method, 21, ""},
+		{"(*PanicNilError).RuntimeError", Method, 21, ""},
+		{"(*Pinner).Pin", Method, 21, ""},
+		{"(*Pinner).Unpin", Method, 21, ""},
+		{"(*StackRecord).Stack", Method, 0, ""},
+		{"(*TypeAssertionError).Error", Method, 0, ""},
+		{"(*TypeAssertionError).RuntimeError", Method, 0, ""},
+		{"(Cleanup).Stop", Method, 24, ""},
+		{"(Error).Error", Method, 0, ""},
+		{"(Error).RuntimeError", Method, 0, ""},
+		{"AddCleanup", Func, 24, "func[T, S any](ptr *T, cleanup func(S), arg S) Cleanup"},
+		{"BlockProfile", Func, 1, "func(p []BlockProfileRecord) (n int, ok bool)"},
+		{"BlockProfileRecord", Type, 1, ""},
+		{"BlockProfileRecord.Count", Field, 1, ""},
+		{"BlockProfileRecord.Cycles", Field, 1, ""},
+		{"BlockProfileRecord.StackRecord", Field, 1, ""},
+		{"Breakpoint", Func, 0, "func()"},
+		{"CPUProfile", Func, 0, "func() []byte"},
+		{"Caller", Func, 0, "func(skip int) (pc uintptr, file string, line int, ok bool)"},
+		{"Callers", Func, 0, "func(skip int, pc []uintptr) int"},
+		{"CallersFrames", Func, 7, "func(callers []uintptr) *Frames"},
+		{"Cleanup", Type, 24, ""},
+		{"Compiler", Const, 0, ""},
+		{"Error", Type, 0, ""},
+		{"Frame", Type, 7, ""},
+		{"Frame.Entry", Field, 7, ""},
+		{"Frame.File", Field, 7, ""},
+		{"Frame.Func", Field, 7, ""},
+		{"Frame.Function", Field, 7, ""},
+		{"Frame.Line", Field, 7, ""},
+		{"Frame.PC", Field, 7, ""},
+		{"Frames", Type, 7, ""},
+		{"Func", Type, 0, ""},
+		{"FuncForPC", Func, 0, "func(pc uintptr) *Func"},
+		{"GC", Func, 0, "func()"},
+		{"GOARCH", Const, 0, ""},
+		{"GOMAXPROCS", Func, 0, "func(n int) int"},
+		{"GOOS", Const, 0, ""},
+		{"GOROOT", Func, 0, "func() string"},
+		{"Goexit", Func, 0, "func()"},
+		{"GoroutineProfile", Func, 0, "func(p []StackRecord) (n int, ok bool)"},
+		{"Gosched", Func, 0, "func()"},
+		{"KeepAlive", Func, 7, "func(x any)"},
+		{"LockOSThread", Func, 0, "func()"},
+		{"MemProfile", Func, 0, "func(p []MemProfileRecord, inuseZero bool) (n int, ok bool)"},
+		{"MemProfileRate", Var, 0, ""},
+		{"MemProfileRecord", Type, 0, ""},
+		{"MemProfileRecord.AllocBytes", Field, 0, ""},
+		{"MemProfileRecord.AllocObjects", Field, 0, ""},
+		{"MemProfileRecord.FreeBytes", Field, 0, ""},
+		{"MemProfileRecord.FreeObjects", Field, 0, ""},
+		{"MemProfileRecord.Stack0", Field, 0, ""},
+		{"MemStats", Type, 0, ""},
+		{"MemStats.Alloc", Field, 0, ""},
+		{"MemStats.BuckHashSys", Field, 0, ""},
+		{"MemStats.BySize", Field, 0, ""},
+		{"MemStats.DebugGC", Field, 0, ""},
+		{"MemStats.EnableGC", Field, 0, ""},
+		{"MemStats.Frees", Field, 0, ""},
+		{"MemStats.GCCPUFraction", Field, 5, ""},
+		{"MemStats.GCSys", Field, 2, ""},
+		{"MemStats.HeapAlloc", Field, 0, ""},
+		{"MemStats.HeapIdle", Field, 0, ""},
+		{"MemStats.HeapInuse", Field, 0, ""},
+		{"MemStats.HeapObjects", Field, 0, ""},
+		{"MemStats.HeapReleased", Field, 0, ""},
+		{"MemStats.HeapSys", Field, 0, ""},
+		{"MemStats.LastGC", Field, 0, ""},
+		{"MemStats.Lookups", Field, 0, ""},
+		{"MemStats.MCacheInuse", Field, 0, ""},
+		{"MemStats.MCacheSys", Field, 0, ""},
+		{"MemStats.MSpanInuse", Field, 0, ""},
+		{"MemStats.MSpanSys", Field, 0, ""},
+		{"MemStats.Mallocs", Field, 0, ""},
+		{"MemStats.NextGC", Field, 0, ""},
+		{"MemStats.NumForcedGC", Field, 8, ""},
+		{"MemStats.NumGC", Field, 0, ""},
+		{"MemStats.OtherSys", Field, 2, ""},
+		{"MemStats.PauseEnd", Field, 4, ""},
+		{"MemStats.PauseNs", Field, 0, ""},
+		{"MemStats.PauseTotalNs", Field, 0, ""},
+		{"MemStats.StackInuse", Field, 0, ""},
+		{"MemStats.StackSys", Field, 0, ""},
+		{"MemStats.Sys", Field, 0, ""},
+		{"MemStats.TotalAlloc", Field, 0, ""},
+		{"MutexProfile", Func, 8, "func(p []BlockProfileRecord) (n int, ok bool)"},
+		{"NumCPU", Func, 0, "func() int"},
+		{"NumCgoCall", Func, 0, "func() int64"},
+		{"NumGoroutine", Func, 0, "func() int"},
+		{"PanicNilError", Type, 21, ""},
+		{"Pinner", Type, 21, ""},
+		{"ReadMemStats", Func, 0, "func(m *MemStats)"},
+		{"ReadTrace", Func, 5, "func() (buf []byte)"},
+		{"SetBlockProfileRate", Func, 1, "func(rate int)"},
+		{"SetCPUProfileRate", Func, 0, "func(hz int)"},
+		{"SetCgoTraceback", Func, 7, "func(version int, traceback unsafe.Pointer, context unsafe.Pointer, symbolizer unsafe.Pointer)"},
+		{"SetDefaultGOMAXPROCS", Func, 25, "func()"},
+		{"SetFinalizer", Func, 0, "func(obj any, finalizer any)"},
+		{"SetMutexProfileFraction", Func, 8, "func(rate int) int"},
+		{"Stack", Func, 0, "func(buf []byte, all bool) int"},
+		{"StackRecord", Type, 0, ""},
+		{"StackRecord.Stack0", Field, 0, ""},
+		{"StartTrace", Func, 5, "func() error"},
+		{"StopTrace", Func, 5, "func()"},
+		{"ThreadCreateProfile", Func, 0, "func(p []StackRecord) (n int, ok bool)"},
+		{"TypeAssertionError", Type, 0, ""},
+		{"UnlockOSThread", Func, 0, "func()"},
+		{"Version", Func, 0, "func() string"},
+	},
+	"runtime/cgo": {
+		{"(Handle).Delete", Method, 17, ""},
+		{"(Handle).Value", Method, 17, ""},
+		{"Handle", Type, 17, ""},
+		{"Incomplete", Type, 20, ""},
+		{"NewHandle", Func, 17, ""},
+	},
+	"runtime/coverage": {
+		{"ClearCounters", Func, 20, "func() error"},
+		{"WriteCounters", Func, 20, "func(w io.Writer) error"},
+		{"WriteCountersDir", Func, 20, "func(dir string) error"},
+		{"WriteMeta", Func, 20, "func(w io.Writer) error"},
+		{"WriteMetaDir", Func, 20, "func(dir string) error"},
+	},
+	"runtime/debug": {
+		{"(*BuildInfo).String", Method, 18, ""},
+		{"BuildInfo", Type, 12, ""},
+		{"BuildInfo.Deps", Field, 12, ""},
+		{"BuildInfo.GoVersion", Field, 18, ""},
+		{"BuildInfo.Main", Field, 12, ""},
+		{"BuildInfo.Path", Field, 12, ""},
+		{"BuildInfo.Settings", Field, 18, ""},
+		{"BuildSetting", Type, 18, ""},
+		{"BuildSetting.Key", Field, 18, ""},
+		{"BuildSetting.Value", Field, 18, ""},
+		{"CrashOptions", Type, 23, ""},
+		{"FreeOSMemory", Func, 1, "func()"},
+		{"GCStats", Type, 1, ""},
+		{"GCStats.LastGC", Field, 1, ""},
+		{"GCStats.NumGC", Field, 1, ""},
+		{"GCStats.Pause", Field, 1, ""},
+		{"GCStats.PauseEnd", Field, 4, ""},
+		{"GCStats.PauseQuantiles", Field, 1, ""},
+		{"GCStats.PauseTotal", Field, 1, ""},
+		{"Module", Type, 12, ""},
+		{"Module.Path", Field, 12, ""},
+		{"Module.Replace", Field, 12, ""},
+		{"Module.Sum", Field, 12, ""},
+		{"Module.Version", Field, 12, ""},
+		{"ParseBuildInfo", Func, 18, "func(data string) (bi *BuildInfo, err error)"},
+		{"PrintStack", Func, 0, "func()"},
+		{"ReadBuildInfo", Func, 12, "func() (info *BuildInfo, ok bool)"},
+		{"ReadGCStats", Func, 1, "func(stats *GCStats)"},
+		{"SetCrashOutput", Func, 23, "func(f *os.File, opts CrashOptions) error"},
+		{"SetGCPercent", Func, 1, "func(percent int) int"},
+		{"SetMaxStack", Func, 2, "func(bytes int) int"},
+		{"SetMaxThreads", Func, 2, "func(threads int) int"},
+		{"SetMemoryLimit", Func, 19, "func(limit int64) int64"},
+		{"SetPanicOnFault", Func, 3, "func(enabled bool) bool"},
+		{"SetTraceback", Func, 6, "func(level string)"},
+		{"Stack", Func, 0, "func() []byte"},
+		{"WriteHeapDump", Func, 3, "func(fd uintptr)"},
+	},
+	"runtime/metrics": {
+		{"(Value).Float64", Method, 16, ""},
+		{"(Value).Float64Histogram", Method, 16, ""},
+		{"(Value).Kind", Method, 16, ""},
+		{"(Value).Uint64", Method, 16, ""},
+		{"All", Func, 16, "func() []Description"},
+		{"Description", Type, 16, ""},
+		{"Description.Cumulative", Field, 16, ""},
+		{"Description.Description", Field, 16, ""},
+		{"Description.Kind", Field, 16, ""},
+		{"Description.Name", Field, 16, ""},
+		{"Float64Histogram", Type, 16, ""},
+		{"Float64Histogram.Buckets", Field, 16, ""},
+		{"Float64Histogram.Counts", Field, 16, ""},
+		{"KindBad", Const, 16, ""},
+		{"KindFloat64", Const, 16, ""},
+		{"KindFloat64Histogram", Const, 16, ""},
+		{"KindUint64", Const, 16, ""},
+		{"Read", Func, 16, "func(m []Sample)"},
+		{"Sample", Type, 16, ""},
+		{"Sample.Name", Field, 16, ""},
+		{"Sample.Value", Field, 16, ""},
+		{"Value", Type, 16, ""},
+		{"ValueKind", Type, 16, ""},
+	},
+	"runtime/pprof": {
+		{"(*Profile).Add", Method, 0, ""},
+		{"(*Profile).Count", Method, 0, ""},
+		{"(*Profile).Name", Method, 0, ""},
+		{"(*Profile).Remove", Method, 0, ""},
+		{"(*Profile).WriteTo", Method, 0, ""},
+		{"Do", Func, 9, "func(ctx context.Context, labels LabelSet, f func(context.Context))"},
+		{"ForLabels", Func, 9, "func(ctx context.Context, f func(key string, value string) bool)"},
+		{"Label", Func, 9, "func(ctx context.Context, key string) (string, bool)"},
+		{"LabelSet", Type, 9, ""},
+		{"Labels", Func, 9, "func(args ...string) LabelSet"},
+		{"Lookup", Func, 0, "func(name string) *Profile"},
+		{"NewProfile", Func, 0, "func(name string) *Profile"},
+		{"Profile", Type, 0, ""},
+		{"Profiles", Func, 0, "func() []*Profile"},
+		{"SetGoroutineLabels", Func, 9, "func(ctx context.Context)"},
+		{"StartCPUProfile", Func, 0, "func(w io.Writer) error"},
+		{"StopCPUProfile", Func, 0, "func()"},
+		{"WithLabels", Func, 9, "func(ctx context.Context, labels LabelSet) context.Context"},
+		{"WriteHeapProfile", Func, 0, "func(w io.Writer) error"},
+	},
+	"runtime/trace": {
+		{"(*FlightRecorder).Enabled", Method, 25, ""},
+		{"(*FlightRecorder).Start", Method, 25, ""},
+		{"(*FlightRecorder).Stop", Method, 25, ""},
+		{"(*FlightRecorder).WriteTo", Method, 25, ""},
+		{"(*Region).End", Method, 11, ""},
+		{"(*Task).End", Method, 11, ""},
+		{"FlightRecorder", Type, 25, ""},
+		{"FlightRecorderConfig", Type, 25, ""},
+		{"FlightRecorderConfig.MaxBytes", Field, 25, ""},
+		{"FlightRecorderConfig.MinAge", Field, 25, ""},
+		{"IsEnabled", Func, 11, "func() bool"},
+		{"Log", Func, 11, "func(ctx context.Context, category string, message string)"},
+		{"Logf", Func, 11, "func(ctx context.Context, category string, format string, args ...any)"},
+		{"NewFlightRecorder", Func, 25, "func(cfg FlightRecorderConfig) *FlightRecorder"},
+		{"NewTask", Func, 11, "func(pctx context.Context, taskType string) (ctx context.Context, task *Task)"},
+		{"Region", Type, 11, ""},
+		{"Start", Func, 5, "func(w io.Writer) error"},
+		{"StartRegion", Func, 11, "func(ctx context.Context, regionType string) *Region"},
+		{"Stop", Func, 5, "func()"},
+		{"Task", Type, 11, ""},
+		{"WithRegion", Func, 11, "func(ctx context.Context, regionType string, fn func())"},
+	},
+	"slices": {
+		{"All", Func, 23, "func[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]"},
+		{"AppendSeq", Func, 23, "func[Slice ~[]E, E any](s Slice, seq iter.Seq[E]) Slice"},
+		{"Backward", Func, 23, "func[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]"},
+		{"BinarySearch", Func, 21, "func[S ~[]E, E cmp.Ordered](x S, target E) (int, bool)"},
+		{"BinarySearchFunc", Func, 21, "func[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool)"},
+		{"Chunk", Func, 23, "func[Slice ~[]E, E any](s Slice, n int) iter.Seq[Slice]"},
+		{"Clip", Func, 21, "func[S ~[]E, E any](s S) S"},
+		{"Clone", Func, 21, "func[S ~[]E, E any](s S) S"},
+		{"Collect", Func, 23, "func[E any](seq iter.Seq[E]) []E"},
+		{"Compact", Func, 21, "func[S ~[]E, E comparable](s S) S"},
+		{"CompactFunc", Func, 21, "func[S ~[]E, E any](s S, eq func(E, E) bool) S"},
+		{"Compare", Func, 21, "func[S ~[]E, E cmp.Ordered](s1 S, s2 S) int"},
+		{"CompareFunc", Func, 21, "func[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int"},
+		{"Concat", Func, 22, "func[S ~[]E, E any](slices ...S) S"},
+		{"Contains", Func, 21, "func[S ~[]E, E comparable](s S, v E) bool"},
+		{"ContainsFunc", Func, 21, "func[S ~[]E, E any](s S, f func(E) bool) bool"},
+		{"Delete", Func, 21, "func[S ~[]E, E any](s S, i int, j int) S"},
+		{"DeleteFunc", Func, 21, "func[S ~[]E, E any](s S, del func(E) bool) S"},
+		{"Equal", Func, 21, "func[S ~[]E, E comparable](s1 S, s2 S) bool"},
+		{"EqualFunc", Func, 21, "func[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool"},
+		{"Grow", Func, 21, "func[S ~[]E, E any](s S, n int) S"},
+		{"Index", Func, 21, "func[S ~[]E, E comparable](s S, v E) int"},
+		{"IndexFunc", Func, 21, "func[S ~[]E, E any](s S, f func(E) bool) int"},
+		{"Insert", Func, 21, "func[S ~[]E, E any](s S, i int, v ...E) S"},
+		{"IsSorted", Func, 21, "func[S ~[]E, E cmp.Ordered](x S) bool"},
+		{"IsSortedFunc", Func, 21, "func[S ~[]E, E any](x S, cmp func(a E, b E) int) bool"},
+		{"Max", Func, 21, "func[S ~[]E, E cmp.Ordered](x S) E"},
+		{"MaxFunc", Func, 21, "func[S ~[]E, E any](x S, cmp func(a E, b E) int) E"},
+		{"Min", Func, 21, "func[S ~[]E, E cmp.Ordered](x S) E"},
+		{"MinFunc", Func, 21, "func[S ~[]E, E any](x S, cmp func(a E, b E) int) E"},
+		{"Repeat", Func, 23, "func[S ~[]E, E any](x S, count int) S"},
+		{"Replace", Func, 21, "func[S ~[]E, E any](s S, i int, j int, v ...E) S"},
+		{"Reverse", Func, 21, "func[S ~[]E, E any](s S)"},
+		{"Sort", Func, 21, "func[S ~[]E, E cmp.Ordered](x S)"},
+		{"SortFunc", Func, 21, "func[S ~[]E, E any](x S, cmp func(a E, b E) int)"},
+		{"SortStableFunc", Func, 21, "func[S ~[]E, E any](x S, cmp func(a E, b E) int)"},
+		{"Sorted", Func, 23, "func[E cmp.Ordered](seq iter.Seq[E]) []E"},
+		{"SortedFunc", Func, 23, "func[E any](seq iter.Seq[E], cmp func(E, E) int) []E"},
+		{"SortedStableFunc", Func, 23, "func[E any](seq iter.Seq[E], cmp func(E, E) int) []E"},
+		{"Values", Func, 23, "func[Slice ~[]E, E any](s Slice) iter.Seq[E]"},
+	},
+	"sort": {
+		{"(Float64Slice).Len", Method, 0, ""},
+		{"(Float64Slice).Less", Method, 0, ""},
+		{"(Float64Slice).Search", Method, 0, ""},
+		{"(Float64Slice).Sort", Method, 0, ""},
+		{"(Float64Slice).Swap", Method, 0, ""},
+		{"(IntSlice).Len", Method, 0, ""},
+		{"(IntSlice).Less", Method, 0, ""},
+		{"(IntSlice).Search", Method, 0, ""},
+		{"(IntSlice).Sort", Method, 0, ""},
+		{"(IntSlice).Swap", Method, 0, ""},
+		{"(Interface).Len", Method, 0, ""},
+		{"(Interface).Less", Method, 0, ""},
+		{"(Interface).Swap", Method, 0, ""},
+		{"(StringSlice).Len", Method, 0, ""},
+		{"(StringSlice).Less", Method, 0, ""},
+		{"(StringSlice).Search", Method, 0, ""},
+		{"(StringSlice).Sort", Method, 0, ""},
+		{"(StringSlice).Swap", Method, 0, ""},
+		{"Find", Func, 19, "func(n int, cmp func(int) int) (i int, found bool)"},
+		{"Float64Slice", Type, 0, ""},
+		{"Float64s", Func, 0, "func(x []float64)"},
+		{"Float64sAreSorted", Func, 0, "func(x []float64) bool"},
+		{"IntSlice", Type, 0, ""},
+		{"Interface", Type, 0, ""},
+		{"Ints", Func, 0, "func(x []int)"},
+		{"IntsAreSorted", Func, 0, "func(x []int) bool"},
+		{"IsSorted", Func, 0, "func(data Interface) bool"},
+		{"Reverse", Func, 1, "func(data Interface) Interface"},
+		{"Search", Func, 0, "func(n int, f func(int) bool) int"},
+		{"SearchFloat64s", Func, 0, "func(a []float64, x float64) int"},
+		{"SearchInts", Func, 0, "func(a []int, x int) int"},
+		{"SearchStrings", Func, 0, "func(a []string, x string) int"},
+		{"Slice", Func, 8, "func(x any, less func(i int, j int) bool)"},
+		{"SliceIsSorted", Func, 8, "func(x any, less func(i int, j int) bool) bool"},
+		{"SliceStable", Func, 8, "func(x any, less func(i int, j int) bool)"},
+		{"Sort", Func, 0, "func(data Interface)"},
+		{"Stable", Func, 2, "func(data Interface)"},
+		{"StringSlice", Type, 0, ""},
+		{"Strings", Func, 0, "func(x []string)"},
+		{"StringsAreSorted", Func, 0, "func(x []string) bool"},
+	},
+	"strconv": {
+		{"(*NumError).Error", Method, 0, ""},
+		{"(*NumError).Unwrap", Method, 14, ""},
+		{"AppendBool", Func, 0, "func(dst []byte, b bool) []byte"},
+		{"AppendFloat", Func, 0, "func(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte"},
+		{"AppendInt", Func, 0, "func(dst []byte, i int64, base int) []byte"},
+		{"AppendQuote", Func, 0, "func(dst []byte, s string) []byte"},
+		{"AppendQuoteRune", Func, 0, "func(dst []byte, r rune) []byte"},
+		{"AppendQuoteRuneToASCII", Func, 0, "func(dst []byte, r rune) []byte"},
+		{"AppendQuoteRuneToGraphic", Func, 6, "func(dst []byte, r rune) []byte"},
+		{"AppendQuoteToASCII", Func, 0, "func(dst []byte, s string) []byte"},
+		{"AppendQuoteToGraphic", Func, 6, "func(dst []byte, s string) []byte"},
+		{"AppendUint", Func, 0, "func(dst []byte, i uint64, base int) []byte"},
+		{"Atoi", Func, 0, "func(s string) (int, error)"},
+		{"CanBackquote", Func, 0, "func(s string) bool"},
+		{"ErrRange", Var, 0, ""},
+		{"ErrSyntax", Var, 0, ""},
+		{"FormatBool", Func, 0, "func(b bool) string"},
+		{"FormatComplex", Func, 15, "func(c complex128, fmt byte, prec int, bitSize int) string"},
+		{"FormatFloat", Func, 0, "func(f float64, fmt byte, prec int, bitSize int) string"},
+		{"FormatInt", Func, 0, "func(i int64, base int) string"},
+		{"FormatUint", Func, 0, "func(i uint64, base int) string"},
+		{"IntSize", Const, 0, ""},
+		{"IsGraphic", Func, 6, "func(r rune) bool"},
+		{"IsPrint", Func, 0, "func(r rune) bool"},
+		{"Itoa", Func, 0, "func(i int) string"},
+		{"NumError", Type, 0, ""},
+		{"NumError.Err", Field, 0, ""},
+		{"NumError.Func", Field, 0, ""},
+		{"NumError.Num", Field, 0, ""},
+		{"ParseBool", Func, 0, "func(str string) (bool, error)"},
+		{"ParseComplex", Func, 15, "func(s string, bitSize int) (complex128, error)"},
+		{"ParseFloat", Func, 0, "func(s string, bitSize int) (float64, error)"},
+		{"ParseInt", Func, 0, "func(s string, base int, bitSize int) (i int64, err error)"},
+		{"ParseUint", Func, 0, "func(s string, base int, bitSize int) (uint64, error)"},
+		{"Quote", Func, 0, "func(s string) string"},
+		{"QuoteRune", Func, 0, "func(r rune) string"},
+		{"QuoteRuneToASCII", Func, 0, "func(r rune) string"},
+		{"QuoteRuneToGraphic", Func, 6, "func(r rune) string"},
+		{"QuoteToASCII", Func, 0, "func(s string) string"},
+		{"QuoteToGraphic", Func, 6, "func(s string) string"},
+		{"QuotedPrefix", Func, 17, "func(s string) (string, error)"},
+		{"Unquote", Func, 0, "func(s string) (string, error)"},
+		{"UnquoteChar", Func, 0, "func(s string, quote byte) (value rune, multibyte bool, tail string, err error)"},
+	},
+	"strings": {
+		{"(*Builder).Cap", Method, 12, ""},
+		{"(*Builder).Grow", Method, 10, ""},
+		{"(*Builder).Len", Method, 10, ""},
+		{"(*Builder).Reset", Method, 10, ""},
+		{"(*Builder).String", Method, 10, ""},
+		{"(*Builder).Write", Method, 10, ""},
+		{"(*Builder).WriteByte", Method, 10, ""},
+		{"(*Builder).WriteRune", Method, 10, ""},
+		{"(*Builder).WriteString", Method, 10, ""},
+		{"(*Reader).Len", Method, 0, ""},
+		{"(*Reader).Read", Method, 0, ""},
+		{"(*Reader).ReadAt", Method, 0, ""},
+		{"(*Reader).ReadByte", Method, 0, ""},
+		{"(*Reader).ReadRune", Method, 0, ""},
+		{"(*Reader).Reset", Method, 7, ""},
+		{"(*Reader).Seek", Method, 0, ""},
+		{"(*Reader).Size", Method, 5, ""},
+		{"(*Reader).UnreadByte", Method, 0, ""},
+		{"(*Reader).UnreadRune", Method, 0, ""},
+		{"(*Reader).WriteTo", Method, 1, ""},
+		{"(*Replacer).Replace", Method, 0, ""},
+		{"(*Replacer).WriteString", Method, 0, ""},
+		{"Builder", Type, 10, ""},
+		{"Clone", Func, 18, "func(s string) string"},
+		{"Compare", Func, 5, "func(a string, b string) int"},
+		{"Contains", Func, 0, "func(s string, substr string) bool"},
+		{"ContainsAny", Func, 0, "func(s string, chars string) bool"},
+		{"ContainsFunc", Func, 21, "func(s string, f func(rune) bool) bool"},
+		{"ContainsRune", Func, 0, "func(s string, r rune) bool"},
+		{"Count", Func, 0, "func(s string, substr string) int"},
+		{"Cut", Func, 18, "func(s string, sep string) (before string, after string, found bool)"},
+		{"CutLast", Func, 27, "func(s string, sep string) (before string, after string, found bool)"},
+		{"CutPrefix", Func, 20, "func(s string, prefix string) (after string, found bool)"},
+		{"CutSuffix", Func, 20, "func(s string, suffix string) (before string, found bool)"},
+		{"EqualFold", Func, 0, "func(s string, t string) bool"},
+		{"Fields", Func, 0, "func(s string) []string"},
+		{"FieldsFunc", Func, 0, "func(s string, f func(rune) bool) []string"},
+		{"FieldsFuncSeq", Func, 24, "func(s string, f func(rune) bool) iter.Seq[string]"},
+		{"FieldsSeq", Func, 24, "func(s string) iter.Seq[string]"},
+		{"HasPrefix", Func, 0, "func(s string, prefix string) bool"},
+		{"HasSuffix", Func, 0, "func(s string, suffix string) bool"},
+		{"Index", Func, 0, "func(s string, substr string) int"},
+		{"IndexAny", Func, 0, "func(s string, chars string) int"},
+		{"IndexByte", Func, 2, "func(s string, c byte) int"},
+		{"IndexFunc", Func, 0, "func(s string, f func(rune) bool) int"},
+		{"IndexRune", Func, 0, "func(s string, r rune) int"},
+		{"Join", Func, 0, "func(elems []string, sep string) string"},
+		{"LastIndex", Func, 0, "func(s string, substr string) int"},
+		{"LastIndexAny", Func, 0, "func(s string, chars string) int"},
+		{"LastIndexByte", Func, 5, "func(s string, c byte) int"},
+		{"LastIndexFunc", Func, 0, "func(s string, f func(rune) bool) int"},
+		{"Lines", Func, 24, "func(s string) iter.Seq[string]"},
+		{"Map", Func, 0, "func(mapping func(rune) rune, s string) string"},
+		{"NewReader", Func, 0, "func(s string) *Reader"},
+		{"NewReplacer", Func, 0, "func(oldnew ...string) *Replacer"},
+		{"Reader", Type, 0, ""},
+		{"Repeat", Func, 0, "func(s string, count int) string"},
+		{"Replace", Func, 0, "func(s string, old string, new string, n int) string"},
+		{"ReplaceAll", Func, 12, "func(s string, old string, new string) string"},
+		{"Replacer", Type, 0, ""},
+		{"Split", Func, 0, "func(s string, sep string) []string"},
+		{"SplitAfter", Func, 0, "func(s string, sep string) []string"},
+		{"SplitAfterN", Func, 0, "func(s string, sep string, n int) []string"},
+		{"SplitAfterSeq", Func, 24, "func(s string, sep string) iter.Seq[string]"},
+		{"SplitN", Func, 0, "func(s string, sep string, n int) []string"},
+		{"SplitSeq", Func, 24, "func(s string, sep string) iter.Seq[string]"},
+		{"Title", Func, 0, "func(s string) string"},
+		{"ToLower", Func, 0, "func(s string) string"},
+		{"ToLowerSpecial", Func, 0, "func(c unicode.SpecialCase, s string) string"},
+		{"ToTitle", Func, 0, "func(s string) string"},
+		{"ToTitleSpecial", Func, 0, "func(c unicode.SpecialCase, s string) string"},
+		{"ToUpper", Func, 0, "func(s string) string"},
+		{"ToUpperSpecial", Func, 0, "func(c unicode.SpecialCase, s string) string"},
+		{"ToValidUTF8", Func, 13, "func(s string, replacement string) string"},
+		{"Trim", Func, 0, "func(s string, cutset string) string"},
+		{"TrimFunc", Func, 0, "func(s string, f func(rune) bool) string"},
+		{"TrimLeft", Func, 0, "func(s string, cutset string) string"},
+		{"TrimLeftFunc", Func, 0, "func(s string, f func(rune) bool) string"},
+		{"TrimPrefix", Func, 1, "func(s string, prefix string) string"},
+		{"TrimRight", Func, 0, "func(s string, cutset string) string"},
+		{"TrimRightFunc", Func, 0, "func(s string, f func(rune) bool) string"},
+		{"TrimSpace", Func, 0, "func(s string) string"},
+		{"TrimSuffix", Func, 1, "func(s string, suffix string) string"},
+	},
+	"structs": {
+		{"HostLayout", Type, 23, ""},
+	},
+	"sync": {
+		{"(*Cond).Broadcast", Method, 0, ""},
+		{"(*Cond).Signal", Method, 0, ""},
+		{"(*Cond).Wait", Method, 0, ""},
+		{"(*Map).Clear", Method, 23, ""},
+		{"(*Map).CompareAndDelete", Method, 20, ""},
+		{"(*Map).CompareAndSwap", Method, 20, ""},
+		{"(*Map).Delete", Method, 9, ""},
+		{"(*Map).Load", Method, 9, ""},
+		{"(*Map).LoadAndDelete", Method, 15, ""},
+		{"(*Map).LoadOrStore", Method, 9, ""},
+		{"(*Map).Range", Method, 9, ""},
+		{"(*Map).Store", Method, 9, ""},
+		{"(*Map).Swap", Method, 20, ""},
+		{"(*Mutex).Lock", Method, 0, ""},
+		{"(*Mutex).TryLock", Method, 18, ""},
+		{"(*Mutex).Unlock", Method, 0, ""},
+		{"(*Once).Do", Method, 0, ""},
+		{"(*Pool).Get", Method, 3, ""},
+		{"(*Pool).Put", Method, 3, ""},
+		{"(*RWMutex).Lock", Method, 0, ""},
+		{"(*RWMutex).RLock", Method, 0, ""},
+		{"(*RWMutex).RLocker", Method, 0, ""},
+		{"(*RWMutex).RUnlock", Method, 0, ""},
+		{"(*RWMutex).TryLock", Method, 18, ""},
+		{"(*RWMutex).TryRLock", Method, 18, ""},
+		{"(*RWMutex).Unlock", Method, 0, ""},
+		{"(*WaitGroup).Add", Method, 0, ""},
+		{"(*WaitGroup).Done", Method, 0, ""},
+		{"(*WaitGroup).Go", Method, 25, ""},
+		{"(*WaitGroup).Wait", Method, 0, ""},
+		{"(Locker).Lock", Method, 0, ""},
+		{"(Locker).Unlock", Method, 0, ""},
+		{"Cond", Type, 0, ""},
+		{"Cond.L", Field, 0, ""},
+		{"Locker", Type, 0, ""},
+		{"Map", Type, 9, ""},
+		{"Mutex", Type, 0, ""},
+		{"NewCond", Func, 0, "func(l Locker) *Cond"},
+		{"Once", Type, 0, ""},
+		{"OnceFunc", Func, 21, "func(f func()) func()"},
+		{"OnceValue", Func, 21, "func[T any](f func() T) func() T"},
+		{"OnceValues", Func, 21, "func[T1, T2 any](f func() (T1, T2)) func() (T1, T2)"},
+		{"Pool", Type, 3, ""},
+		{"Pool.New", Field, 3, ""},
+		{"RWMutex", Type, 0, ""},
+		{"WaitGroup", Type, 0, ""},
+	},
+	"sync/atomic": {
+		{"(*Bool).CompareAndSwap", Method, 19, ""},
+		{"(*Bool).Load", Method, 19, ""},
+		{"(*Bool).Store", Method, 19, ""},
+		{"(*Bool).Swap", Method, 19, ""},
+		{"(*Int32).Add", Method, 19, ""},
+		{"(*Int32).And", Method, 23, ""},
+		{"(*Int32).CompareAndSwap", Method, 19, ""},
+		{"(*Int32).Load", Method, 19, ""},
+		{"(*Int32).Or", Method, 23, ""},
+		{"(*Int32).Store", Method, 19, ""},
+		{"(*Int32).Swap", Method, 19, ""},
+		{"(*Int64).Add", Method, 19, ""},
+		{"(*Int64).And", Method, 23, ""},
+		{"(*Int64).CompareAndSwap", Method, 19, ""},
+		{"(*Int64).Load", Method, 19, ""},
+		{"(*Int64).Or", Method, 23, ""},
+		{"(*Int64).Store", Method, 19, ""},
+		{"(*Int64).Swap", Method, 19, ""},
+		{"(*Pointer).CompareAndSwap", Method, 19, ""},
+		{"(*Pointer).Load", Method, 19, ""},
+		{"(*Pointer).Store", Method, 19, ""},
+		{"(*Pointer).Swap", Method, 19, ""},
+		{"(*Uint32).Add", Method, 19, ""},
+		{"(*Uint32).And", Method, 23, ""},
+		{"(*Uint32).CompareAndSwap", Method, 19, ""},
+		{"(*Uint32).Load", Method, 19, ""},
+		{"(*Uint32).Or", Method, 23, ""},
+		{"(*Uint32).Store", Method, 19, ""},
+		{"(*Uint32).Swap", Method, 19, ""},
+		{"(*Uint64).Add", Method, 19, ""},
+		{"(*Uint64).And", Method, 23, ""},
+		{"(*Uint64).CompareAndSwap", Method, 19, ""},
+		{"(*Uint64).Load", Method, 19, ""},
+		{"(*Uint64).Or", Method, 23, ""},
+		{"(*Uint64).Store", Method, 19, ""},
+		{"(*Uint64).Swap", Method, 19, ""},
+		{"(*Uintptr).Add", Method, 19, ""},
+		{"(*Uintptr).And", Method, 23, ""},
+		{"(*Uintptr).CompareAndSwap", Method, 19, ""},
+		{"(*Uintptr).Load", Method, 19, ""},
+		{"(*Uintptr).Or", Method, 23, ""},
+		{"(*Uintptr).Store", Method, 19, ""},
+		{"(*Uintptr).Swap", Method, 19, ""},
+		{"(*Value).CompareAndSwap", Method, 17, ""},
+		{"(*Value).Load", Method, 4, ""},
+		{"(*Value).Store", Method, 4, ""},
+		{"(*Value).Swap", Method, 17, ""},
+		{"AddInt32", Func, 0, "func(addr *int32, delta int32) (new int32)"},
+		{"AddInt64", Func, 0, "func(addr *int64, delta int64) (new int64)"},
+		{"AddUint32", Func, 0, "func(addr *uint32, delta uint32) (new uint32)"},
+		{"AddUint64", Func, 0, "func(addr *uint64, delta uint64) (new uint64)"},
+		{"AddUintptr", Func, 0, "func(addr *uintptr, delta uintptr) (new uintptr)"},
+		{"AndInt32", Func, 23, "func(addr *int32, mask int32) (old int32)"},
+		{"AndInt64", Func, 23, "func(addr *int64, mask int64) (old int64)"},
+		{"AndUint32", Func, 23, "func(addr *uint32, mask uint32) (old uint32)"},
+		{"AndUint64", Func, 23, "func(addr *uint64, mask uint64) (old uint64)"},
+		{"AndUintptr", Func, 23, "func(addr *uintptr, mask uintptr) (old uintptr)"},
+		{"Bool", Type, 19, ""},
+		{"CompareAndSwapInt32", Func, 0, "func(addr *int32, old int32, new int32) (swapped bool)"},
+		{"CompareAndSwapInt64", Func, 0, "func(addr *int64, old int64, new int64) (swapped bool)"},
+		{"CompareAndSwapPointer", Func, 0, "func(addr *unsafe.Pointer, old unsafe.Pointer, new unsafe.Pointer) (swapped bool)"},
+		{"CompareAndSwapUint32", Func, 0, "func(addr *uint32, old uint32, new uint32) (swapped bool)"},
+		{"CompareAndSwapUint64", Func, 0, "func(addr *uint64, old uint64, new uint64) (swapped bool)"},
+		{"CompareAndSwapUintptr", Func, 0, "func(addr *uintptr, old uintptr, new uintptr) (swapped bool)"},
+		{"Int32", Type, 19, ""},
+		{"Int64", Type, 19, ""},
+		{"LoadInt32", Func, 0, "func(addr *int32) (val int32)"},
+		{"LoadInt64", Func, 0, "func(addr *int64) (val int64)"},
+		{"LoadPointer", Func, 0, "func(addr *unsafe.Pointer) (val unsafe.Pointer)"},
+		{"LoadUint32", Func, 0, "func(addr *uint32) (val uint32)"},
+		{"LoadUint64", Func, 0, "func(addr *uint64) (val uint64)"},
+		{"LoadUintptr", Func, 0, "func(addr *uintptr) (val uintptr)"},
+		{"OrInt32", Func, 23, "func(addr *int32, mask int32) (old int32)"},
+		{"OrInt64", Func, 23, "func(addr *int64, mask int64) (old int64)"},
+		{"OrUint32", Func, 23, "func(addr *uint32, mask uint32) (old uint32)"},
+		{"OrUint64", Func, 23, "func(addr *uint64, mask uint64) (old uint64)"},
+		{"OrUintptr", Func, 23, "func(addr *uintptr, mask uintptr) (old uintptr)"},
+		{"Pointer", Type, 19, ""},
+		{"StoreInt32", Func, 0, "func(addr *int32, val int32)"},
+		{"StoreInt64", Func, 0, "func(addr *int64, val int64)"},
+		{"StorePointer", Func, 0, "func(addr *unsafe.Pointer, val unsafe.Pointer)"},
+		{"StoreUint32", Func, 0, "func(addr *uint32, val uint32)"},
+		{"StoreUint64", Func, 0, "func(addr *uint64, val uint64)"},
+		{"StoreUintptr", Func, 0, "func(addr *uintptr, val uintptr)"},
+		{"SwapInt32", Func, 2, "func(addr *int32, new int32) (old int32)"},
+		{"SwapInt64", Func, 2, "func(addr *int64, new int64) (old int64)"},
+		{"SwapPointer", Func, 2, "func(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)"},
+		{"SwapUint32", Func, 2, "func(addr *uint32, new uint32) (old uint32)"},
+		{"SwapUint64", Func, 2, "func(addr *uint64, new uint64) (old uint64)"},
+		{"SwapUintptr", Func, 2, "func(addr *uintptr, new uintptr) (old uintptr)"},
+		{"Uint32", Type, 19, ""},
+		{"Uint64", Type, 19, ""},
+		{"Uintptr", Type, 19, ""},
+		{"Value", Type, 4, ""},
+	},
+	"syscall": {
+		{"(*Cmsghdr).SetLen", Method, 0, ""},
+		{"(*DLL).FindProc", Method, 0, ""},
+		{"(*DLL).MustFindProc", Method, 0, ""},
+		{"(*DLL).Release", Method, 0, ""},
+		{"(*DLLError).Error", Method, 0, ""},
+		{"(*DLLError).Unwrap", Method, 16, ""},
+		{"(*Filetime).Nanoseconds", Method, 0, ""},
+		{"(*Iovec).SetLen", Method, 0, ""},
+		{"(*LazyDLL).Handle", Method, 0, ""},
+		{"(*LazyDLL).Load", Method, 0, ""},
+		{"(*LazyDLL).NewProc", Method, 0, ""},
+		{"(*LazyProc).Addr", Method, 0, ""},
+		{"(*LazyProc).Call", Method, 0, ""},
+		{"(*LazyProc).Find", Method, 0, ""},
+		{"(*Msghdr).SetControllen", Method, 0, ""},
+		{"(*Proc).Addr", Method, 0, ""},
+		{"(*Proc).Call", Method, 0, ""},
+		{"(*PtraceRegs).PC", Method, 0, ""},
+		{"(*PtraceRegs).SetPC", Method, 0, ""},
+		{"(*RawSockaddrAny).Sockaddr", Method, 0, ""},
+		{"(*SID).Copy", Method, 0, ""},
+		{"(*SID).Len", Method, 0, ""},
+		{"(*SID).LookupAccount", Method, 0, ""},
+		{"(*SID).String", Method, 0, ""},
+		{"(*Timespec).Nano", Method, 0, ""},
+		{"(*Timespec).Unix", Method, 0, ""},
+		{"(*Timeval).Nano", Method, 0, ""},
+		{"(*Timeval).Nanoseconds", Method, 0, ""},
+		{"(*Timeval).Unix", Method, 0, ""},
+		{"(Conn).SyscallConn", Method, 9, ""},
+		{"(Errno).Error", Method, 0, ""},
+		{"(Errno).Is", Method, 13, ""},
+		{"(Errno).Temporary", Method, 0, ""},
+		{"(Errno).Timeout", Method, 0, ""},
+		{"(RawConn).Control", Method, 9, ""},
+		{"(RawConn).Read", Method, 9, ""},
+		{"(RawConn).Write", Method, 9, ""},
+		{"(Signal).Signal", Method, 0, ""},
+		{"(Signal).String", Method, 0, ""},
+		{"(Token).Close", Method, 0, ""},
+		{"(Token).GetTokenPrimaryGroup", Method, 0, ""},
+		{"(Token).GetTokenUser", Method, 0, ""},
+		{"(Token).GetUserProfileDirectory", Method, 0, ""},
+		{"(WaitStatus).Continued", Method, 0, ""},
+		{"(WaitStatus).CoreDump", Method, 0, ""},
+		{"(WaitStatus).ExitStatus", Method, 0, ""},
+		{"(WaitStatus).Exited", Method, 0, ""},
+		{"(WaitStatus).Signal", Method, 0, ""},
+		{"(WaitStatus).Signaled", Method, 0, ""},
+		{"(WaitStatus).StopSignal", Method, 0, ""},
+		{"(WaitStatus).Stopped", Method, 0, ""},
+		{"(WaitStatus).TrapCause", Method, 0, ""},
+		{"AF_ALG", Const, 0, ""},
+		{"AF_APPLETALK", Const, 0, ""},
+		{"AF_ARP", Const, 0, ""},
+		{"AF_ASH", Const, 0, ""},
+		{"AF_ATM", Const, 0, ""},
+		{"AF_ATMPVC", Const, 0, ""},
+		{"AF_ATMSVC", Const, 0, ""},
+		{"AF_AX25", Const, 0, ""},
+		{"AF_BLUETOOTH", Const, 0, ""},
+		{"AF_BRIDGE", Const, 0, ""},
+		{"AF_CAIF", Const, 0, ""},
+		{"AF_CAN", Const, 0, ""},
+		{"AF_CCITT", Const, 0, ""},
+		{"AF_CHAOS", Const, 0, ""},
+		{"AF_CNT", Const, 0, ""},
+		{"AF_COIP", Const, 0, ""},
+		{"AF_DATAKIT", Const, 0, ""},
+		{"AF_DECnet", Const, 0, ""},
+		{"AF_DLI", Const, 0, ""},
+		{"AF_E164", Const, 0, ""},
+		{"AF_ECMA", Const, 0, ""},
+		{"AF_ECONET", Const, 0, ""},
+		{"AF_ENCAP", Const, 1, ""},
+		{"AF_FILE", Const, 0, ""},
+		{"AF_HYLINK", Const, 0, ""},
+		{"AF_IEEE80211", Const, 0, ""},
+		{"AF_IEEE802154", Const, 0, ""},
+		{"AF_IMPLINK", Const, 0, ""},
+		{"AF_INET", Const, 0, ""},
+		{"AF_INET6", Const, 0, ""},
+		{"AF_INET6_SDP", Const, 3, ""},
+		{"AF_INET_SDP", Const, 3, ""},
+		{"AF_IPX", Const, 0, ""},
+		{"AF_IRDA", Const, 0, ""},
+		{"AF_ISDN", Const, 0, ""},
+		{"AF_ISO", Const, 0, ""},
+		{"AF_IUCV", Const, 0, ""},
+		{"AF_KEY", Const, 0, ""},
+		{"AF_LAT", Const, 0, ""},
+		{"AF_LINK", Const, 0, ""},
+		{"AF_LLC", Const, 0, ""},
+		{"AF_LOCAL", Const, 0, ""},
+		{"AF_MAX", Const, 0, ""},
+		{"AF_MPLS", Const, 1, ""},
+		{"AF_NATM", Const, 0, ""},
+		{"AF_NDRV", Const, 0, ""},
+		{"AF_NETBEUI", Const, 0, ""},
+		{"AF_NETBIOS", Const, 0, ""},
+		{"AF_NETGRAPH", Const, 0, ""},
+		{"AF_NETLINK", Const, 0, ""},
+		{"AF_NETROM", Const, 0, ""},
+		{"AF_NS", Const, 0, ""},
+		{"AF_OROUTE", Const, 1, ""},
+		{"AF_OSI", Const, 0, ""},
+		{"AF_PACKET", Const, 0, ""},
+		{"AF_PHONET", Const, 0, ""},
+		{"AF_PPP", Const, 0, ""},
+		{"AF_PPPOX", Const, 0, ""},
+		{"AF_PUP", Const, 0, ""},
+		{"AF_RDS", Const, 0, ""},
+		{"AF_RESERVED_36", Const, 0, ""},
+		{"AF_ROSE", Const, 0, ""},
+		{"AF_ROUTE", Const, 0, ""},
+		{"AF_RXRPC", Const, 0, ""},
+		{"AF_SCLUSTER", Const, 0, ""},
+		{"AF_SECURITY", Const, 0, ""},
+		{"AF_SIP", Const, 0, ""},
+		{"AF_SLOW", Const, 0, ""},
+		{"AF_SNA", Const, 0, ""},
+		{"AF_SYSTEM", Const, 0, ""},
+		{"AF_TIPC", Const, 0, ""},
+		{"AF_UNIX", Const, 0, ""},
+		{"AF_UNSPEC", Const, 0, ""},
+		{"AF_UTUN", Const, 16, ""},
+		{"AF_VENDOR00", Const, 0, ""},
+		{"AF_VENDOR01", Const, 0, ""},
+		{"AF_VENDOR02", Const, 0, ""},
+		{"AF_VENDOR03", Const, 0, ""},
+		{"AF_VENDOR04", Const, 0, ""},
+		{"AF_VENDOR05", Const, 0, ""},
+		{"AF_VENDOR06", Const, 0, ""},
+		{"AF_VENDOR07", Const, 0, ""},
+		{"AF_VENDOR08", Const, 0, ""},
+		{"AF_VENDOR09", Const, 0, ""},
+		{"AF_VENDOR10", Const, 0, ""},
+		{"AF_VENDOR11", Const, 0, ""},
+		{"AF_VENDOR12", Const, 0, ""},
+		{"AF_VENDOR13", Const, 0, ""},
+		{"AF_VENDOR14", Const, 0, ""},
+		{"AF_VENDOR15", Const, 0, ""},
+		{"AF_VENDOR16", Const, 0, ""},
+		{"AF_VENDOR17", Const, 0, ""},
+		{"AF_VENDOR18", Const, 0, ""},
+		{"AF_VENDOR19", Const, 0, ""},
+		{"AF_VENDOR20", Const, 0, ""},
+		{"AF_VENDOR21", Const, 0, ""},
+		{"AF_VENDOR22", Const, 0, ""},
+		{"AF_VENDOR23", Const, 0, ""},
+		{"AF_VENDOR24", Const, 0, ""},
+		{"AF_VENDOR25", Const, 0, ""},
+		{"AF_VENDOR26", Const, 0, ""},
+		{"AF_VENDOR27", Const, 0, ""},
+		{"AF_VENDOR28", Const, 0, ""},
+		{"AF_VENDOR29", Const, 0, ""},
+		{"AF_VENDOR30", Const, 0, ""},
+		{"AF_VENDOR31", Const, 0, ""},
+		{"AF_VENDOR32", Const, 0, ""},
+		{"AF_VENDOR33", Const, 0, ""},
+		{"AF_VENDOR34", Const, 0, ""},
+		{"AF_VENDOR35", Const, 0, ""},
+		{"AF_VENDOR36", Const, 0, ""},
+		{"AF_VENDOR37", Const, 0, ""},
+		{"AF_VENDOR38", Const, 0, ""},
+		{"AF_VENDOR39", Const, 0, ""},
+		{"AF_VENDOR40", Const, 0, ""},
+		{"AF_VENDOR41", Const, 0, ""},
+		{"AF_VENDOR42", Const, 0, ""},
+		{"AF_VENDOR43", Const, 0, ""},
+		{"AF_VENDOR44", Const, 0, ""},
+		{"AF_VENDOR45", Const, 0, ""},
+		{"AF_VENDOR46", Const, 0, ""},
+		{"AF_VENDOR47", Const, 0, ""},
+		{"AF_WANPIPE", Const, 0, ""},
+		{"AF_X25", Const, 0, ""},
+		{"AI_CANONNAME", Const, 1, ""},
+		{"AI_NUMERICHOST", Const, 1, ""},
+		{"AI_PASSIVE", Const, 1, ""},
+		{"APPLICATION_ERROR", Const, 0, ""},
+		{"ARPHRD_ADAPT", Const, 0, ""},
+		{"ARPHRD_APPLETLK", Const, 0, ""},
+		{"ARPHRD_ARCNET", Const, 0, ""},
+		{"ARPHRD_ASH", Const, 0, ""},
+		{"ARPHRD_ATM", Const, 0, ""},
+		{"ARPHRD_AX25", Const, 0, ""},
+		{"ARPHRD_BIF", Const, 0, ""},
+		{"ARPHRD_CHAOS", Const, 0, ""},
+		{"ARPHRD_CISCO", Const, 0, ""},
+		{"ARPHRD_CSLIP", Const, 0, ""},
+		{"ARPHRD_CSLIP6", Const, 0, ""},
+		{"ARPHRD_DDCMP", Const, 0, ""},
+		{"ARPHRD_DLCI", Const, 0, ""},
+		{"ARPHRD_ECONET", Const, 0, ""},
+		{"ARPHRD_EETHER", Const, 0, ""},
+		{"ARPHRD_ETHER", Const, 0, ""},
+		{"ARPHRD_EUI64", Const, 0, ""},
+		{"ARPHRD_FCAL", Const, 0, ""},
+		{"ARPHRD_FCFABRIC", Const, 0, ""},
+		{"ARPHRD_FCPL", Const, 0, ""},
+		{"ARPHRD_FCPP", Const, 0, ""},
+		{"ARPHRD_FDDI", Const, 0, ""},
+		{"ARPHRD_FRAD", Const, 0, ""},
+		{"ARPHRD_FRELAY", Const, 1, ""},
+		{"ARPHRD_HDLC", Const, 0, ""},
+		{"ARPHRD_HIPPI", Const, 0, ""},
+		{"ARPHRD_HWX25", Const, 0, ""},
+		{"ARPHRD_IEEE1394", Const, 0, ""},
+		{"ARPHRD_IEEE802", Const, 0, ""},
+		{"ARPHRD_IEEE80211", Const, 0, ""},
+		{"ARPHRD_IEEE80211_PRISM", Const, 0, ""},
+		{"ARPHRD_IEEE80211_RADIOTAP", Const, 0, ""},
+		{"ARPHRD_IEEE802154", Const, 0, ""},
+		{"ARPHRD_IEEE802154_PHY", Const, 0, ""},
+		{"ARPHRD_IEEE802_TR", Const, 0, ""},
+		{"ARPHRD_INFINIBAND", Const, 0, ""},
+		{"ARPHRD_IPDDP", Const, 0, ""},
+		{"ARPHRD_IPGRE", Const, 0, ""},
+		{"ARPHRD_IRDA", Const, 0, ""},
+		{"ARPHRD_LAPB", Const, 0, ""},
+		{"ARPHRD_LOCALTLK", Const, 0, ""},
+		{"ARPHRD_LOOPBACK", Const, 0, ""},
+		{"ARPHRD_METRICOM", Const, 0, ""},
+		{"ARPHRD_NETROM", Const, 0, ""},
+		{"ARPHRD_NONE", Const, 0, ""},
+		{"ARPHRD_PIMREG", Const, 0, ""},
+		{"ARPHRD_PPP", Const, 0, ""},
+		{"ARPHRD_PRONET", Const, 0, ""},
+		{"ARPHRD_RAWHDLC", Const, 0, ""},
+		{"ARPHRD_ROSE", Const, 0, ""},
+		{"ARPHRD_RSRVD", Const, 0, ""},
+		{"ARPHRD_SIT", Const, 0, ""},
+		{"ARPHRD_SKIP", Const, 0, ""},
+		{"ARPHRD_SLIP", Const, 0, ""},
+		{"ARPHRD_SLIP6", Const, 0, ""},
+		{"ARPHRD_STRIP", Const, 1, ""},
+		{"ARPHRD_TUNNEL", Const, 0, ""},
+		{"ARPHRD_TUNNEL6", Const, 0, ""},
+		{"ARPHRD_VOID", Const, 0, ""},
+		{"ARPHRD_X25", Const, 0, ""},
+		{"AUTHTYPE_CLIENT", Const, 0, ""},
+		{"AUTHTYPE_SERVER", Const, 0, ""},
+		{"Accept", Func, 0, "func(fd int) (nfd int, sa Sockaddr, err error)"},
+		{"Accept4", Func, 1, "func(fd int, flags int) (nfd int, sa Sockaddr, err error)"},
+		{"AcceptEx", Func, 0, ""},
+		{"Access", Func, 0, "func(path string, mode uint32) (err error)"},
+		{"Acct", Func, 0, "func(path string) (err error)"},
+		{"AddrinfoW", Type, 1, ""},
+		{"AddrinfoW.Addr", Field, 1, ""},
+		{"AddrinfoW.Addrlen", Field, 1, ""},
+		{"AddrinfoW.Canonname", Field, 1, ""},
+		{"AddrinfoW.Family", Field, 1, ""},
+		{"AddrinfoW.Flags", Field, 1, ""},
+		{"AddrinfoW.Next", Field, 1, ""},
+		{"AddrinfoW.Protocol", Field, 1, ""},
+		{"AddrinfoW.Socktype", Field, 1, ""},
+		{"Adjtime", Func, 0, ""},
+		{"Adjtimex", Func, 0, "func(buf *Timex) (state int, err error)"},
+		{"AllThreadsSyscall", Func, 16, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err Errno)"},
+		{"AllThreadsSyscall6", Func, 16, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err Errno)"},
+		{"AttachLsf", Func, 0, "func(fd int, i []SockFilter) error"},
+		{"B0", Const, 0, ""},
+		{"B1000000", Const, 0, ""},
+		{"B110", Const, 0, ""},
+		{"B115200", Const, 0, ""},
+		{"B1152000", Const, 0, ""},
+		{"B1200", Const, 0, ""},
+		{"B134", Const, 0, ""},
+		{"B14400", Const, 1, ""},
+		{"B150", Const, 0, ""},
+		{"B1500000", Const, 0, ""},
+		{"B1800", Const, 0, ""},
+		{"B19200", Const, 0, ""},
+		{"B200", Const, 0, ""},
+		{"B2000000", Const, 0, ""},
+		{"B230400", Const, 0, ""},
+		{"B2400", Const, 0, ""},
+		{"B2500000", Const, 0, ""},
+		{"B28800", Const, 1, ""},
+		{"B300", Const, 0, ""},
+		{"B3000000", Const, 0, ""},
+		{"B3500000", Const, 0, ""},
+		{"B38400", Const, 0, ""},
+		{"B4000000", Const, 0, ""},
+		{"B460800", Const, 0, ""},
+		{"B4800", Const, 0, ""},
+		{"B50", Const, 0, ""},
+		{"B500000", Const, 0, ""},
+		{"B57600", Const, 0, ""},
+		{"B576000", Const, 0, ""},
+		{"B600", Const, 0, ""},
+		{"B7200", Const, 1, ""},
+		{"B75", Const, 0, ""},
+		{"B76800", Const, 1, ""},
+		{"B921600", Const, 0, ""},
+		{"B9600", Const, 0, ""},
+		{"BASE_PROTOCOL", Const, 2, ""},
+		{"BIOCFEEDBACK", Const, 0, ""},
+		{"BIOCFLUSH", Const, 0, ""},
+		{"BIOCGBLEN", Const, 0, ""},
+		{"BIOCGDIRECTION", Const, 0, ""},
+		{"BIOCGDIRFILT", Const, 1, ""},
+		{"BIOCGDLT", Const, 0, ""},
+		{"BIOCGDLTLIST", Const, 0, ""},
+		{"BIOCGETBUFMODE", Const, 0, ""},
+		{"BIOCGETIF", Const, 0, ""},
+		{"BIOCGETZMAX", Const, 0, ""},
+		{"BIOCGFEEDBACK", Const, 1, ""},
+		{"BIOCGFILDROP", Const, 1, ""},
+		{"BIOCGHDRCMPLT", Const, 0, ""},
+		{"BIOCGRSIG", Const, 0, ""},
+		{"BIOCGRTIMEOUT", Const, 0, ""},
+		{"BIOCGSEESENT", Const, 0, ""},
+		{"BIOCGSTATS", Const, 0, ""},
+		{"BIOCGSTATSOLD", Const, 1, ""},
+		{"BIOCGTSTAMP", Const, 1, ""},
+		{"BIOCIMMEDIATE", Const, 0, ""},
+		{"BIOCLOCK", Const, 0, ""},
+		{"BIOCPROMISC", Const, 0, ""},
+		{"BIOCROTZBUF", Const, 0, ""},
+		{"BIOCSBLEN", Const, 0, ""},
+		{"BIOCSDIRECTION", Const, 0, ""},
+		{"BIOCSDIRFILT", Const, 1, ""},
+		{"BIOCSDLT", Const, 0, ""},
+		{"BIOCSETBUFMODE", Const, 0, ""},
+		{"BIOCSETF", Const, 0, ""},
+		{"BIOCSETFNR", Const, 0, ""},
+		{"BIOCSETIF", Const, 0, ""},
+		{"BIOCSETWF", Const, 0, ""},
+		{"BIOCSETZBUF", Const, 0, ""},
+		{"BIOCSFEEDBACK", Const, 1, ""},
+		{"BIOCSFILDROP", Const, 1, ""},
+		{"BIOCSHDRCMPLT", Const, 0, ""},
+		{"BIOCSRSIG", Const, 0, ""},
+		{"BIOCSRTIMEOUT", Const, 0, ""},
+		{"BIOCSSEESENT", Const, 0, ""},
+		{"BIOCSTCPF", Const, 1, ""},
+		{"BIOCSTSTAMP", Const, 1, ""},
+		{"BIOCSUDPF", Const, 1, ""},
+		{"BIOCVERSION", Const, 0, ""},
+		{"BPF_A", Const, 0, ""},
+		{"BPF_ABS", Const, 0, ""},
+		{"BPF_ADD", Const, 0, ""},
+		{"BPF_ALIGNMENT", Const, 0, ""},
+		{"BPF_ALIGNMENT32", Const, 1, ""},
+		{"BPF_ALU", Const, 0, ""},
+		{"BPF_AND", Const, 0, ""},
+		{"BPF_B", Const, 0, ""},
+		{"BPF_BUFMODE_BUFFER", Const, 0, ""},
+		{"BPF_BUFMODE_ZBUF", Const, 0, ""},
+		{"BPF_DFLTBUFSIZE", Const, 1, ""},
+		{"BPF_DIRECTION_IN", Const, 1, ""},
+		{"BPF_DIRECTION_OUT", Const, 1, ""},
+		{"BPF_DIV", Const, 0, ""},
+		{"BPF_H", Const, 0, ""},
+		{"BPF_IMM", Const, 0, ""},
+		{"BPF_IND", Const, 0, ""},
+		{"BPF_JA", Const, 0, ""},
+		{"BPF_JEQ", Const, 0, ""},
+		{"BPF_JGE", Const, 0, ""},
+		{"BPF_JGT", Const, 0, ""},
+		{"BPF_JMP", Const, 0, ""},
+		{"BPF_JSET", Const, 0, ""},
+		{"BPF_K", Const, 0, ""},
+		{"BPF_LD", Const, 0, ""},
+		{"BPF_LDX", Const, 0, ""},
+		{"BPF_LEN", Const, 0, ""},
+		{"BPF_LSH", Const, 0, ""},
+		{"BPF_MAJOR_VERSION", Const, 0, ""},
+		{"BPF_MAXBUFSIZE", Const, 0, ""},
+		{"BPF_MAXINSNS", Const, 0, ""},
+		{"BPF_MEM", Const, 0, ""},
+		{"BPF_MEMWORDS", Const, 0, ""},
+		{"BPF_MINBUFSIZE", Const, 0, ""},
+		{"BPF_MINOR_VERSION", Const, 0, ""},
+		{"BPF_MISC", Const, 0, ""},
+		{"BPF_MSH", Const, 0, ""},
+		{"BPF_MUL", Const, 0, ""},
+		{"BPF_NEG", Const, 0, ""},
+		{"BPF_OR", Const, 0, ""},
+		{"BPF_RELEASE", Const, 0, ""},
+		{"BPF_RET", Const, 0, ""},
+		{"BPF_RSH", Const, 0, ""},
+		{"BPF_ST", Const, 0, ""},
+		{"BPF_STX", Const, 0, ""},
+		{"BPF_SUB", Const, 0, ""},
+		{"BPF_TAX", Const, 0, ""},
+		{"BPF_TXA", Const, 0, ""},
+		{"BPF_T_BINTIME", Const, 1, ""},
+		{"BPF_T_BINTIME_FAST", Const, 1, ""},
+		{"BPF_T_BINTIME_MONOTONIC", Const, 1, ""},
+		{"BPF_T_BINTIME_MONOTONIC_FAST", Const, 1, ""},
+		{"BPF_T_FAST", Const, 1, ""},
+		{"BPF_T_FLAG_MASK", Const, 1, ""},
+		{"BPF_T_FORMAT_MASK", Const, 1, ""},
+		{"BPF_T_MICROTIME", Const, 1, ""},
+		{"BPF_T_MICROTIME_FAST", Const, 1, ""},
+		{"BPF_T_MICROTIME_MONOTONIC", Const, 1, ""},
+		{"BPF_T_MICROTIME_MONOTONIC_FAST", Const, 1, ""},
+		{"BPF_T_MONOTONIC", Const, 1, ""},
+		{"BPF_T_MONOTONIC_FAST", Const, 1, ""},
+		{"BPF_T_NANOTIME", Const, 1, ""},
+		{"BPF_T_NANOTIME_FAST", Const, 1, ""},
+		{"BPF_T_NANOTIME_MONOTONIC", Const, 1, ""},
+		{"BPF_T_NANOTIME_MONOTONIC_FAST", Const, 1, ""},
+		{"BPF_T_NONE", Const, 1, ""},
+		{"BPF_T_NORMAL", Const, 1, ""},
+		{"BPF_W", Const, 0, ""},
+		{"BPF_X", Const, 0, ""},
+		{"BRKINT", Const, 0, ""},
+		{"Bind", Func, 0, "func(fd int, sa Sockaddr) (err error)"},
+		{"BindToDevice", Func, 0, "func(fd int, device string) (err error)"},
+		{"BpfBuflen", Func, 0, ""},
+		{"BpfDatalink", Func, 0, ""},
+		{"BpfHdr", Type, 0, ""},
+		{"BpfHdr.Caplen", Field, 0, ""},
+		{"BpfHdr.Datalen", Field, 0, ""},
+		{"BpfHdr.Hdrlen", Field, 0, ""},
+		{"BpfHdr.Pad_cgo_0", Field, 0, ""},
+		{"BpfHdr.Tstamp", Field, 0, ""},
+		{"BpfHeadercmpl", Func, 0, ""},
+		{"BpfInsn", Type, 0, ""},
+		{"BpfInsn.Code", Field, 0, ""},
+		{"BpfInsn.Jf", Field, 0, ""},
+		{"BpfInsn.Jt", Field, 0, ""},
+		{"BpfInsn.K", Field, 0, ""},
+		{"BpfInterface", Func, 0, ""},
+		{"BpfJump", Func, 0, ""},
+		{"BpfProgram", Type, 0, ""},
+		{"BpfProgram.Insns", Field, 0, ""},
+		{"BpfProgram.Len", Field, 0, ""},
+		{"BpfProgram.Pad_cgo_0", Field, 0, ""},
+		{"BpfStat", Type, 0, ""},
+		{"BpfStat.Capt", Field, 2, ""},
+		{"BpfStat.Drop", Field, 0, ""},
+		{"BpfStat.Padding", Field, 2, ""},
+		{"BpfStat.Recv", Field, 0, ""},
+		{"BpfStats", Func, 0, ""},
+		{"BpfStmt", Func, 0, ""},
+		{"BpfTimeout", Func, 0, ""},
+		{"BpfTimeval", Type, 2, ""},
+		{"BpfTimeval.Sec", Field, 2, ""},
+		{"BpfTimeval.Usec", Field, 2, ""},
+		{"BpfVersion", Type, 0, ""},
+		{"BpfVersion.Major", Field, 0, ""},
+		{"BpfVersion.Minor", Field, 0, ""},
+		{"BpfZbuf", Type, 0, ""},
+		{"BpfZbuf.Bufa", Field, 0, ""},
+		{"BpfZbuf.Bufb", Field, 0, ""},
+		{"BpfZbuf.Buflen", Field, 0, ""},
+		{"BpfZbufHeader", Type, 0, ""},
+		{"BpfZbufHeader.Kernel_gen", Field, 0, ""},
+		{"BpfZbufHeader.Kernel_len", Field, 0, ""},
+		{"BpfZbufHeader.User_gen", Field, 0, ""},
+		{"BpfZbufHeader.X_bzh_pad", Field, 0, ""},
+		{"ByHandleFileInformation", Type, 0, ""},
+		{"ByHandleFileInformation.CreationTime", Field, 0, ""},
+		{"ByHandleFileInformation.FileAttributes", Field, 0, ""},
+		{"ByHandleFileInformation.FileIndexHigh", Field, 0, ""},
+		{"ByHandleFileInformation.FileIndexLow", Field, 0, ""},
+		{"ByHandleFileInformation.FileSizeHigh", Field, 0, ""},
+		{"ByHandleFileInformation.FileSizeLow", Field, 0, ""},
+		{"ByHandleFileInformation.LastAccessTime", Field, 0, ""},
+		{"ByHandleFileInformation.LastWriteTime", Field, 0, ""},
+		{"ByHandleFileInformation.NumberOfLinks", Field, 0, ""},
+		{"ByHandleFileInformation.VolumeSerialNumber", Field, 0, ""},
+		{"BytePtrFromString", Func, 1, "func(s string) (*byte, error)"},
+		{"ByteSliceFromString", Func, 1, "func(s string) ([]byte, error)"},
+		{"CCR0_FLUSH", Const, 1, ""},
+		{"CERT_CHAIN_POLICY_AUTHENTICODE", Const, 0, ""},
+		{"CERT_CHAIN_POLICY_AUTHENTICODE_TS", Const, 0, ""},
+		{"CERT_CHAIN_POLICY_BASE", Const, 0, ""},
+		{"CERT_CHAIN_POLICY_BASIC_CONSTRAINTS", Const, 0, ""},
+		{"CERT_CHAIN_POLICY_EV", Const, 0, ""},
+		{"CERT_CHAIN_POLICY_MICROSOFT_ROOT", Const, 0, ""},
+		{"CERT_CHAIN_POLICY_NT_AUTH", Const, 0, ""},
+		{"CERT_CHAIN_POLICY_SSL", Const, 0, ""},
+		{"CERT_E_CN_NO_MATCH", Const, 0, ""},
+		{"CERT_E_EXPIRED", Const, 0, ""},
+		{"CERT_E_PURPOSE", Const, 0, ""},
+		{"CERT_E_ROLE", Const, 0, ""},
+		{"CERT_E_UNTRUSTEDROOT", Const, 0, ""},
+		{"CERT_STORE_ADD_ALWAYS", Const, 0, ""},
+		{"CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG", Const, 0, ""},
+		{"CERT_STORE_PROV_MEMORY", Const, 0, ""},
+		{"CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT", Const, 0, ""},
+		{"CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT", Const, 0, ""},
+		{"CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT", Const, 0, ""},
+		{"CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT", Const, 0, ""},
+		{"CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT", Const, 0, ""},
+		{"CERT_TRUST_INVALID_BASIC_CONSTRAINTS", Const, 0, ""},
+		{"CERT_TRUST_INVALID_EXTENSION", Const, 0, ""},
+		{"CERT_TRUST_INVALID_NAME_CONSTRAINTS", Const, 0, ""},
+		{"CERT_TRUST_INVALID_POLICY_CONSTRAINTS", Const, 0, ""},
+		{"CERT_TRUST_IS_CYCLIC", Const, 0, ""},
+		{"CERT_TRUST_IS_EXPLICIT_DISTRUST", Const, 0, ""},
+		{"CERT_TRUST_IS_NOT_SIGNATURE_VALID", Const, 0, ""},
+		{"CERT_TRUST_IS_NOT_TIME_VALID", Const, 0, ""},
+		{"CERT_TRUST_IS_NOT_VALID_FOR_USAGE", Const, 0, ""},
+		{"CERT_TRUST_IS_OFFLINE_REVOCATION", Const, 0, ""},
+		{"CERT_TRUST_IS_REVOKED", Const, 0, ""},
+		{"CERT_TRUST_IS_UNTRUSTED_ROOT", Const, 0, ""},
+		{"CERT_TRUST_NO_ERROR", Const, 0, ""},
+		{"CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY", Const, 0, ""},
+		{"CERT_TRUST_REVOCATION_STATUS_UNKNOWN", Const, 0, ""},
+		{"CFLUSH", Const, 1, ""},
+		{"CLOCAL", Const, 0, ""},
+		{"CLONE_CHILD_CLEARTID", Const, 2, ""},
+		{"CLONE_CHILD_SETTID", Const, 2, ""},
+		{"CLONE_CLEAR_SIGHAND", Const, 20, ""},
+		{"CLONE_CSIGNAL", Const, 3, ""},
+		{"CLONE_DETACHED", Const, 2, ""},
+		{"CLONE_FILES", Const, 2, ""},
+		{"CLONE_FS", Const, 2, ""},
+		{"CLONE_INTO_CGROUP", Const, 20, ""},
+		{"CLONE_IO", Const, 2, ""},
+		{"CLONE_NEWCGROUP", Const, 20, ""},
+		{"CLONE_NEWIPC", Const, 2, ""},
+		{"CLONE_NEWNET", Const, 2, ""},
+		{"CLONE_NEWNS", Const, 2, ""},
+		{"CLONE_NEWPID", Const, 2, ""},
+		{"CLONE_NEWTIME", Const, 20, ""},
+		{"CLONE_NEWUSER", Const, 2, ""},
+		{"CLONE_NEWUTS", Const, 2, ""},
+		{"CLONE_PARENT", Const, 2, ""},
+		{"CLONE_PARENT_SETTID", Const, 2, ""},
+		{"CLONE_PID", Const, 3, ""},
+		{"CLONE_PIDFD", Const, 20, ""},
+		{"CLONE_PTRACE", Const, 2, ""},
+		{"CLONE_SETTLS", Const, 2, ""},
+		{"CLONE_SIGHAND", Const, 2, ""},
+		{"CLONE_SYSVSEM", Const, 2, ""},
+		{"CLONE_THREAD", Const, 2, ""},
+		{"CLONE_UNTRACED", Const, 2, ""},
+		{"CLONE_VFORK", Const, 2, ""},
+		{"CLONE_VM", Const, 2, ""},
+		{"CPUID_CFLUSH", Const, 1, ""},
+		{"CREAD", Const, 0, ""},
+		{"CREATE_ALWAYS", Const, 0, ""},
+		{"CREATE_NEW", Const, 0, ""},
+		{"CREATE_NEW_PROCESS_GROUP", Const, 1, ""},
+		{"CREATE_UNICODE_ENVIRONMENT", Const, 0, ""},
+		{"CRYPT_DEFAULT_CONTAINER_OPTIONAL", Const, 0, ""},
+		{"CRYPT_DELETEKEYSET", Const, 0, ""},
+		{"CRYPT_MACHINE_KEYSET", Const, 0, ""},
+		{"CRYPT_NEWKEYSET", Const, 0, ""},
+		{"CRYPT_SILENT", Const, 0, ""},
+		{"CRYPT_VERIFYCONTEXT", Const, 0, ""},
+		{"CS5", Const, 0, ""},
+		{"CS6", Const, 0, ""},
+		{"CS7", Const, 0, ""},
+		{"CS8", Const, 0, ""},
+		{"CSIZE", Const, 0, ""},
+		{"CSTART", Const, 1, ""},
+		{"CSTATUS", Const, 1, ""},
+		{"CSTOP", Const, 1, ""},
+		{"CSTOPB", Const, 0, ""},
+		{"CSUSP", Const, 1, ""},
+		{"CTL_MAXNAME", Const, 0, ""},
+		{"CTL_NET", Const, 0, ""},
+		{"CTL_QUERY", Const, 1, ""},
+		{"CTRL_BREAK_EVENT", Const, 1, ""},
+		{"CTRL_CLOSE_EVENT", Const, 14, ""},
+		{"CTRL_C_EVENT", Const, 1, ""},
+		{"CTRL_LOGOFF_EVENT", Const, 14, ""},
+		{"CTRL_SHUTDOWN_EVENT", Const, 14, ""},
+		{"CancelIo", Func, 0, ""},
+		{"CancelIoEx", Func, 1, ""},
+		{"CertAddCertificateContextToStore", Func, 0, ""},
+		{"CertChainContext", Type, 0, ""},
+		{"CertChainContext.ChainCount", Field, 0, ""},
+		{"CertChainContext.Chains", Field, 0, ""},
+		{"CertChainContext.HasRevocationFreshnessTime", Field, 0, ""},
+		{"CertChainContext.LowerQualityChainCount", Field, 0, ""},
+		{"CertChainContext.LowerQualityChains", Field, 0, ""},
+		{"CertChainContext.RevocationFreshnessTime", Field, 0, ""},
+		{"CertChainContext.Size", Field, 0, ""},
+		{"CertChainContext.TrustStatus", Field, 0, ""},
+		{"CertChainElement", Type, 0, ""},
+		{"CertChainElement.ApplicationUsage", Field, 0, ""},
+		{"CertChainElement.CertContext", Field, 0, ""},
+		{"CertChainElement.ExtendedErrorInfo", Field, 0, ""},
+		{"CertChainElement.IssuanceUsage", Field, 0, ""},
+		{"CertChainElement.RevocationInfo", Field, 0, ""},
+		{"CertChainElement.Size", Field, 0, ""},
+		{"CertChainElement.TrustStatus", Field, 0, ""},
+		{"CertChainPara", Type, 0, ""},
+		{"CertChainPara.CacheResync", Field, 0, ""},
+		{"CertChainPara.CheckRevocationFreshnessTime", Field, 0, ""},
+		{"CertChainPara.RequestedUsage", Field, 0, ""},
+		{"CertChainPara.RequstedIssuancePolicy", Field, 0, ""},
+		{"CertChainPara.RevocationFreshnessTime", Field, 0, ""},
+		{"CertChainPara.Size", Field, 0, ""},
+		{"CertChainPara.URLRetrievalTimeout", Field, 0, ""},
+		{"CertChainPolicyPara", Type, 0, ""},
+		{"CertChainPolicyPara.ExtraPolicyPara", Field, 0, ""},
+		{"CertChainPolicyPara.Flags", Field, 0, ""},
+		{"CertChainPolicyPara.Size", Field, 0, ""},
+		{"CertChainPolicyStatus", Type, 0, ""},
+		{"CertChainPolicyStatus.ChainIndex", Field, 0, ""},
+		{"CertChainPolicyStatus.ElementIndex", Field, 0, ""},
+		{"CertChainPolicyStatus.Error", Field, 0, ""},
+		{"CertChainPolicyStatus.ExtraPolicyStatus", Field, 0, ""},
+		{"CertChainPolicyStatus.Size", Field, 0, ""},
+		{"CertCloseStore", Func, 0, ""},
+		{"CertContext", Type, 0, ""},
+		{"CertContext.CertInfo", Field, 0, ""},
+		{"CertContext.EncodedCert", Field, 0, ""},
+		{"CertContext.EncodingType", Field, 0, ""},
+		{"CertContext.Length", Field, 0, ""},
+		{"CertContext.Store", Field, 0, ""},
+		{"CertCreateCertificateContext", Func, 0, ""},
+		{"CertEnhKeyUsage", Type, 0, ""},
+		{"CertEnhKeyUsage.Length", Field, 0, ""},
+		{"CertEnhKeyUsage.UsageIdentifiers", Field, 0, ""},
+		{"CertEnumCertificatesInStore", Func, 0, ""},
+		{"CertFreeCertificateChain", Func, 0, ""},
+		{"CertFreeCertificateContext", Func, 0, ""},
+		{"CertGetCertificateChain", Func, 0, ""},
+		{"CertInfo", Type, 11, ""},
+		{"CertOpenStore", Func, 0, ""},
+		{"CertOpenSystemStore", Func, 0, ""},
+		{"CertRevocationCrlInfo", Type, 11, ""},
+		{"CertRevocationInfo", Type, 0, ""},
+		{"CertRevocationInfo.CrlInfo", Field, 0, ""},
+		{"CertRevocationInfo.FreshnessTime", Field, 0, ""},
+		{"CertRevocationInfo.HasFreshnessTime", Field, 0, ""},
+		{"CertRevocationInfo.OidSpecificInfo", Field, 0, ""},
+		{"CertRevocationInfo.RevocationOid", Field, 0, ""},
+		{"CertRevocationInfo.RevocationResult", Field, 0, ""},
+		{"CertRevocationInfo.Size", Field, 0, ""},
+		{"CertSimpleChain", Type, 0, ""},
+		{"CertSimpleChain.Elements", Field, 0, ""},
+		{"CertSimpleChain.HasRevocationFreshnessTime", Field, 0, ""},
+		{"CertSimpleChain.NumElements", Field, 0, ""},
+		{"CertSimpleChain.RevocationFreshnessTime", Field, 0, ""},
+		{"CertSimpleChain.Size", Field, 0, ""},
+		{"CertSimpleChain.TrustListInfo", Field, 0, ""},
+		{"CertSimpleChain.TrustStatus", Field, 0, ""},
+		{"CertTrustListInfo", Type, 11, ""},
+		{"CertTrustStatus", Type, 0, ""},
+		{"CertTrustStatus.ErrorStatus", Field, 0, ""},
+		{"CertTrustStatus.InfoStatus", Field, 0, ""},
+		{"CertUsageMatch", Type, 0, ""},
+		{"CertUsageMatch.Type", Field, 0, ""},
+		{"CertUsageMatch.Usage", Field, 0, ""},
+		{"CertVerifyCertificateChainPolicy", Func, 0, ""},
+		{"Chdir", Func, 0, "func(path string) (err error)"},
+		{"CheckBpfVersion", Func, 0, ""},
+		{"Chflags", Func, 0, ""},
+		{"Chmod", Func, 0, "func(path string, mode uint32) (err error)"},
+		{"Chown", Func, 0, "func(path string, uid int, gid int) (err error)"},
+		{"Chroot", Func, 0, "func(path string) (err error)"},
+		{"Clearenv", Func, 0, "func()"},
+		{"Close", Func, 0, "func(fd int) (err error)"},
+		{"CloseHandle", Func, 0, ""},
+		{"CloseOnExec", Func, 0, "func(fd int)"},
+		{"Closesocket", Func, 0, ""},
+		{"CmsgLen", Func, 0, "func(datalen int) int"},
+		{"CmsgSpace", Func, 0, "func(datalen int) int"},
+		{"Cmsghdr", Type, 0, ""},
+		{"Cmsghdr.Len", Field, 0, ""},
+		{"Cmsghdr.Level", Field, 0, ""},
+		{"Cmsghdr.Type", Field, 0, ""},
+		{"Cmsghdr.X__cmsg_data", Field, 0, ""},
+		{"CommandLineToArgv", Func, 0, ""},
+		{"ComputerName", Func, 0, ""},
+		{"Conn", Type, 9, ""},
+		{"Connect", Func, 0, "func(fd int, sa Sockaddr) (err error)"},
+		{"ConnectEx", Func, 1, ""},
+		{"ConvertSidToStringSid", Func, 0, ""},
+		{"ConvertStringSidToSid", Func, 0, ""},
+		{"CopySid", Func, 0, ""},
+		{"Creat", Func, 0, "func(path string, mode uint32) (fd int, err error)"},
+		{"CreateDirectory", Func, 0, ""},
+		{"CreateFile", Func, 0, ""},
+		{"CreateFileMapping", Func, 0, ""},
+		{"CreateHardLink", Func, 4, ""},
+		{"CreateIoCompletionPort", Func, 0, ""},
+		{"CreatePipe", Func, 0, ""},
+		{"CreateProcess", Func, 0, ""},
+		{"CreateProcessAsUser", Func, 10, ""},
+		{"CreateSymbolicLink", Func, 4, ""},
+		{"CreateToolhelp32Snapshot", Func, 4, ""},
+		{"Credential", Type, 0, ""},
+		{"Credential.Gid", Field, 0, ""},
+		{"Credential.Groups", Field, 0, ""},
+		{"Credential.NoSetGroups", Field, 9, ""},
+		{"Credential.Uid", Field, 0, ""},
+		{"CryptAcquireContext", Func, 0, ""},
+		{"CryptGenRandom", Func, 0, ""},
+		{"CryptReleaseContext", Func, 0, ""},
+		{"DIOCBSFLUSH", Const, 1, ""},
+		{"DIOCOSFPFLUSH", Const, 1, ""},
+		{"DLL", Type, 0, ""},
+		{"DLL.Handle", Field, 0, ""},
+		{"DLL.Name", Field, 0, ""},
+		{"DLLError", Type, 0, ""},
+		{"DLLError.Err", Field, 0, ""},
+		{"DLLError.Msg", Field, 0, ""},
+		{"DLLError.ObjName", Field, 0, ""},
+		{"DLT_A429", Const, 0, ""},
+		{"DLT_A653_ICM", Const, 0, ""},
+		{"DLT_AIRONET_HEADER", Const, 0, ""},
+		{"DLT_AOS", Const, 1, ""},
+		{"DLT_APPLE_IP_OVER_IEEE1394", Const, 0, ""},
+		{"DLT_ARCNET", Const, 0, ""},
+		{"DLT_ARCNET_LINUX", Const, 0, ""},
+		{"DLT_ATM_CLIP", Const, 0, ""},
+		{"DLT_ATM_RFC1483", Const, 0, ""},
+		{"DLT_AURORA", Const, 0, ""},
+		{"DLT_AX25", Const, 0, ""},
+		{"DLT_AX25_KISS", Const, 0, ""},
+		{"DLT_BACNET_MS_TP", Const, 0, ""},
+		{"DLT_BLUETOOTH_HCI_H4", Const, 0, ""},
+		{"DLT_BLUETOOTH_HCI_H4_WITH_PHDR", Const, 0, ""},
+		{"DLT_CAN20B", Const, 0, ""},
+		{"DLT_CAN_SOCKETCAN", Const, 1, ""},
+		{"DLT_CHAOS", Const, 0, ""},
+		{"DLT_CHDLC", Const, 0, ""},
+		{"DLT_CISCO_IOS", Const, 0, ""},
+		{"DLT_C_HDLC", Const, 0, ""},
+		{"DLT_C_HDLC_WITH_DIR", Const, 0, ""},
+		{"DLT_DBUS", Const, 1, ""},
+		{"DLT_DECT", Const, 1, ""},
+		{"DLT_DOCSIS", Const, 0, ""},
+		{"DLT_DVB_CI", Const, 1, ""},
+		{"DLT_ECONET", Const, 0, ""},
+		{"DLT_EN10MB", Const, 0, ""},
+		{"DLT_EN3MB", Const, 0, ""},
+		{"DLT_ENC", Const, 0, ""},
+		{"DLT_ERF", Const, 0, ""},
+		{"DLT_ERF_ETH", Const, 0, ""},
+		{"DLT_ERF_POS", Const, 0, ""},
+		{"DLT_FC_2", Const, 1, ""},
+		{"DLT_FC_2_WITH_FRAME_DELIMS", Const, 1, ""},
+		{"DLT_FDDI", Const, 0, ""},
+		{"DLT_FLEXRAY", Const, 0, ""},
+		{"DLT_FRELAY", Const, 0, ""},
+		{"DLT_FRELAY_WITH_DIR", Const, 0, ""},
+		{"DLT_GCOM_SERIAL", Const, 0, ""},
+		{"DLT_GCOM_T1E1", Const, 0, ""},
+		{"DLT_GPF_F", Const, 0, ""},
+		{"DLT_GPF_T", Const, 0, ""},
+		{"DLT_GPRS_LLC", Const, 0, ""},
+		{"DLT_GSMTAP_ABIS", Const, 1, ""},
+		{"DLT_GSMTAP_UM", Const, 1, ""},
+		{"DLT_HDLC", Const, 1, ""},
+		{"DLT_HHDLC", Const, 0, ""},
+		{"DLT_HIPPI", Const, 1, ""},
+		{"DLT_IBM_SN", Const, 0, ""},
+		{"DLT_IBM_SP", Const, 0, ""},
+		{"DLT_IEEE802", Const, 0, ""},
+		{"DLT_IEEE802_11", Const, 0, ""},
+		{"DLT_IEEE802_11_RADIO", Const, 0, ""},
+		{"DLT_IEEE802_11_RADIO_AVS", Const, 0, ""},
+		{"DLT_IEEE802_15_4", Const, 0, ""},
+		{"DLT_IEEE802_15_4_LINUX", Const, 0, ""},
+		{"DLT_IEEE802_15_4_NOFCS", Const, 1, ""},
+		{"DLT_IEEE802_15_4_NONASK_PHY", Const, 0, ""},
+		{"DLT_IEEE802_16_MAC_CPS", Const, 0, ""},
+		{"DLT_IEEE802_16_MAC_CPS_RADIO", Const, 0, ""},
+		{"DLT_IPFILTER", Const, 0, ""},
+		{"DLT_IPMB", Const, 0, ""},
+		{"DLT_IPMB_LINUX", Const, 0, ""},
+		{"DLT_IPNET", Const, 1, ""},
+		{"DLT_IPOIB", Const, 1, ""},
+		{"DLT_IPV4", Const, 1, ""},
+		{"DLT_IPV6", Const, 1, ""},
+		{"DLT_IP_OVER_FC", Const, 0, ""},
+		{"DLT_JUNIPER_ATM1", Const, 0, ""},
+		{"DLT_JUNIPER_ATM2", Const, 0, ""},
+		{"DLT_JUNIPER_ATM_CEMIC", Const, 1, ""},
+		{"DLT_JUNIPER_CHDLC", Const, 0, ""},
+		{"DLT_JUNIPER_ES", Const, 0, ""},
+		{"DLT_JUNIPER_ETHER", Const, 0, ""},
+		{"DLT_JUNIPER_FIBRECHANNEL", Const, 1, ""},
+		{"DLT_JUNIPER_FRELAY", Const, 0, ""},
+		{"DLT_JUNIPER_GGSN", Const, 0, ""},
+		{"DLT_JUNIPER_ISM", Const, 0, ""},
+		{"DLT_JUNIPER_MFR", Const, 0, ""},
+		{"DLT_JUNIPER_MLFR", Const, 0, ""},
+		{"DLT_JUNIPER_MLPPP", Const, 0, ""},
+		{"DLT_JUNIPER_MONITOR", Const, 0, ""},
+		{"DLT_JUNIPER_PIC_PEER", Const, 0, ""},
+		{"DLT_JUNIPER_PPP", Const, 0, ""},
+		{"DLT_JUNIPER_PPPOE", Const, 0, ""},
+		{"DLT_JUNIPER_PPPOE_ATM", Const, 0, ""},
+		{"DLT_JUNIPER_SERVICES", Const, 0, ""},
+		{"DLT_JUNIPER_SRX_E2E", Const, 1, ""},
+		{"DLT_JUNIPER_ST", Const, 0, ""},
+		{"DLT_JUNIPER_VP", Const, 0, ""},
+		{"DLT_JUNIPER_VS", Const, 1, ""},
+		{"DLT_LAPB_WITH_DIR", Const, 0, ""},
+		{"DLT_LAPD", Const, 0, ""},
+		{"DLT_LIN", Const, 0, ""},
+		{"DLT_LINUX_EVDEV", Const, 1, ""},
+		{"DLT_LINUX_IRDA", Const, 0, ""},
+		{"DLT_LINUX_LAPD", Const, 0, ""},
+		{"DLT_LINUX_PPP_WITHDIRECTION", Const, 0, ""},
+		{"DLT_LINUX_SLL", Const, 0, ""},
+		{"DLT_LOOP", Const, 0, ""},
+		{"DLT_LTALK", Const, 0, ""},
+		{"DLT_MATCHING_MAX", Const, 1, ""},
+		{"DLT_MATCHING_MIN", Const, 1, ""},
+		{"DLT_MFR", Const, 0, ""},
+		{"DLT_MOST", Const, 0, ""},
+		{"DLT_MPEG_2_TS", Const, 1, ""},
+		{"DLT_MPLS", Const, 1, ""},
+		{"DLT_MTP2", Const, 0, ""},
+		{"DLT_MTP2_WITH_PHDR", Const, 0, ""},
+		{"DLT_MTP3", Const, 0, ""},
+		{"DLT_MUX27010", Const, 1, ""},
+		{"DLT_NETANALYZER", Const, 1, ""},
+		{"DLT_NETANALYZER_TRANSPARENT", Const, 1, ""},
+		{"DLT_NFC_LLCP", Const, 1, ""},
+		{"DLT_NFLOG", Const, 1, ""},
+		{"DLT_NG40", Const, 1, ""},
+		{"DLT_NULL", Const, 0, ""},
+		{"DLT_PCI_EXP", Const, 0, ""},
+		{"DLT_PFLOG", Const, 0, ""},
+		{"DLT_PFSYNC", Const, 0, ""},
+		{"DLT_PPI", Const, 0, ""},
+		{"DLT_PPP", Const, 0, ""},
+		{"DLT_PPP_BSDOS", Const, 0, ""},
+		{"DLT_PPP_ETHER", Const, 0, ""},
+		{"DLT_PPP_PPPD", Const, 0, ""},
+		{"DLT_PPP_SERIAL", Const, 0, ""},
+		{"DLT_PPP_WITH_DIR", Const, 0, ""},
+		{"DLT_PPP_WITH_DIRECTION", Const, 0, ""},
+		{"DLT_PRISM_HEADER", Const, 0, ""},
+		{"DLT_PRONET", Const, 0, ""},
+		{"DLT_RAIF1", Const, 0, ""},
+		{"DLT_RAW", Const, 0, ""},
+		{"DLT_RAWAF_MASK", Const, 1, ""},
+		{"DLT_RIO", Const, 0, ""},
+		{"DLT_SCCP", Const, 0, ""},
+		{"DLT_SITA", Const, 0, ""},
+		{"DLT_SLIP", Const, 0, ""},
+		{"DLT_SLIP_BSDOS", Const, 0, ""},
+		{"DLT_STANAG_5066_D_PDU", Const, 1, ""},
+		{"DLT_SUNATM", Const, 0, ""},
+		{"DLT_SYMANTEC_FIREWALL", Const, 0, ""},
+		{"DLT_TZSP", Const, 0, ""},
+		{"DLT_USB", Const, 0, ""},
+		{"DLT_USB_LINUX", Const, 0, ""},
+		{"DLT_USB_LINUX_MMAPPED", Const, 1, ""},
+		{"DLT_USER0", Const, 0, ""},
+		{"DLT_USER1", Const, 0, ""},
+		{"DLT_USER10", Const, 0, ""},
+		{"DLT_USER11", Const, 0, ""},
+		{"DLT_USER12", Const, 0, ""},
+		{"DLT_USER13", Const, 0, ""},
+		{"DLT_USER14", Const, 0, ""},
+		{"DLT_USER15", Const, 0, ""},
+		{"DLT_USER2", Const, 0, ""},
+		{"DLT_USER3", Const, 0, ""},
+		{"DLT_USER4", Const, 0, ""},
+		{"DLT_USER5", Const, 0, ""},
+		{"DLT_USER6", Const, 0, ""},
+		{"DLT_USER7", Const, 0, ""},
+		{"DLT_USER8", Const, 0, ""},
+		{"DLT_USER9", Const, 0, ""},
+		{"DLT_WIHART", Const, 1, ""},
+		{"DLT_X2E_SERIAL", Const, 0, ""},
+		{"DLT_X2E_XORAYA", Const, 0, ""},
+		{"DNSMXData", Type, 0, ""},
+		{"DNSMXData.NameExchange", Field, 0, ""},
+		{"DNSMXData.Pad", Field, 0, ""},
+		{"DNSMXData.Preference", Field, 0, ""},
+		{"DNSPTRData", Type, 0, ""},
+		{"DNSPTRData.Host", Field, 0, ""},
+		{"DNSRecord", Type, 0, ""},
+		{"DNSRecord.Data", Field, 0, ""},
+		{"DNSRecord.Dw", Field, 0, ""},
+		{"DNSRecord.Length", Field, 0, ""},
+		{"DNSRecord.Name", Field, 0, ""},
+		{"DNSRecord.Next", Field, 0, ""},
+		{"DNSRecord.Reserved", Field, 0, ""},
+		{"DNSRecord.Ttl", Field, 0, ""},
+		{"DNSRecord.Type", Field, 0, ""},
+		{"DNSSRVData", Type, 0, ""},
+		{"DNSSRVData.Pad", Field, 0, ""},
+		{"DNSSRVData.Port", Field, 0, ""},
+		{"DNSSRVData.Priority", Field, 0, ""},
+		{"DNSSRVData.Target", Field, 0, ""},
+		{"DNSSRVData.Weight", Field, 0, ""},
+		{"DNSTXTData", Type, 0, ""},
+		{"DNSTXTData.StringArray", Field, 0, ""},
+		{"DNSTXTData.StringCount", Field, 0, ""},
+		{"DNS_INFO_NO_RECORDS", Const, 4, ""},
+		{"DNS_TYPE_A", Const, 0, ""},
+		{"DNS_TYPE_A6", Const, 0, ""},
+		{"DNS_TYPE_AAAA", Const, 0, ""},
+		{"DNS_TYPE_ADDRS", Const, 0, ""},
+		{"DNS_TYPE_AFSDB", Const, 0, ""},
+		{"DNS_TYPE_ALL", Const, 0, ""},
+		{"DNS_TYPE_ANY", Const, 0, ""},
+		{"DNS_TYPE_ATMA", Const, 0, ""},
+		{"DNS_TYPE_AXFR", Const, 0, ""},
+		{"DNS_TYPE_CERT", Const, 0, ""},
+		{"DNS_TYPE_CNAME", Const, 0, ""},
+		{"DNS_TYPE_DHCID", Const, 0, ""},
+		{"DNS_TYPE_DNAME", Const, 0, ""},
+		{"DNS_TYPE_DNSKEY", Const, 0, ""},
+		{"DNS_TYPE_DS", Const, 0, ""},
+		{"DNS_TYPE_EID", Const, 0, ""},
+		{"DNS_TYPE_GID", Const, 0, ""},
+		{"DNS_TYPE_GPOS", Const, 0, ""},
+		{"DNS_TYPE_HINFO", Const, 0, ""},
+		{"DNS_TYPE_ISDN", Const, 0, ""},
+		{"DNS_TYPE_IXFR", Const, 0, ""},
+		{"DNS_TYPE_KEY", Const, 0, ""},
+		{"DNS_TYPE_KX", Const, 0, ""},
+		{"DNS_TYPE_LOC", Const, 0, ""},
+		{"DNS_TYPE_MAILA", Const, 0, ""},
+		{"DNS_TYPE_MAILB", Const, 0, ""},
+		{"DNS_TYPE_MB", Const, 0, ""},
+		{"DNS_TYPE_MD", Const, 0, ""},
+		{"DNS_TYPE_MF", Const, 0, ""},
+		{"DNS_TYPE_MG", Const, 0, ""},
+		{"DNS_TYPE_MINFO", Const, 0, ""},
+		{"DNS_TYPE_MR", Const, 0, ""},
+		{"DNS_TYPE_MX", Const, 0, ""},
+		{"DNS_TYPE_NAPTR", Const, 0, ""},
+		{"DNS_TYPE_NBSTAT", Const, 0, ""},
+		{"DNS_TYPE_NIMLOC", Const, 0, ""},
+		{"DNS_TYPE_NS", Const, 0, ""},
+		{"DNS_TYPE_NSAP", Const, 0, ""},
+		{"DNS_TYPE_NSAPPTR", Const, 0, ""},
+		{"DNS_TYPE_NSEC", Const, 0, ""},
+		{"DNS_TYPE_NULL", Const, 0, ""},
+		{"DNS_TYPE_NXT", Const, 0, ""},
+		{"DNS_TYPE_OPT", Const, 0, ""},
+		{"DNS_TYPE_PTR", Const, 0, ""},
+		{"DNS_TYPE_PX", Const, 0, ""},
+		{"DNS_TYPE_RP", Const, 0, ""},
+		{"DNS_TYPE_RRSIG", Const, 0, ""},
+		{"DNS_TYPE_RT", Const, 0, ""},
+		{"DNS_TYPE_SIG", Const, 0, ""},
+		{"DNS_TYPE_SINK", Const, 0, ""},
+		{"DNS_TYPE_SOA", Const, 0, ""},
+		{"DNS_TYPE_SRV", Const, 0, ""},
+		{"DNS_TYPE_TEXT", Const, 0, ""},
+		{"DNS_TYPE_TKEY", Const, 0, ""},
+		{"DNS_TYPE_TSIG", Const, 0, ""},
+		{"DNS_TYPE_UID", Const, 0, ""},
+		{"DNS_TYPE_UINFO", Const, 0, ""},
+		{"DNS_TYPE_UNSPEC", Const, 0, ""},
+		{"DNS_TYPE_WINS", Const, 0, ""},
+		{"DNS_TYPE_WINSR", Const, 0, ""},
+		{"DNS_TYPE_WKS", Const, 0, ""},
+		{"DNS_TYPE_X25", Const, 0, ""},
+		{"DT_BLK", Const, 0, ""},
+		{"DT_CHR", Const, 0, ""},
+		{"DT_DIR", Const, 0, ""},
+		{"DT_FIFO", Const, 0, ""},
+		{"DT_LNK", Const, 0, ""},
+		{"DT_REG", Const, 0, ""},
+		{"DT_SOCK", Const, 0, ""},
+		{"DT_UNKNOWN", Const, 0, ""},
+		{"DT_WHT", Const, 0, ""},
+		{"DUPLICATE_CLOSE_SOURCE", Const, 0, ""},
+		{"DUPLICATE_SAME_ACCESS", Const, 0, ""},
+		{"DeleteFile", Func, 0, ""},
+		{"DetachLsf", Func, 0, "func(fd int) error"},
+		{"DeviceIoControl", Func, 4, ""},
+		{"Dirent", Type, 0, ""},
+		{"Dirent.Fileno", Field, 0, ""},
+		{"Dirent.Ino", Field, 0, ""},
+		{"Dirent.Name", Field, 0, ""},
+		{"Dirent.Namlen", Field, 0, ""},
+		{"Dirent.Off", Field, 0, ""},
+		{"Dirent.Pad0", Field, 12, ""},
+		{"Dirent.Pad1", Field, 12, ""},
+		{"Dirent.Pad_cgo_0", Field, 0, ""},
+		{"Dirent.Reclen", Field, 0, ""},
+		{"Dirent.Seekoff", Field, 0, ""},
+		{"Dirent.Type", Field, 0, ""},
+		{"Dirent.X__d_padding", Field, 3, ""},
+		{"DnsNameCompare", Func, 4, ""},
+		{"DnsQuery", Func, 0, ""},
+		{"DnsRecordListFree", Func, 0, ""},
+		{"DnsSectionAdditional", Const, 4, ""},
+		{"DnsSectionAnswer", Const, 4, ""},
+		{"DnsSectionAuthority", Const, 4, ""},
+		{"DnsSectionQuestion", Const, 4, ""},
+		{"Dup", Func, 0, "func(oldfd int) (fd int, err error)"},
+		{"Dup2", Func, 0, "func(oldfd int, newfd int) (err error)"},
+		{"Dup3", Func, 2, "func(oldfd int, newfd int, flags int) (err error)"},
+		{"DuplicateHandle", Func, 0, ""},
+		{"E2BIG", Const, 0, ""},
+		{"EACCES", Const, 0, ""},
+		{"EADDRINUSE", Const, 0, ""},
+		{"EADDRNOTAVAIL", Const, 0, ""},
+		{"EADV", Const, 0, ""},
+		{"EAFNOSUPPORT", Const, 0, ""},
+		{"EAGAIN", Const, 0, ""},
+		{"EALREADY", Const, 0, ""},
+		{"EAUTH", Const, 0, ""},
+		{"EBADARCH", Const, 0, ""},
+		{"EBADE", Const, 0, ""},
+		{"EBADEXEC", Const, 0, ""},
+		{"EBADF", Const, 0, ""},
+		{"EBADFD", Const, 0, ""},
+		{"EBADMACHO", Const, 0, ""},
+		{"EBADMSG", Const, 0, ""},
+		{"EBADR", Const, 0, ""},
+		{"EBADRPC", Const, 0, ""},
+		{"EBADRQC", Const, 0, ""},
+		{"EBADSLT", Const, 0, ""},
+		{"EBFONT", Const, 0, ""},
+		{"EBUSY", Const, 0, ""},
+		{"ECANCELED", Const, 0, ""},
+		{"ECAPMODE", Const, 1, ""},
+		{"ECHILD", Const, 0, ""},
+		{"ECHO", Const, 0, ""},
+		{"ECHOCTL", Const, 0, ""},
+		{"ECHOE", Const, 0, ""},
+		{"ECHOK", Const, 0, ""},
+		{"ECHOKE", Const, 0, ""},
+		{"ECHONL", Const, 0, ""},
+		{"ECHOPRT", Const, 0, ""},
+		{"ECHRNG", Const, 0, ""},
+		{"ECOMM", Const, 0, ""},
+		{"ECONNABORTED", Const, 0, ""},
+		{"ECONNREFUSED", Const, 0, ""},
+		{"ECONNRESET", Const, 0, ""},
+		{"EDEADLK", Const, 0, ""},
+		{"EDEADLOCK", Const, 0, ""},
+		{"EDESTADDRREQ", Const, 0, ""},
+		{"EDEVERR", Const, 0, ""},
+		{"EDOM", Const, 0, ""},
+		{"EDOOFUS", Const, 0, ""},
+		{"EDOTDOT", Const, 0, ""},
+		{"EDQUOT", Const, 0, ""},
+		{"EEXIST", Const, 0, ""},
+		{"EFAULT", Const, 0, ""},
+		{"EFBIG", Const, 0, ""},
+		{"EFER_LMA", Const, 1, ""},
+		{"EFER_LME", Const, 1, ""},
+		{"EFER_NXE", Const, 1, ""},
+		{"EFER_SCE", Const, 1, ""},
+		{"EFTYPE", Const, 0, ""},
+		{"EHOSTDOWN", Const, 0, ""},
+		{"EHOSTUNREACH", Const, 0, ""},
+		{"EHWPOISON", Const, 0, ""},
+		{"EIDRM", Const, 0, ""},
+		{"EILSEQ", Const, 0, ""},
+		{"EINPROGRESS", Const, 0, ""},
+		{"EINTR", Const, 0, ""},
+		{"EINVAL", Const, 0, ""},
+		{"EIO", Const, 0, ""},
+		{"EIPSEC", Const, 1, ""},
+		{"EISCONN", Const, 0, ""},
+		{"EISDIR", Const, 0, ""},
+		{"EISNAM", Const, 0, ""},
+		{"EKEYEXPIRED", Const, 0, ""},
+		{"EKEYREJECTED", Const, 0, ""},
+		{"EKEYREVOKED", Const, 0, ""},
+		{"EL2HLT", Const, 0, ""},
+		{"EL2NSYNC", Const, 0, ""},
+		{"EL3HLT", Const, 0, ""},
+		{"EL3RST", Const, 0, ""},
+		{"ELAST", Const, 0, ""},
+		{"ELF_NGREG", Const, 0, ""},
+		{"ELF_PRARGSZ", Const, 0, ""},
+		{"ELIBACC", Const, 0, ""},
+		{"ELIBBAD", Const, 0, ""},
+		{"ELIBEXEC", Const, 0, ""},
+		{"ELIBMAX", Const, 0, ""},
+		{"ELIBSCN", Const, 0, ""},
+		{"ELNRNG", Const, 0, ""},
+		{"ELOOP", Const, 0, ""},
+		{"EMEDIUMTYPE", Const, 0, ""},
+		{"EMFILE", Const, 0, ""},
+		{"EMLINK", Const, 0, ""},
+		{"EMSGSIZE", Const, 0, ""},
+		{"EMT_TAGOVF", Const, 1, ""},
+		{"EMULTIHOP", Const, 0, ""},
+		{"EMUL_ENABLED", Const, 1, ""},
+		{"EMUL_LINUX", Const, 1, ""},
+		{"EMUL_LINUX32", Const, 1, ""},
+		{"EMUL_MAXID", Const, 1, ""},
+		{"EMUL_NATIVE", Const, 1, ""},
+		{"ENAMETOOLONG", Const, 0, ""},
+		{"ENAVAIL", Const, 0, ""},
+		{"ENDRUNDISC", Const, 1, ""},
+		{"ENEEDAUTH", Const, 0, ""},
+		{"ENETDOWN", Const, 0, ""},
+		{"ENETRESET", Const, 0, ""},
+		{"ENETUNREACH", Const, 0, ""},
+		{"ENFILE", Const, 0, ""},
+		{"ENOANO", Const, 0, ""},
+		{"ENOATTR", Const, 0, ""},
+		{"ENOBUFS", Const, 0, ""},
+		{"ENOCSI", Const, 0, ""},
+		{"ENODATA", Const, 0, ""},
+		{"ENODEV", Const, 0, ""},
+		{"ENOENT", Const, 0, ""},
+		{"ENOEXEC", Const, 0, ""},
+		{"ENOKEY", Const, 0, ""},
+		{"ENOLCK", Const, 0, ""},
+		{"ENOLINK", Const, 0, ""},
+		{"ENOMEDIUM", Const, 0, ""},
+		{"ENOMEM", Const, 0, ""},
+		{"ENOMSG", Const, 0, ""},
+		{"ENONET", Const, 0, ""},
+		{"ENOPKG", Const, 0, ""},
+		{"ENOPOLICY", Const, 0, ""},
+		{"ENOPROTOOPT", Const, 0, ""},
+		{"ENOSPC", Const, 0, ""},
+		{"ENOSR", Const, 0, ""},
+		{"ENOSTR", Const, 0, ""},
+		{"ENOSYS", Const, 0, ""},
+		{"ENOTBLK", Const, 0, ""},
+		{"ENOTCAPABLE", Const, 0, ""},
+		{"ENOTCONN", Const, 0, ""},
+		{"ENOTDIR", Const, 0, ""},
+		{"ENOTEMPTY", Const, 0, ""},
+		{"ENOTNAM", Const, 0, ""},
+		{"ENOTRECOVERABLE", Const, 0, ""},
+		{"ENOTSOCK", Const, 0, ""},
+		{"ENOTSUP", Const, 0, ""},
+		{"ENOTTY", Const, 0, ""},
+		{"ENOTUNIQ", Const, 0, ""},
+		{"ENXIO", Const, 0, ""},
+		{"EN_SW_CTL_INF", Const, 1, ""},
+		{"EN_SW_CTL_PREC", Const, 1, ""},
+		{"EN_SW_CTL_ROUND", Const, 1, ""},
+		{"EN_SW_DATACHAIN", Const, 1, ""},
+		{"EN_SW_DENORM", Const, 1, ""},
+		{"EN_SW_INVOP", Const, 1, ""},
+		{"EN_SW_OVERFLOW", Const, 1, ""},
+		{"EN_SW_PRECLOSS", Const, 1, ""},
+		{"EN_SW_UNDERFLOW", Const, 1, ""},
+		{"EN_SW_ZERODIV", Const, 1, ""},
+		{"EOPNOTSUPP", Const, 0, ""},
+		{"EOVERFLOW", Const, 0, ""},
+		{"EOWNERDEAD", Const, 0, ""},
+		{"EPERM", Const, 0, ""},
+		{"EPFNOSUPPORT", Const, 0, ""},
+		{"EPIPE", Const, 0, ""},
+		{"EPOLLERR", Const, 0, ""},
+		{"EPOLLET", Const, 0, ""},
+		{"EPOLLHUP", Const, 0, ""},
+		{"EPOLLIN", Const, 0, ""},
+		{"EPOLLMSG", Const, 0, ""},
+		{"EPOLLONESHOT", Const, 0, ""},
+		{"EPOLLOUT", Const, 0, ""},
+		{"EPOLLPRI", Const, 0, ""},
+		{"EPOLLRDBAND", Const, 0, ""},
+		{"EPOLLRDHUP", Const, 0, ""},
+		{"EPOLLRDNORM", Const, 0, ""},
+		{"EPOLLWRBAND", Const, 0, ""},
+		{"EPOLLWRNORM", Const, 0, ""},
+		{"EPOLL_CLOEXEC", Const, 0, ""},
+		{"EPOLL_CTL_ADD", Const, 0, ""},
+		{"EPOLL_CTL_DEL", Const, 0, ""},
+		{"EPOLL_CTL_MOD", Const, 0, ""},
+		{"EPOLL_NONBLOCK", Const, 0, ""},
+		{"EPROCLIM", Const, 0, ""},
+		{"EPROCUNAVAIL", Const, 0, ""},
+		{"EPROGMISMATCH", Const, 0, ""},
+		{"EPROGUNAVAIL", Const, 0, ""},
+		{"EPROTO", Const, 0, ""},
+		{"EPROTONOSUPPORT", Const, 0, ""},
+		{"EPROTOTYPE", Const, 0, ""},
+		{"EPWROFF", Const, 0, ""},
+		{"EQFULL", Const, 16, ""},
+		{"ERANGE", Const, 0, ""},
+		{"EREMCHG", Const, 0, ""},
+		{"EREMOTE", Const, 0, ""},
+		{"EREMOTEIO", Const, 0, ""},
+		{"ERESTART", Const, 0, ""},
+		{"ERFKILL", Const, 0, ""},
+		{"EROFS", Const, 0, ""},
+		{"ERPCMISMATCH", Const, 0, ""},
+		{"ERROR_ACCESS_DENIED", Const, 0, ""},
+		{"ERROR_ALREADY_EXISTS", Const, 0, ""},
+		{"ERROR_BROKEN_PIPE", Const, 0, ""},
+		{"ERROR_BUFFER_OVERFLOW", Const, 0, ""},
+		{"ERROR_DIR_NOT_EMPTY", Const, 8, ""},
+		{"ERROR_ENVVAR_NOT_FOUND", Const, 0, ""},
+		{"ERROR_FILE_EXISTS", Const, 0, ""},
+		{"ERROR_FILE_NOT_FOUND", Const, 0, ""},
+		{"ERROR_HANDLE_EOF", Const, 2, ""},
+		{"ERROR_INSUFFICIENT_BUFFER", Const, 0, ""},
+		{"ERROR_IO_PENDING", Const, 0, ""},
+		{"ERROR_MOD_NOT_FOUND", Const, 0, ""},
+		{"ERROR_MORE_DATA", Const, 3, ""},
+		{"ERROR_NETNAME_DELETED", Const, 3, ""},
+		{"ERROR_NOT_FOUND", Const, 1, ""},
+		{"ERROR_NO_MORE_FILES", Const, 0, ""},
+		{"ERROR_OPERATION_ABORTED", Const, 0, ""},
+		{"ERROR_PATH_NOT_FOUND", Const, 0, ""},
+		{"ERROR_PRIVILEGE_NOT_HELD", Const, 4, ""},
+		{"ERROR_PROC_NOT_FOUND", Const, 0, ""},
+		{"ESHLIBVERS", Const, 0, ""},
+		{"ESHUTDOWN", Const, 0, ""},
+		{"ESOCKTNOSUPPORT", Const, 0, ""},
+		{"ESPIPE", Const, 0, ""},
+		{"ESRCH", Const, 0, ""},
+		{"ESRMNT", Const, 0, ""},
+		{"ESTALE", Const, 0, ""},
+		{"ESTRPIPE", Const, 0, ""},
+		{"ETHERCAP_JUMBO_MTU", Const, 1, ""},
+		{"ETHERCAP_VLAN_HWTAGGING", Const, 1, ""},
+		{"ETHERCAP_VLAN_MTU", Const, 1, ""},
+		{"ETHERMIN", Const, 1, ""},
+		{"ETHERMTU", Const, 1, ""},
+		{"ETHERMTU_JUMBO", Const, 1, ""},
+		{"ETHERTYPE_8023", Const, 1, ""},
+		{"ETHERTYPE_AARP", Const, 1, ""},
+		{"ETHERTYPE_ACCTON", Const, 1, ""},
+		{"ETHERTYPE_AEONIC", Const, 1, ""},
+		{"ETHERTYPE_ALPHA", Const, 1, ""},
+		{"ETHERTYPE_AMBER", Const, 1, ""},
+		{"ETHERTYPE_AMOEBA", Const, 1, ""},
+		{"ETHERTYPE_AOE", Const, 1, ""},
+		{"ETHERTYPE_APOLLO", Const, 1, ""},
+		{"ETHERTYPE_APOLLODOMAIN", Const, 1, ""},
+		{"ETHERTYPE_APPLETALK", Const, 1, ""},
+		{"ETHERTYPE_APPLITEK", Const, 1, ""},
+		{"ETHERTYPE_ARGONAUT", Const, 1, ""},
+		{"ETHERTYPE_ARP", Const, 1, ""},
+		{"ETHERTYPE_AT", Const, 1, ""},
+		{"ETHERTYPE_ATALK", Const, 1, ""},
+		{"ETHERTYPE_ATOMIC", Const, 1, ""},
+		{"ETHERTYPE_ATT", Const, 1, ""},
+		{"ETHERTYPE_ATTSTANFORD", Const, 1, ""},
+		{"ETHERTYPE_AUTOPHON", Const, 1, ""},
+		{"ETHERTYPE_AXIS", Const, 1, ""},
+		{"ETHERTYPE_BCLOOP", Const, 1, ""},
+		{"ETHERTYPE_BOFL", Const, 1, ""},
+		{"ETHERTYPE_CABLETRON", Const, 1, ""},
+		{"ETHERTYPE_CHAOS", Const, 1, ""},
+		{"ETHERTYPE_COMDESIGN", Const, 1, ""},
+		{"ETHERTYPE_COMPUGRAPHIC", Const, 1, ""},
+		{"ETHERTYPE_COUNTERPOINT", Const, 1, ""},
+		{"ETHERTYPE_CRONUS", Const, 1, ""},
+		{"ETHERTYPE_CRONUSVLN", Const, 1, ""},
+		{"ETHERTYPE_DCA", Const, 1, ""},
+		{"ETHERTYPE_DDE", Const, 1, ""},
+		{"ETHERTYPE_DEBNI", Const, 1, ""},
+		{"ETHERTYPE_DECAM", Const, 1, ""},
+		{"ETHERTYPE_DECCUST", Const, 1, ""},
+		{"ETHERTYPE_DECDIAG", Const, 1, ""},
+		{"ETHERTYPE_DECDNS", Const, 1, ""},
+		{"ETHERTYPE_DECDTS", Const, 1, ""},
+		{"ETHERTYPE_DECEXPER", Const, 1, ""},
+		{"ETHERTYPE_DECLAST", Const, 1, ""},
+		{"ETHERTYPE_DECLTM", Const, 1, ""},
+		{"ETHERTYPE_DECMUMPS", Const, 1, ""},
+		{"ETHERTYPE_DECNETBIOS", Const, 1, ""},
+		{"ETHERTYPE_DELTACON", Const, 1, ""},
+		{"ETHERTYPE_DIDDLE", Const, 1, ""},
+		{"ETHERTYPE_DLOG1", Const, 1, ""},
+		{"ETHERTYPE_DLOG2", Const, 1, ""},
+		{"ETHERTYPE_DN", Const, 1, ""},
+		{"ETHERTYPE_DOGFIGHT", Const, 1, ""},
+		{"ETHERTYPE_DSMD", Const, 1, ""},
+		{"ETHERTYPE_ECMA", Const, 1, ""},
+		{"ETHERTYPE_ENCRYPT", Const, 1, ""},
+		{"ETHERTYPE_ES", Const, 1, ""},
+		{"ETHERTYPE_EXCELAN", Const, 1, ""},
+		{"ETHERTYPE_EXPERDATA", Const, 1, ""},
+		{"ETHERTYPE_FLIP", Const, 1, ""},
+		{"ETHERTYPE_FLOWCONTROL", Const, 1, ""},
+		{"ETHERTYPE_FRARP", Const, 1, ""},
+		{"ETHERTYPE_GENDYN", Const, 1, ""},
+		{"ETHERTYPE_HAYES", Const, 1, ""},
+		{"ETHERTYPE_HIPPI_FP", Const, 1, ""},
+		{"ETHERTYPE_HITACHI", Const, 1, ""},
+		{"ETHERTYPE_HP", Const, 1, ""},
+		{"ETHERTYPE_IEEEPUP", Const, 1, ""},
+		{"ETHERTYPE_IEEEPUPAT", Const, 1, ""},
+		{"ETHERTYPE_IMLBL", Const, 1, ""},
+		{"ETHERTYPE_IMLBLDIAG", Const, 1, ""},
+		{"ETHERTYPE_IP", Const, 1, ""},
+		{"ETHERTYPE_IPAS", Const, 1, ""},
+		{"ETHERTYPE_IPV6", Const, 1, ""},
+		{"ETHERTYPE_IPX", Const, 1, ""},
+		{"ETHERTYPE_IPXNEW", Const, 1, ""},
+		{"ETHERTYPE_KALPANA", Const, 1, ""},
+		{"ETHERTYPE_LANBRIDGE", Const, 1, ""},
+		{"ETHERTYPE_LANPROBE", Const, 1, ""},
+		{"ETHERTYPE_LAT", Const, 1, ""},
+		{"ETHERTYPE_LBACK", Const, 1, ""},
+		{"ETHERTYPE_LITTLE", Const, 1, ""},
+		{"ETHERTYPE_LLDP", Const, 1, ""},
+		{"ETHERTYPE_LOGICRAFT", Const, 1, ""},
+		{"ETHERTYPE_LOOPBACK", Const, 1, ""},
+		{"ETHERTYPE_MATRA", Const, 1, ""},
+		{"ETHERTYPE_MAX", Const, 1, ""},
+		{"ETHERTYPE_MERIT", Const, 1, ""},
+		{"ETHERTYPE_MICP", Const, 1, ""},
+		{"ETHERTYPE_MOPDL", Const, 1, ""},
+		{"ETHERTYPE_MOPRC", Const, 1, ""},
+		{"ETHERTYPE_MOTOROLA", Const, 1, ""},
+		{"ETHERTYPE_MPLS", Const, 1, ""},
+		{"ETHERTYPE_MPLS_MCAST", Const, 1, ""},
+		{"ETHERTYPE_MUMPS", Const, 1, ""},
+		{"ETHERTYPE_NBPCC", Const, 1, ""},
+		{"ETHERTYPE_NBPCLAIM", Const, 1, ""},
+		{"ETHERTYPE_NBPCLREQ", Const, 1, ""},
+		{"ETHERTYPE_NBPCLRSP", Const, 1, ""},
+		{"ETHERTYPE_NBPCREQ", Const, 1, ""},
+		{"ETHERTYPE_NBPCRSP", Const, 1, ""},
+		{"ETHERTYPE_NBPDG", Const, 1, ""},
+		{"ETHERTYPE_NBPDGB", Const, 1, ""},
+		{"ETHERTYPE_NBPDLTE", Const, 1, ""},
+		{"ETHERTYPE_NBPRAR", Const, 1, ""},
+		{"ETHERTYPE_NBPRAS", Const, 1, ""},
+		{"ETHERTYPE_NBPRST", Const, 1, ""},
+		{"ETHERTYPE_NBPSCD", Const, 1, ""},
+		{"ETHERTYPE_NBPVCD", Const, 1, ""},
+		{"ETHERTYPE_NBS", Const, 1, ""},
+		{"ETHERTYPE_NCD", Const, 1, ""},
+		{"ETHERTYPE_NESTAR", Const, 1, ""},
+		{"ETHERTYPE_NETBEUI", Const, 1, ""},
+		{"ETHERTYPE_NOVELL", Const, 1, ""},
+		{"ETHERTYPE_NS", Const, 1, ""},
+		{"ETHERTYPE_NSAT", Const, 1, ""},
+		{"ETHERTYPE_NSCOMPAT", Const, 1, ""},
+		{"ETHERTYPE_NTRAILER", Const, 1, ""},
+		{"ETHERTYPE_OS9", Const, 1, ""},
+		{"ETHERTYPE_OS9NET", Const, 1, ""},
+		{"ETHERTYPE_PACER", Const, 1, ""},
+		{"ETHERTYPE_PAE", Const, 1, ""},
+		{"ETHERTYPE_PCS", Const, 1, ""},
+		{"ETHERTYPE_PLANNING", Const, 1, ""},
+		{"ETHERTYPE_PPP", Const, 1, ""},
+		{"ETHERTYPE_PPPOE", Const, 1, ""},
+		{"ETHERTYPE_PPPOEDISC", Const, 1, ""},
+		{"ETHERTYPE_PRIMENTS", Const, 1, ""},
+		{"ETHERTYPE_PUP", Const, 1, ""},
+		{"ETHERTYPE_PUPAT", Const, 1, ""},
+		{"ETHERTYPE_QINQ", Const, 1, ""},
+		{"ETHERTYPE_RACAL", Const, 1, ""},
+		{"ETHERTYPE_RATIONAL", Const, 1, ""},
+		{"ETHERTYPE_RAWFR", Const, 1, ""},
+		{"ETHERTYPE_RCL", Const, 1, ""},
+		{"ETHERTYPE_RDP", Const, 1, ""},
+		{"ETHERTYPE_RETIX", Const, 1, ""},
+		{"ETHERTYPE_REVARP", Const, 1, ""},
+		{"ETHERTYPE_SCA", Const, 1, ""},
+		{"ETHERTYPE_SECTRA", Const, 1, ""},
+		{"ETHERTYPE_SECUREDATA", Const, 1, ""},
+		{"ETHERTYPE_SGITW", Const, 1, ""},
+		{"ETHERTYPE_SG_BOUNCE", Const, 1, ""},
+		{"ETHERTYPE_SG_DIAG", Const, 1, ""},
+		{"ETHERTYPE_SG_NETGAMES", Const, 1, ""},
+		{"ETHERTYPE_SG_RESV", Const, 1, ""},
+		{"ETHERTYPE_SIMNET", Const, 1, ""},
+		{"ETHERTYPE_SLOW", Const, 1, ""},
+		{"ETHERTYPE_SLOWPROTOCOLS", Const, 1, ""},
+		{"ETHERTYPE_SNA", Const, 1, ""},
+		{"ETHERTYPE_SNMP", Const, 1, ""},
+		{"ETHERTYPE_SONIX", Const, 1, ""},
+		{"ETHERTYPE_SPIDER", Const, 1, ""},
+		{"ETHERTYPE_SPRITE", Const, 1, ""},
+		{"ETHERTYPE_STP", Const, 1, ""},
+		{"ETHERTYPE_TALARIS", Const, 1, ""},
+		{"ETHERTYPE_TALARISMC", Const, 1, ""},
+		{"ETHERTYPE_TCPCOMP", Const, 1, ""},
+		{"ETHERTYPE_TCPSM", Const, 1, ""},
+		{"ETHERTYPE_TEC", Const, 1, ""},
+		{"ETHERTYPE_TIGAN", Const, 1, ""},
+		{"ETHERTYPE_TRAIL", Const, 1, ""},
+		{"ETHERTYPE_TRANSETHER", Const, 1, ""},
+		{"ETHERTYPE_TYMSHARE", Const, 1, ""},
+		{"ETHERTYPE_UBBST", Const, 1, ""},
+		{"ETHERTYPE_UBDEBUG", Const, 1, ""},
+		{"ETHERTYPE_UBDIAGLOOP", Const, 1, ""},
+		{"ETHERTYPE_UBDL", Const, 1, ""},
+		{"ETHERTYPE_UBNIU", Const, 1, ""},
+		{"ETHERTYPE_UBNMC", Const, 1, ""},
+		{"ETHERTYPE_VALID", Const, 1, ""},
+		{"ETHERTYPE_VARIAN", Const, 1, ""},
+		{"ETHERTYPE_VAXELN", Const, 1, ""},
+		{"ETHERTYPE_VEECO", Const, 1, ""},
+		{"ETHERTYPE_VEXP", Const, 1, ""},
+		{"ETHERTYPE_VGLAB", Const, 1, ""},
+		{"ETHERTYPE_VINES", Const, 1, ""},
+		{"ETHERTYPE_VINESECHO", Const, 1, ""},
+		{"ETHERTYPE_VINESLOOP", Const, 1, ""},
+		{"ETHERTYPE_VITAL", Const, 1, ""},
+		{"ETHERTYPE_VLAN", Const, 1, ""},
+		{"ETHERTYPE_VLTLMAN", Const, 1, ""},
+		{"ETHERTYPE_VPROD", Const, 1, ""},
+		{"ETHERTYPE_VURESERVED", Const, 1, ""},
+		{"ETHERTYPE_WATERLOO", Const, 1, ""},
+		{"ETHERTYPE_WELLFLEET", Const, 1, ""},
+		{"ETHERTYPE_X25", Const, 1, ""},
+		{"ETHERTYPE_X75", Const, 1, ""},
+		{"ETHERTYPE_XNSSM", Const, 1, ""},
+		{"ETHERTYPE_XTP", Const, 1, ""},
+		{"ETHER_ADDR_LEN", Const, 1, ""},
+		{"ETHER_ALIGN", Const, 1, ""},
+		{"ETHER_CRC_LEN", Const, 1, ""},
+		{"ETHER_CRC_POLY_BE", Const, 1, ""},
+		{"ETHER_CRC_POLY_LE", Const, 1, ""},
+		{"ETHER_HDR_LEN", Const, 1, ""},
+		{"ETHER_MAX_DIX_LEN", Const, 1, ""},
+		{"ETHER_MAX_LEN", Const, 1, ""},
+		{"ETHER_MAX_LEN_JUMBO", Const, 1, ""},
+		{"ETHER_MIN_LEN", Const, 1, ""},
+		{"ETHER_PPPOE_ENCAP_LEN", Const, 1, ""},
+		{"ETHER_TYPE_LEN", Const, 1, ""},
+		{"ETHER_VLAN_ENCAP_LEN", Const, 1, ""},
+		{"ETH_P_1588", Const, 0, ""},
+		{"ETH_P_8021Q", Const, 0, ""},
+		{"ETH_P_802_2", Const, 0, ""},
+		{"ETH_P_802_3", Const, 0, ""},
+		{"ETH_P_AARP", Const, 0, ""},
+		{"ETH_P_ALL", Const, 0, ""},
+		{"ETH_P_AOE", Const, 0, ""},
+		{"ETH_P_ARCNET", Const, 0, ""},
+		{"ETH_P_ARP", Const, 0, ""},
+		{"ETH_P_ATALK", Const, 0, ""},
+		{"ETH_P_ATMFATE", Const, 0, ""},
+		{"ETH_P_ATMMPOA", Const, 0, ""},
+		{"ETH_P_AX25", Const, 0, ""},
+		{"ETH_P_BPQ", Const, 0, ""},
+		{"ETH_P_CAIF", Const, 0, ""},
+		{"ETH_P_CAN", Const, 0, ""},
+		{"ETH_P_CONTROL", Const, 0, ""},
+		{"ETH_P_CUST", Const, 0, ""},
+		{"ETH_P_DDCMP", Const, 0, ""},
+		{"ETH_P_DEC", Const, 0, ""},
+		{"ETH_P_DIAG", Const, 0, ""},
+		{"ETH_P_DNA_DL", Const, 0, ""},
+		{"ETH_P_DNA_RC", Const, 0, ""},
+		{"ETH_P_DNA_RT", Const, 0, ""},
+		{"ETH_P_DSA", Const, 0, ""},
+		{"ETH_P_ECONET", Const, 0, ""},
+		{"ETH_P_EDSA", Const, 0, ""},
+		{"ETH_P_FCOE", Const, 0, ""},
+		{"ETH_P_FIP", Const, 0, ""},
+		{"ETH_P_HDLC", Const, 0, ""},
+		{"ETH_P_IEEE802154", Const, 0, ""},
+		{"ETH_P_IEEEPUP", Const, 0, ""},
+		{"ETH_P_IEEEPUPAT", Const, 0, ""},
+		{"ETH_P_IP", Const, 0, ""},
+		{"ETH_P_IPV6", Const, 0, ""},
+		{"ETH_P_IPX", Const, 0, ""},
+		{"ETH_P_IRDA", Const, 0, ""},
+		{"ETH_P_LAT", Const, 0, ""},
+		{"ETH_P_LINK_CTL", Const, 0, ""},
+		{"ETH_P_LOCALTALK", Const, 0, ""},
+		{"ETH_P_LOOP", Const, 0, ""},
+		{"ETH_P_MOBITEX", Const, 0, ""},
+		{"ETH_P_MPLS_MC", Const, 0, ""},
+		{"ETH_P_MPLS_UC", Const, 0, ""},
+		{"ETH_P_PAE", Const, 0, ""},
+		{"ETH_P_PAUSE", Const, 0, ""},
+		{"ETH_P_PHONET", Const, 0, ""},
+		{"ETH_P_PPPTALK", Const, 0, ""},
+		{"ETH_P_PPP_DISC", Const, 0, ""},
+		{"ETH_P_PPP_MP", Const, 0, ""},
+		{"ETH_P_PPP_SES", Const, 0, ""},
+		{"ETH_P_PUP", Const, 0, ""},
+		{"ETH_P_PUPAT", Const, 0, ""},
+		{"ETH_P_RARP", Const, 0, ""},
+		{"ETH_P_SCA", Const, 0, ""},
+		{"ETH_P_SLOW", Const, 0, ""},
+		{"ETH_P_SNAP", Const, 0, ""},
+		{"ETH_P_TEB", Const, 0, ""},
+		{"ETH_P_TIPC", Const, 0, ""},
+		{"ETH_P_TRAILER", Const, 0, ""},
+		{"ETH_P_TR_802_2", Const, 0, ""},
+		{"ETH_P_WAN_PPP", Const, 0, ""},
+		{"ETH_P_WCCP", Const, 0, ""},
+		{"ETH_P_X25", Const, 0, ""},
+		{"ETIME", Const, 0, ""},
+		{"ETIMEDOUT", Const, 0, ""},
+		{"ETOOMANYREFS", Const, 0, ""},
+		{"ETXTBSY", Const, 0, ""},
+		{"EUCLEAN", Const, 0, ""},
+		{"EUNATCH", Const, 0, ""},
+		{"EUSERS", Const, 0, ""},
+		{"EVFILT_AIO", Const, 0, ""},
+		{"EVFILT_FS", Const, 0, ""},
+		{"EVFILT_LIO", Const, 0, ""},
+		{"EVFILT_MACHPORT", Const, 0, ""},
+		{"EVFILT_PROC", Const, 0, ""},
+		{"EVFILT_READ", Const, 0, ""},
+		{"EVFILT_SIGNAL", Const, 0, ""},
+		{"EVFILT_SYSCOUNT", Const, 0, ""},
+		{"EVFILT_THREADMARKER", Const, 0, ""},
+		{"EVFILT_TIMER", Const, 0, ""},
+		{"EVFILT_USER", Const, 0, ""},
+		{"EVFILT_VM", Const, 0, ""},
+		{"EVFILT_VNODE", Const, 0, ""},
+		{"EVFILT_WRITE", Const, 0, ""},
+		{"EV_ADD", Const, 0, ""},
+		{"EV_CLEAR", Const, 0, ""},
+		{"EV_DELETE", Const, 0, ""},
+		{"EV_DISABLE", Const, 0, ""},
+		{"EV_DISPATCH", Const, 0, ""},
+		{"EV_DROP", Const, 3, ""},
+		{"EV_ENABLE", Const, 0, ""},
+		{"EV_EOF", Const, 0, ""},
+		{"EV_ERROR", Const, 0, ""},
+		{"EV_FLAG0", Const, 0, ""},
+		{"EV_FLAG1", Const, 0, ""},
+		{"EV_ONESHOT", Const, 0, ""},
+		{"EV_OOBAND", Const, 0, ""},
+		{"EV_POLL", Const, 0, ""},
+		{"EV_RECEIPT", Const, 0, ""},
+		{"EV_SYSFLAGS", Const, 0, ""},
+		{"EWINDOWS", Const, 0, ""},
+		{"EWOULDBLOCK", Const, 0, ""},
+		{"EXDEV", Const, 0, ""},
+		{"EXFULL", Const, 0, ""},
+		{"EXTA", Const, 0, ""},
+		{"EXTB", Const, 0, ""},
+		{"EXTPROC", Const, 0, ""},
+		{"Environ", Func, 0, "func() []string"},
+		{"EpollCreate", Func, 0, "func(size int) (fd int, err error)"},
+		{"EpollCreate1", Func, 0, "func(flag int) (fd int, err error)"},
+		{"EpollCtl", Func, 0, "func(epfd int, op int, fd int, event *EpollEvent) (err error)"},
+		{"EpollEvent", Type, 0, ""},
+		{"EpollEvent.Events", Field, 0, ""},
+		{"EpollEvent.Fd", Field, 0, ""},
+		{"EpollEvent.Pad", Field, 0, ""},
+		{"EpollEvent.PadFd", Field, 0, ""},
+		{"EpollWait", Func, 0, "func(epfd int, events []EpollEvent, msec int) (n int, err error)"},
+		{"Errno", Type, 0, ""},
+		{"EscapeArg", Func, 0, ""},
+		{"Exchangedata", Func, 0, ""},
+		{"Exec", Func, 0, "func(argv0 string, argv []string, envv []string) (err error)"},
+		{"Exit", Func, 0, "func(code int)"},
+		{"ExitProcess", Func, 0, ""},
+		{"FD_CLOEXEC", Const, 0, ""},
+		{"FD_SETSIZE", Const, 0, ""},
+		{"FILE_ACTION_ADDED", Const, 0, ""},
+		{"FILE_ACTION_MODIFIED", Const, 0, ""},
+		{"FILE_ACTION_REMOVED", Const, 0, ""},
+		{"FILE_ACTION_RENAMED_NEW_NAME", Const, 0, ""},
+		{"FILE_ACTION_RENAMED_OLD_NAME", Const, 0, ""},
+		{"FILE_APPEND_DATA", Const, 0, ""},
+		{"FILE_ATTRIBUTE_ARCHIVE", Const, 0, ""},
+		{"FILE_ATTRIBUTE_DIRECTORY", Const, 0, ""},
+		{"FILE_ATTRIBUTE_HIDDEN", Const, 0, ""},
+		{"FILE_ATTRIBUTE_NORMAL", Const, 0, ""},
+		{"FILE_ATTRIBUTE_READONLY", Const, 0, ""},
+		{"FILE_ATTRIBUTE_REPARSE_POINT", Const, 4, ""},
+		{"FILE_ATTRIBUTE_SYSTEM", Const, 0, ""},
+		{"FILE_BEGIN", Const, 0, ""},
+		{"FILE_CURRENT", Const, 0, ""},
+		{"FILE_END", Const, 0, ""},
+		{"FILE_FLAG_BACKUP_SEMANTICS", Const, 0, ""},
+		{"FILE_FLAG_OPEN_REPARSE_POINT", Const, 4, ""},
+		{"FILE_FLAG_OVERLAPPED", Const, 0, ""},
+		{"FILE_LIST_DIRECTORY", Const, 0, ""},
+		{"FILE_MAP_COPY", Const, 0, ""},
+		{"FILE_MAP_EXECUTE", Const, 0, ""},
+		{"FILE_MAP_READ", Const, 0, ""},
+		{"FILE_MAP_WRITE", Const, 0, ""},
+		{"FILE_NOTIFY_CHANGE_ATTRIBUTES", Const, 0, ""},
+		{"FILE_NOTIFY_CHANGE_CREATION", Const, 0, ""},
+		{"FILE_NOTIFY_CHANGE_DIR_NAME", Const, 0, ""},
+		{"FILE_NOTIFY_CHANGE_FILE_NAME", Const, 0, ""},
+		{"FILE_NOTIFY_CHANGE_LAST_ACCESS", Const, 0, ""},
+		{"FILE_NOTIFY_CHANGE_LAST_WRITE", Const, 0, ""},
+		{"FILE_NOTIFY_CHANGE_SIZE", Const, 0, ""},
+		{"FILE_SHARE_DELETE", Const, 0, ""},
+		{"FILE_SHARE_READ", Const, 0, ""},
+		{"FILE_SHARE_WRITE", Const, 0, ""},
+		{"FILE_SKIP_COMPLETION_PORT_ON_SUCCESS", Const, 2, ""},
+		{"FILE_SKIP_SET_EVENT_ON_HANDLE", Const, 2, ""},
+		{"FILE_TYPE_CHAR", Const, 0, ""},
+		{"FILE_TYPE_DISK", Const, 0, ""},
+		{"FILE_TYPE_PIPE", Const, 0, ""},
+		{"FILE_TYPE_REMOTE", Const, 0, ""},
+		{"FILE_TYPE_UNKNOWN", Const, 0, ""},
+		{"FILE_WRITE_ATTRIBUTES", Const, 0, ""},
+		{"FLUSHO", Const, 0, ""},
+		{"FORMAT_MESSAGE_ALLOCATE_BUFFER", Const, 0, ""},
+		{"FORMAT_MESSAGE_ARGUMENT_ARRAY", Const, 0, ""},
+		{"FORMAT_MESSAGE_FROM_HMODULE", Const, 0, ""},
+		{"FORMAT_MESSAGE_FROM_STRING", Const, 0, ""},
+		{"FORMAT_MESSAGE_FROM_SYSTEM", Const, 0, ""},
+		{"FORMAT_MESSAGE_IGNORE_INSERTS", Const, 0, ""},
+		{"FORMAT_MESSAGE_MAX_WIDTH_MASK", Const, 0, ""},
+		{"FSCTL_GET_REPARSE_POINT", Const, 4, ""},
+		{"F_ADDFILESIGS", Const, 0, ""},
+		{"F_ADDSIGS", Const, 0, ""},
+		{"F_ALLOCATEALL", Const, 0, ""},
+		{"F_ALLOCATECONTIG", Const, 0, ""},
+		{"F_CANCEL", Const, 0, ""},
+		{"F_CHKCLEAN", Const, 0, ""},
+		{"F_CLOSEM", Const, 1, ""},
+		{"F_DUP2FD", Const, 0, ""},
+		{"F_DUP2FD_CLOEXEC", Const, 1, ""},
+		{"F_DUPFD", Const, 0, ""},
+		{"F_DUPFD_CLOEXEC", Const, 0, ""},
+		{"F_EXLCK", Const, 0, ""},
+		{"F_FINDSIGS", Const, 16, ""},
+		{"F_FLUSH_DATA", Const, 0, ""},
+		{"F_FREEZE_FS", Const, 0, ""},
+		{"F_FSCTL", Const, 1, ""},
+		{"F_FSDIRMASK", Const, 1, ""},
+		{"F_FSIN", Const, 1, ""},
+		{"F_FSINOUT", Const, 1, ""},
+		{"F_FSOUT", Const, 1, ""},
+		{"F_FSPRIV", Const, 1, ""},
+		{"F_FSVOID", Const, 1, ""},
+		{"F_FULLFSYNC", Const, 0, ""},
+		{"F_GETCODEDIR", Const, 16, ""},
+		{"F_GETFD", Const, 0, ""},
+		{"F_GETFL", Const, 0, ""},
+		{"F_GETLEASE", Const, 0, ""},
+		{"F_GETLK", Const, 0, ""},
+		{"F_GETLK64", Const, 0, ""},
+		{"F_GETLKPID", Const, 0, ""},
+		{"F_GETNOSIGPIPE", Const, 0, ""},
+		{"F_GETOWN", Const, 0, ""},
+		{"F_GETOWN_EX", Const, 0, ""},
+		{"F_GETPATH", Const, 0, ""},
+		{"F_GETPATH_MTMINFO", Const, 0, ""},
+		{"F_GETPIPE_SZ", Const, 0, ""},
+		{"F_GETPROTECTIONCLASS", Const, 0, ""},
+		{"F_GETPROTECTIONLEVEL", Const, 16, ""},
+		{"F_GETSIG", Const, 0, ""},
+		{"F_GLOBAL_NOCACHE", Const, 0, ""},
+		{"F_LOCK", Const, 0, ""},
+		{"F_LOG2PHYS", Const, 0, ""},
+		{"F_LOG2PHYS_EXT", Const, 0, ""},
+		{"F_MARKDEPENDENCY", Const, 0, ""},
+		{"F_MAXFD", Const, 1, ""},
+		{"F_NOCACHE", Const, 0, ""},
+		{"F_NODIRECT", Const, 0, ""},
+		{"F_NOTIFY", Const, 0, ""},
+		{"F_OGETLK", Const, 0, ""},
+		{"F_OK", Const, 0, ""},
+		{"F_OSETLK", Const, 0, ""},
+		{"F_OSETLKW", Const, 0, ""},
+		{"F_PARAM_MASK", Const, 1, ""},
+		{"F_PARAM_MAX", Const, 1, ""},
+		{"F_PATHPKG_CHECK", Const, 0, ""},
+		{"F_PEOFPOSMODE", Const, 0, ""},
+		{"F_PREALLOCATE", Const, 0, ""},
+		{"F_RDADVISE", Const, 0, ""},
+		{"F_RDAHEAD", Const, 0, ""},
+		{"F_RDLCK", Const, 0, ""},
+		{"F_READAHEAD", Const, 0, ""},
+		{"F_READBOOTSTRAP", Const, 0, ""},
+		{"F_SETBACKINGSTORE", Const, 0, ""},
+		{"F_SETFD", Const, 0, ""},
+		{"F_SETFL", Const, 0, ""},
+		{"F_SETLEASE", Const, 0, ""},
+		{"F_SETLK", Const, 0, ""},
+		{"F_SETLK64", Const, 0, ""},
+		{"F_SETLKW", Const, 0, ""},
+		{"F_SETLKW64", Const, 0, ""},
+		{"F_SETLKWTIMEOUT", Const, 16, ""},
+		{"F_SETLK_REMOTE", Const, 0, ""},
+		{"F_SETNOSIGPIPE", Const, 0, ""},
+		{"F_SETOWN", Const, 0, ""},
+		{"F_SETOWN_EX", Const, 0, ""},
+		{"F_SETPIPE_SZ", Const, 0, ""},
+		{"F_SETPROTECTIONCLASS", Const, 0, ""},
+		{"F_SETSIG", Const, 0, ""},
+		{"F_SETSIZE", Const, 0, ""},
+		{"F_SHLCK", Const, 0, ""},
+		{"F_SINGLE_WRITER", Const, 16, ""},
+		{"F_TEST", Const, 0, ""},
+		{"F_THAW_FS", Const, 0, ""},
+		{"F_TLOCK", Const, 0, ""},
+		{"F_TRANSCODEKEY", Const, 16, ""},
+		{"F_ULOCK", Const, 0, ""},
+		{"F_UNLCK", Const, 0, ""},
+		{"F_UNLCKSYS", Const, 0, ""},
+		{"F_VOLPOSMODE", Const, 0, ""},
+		{"F_WRITEBOOTSTRAP", Const, 0, ""},
+		{"F_WRLCK", Const, 0, ""},
+		{"Faccessat", Func, 0, "func(dirfd int, path string, mode uint32, flags int) (err error)"},
+		{"Fallocate", Func, 0, "func(fd int, mode uint32, off int64, len int64) (err error)"},
+		{"Fbootstraptransfer_t", Type, 0, ""},
+		{"Fbootstraptransfer_t.Buffer", Field, 0, ""},
+		{"Fbootstraptransfer_t.Length", Field, 0, ""},
+		{"Fbootstraptransfer_t.Offset", Field, 0, ""},
+		{"Fchdir", Func, 0, "func(fd int) (err error)"},
+		{"Fchflags", Func, 0, ""},
+		{"Fchmod", Func, 0, "func(fd int, mode uint32) (err error)"},
+		{"Fchmodat", Func, 0, "func(dirfd int, path string, mode uint32, flags int) error"},
+		{"Fchown", Func, 0, "func(fd int, uid int, gid int) (err error)"},
+		{"Fchownat", Func, 0, "func(dirfd int, path string, uid int, gid int, flags int) (err error)"},
+		{"FcntlFlock", Func, 3, "func(fd uintptr, cmd int, lk *Flock_t) error"},
+		{"FdSet", Type, 0, ""},
+		{"FdSet.Bits", Field, 0, ""},
+		{"FdSet.X__fds_bits", Field, 0, ""},
+		{"Fdatasync", Func, 0, "func(fd int) (err error)"},
+		{"FileNotifyInformation", Type, 0, ""},
+		{"FileNotifyInformation.Action", Field, 0, ""},
+		{"FileNotifyInformation.FileName", Field, 0, ""},
+		{"FileNotifyInformation.FileNameLength", Field, 0, ""},
+		{"FileNotifyInformation.NextEntryOffset", Field, 0, ""},
+		{"Filetime", Type, 0, ""},
+		{"Filetime.HighDateTime", Field, 0, ""},
+		{"Filetime.LowDateTime", Field, 0, ""},
+		{"FindClose", Func, 0, ""},
+		{"FindFirstFile", Func, 0, ""},
+		{"FindNextFile", Func, 0, ""},
+		{"Flock", Func, 0, "func(fd int, how int) (err error)"},
+		{"Flock_t", Type, 0, ""},
+		{"Flock_t.Len", Field, 0, ""},
+		{"Flock_t.Pad_cgo_0", Field, 0, ""},
+		{"Flock_t.Pad_cgo_1", Field, 3, ""},
+		{"Flock_t.Pid", Field, 0, ""},
+		{"Flock_t.Start", Field, 0, ""},
+		{"Flock_t.Sysid", Field, 0, ""},
+		{"Flock_t.Type", Field, 0, ""},
+		{"Flock_t.Whence", Field, 0, ""},
+		{"FlushBpf", Func, 0, ""},
+		{"FlushFileBuffers", Func, 0, ""},
+		{"FlushViewOfFile", Func, 0, ""},
+		{"ForkExec", Func, 0, "func(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)"},
+		{"ForkLock", Var, 0, ""},
+		{"FormatMessage", Func, 0, ""},
+		{"Fpathconf", Func, 0, ""},
+		{"FreeAddrInfoW", Func, 1, ""},
+		{"FreeEnvironmentStrings", Func, 0, ""},
+		{"FreeLibrary", Func, 0, ""},
+		{"Fsid", Type, 0, ""},
+		{"Fsid.Val", Field, 0, ""},
+		{"Fsid.X__fsid_val", Field, 2, ""},
+		{"Fsid.X__val", Field, 0, ""},
+		{"Fstat", Func, 0, "func(fd int, stat *Stat_t) (err error)"},
+		{"Fstatat", Func, 12, ""},
+		{"Fstatfs", Func, 0, "func(fd int, buf *Statfs_t) (err error)"},
+		{"Fstore_t", Type, 0, ""},
+		{"Fstore_t.Bytesalloc", Field, 0, ""},
+		{"Fstore_t.Flags", Field, 0, ""},
+		{"Fstore_t.Length", Field, 0, ""},
+		{"Fstore_t.Offset", Field, 0, ""},
+		{"Fstore_t.Posmode", Field, 0, ""},
+		{"Fsync", Func, 0, "func(fd int) (err error)"},
+		{"Ftruncate", Func, 0, "func(fd int, length int64) (err error)"},
+		{"FullPath", Func, 4, ""},
+		{"Futimes", Func, 0, "func(fd int, tv []Timeval) (err error)"},
+		{"Futimesat", Func, 0, "func(dirfd int, path string, tv []Timeval) (err error)"},
+		{"GENERIC_ALL", Const, 0, ""},
+		{"GENERIC_EXECUTE", Const, 0, ""},
+		{"GENERIC_READ", Const, 0, ""},
+		{"GENERIC_WRITE", Const, 0, ""},
+		{"GUID", Type, 1, ""},
+		{"GUID.Data1", Field, 1, ""},
+		{"GUID.Data2", Field, 1, ""},
+		{"GUID.Data3", Field, 1, ""},
+		{"GUID.Data4", Field, 1, ""},
+		{"GetAcceptExSockaddrs", Func, 0, ""},
+		{"GetAdaptersInfo", Func, 0, ""},
+		{"GetAddrInfoW", Func, 1, ""},
+		{"GetCommandLine", Func, 0, ""},
+		{"GetComputerName", Func, 0, ""},
+		{"GetConsoleMode", Func, 1, ""},
+		{"GetCurrentDirectory", Func, 0, ""},
+		{"GetCurrentProcess", Func, 0, ""},
+		{"GetEnvironmentStrings", Func, 0, ""},
+		{"GetEnvironmentVariable", Func, 0, ""},
+		{"GetExitCodeProcess", Func, 0, ""},
+		{"GetFileAttributes", Func, 0, ""},
+		{"GetFileAttributesEx", Func, 0, ""},
+		{"GetFileExInfoStandard", Const, 0, ""},
+		{"GetFileExMaxInfoLevel", Const, 0, ""},
+		{"GetFileInformationByHandle", Func, 0, ""},
+		{"GetFileType", Func, 0, ""},
+		{"GetFullPathName", Func, 0, ""},
+		{"GetHostByName", Func, 0, ""},
+		{"GetIfEntry", Func, 0, ""},
+		{"GetLastError", Func, 0, ""},
+		{"GetLengthSid", Func, 0, ""},
+		{"GetLongPathName", Func, 0, ""},
+		{"GetProcAddress", Func, 0, ""},
+		{"GetProcessTimes", Func, 0, ""},
+		{"GetProtoByName", Func, 0, ""},
+		{"GetQueuedCompletionStatus", Func, 0, ""},
+		{"GetServByName", Func, 0, ""},
+		{"GetShortPathName", Func, 0, ""},
+		{"GetStartupInfo", Func, 0, ""},
+		{"GetStdHandle", Func, 0, ""},
+		{"GetSystemTimeAsFileTime", Func, 0, ""},
+		{"GetTempPath", Func, 0, ""},
+		{"GetTimeZoneInformation", Func, 0, ""},
+		{"GetTokenInformation", Func, 0, ""},
+		{"GetUserNameEx", Func, 0, ""},
+		{"GetUserProfileDirectory", Func, 0, ""},
+		{"GetVersion", Func, 0, ""},
+		{"Getcwd", Func, 0, "func(buf []byte) (n int, err error)"},
+		{"Getdents", Func, 0, "func(fd int, buf []byte) (n int, err error)"},
+		{"Getdirentries", Func, 0, ""},
+		{"Getdtablesize", Func, 0, ""},
+		{"Getegid", Func, 0, "func() (egid int)"},
+		{"Getenv", Func, 0, "func(key string) (value string, found bool)"},
+		{"Geteuid", Func, 0, "func() (euid int)"},
+		{"Getfsstat", Func, 0, ""},
+		{"Getgid", Func, 0, "func() (gid int)"},
+		{"Getgroups", Func, 0, "func() (gids []int, err error)"},
+		{"Getpagesize", Func, 0, "func() int"},
+		{"Getpeername", Func, 0, "func(fd int) (sa Sockaddr, err error)"},
+		{"Getpgid", Func, 0, "func(pid int) (pgid int, err error)"},
+		{"Getpgrp", Func, 0, "func() (pid int)"},
+		{"Getpid", Func, 0, "func() (pid int)"},
+		{"Getppid", Func, 0, "func() (ppid int)"},
+		{"Getpriority", Func, 0, "func(which int, who int) (prio int, err error)"},
+		{"Getrlimit", Func, 0, "func(resource int, rlim *Rlimit) (err error)"},
+		{"Getrusage", Func, 0, "func(who int, rusage *Rusage) (err error)"},
+		{"Getsid", Func, 0, ""},
+		{"Getsockname", Func, 0, "func(fd int) (sa Sockaddr, err error)"},
+		{"Getsockopt", Func, 1, ""},
+		{"GetsockoptByte", Func, 0, ""},
+		{"GetsockoptICMPv6Filter", Func, 2, "func(fd int, level int, opt int) (*ICMPv6Filter, error)"},
+		{"GetsockoptIPMreq", Func, 0, "func(fd int, level int, opt int) (*IPMreq, error)"},
+		{"GetsockoptIPMreqn", Func, 0, "func(fd int, level int, opt int) (*IPMreqn, error)"},
+		{"GetsockoptIPv6MTUInfo", Func, 2, "func(fd int, level int, opt int) (*IPv6MTUInfo, error)"},
+		{"GetsockoptIPv6Mreq", Func, 0, "func(fd int, level int, opt int) (*IPv6Mreq, error)"},
+		{"GetsockoptInet4Addr", Func, 0, "func(fd int, level int, opt int) (value [4]byte, err error)"},
+		{"GetsockoptInt", Func, 0, "func(fd int, level int, opt int) (value int, err error)"},
+		{"GetsockoptUcred", Func, 1, "func(fd int, level int, opt int) (*Ucred, error)"},
+		{"Gettid", Func, 0, "func() (tid int)"},
+		{"Gettimeofday", Func, 0, "func(tv *Timeval) (err error)"},
+		{"Getuid", Func, 0, "func() (uid int)"},
+		{"Getwd", Func, 0, "func() (wd string, err error)"},
+		{"Getxattr", Func, 1, "func(path string, attr string, dest []byte) (sz int, err error)"},
+		{"HANDLE_FLAG_INHERIT", Const, 0, ""},
+		{"HKEY_CLASSES_ROOT", Const, 0, ""},
+		{"HKEY_CURRENT_CONFIG", Const, 0, ""},
+		{"HKEY_CURRENT_USER", Const, 0, ""},
+		{"HKEY_DYN_DATA", Const, 0, ""},
+		{"HKEY_LOCAL_MACHINE", Const, 0, ""},
+		{"HKEY_PERFORMANCE_DATA", Const, 0, ""},
+		{"HKEY_USERS", Const, 0, ""},
+		{"HUPCL", Const, 0, ""},
+		{"Handle", Type, 0, ""},
+		{"Hostent", Type, 0, ""},
+		{"Hostent.AddrList", Field, 0, ""},
+		{"Hostent.AddrType", Field, 0, ""},
+		{"Hostent.Aliases", Field, 0, ""},
+		{"Hostent.Length", Field, 0, ""},
+		{"Hostent.Name", Field, 0, ""},
+		{"ICANON", Const, 0, ""},
+		{"ICMP6_FILTER", Const, 2, ""},
+		{"ICMPV6_FILTER", Const, 2, ""},
+		{"ICMPv6Filter", Type, 2, ""},
+		{"ICMPv6Filter.Data", Field, 2, ""},
+		{"ICMPv6Filter.Filt", Field, 2, ""},
+		{"ICRNL", Const, 0, ""},
+		{"IEXTEN", Const, 0, ""},
+		{"IFAN_ARRIVAL", Const, 1, ""},
+		{"IFAN_DEPARTURE", Const, 1, ""},
+		{"IFA_ADDRESS", Const, 0, ""},
+		{"IFA_ANYCAST", Const, 0, ""},
+		{"IFA_BROADCAST", Const, 0, ""},
+		{"IFA_CACHEINFO", Const, 0, ""},
+		{"IFA_F_DADFAILED", Const, 0, ""},
+		{"IFA_F_DEPRECATED", Const, 0, ""},
+		{"IFA_F_HOMEADDRESS", Const, 0, ""},
+		{"IFA_F_NODAD", Const, 0, ""},
+		{"IFA_F_OPTIMISTIC", Const, 0, ""},
+		{"IFA_F_PERMANENT", Const, 0, ""},
+		{"IFA_F_SECONDARY", Const, 0, ""},
+		{"IFA_F_TEMPORARY", Const, 0, ""},
+		{"IFA_F_TENTATIVE", Const, 0, ""},
+		{"IFA_LABEL", Const, 0, ""},
+		{"IFA_LOCAL", Const, 0, ""},
+		{"IFA_MAX", Const, 0, ""},
+		{"IFA_MULTICAST", Const, 0, ""},
+		{"IFA_ROUTE", Const, 1, ""},
+		{"IFA_UNSPEC", Const, 0, ""},
+		{"IFF_ALLMULTI", Const, 0, ""},
+		{"IFF_ALTPHYS", Const, 0, ""},
+		{"IFF_AUTOMEDIA", Const, 0, ""},
+		{"IFF_BROADCAST", Const, 0, ""},
+		{"IFF_CANTCHANGE", Const, 0, ""},
+		{"IFF_CANTCONFIG", Const, 1, ""},
+		{"IFF_DEBUG", Const, 0, ""},
+		{"IFF_DRV_OACTIVE", Const, 0, ""},
+		{"IFF_DRV_RUNNING", Const, 0, ""},
+		{"IFF_DYING", Const, 0, ""},
+		{"IFF_DYNAMIC", Const, 0, ""},
+		{"IFF_LINK0", Const, 0, ""},
+		{"IFF_LINK1", Const, 0, ""},
+		{"IFF_LINK2", Const, 0, ""},
+		{"IFF_LOOPBACK", Const, 0, ""},
+		{"IFF_MASTER", Const, 0, ""},
+		{"IFF_MONITOR", Const, 0, ""},
+		{"IFF_MULTICAST", Const, 0, ""},
+		{"IFF_NOARP", Const, 0, ""},
+		{"IFF_NOTRAILERS", Const, 0, ""},
+		{"IFF_NO_PI", Const, 0, ""},
+		{"IFF_OACTIVE", Const, 0, ""},
+		{"IFF_ONE_QUEUE", Const, 0, ""},
+		{"IFF_POINTOPOINT", Const, 0, ""},
+		{"IFF_POINTTOPOINT", Const, 0, ""},
+		{"IFF_PORTSEL", Const, 0, ""},
+		{"IFF_PPROMISC", Const, 0, ""},
+		{"IFF_PROMISC", Const, 0, ""},
+		{"IFF_RENAMING", Const, 0, ""},
+		{"IFF_RUNNING", Const, 0, ""},
+		{"IFF_SIMPLEX", Const, 0, ""},
+		{"IFF_SLAVE", Const, 0, ""},
+		{"IFF_SMART", Const, 0, ""},
+		{"IFF_STATICARP", Const, 0, ""},
+		{"IFF_TAP", Const, 0, ""},
+		{"IFF_TUN", Const, 0, ""},
+		{"IFF_TUN_EXCL", Const, 0, ""},
+		{"IFF_UP", Const, 0, ""},
+		{"IFF_VNET_HDR", Const, 0, ""},
+		{"IFLA_ADDRESS", Const, 0, ""},
+		{"IFLA_BROADCAST", Const, 0, ""},
+		{"IFLA_COST", Const, 0, ""},
+		{"IFLA_IFALIAS", Const, 0, ""},
+		{"IFLA_IFNAME", Const, 0, ""},
+		{"IFLA_LINK", Const, 0, ""},
+		{"IFLA_LINKINFO", Const, 0, ""},
+		{"IFLA_LINKMODE", Const, 0, ""},
+		{"IFLA_MAP", Const, 0, ""},
+		{"IFLA_MASTER", Const, 0, ""},
+		{"IFLA_MAX", Const, 0, ""},
+		{"IFLA_MTU", Const, 0, ""},
+		{"IFLA_NET_NS_PID", Const, 0, ""},
+		{"IFLA_OPERSTATE", Const, 0, ""},
+		{"IFLA_PRIORITY", Const, 0, ""},
+		{"IFLA_PROTINFO", Const, 0, ""},
+		{"IFLA_QDISC", Const, 0, ""},
+		{"IFLA_STATS", Const, 0, ""},
+		{"IFLA_TXQLEN", Const, 0, ""},
+		{"IFLA_UNSPEC", Const, 0, ""},
+		{"IFLA_WEIGHT", Const, 0, ""},
+		{"IFLA_WIRELESS", Const, 0, ""},
+		{"IFNAMSIZ", Const, 0, ""},
+		{"IFT_1822", Const, 0, ""},
+		{"IFT_A12MPPSWITCH", Const, 0, ""},
+		{"IFT_AAL2", Const, 0, ""},
+		{"IFT_AAL5", Const, 0, ""},
+		{"IFT_ADSL", Const, 0, ""},
+		{"IFT_AFLANE8023", Const, 0, ""},
+		{"IFT_AFLANE8025", Const, 0, ""},
+		{"IFT_ARAP", Const, 0, ""},
+		{"IFT_ARCNET", Const, 0, ""},
+		{"IFT_ARCNETPLUS", Const, 0, ""},
+		{"IFT_ASYNC", Const, 0, ""},
+		{"IFT_ATM", Const, 0, ""},
+		{"IFT_ATMDXI", Const, 0, ""},
+		{"IFT_ATMFUNI", Const, 0, ""},
+		{"IFT_ATMIMA", Const, 0, ""},
+		{"IFT_ATMLOGICAL", Const, 0, ""},
+		{"IFT_ATMRADIO", Const, 0, ""},
+		{"IFT_ATMSUBINTERFACE", Const, 0, ""},
+		{"IFT_ATMVCIENDPT", Const, 0, ""},
+		{"IFT_ATMVIRTUAL", Const, 0, ""},
+		{"IFT_BGPPOLICYACCOUNTING", Const, 0, ""},
+		{"IFT_BLUETOOTH", Const, 1, ""},
+		{"IFT_BRIDGE", Const, 0, ""},
+		{"IFT_BSC", Const, 0, ""},
+		{"IFT_CARP", Const, 0, ""},
+		{"IFT_CCTEMUL", Const, 0, ""},
+		{"IFT_CELLULAR", Const, 0, ""},
+		{"IFT_CEPT", Const, 0, ""},
+		{"IFT_CES", Const, 0, ""},
+		{"IFT_CHANNEL", Const, 0, ""},
+		{"IFT_CNR", Const, 0, ""},
+		{"IFT_COFFEE", Const, 0, ""},
+		{"IFT_COMPOSITELINK", Const, 0, ""},
+		{"IFT_DCN", Const, 0, ""},
+		{"IFT_DIGITALPOWERLINE", Const, 0, ""},
+		{"IFT_DIGITALWRAPPEROVERHEADCHANNEL", Const, 0, ""},
+		{"IFT_DLSW", Const, 0, ""},
+		{"IFT_DOCSCABLEDOWNSTREAM", Const, 0, ""},
+		{"IFT_DOCSCABLEMACLAYER", Const, 0, ""},
+		{"IFT_DOCSCABLEUPSTREAM", Const, 0, ""},
+		{"IFT_DOCSCABLEUPSTREAMCHANNEL", Const, 1, ""},
+		{"IFT_DS0", Const, 0, ""},
+		{"IFT_DS0BUNDLE", Const, 0, ""},
+		{"IFT_DS1FDL", Const, 0, ""},
+		{"IFT_DS3", Const, 0, ""},
+		{"IFT_DTM", Const, 0, ""},
+		{"IFT_DUMMY", Const, 1, ""},
+		{"IFT_DVBASILN", Const, 0, ""},
+		{"IFT_DVBASIOUT", Const, 0, ""},
+		{"IFT_DVBRCCDOWNSTREAM", Const, 0, ""},
+		{"IFT_DVBRCCMACLAYER", Const, 0, ""},
+		{"IFT_DVBRCCUPSTREAM", Const, 0, ""},
+		{"IFT_ECONET", Const, 1, ""},
+		{"IFT_ENC", Const, 0, ""},
+		{"IFT_EON", Const, 0, ""},
+		{"IFT_EPLRS", Const, 0, ""},
+		{"IFT_ESCON", Const, 0, ""},
+		{"IFT_ETHER", Const, 0, ""},
+		{"IFT_FAITH", Const, 0, ""},
+		{"IFT_FAST", Const, 0, ""},
+		{"IFT_FASTETHER", Const, 0, ""},
+		{"IFT_FASTETHERFX", Const, 0, ""},
+		{"IFT_FDDI", Const, 0, ""},
+		{"IFT_FIBRECHANNEL", Const, 0, ""},
+		{"IFT_FRAMERELAYINTERCONNECT", Const, 0, ""},
+		{"IFT_FRAMERELAYMPI", Const, 0, ""},
+		{"IFT_FRDLCIENDPT", Const, 0, ""},
+		{"IFT_FRELAY", Const, 0, ""},
+		{"IFT_FRELAYDCE", Const, 0, ""},
+		{"IFT_FRF16MFRBUNDLE", Const, 0, ""},
+		{"IFT_FRFORWARD", Const, 0, ""},
+		{"IFT_G703AT2MB", Const, 0, ""},
+		{"IFT_G703AT64K", Const, 0, ""},
+		{"IFT_GIF", Const, 0, ""},
+		{"IFT_GIGABITETHERNET", Const, 0, ""},
+		{"IFT_GR303IDT", Const, 0, ""},
+		{"IFT_GR303RDT", Const, 0, ""},
+		{"IFT_H323GATEKEEPER", Const, 0, ""},
+		{"IFT_H323PROXY", Const, 0, ""},
+		{"IFT_HDH1822", Const, 0, ""},
+		{"IFT_HDLC", Const, 0, ""},
+		{"IFT_HDSL2", Const, 0, ""},
+		{"IFT_HIPERLAN2", Const, 0, ""},
+		{"IFT_HIPPI", Const, 0, ""},
+		{"IFT_HIPPIINTERFACE", Const, 0, ""},
+		{"IFT_HOSTPAD", Const, 0, ""},
+		{"IFT_HSSI", Const, 0, ""},
+		{"IFT_HY", Const, 0, ""},
+		{"IFT_IBM370PARCHAN", Const, 0, ""},
+		{"IFT_IDSL", Const, 0, ""},
+		{"IFT_IEEE1394", Const, 0, ""},
+		{"IFT_IEEE80211", Const, 0, ""},
+		{"IFT_IEEE80212", Const, 0, ""},
+		{"IFT_IEEE8023ADLAG", Const, 0, ""},
+		{"IFT_IFGSN", Const, 0, ""},
+		{"IFT_IMT", Const, 0, ""},
+		{"IFT_INFINIBAND", Const, 1, ""},
+		{"IFT_INTERLEAVE", Const, 0, ""},
+		{"IFT_IP", Const, 0, ""},
+		{"IFT_IPFORWARD", Const, 0, ""},
+		{"IFT_IPOVERATM", Const, 0, ""},
+		{"IFT_IPOVERCDLC", Const, 0, ""},
+		{"IFT_IPOVERCLAW", Const, 0, ""},
+		{"IFT_IPSWITCH", Const, 0, ""},
+		{"IFT_IPXIP", Const, 0, ""},
+		{"IFT_ISDN", Const, 0, ""},
+		{"IFT_ISDNBASIC", Const, 0, ""},
+		{"IFT_ISDNPRIMARY", Const, 0, ""},
+		{"IFT_ISDNS", Const, 0, ""},
+		{"IFT_ISDNU", Const, 0, ""},
+		{"IFT_ISO88022LLC", Const, 0, ""},
+		{"IFT_ISO88023", Const, 0, ""},
+		{"IFT_ISO88024", Const, 0, ""},
+		{"IFT_ISO88025", Const, 0, ""},
+		{"IFT_ISO88025CRFPINT", Const, 0, ""},
+		{"IFT_ISO88025DTR", Const, 0, ""},
+		{"IFT_ISO88025FIBER", Const, 0, ""},
+		{"IFT_ISO88026", Const, 0, ""},
+		{"IFT_ISUP", Const, 0, ""},
+		{"IFT_L2VLAN", Const, 0, ""},
+		{"IFT_L3IPVLAN", Const, 0, ""},
+		{"IFT_L3IPXVLAN", Const, 0, ""},
+		{"IFT_LAPB", Const, 0, ""},
+		{"IFT_LAPD", Const, 0, ""},
+		{"IFT_LAPF", Const, 0, ""},
+		{"IFT_LINEGROUP", Const, 1, ""},
+		{"IFT_LOCALTALK", Const, 0, ""},
+		{"IFT_LOOP", Const, 0, ""},
+		{"IFT_MEDIAMAILOVERIP", Const, 0, ""},
+		{"IFT_MFSIGLINK", Const, 0, ""},
+		{"IFT_MIOX25", Const, 0, ""},
+		{"IFT_MODEM", Const, 0, ""},
+		{"IFT_MPC", Const, 0, ""},
+		{"IFT_MPLS", Const, 0, ""},
+		{"IFT_MPLSTUNNEL", Const, 0, ""},
+		{"IFT_MSDSL", Const, 0, ""},
+		{"IFT_MVL", Const, 0, ""},
+		{"IFT_MYRINET", Const, 0, ""},
+		{"IFT_NFAS", Const, 0, ""},
+		{"IFT_NSIP", Const, 0, ""},
+		{"IFT_OPTICALCHANNEL", Const, 0, ""},
+		{"IFT_OPTICALTRANSPORT", Const, 0, ""},
+		{"IFT_OTHER", Const, 0, ""},
+		{"IFT_P10", Const, 0, ""},
+		{"IFT_P80", Const, 0, ""},
+		{"IFT_PARA", Const, 0, ""},
+		{"IFT_PDP", Const, 0, ""},
+		{"IFT_PFLOG", Const, 0, ""},
+		{"IFT_PFLOW", Const, 1, ""},
+		{"IFT_PFSYNC", Const, 0, ""},
+		{"IFT_PLC", Const, 0, ""},
+		{"IFT_PON155", Const, 1, ""},
+		{"IFT_PON622", Const, 1, ""},
+		{"IFT_POS", Const, 0, ""},
+		{"IFT_PPP", Const, 0, ""},
+		{"IFT_PPPMULTILINKBUNDLE", Const, 0, ""},
+		{"IFT_PROPATM", Const, 1, ""},
+		{"IFT_PROPBWAP2MP", Const, 0, ""},
+		{"IFT_PROPCNLS", Const, 0, ""},
+		{"IFT_PROPDOCSWIRELESSDOWNSTREAM", Const, 0, ""},
+		{"IFT_PROPDOCSWIRELESSMACLAYER", Const, 0, ""},
+		{"IFT_PROPDOCSWIRELESSUPSTREAM", Const, 0, ""},
+		{"IFT_PROPMUX", Const, 0, ""},
+		{"IFT_PROPVIRTUAL", Const, 0, ""},
+		{"IFT_PROPWIRELESSP2P", Const, 0, ""},
+		{"IFT_PTPSERIAL", Const, 0, ""},
+		{"IFT_PVC", Const, 0, ""},
+		{"IFT_Q2931", Const, 1, ""},
+		{"IFT_QLLC", Const, 0, ""},
+		{"IFT_RADIOMAC", Const, 0, ""},
+		{"IFT_RADSL", Const, 0, ""},
+		{"IFT_REACHDSL", Const, 0, ""},
+		{"IFT_RFC1483", Const, 0, ""},
+		{"IFT_RS232", Const, 0, ""},
+		{"IFT_RSRB", Const, 0, ""},
+		{"IFT_SDLC", Const, 0, ""},
+		{"IFT_SDSL", Const, 0, ""},
+		{"IFT_SHDSL", Const, 0, ""},
+		{"IFT_SIP", Const, 0, ""},
+		{"IFT_SIPSIG", Const, 1, ""},
+		{"IFT_SIPTG", Const, 1, ""},
+		{"IFT_SLIP", Const, 0, ""},
+		{"IFT_SMDSDXI", Const, 0, ""},
+		{"IFT_SMDSICIP", Const, 0, ""},
+		{"IFT_SONET", Const, 0, ""},
+		{"IFT_SONETOVERHEADCHANNEL", Const, 0, ""},
+		{"IFT_SONETPATH", Const, 0, ""},
+		{"IFT_SONETVT", Const, 0, ""},
+		{"IFT_SRP", Const, 0, ""},
+		{"IFT_SS7SIGLINK", Const, 0, ""},
+		{"IFT_STACKTOSTACK", Const, 0, ""},
+		{"IFT_STARLAN", Const, 0, ""},
+		{"IFT_STF", Const, 0, ""},
+		{"IFT_T1", Const, 0, ""},
+		{"IFT_TDLC", Const, 0, ""},
+		{"IFT_TELINK", Const, 1, ""},
+		{"IFT_TERMPAD", Const, 0, ""},
+		{"IFT_TR008", Const, 0, ""},
+		{"IFT_TRANSPHDLC", Const, 0, ""},
+		{"IFT_TUNNEL", Const, 0, ""},
+		{"IFT_ULTRA", Const, 0, ""},
+		{"IFT_USB", Const, 0, ""},
+		{"IFT_V11", Const, 0, ""},
+		{"IFT_V35", Const, 0, ""},
+		{"IFT_V36", Const, 0, ""},
+		{"IFT_V37", Const, 0, ""},
+		{"IFT_VDSL", Const, 0, ""},
+		{"IFT_VIRTUALIPADDRESS", Const, 0, ""},
+		{"IFT_VIRTUALTG", Const, 1, ""},
+		{"IFT_VOICEDID", Const, 1, ""},
+		{"IFT_VOICEEM", Const, 0, ""},
+		{"IFT_VOICEEMFGD", Const, 1, ""},
+		{"IFT_VOICEENCAP", Const, 0, ""},
+		{"IFT_VOICEFGDEANA", Const, 1, ""},
+		{"IFT_VOICEFXO", Const, 0, ""},
+		{"IFT_VOICEFXS", Const, 0, ""},
+		{"IFT_VOICEOVERATM", Const, 0, ""},
+		{"IFT_VOICEOVERCABLE", Const, 1, ""},
+		{"IFT_VOICEOVERFRAMERELAY", Const, 0, ""},
+		{"IFT_VOICEOVERIP", Const, 0, ""},
+		{"IFT_X213", Const, 0, ""},
+		{"IFT_X25", Const, 0, ""},
+		{"IFT_X25DDN", Const, 0, ""},
+		{"IFT_X25HUNTGROUP", Const, 0, ""},
+		{"IFT_X25MLP", Const, 0, ""},
+		{"IFT_X25PLE", Const, 0, ""},
+		{"IFT_XETHER", Const, 0, ""},
+		{"IGNBRK", Const, 0, ""},
+		{"IGNCR", Const, 0, ""},
+		{"IGNORE", Const, 0, ""},
+		{"IGNPAR", Const, 0, ""},
+		{"IMAXBEL", Const, 0, ""},
+		{"INFINITE", Const, 0, ""},
+		{"INLCR", Const, 0, ""},
+		{"INPCK", Const, 0, ""},
+		{"INVALID_FILE_ATTRIBUTES", Const, 0, ""},
+		{"IN_ACCESS", Const, 0, ""},
+		{"IN_ALL_EVENTS", Const, 0, ""},
+		{"IN_ATTRIB", Const, 0, ""},
+		{"IN_CLASSA_HOST", Const, 0, ""},
+		{"IN_CLASSA_MAX", Const, 0, ""},
+		{"IN_CLASSA_NET", Const, 0, ""},
+		{"IN_CLASSA_NSHIFT", Const, 0, ""},
+		{"IN_CLASSB_HOST", Const, 0, ""},
+		{"IN_CLASSB_MAX", Const, 0, ""},
+		{"IN_CLASSB_NET", Const, 0, ""},
+		{"IN_CLASSB_NSHIFT", Const, 0, ""},
+		{"IN_CLASSC_HOST", Const, 0, ""},
+		{"IN_CLASSC_NET", Const, 0, ""},
+		{"IN_CLASSC_NSHIFT", Const, 0, ""},
+		{"IN_CLASSD_HOST", Const, 0, ""},
+		{"IN_CLASSD_NET", Const, 0, ""},
+		{"IN_CLASSD_NSHIFT", Const, 0, ""},
+		{"IN_CLOEXEC", Const, 0, ""},
+		{"IN_CLOSE", Const, 0, ""},
+		{"IN_CLOSE_NOWRITE", Const, 0, ""},
+		{"IN_CLOSE_WRITE", Const, 0, ""},
+		{"IN_CREATE", Const, 0, ""},
+		{"IN_DELETE", Const, 0, ""},
+		{"IN_DELETE_SELF", Const, 0, ""},
+		{"IN_DONT_FOLLOW", Const, 0, ""},
+		{"IN_EXCL_UNLINK", Const, 0, ""},
+		{"IN_IGNORED", Const, 0, ""},
+		{"IN_ISDIR", Const, 0, ""},
+		{"IN_LINKLOCALNETNUM", Const, 0, ""},
+		{"IN_LOOPBACKNET", Const, 0, ""},
+		{"IN_MASK_ADD", Const, 0, ""},
+		{"IN_MODIFY", Const, 0, ""},
+		{"IN_MOVE", Const, 0, ""},
+		{"IN_MOVED_FROM", Const, 0, ""},
+		{"IN_MOVED_TO", Const, 0, ""},
+		{"IN_MOVE_SELF", Const, 0, ""},
+		{"IN_NONBLOCK", Const, 0, ""},
+		{"IN_ONESHOT", Const, 0, ""},
+		{"IN_ONLYDIR", Const, 0, ""},
+		{"IN_OPEN", Const, 0, ""},
+		{"IN_Q_OVERFLOW", Const, 0, ""},
+		{"IN_RFC3021_HOST", Const, 1, ""},
+		{"IN_RFC3021_MASK", Const, 1, ""},
+		{"IN_RFC3021_NET", Const, 1, ""},
+		{"IN_RFC3021_NSHIFT", Const, 1, ""},
+		{"IN_UNMOUNT", Const, 0, ""},
+		{"IOC_IN", Const, 1, ""},
+		{"IOC_INOUT", Const, 1, ""},
+		{"IOC_OUT", Const, 1, ""},
+		{"IOC_VENDOR", Const, 3, ""},
+		{"IOC_WS2", Const, 1, ""},
+		{"IO_REPARSE_TAG_SYMLINK", Const, 4, ""},
+		{"IPMreq", Type, 0, ""},
+		{"IPMreq.Interface", Field, 0, ""},
+		{"IPMreq.Multiaddr", Field, 0, ""},
+		{"IPMreqn", Type, 0, ""},
+		{"IPMreqn.Address", Field, 0, ""},
+		{"IPMreqn.Ifindex", Field, 0, ""},
+		{"IPMreqn.Multiaddr", Field, 0, ""},
+		{"IPPROTO_3PC", Const, 0, ""},
+		{"IPPROTO_ADFS", Const, 0, ""},
+		{"IPPROTO_AH", Const, 0, ""},
+		{"IPPROTO_AHIP", Const, 0, ""},
+		{"IPPROTO_APES", Const, 0, ""},
+		{"IPPROTO_ARGUS", Const, 0, ""},
+		{"IPPROTO_AX25", Const, 0, ""},
+		{"IPPROTO_BHA", Const, 0, ""},
+		{"IPPROTO_BLT", Const, 0, ""},
+		{"IPPROTO_BRSATMON", Const, 0, ""},
+		{"IPPROTO_CARP", Const, 0, ""},
+		{"IPPROTO_CFTP", Const, 0, ""},
+		{"IPPROTO_CHAOS", Const, 0, ""},
+		{"IPPROTO_CMTP", Const, 0, ""},
+		{"IPPROTO_COMP", Const, 0, ""},
+		{"IPPROTO_CPHB", Const, 0, ""},
+		{"IPPROTO_CPNX", Const, 0, ""},
+		{"IPPROTO_DCCP", Const, 0, ""},
+		{"IPPROTO_DDP", Const, 0, ""},
+		{"IPPROTO_DGP", Const, 0, ""},
+		{"IPPROTO_DIVERT", Const, 0, ""},
+		{"IPPROTO_DIVERT_INIT", Const, 3, ""},
+		{"IPPROTO_DIVERT_RESP", Const, 3, ""},
+		{"IPPROTO_DONE", Const, 0, ""},
+		{"IPPROTO_DSTOPTS", Const, 0, ""},
+		{"IPPROTO_EGP", Const, 0, ""},
+		{"IPPROTO_EMCON", Const, 0, ""},
+		{"IPPROTO_ENCAP", Const, 0, ""},
+		{"IPPROTO_EON", Const, 0, ""},
+		{"IPPROTO_ESP", Const, 0, ""},
+		{"IPPROTO_ETHERIP", Const, 0, ""},
+		{"IPPROTO_FRAGMENT", Const, 0, ""},
+		{"IPPROTO_GGP", Const, 0, ""},
+		{"IPPROTO_GMTP", Const, 0, ""},
+		{"IPPROTO_GRE", Const, 0, ""},
+		{"IPPROTO_HELLO", Const, 0, ""},
+		{"IPPROTO_HMP", Const, 0, ""},
+		{"IPPROTO_HOPOPTS", Const, 0, ""},
+		{"IPPROTO_ICMP", Const, 0, ""},
+		{"IPPROTO_ICMPV6", Const, 0, ""},
+		{"IPPROTO_IDP", Const, 0, ""},
+		{"IPPROTO_IDPR", Const, 0, ""},
+		{"IPPROTO_IDRP", Const, 0, ""},
+		{"IPPROTO_IGMP", Const, 0, ""},
+		{"IPPROTO_IGP", Const, 0, ""},
+		{"IPPROTO_IGRP", Const, 0, ""},
+		{"IPPROTO_IL", Const, 0, ""},
+		{"IPPROTO_INLSP", Const, 0, ""},
+		{"IPPROTO_INP", Const, 0, ""},
+		{"IPPROTO_IP", Const, 0, ""},
+		{"IPPROTO_IPCOMP", Const, 0, ""},
+		{"IPPROTO_IPCV", Const, 0, ""},
+		{"IPPROTO_IPEIP", Const, 0, ""},
+		{"IPPROTO_IPIP", Const, 0, ""},
+		{"IPPROTO_IPPC", Const, 0, ""},
+		{"IPPROTO_IPV4", Const, 0, ""},
+		{"IPPROTO_IPV6", Const, 0, ""},
+		{"IPPROTO_IPV6_ICMP", Const, 1, ""},
+		{"IPPROTO_IRTP", Const, 0, ""},
+		{"IPPROTO_KRYPTOLAN", Const, 0, ""},
+		{"IPPROTO_LARP", Const, 0, ""},
+		{"IPPROTO_LEAF1", Const, 0, ""},
+		{"IPPROTO_LEAF2", Const, 0, ""},
+		{"IPPROTO_MAX", Const, 0, ""},
+		{"IPPROTO_MAXID", Const, 0, ""},
+		{"IPPROTO_MEAS", Const, 0, ""},
+		{"IPPROTO_MH", Const, 1, ""},
+		{"IPPROTO_MHRP", Const, 0, ""},
+		{"IPPROTO_MICP", Const, 0, ""},
+		{"IPPROTO_MOBILE", Const, 0, ""},
+		{"IPPROTO_MPLS", Const, 1, ""},
+		{"IPPROTO_MTP", Const, 0, ""},
+		{"IPPROTO_MUX", Const, 0, ""},
+		{"IPPROTO_ND", Const, 0, ""},
+		{"IPPROTO_NHRP", Const, 0, ""},
+		{"IPPROTO_NONE", Const, 0, ""},
+		{"IPPROTO_NSP", Const, 0, ""},
+		{"IPPROTO_NVPII", Const, 0, ""},
+		{"IPPROTO_OLD_DIVERT", Const, 0, ""},
+		{"IPPROTO_OSPFIGP", Const, 0, ""},
+		{"IPPROTO_PFSYNC", Const, 0, ""},
+		{"IPPROTO_PGM", Const, 0, ""},
+		{"IPPROTO_PIGP", Const, 0, ""},
+		{"IPPROTO_PIM", Const, 0, ""},
+		{"IPPROTO_PRM", Const, 0, ""},
+		{"IPPROTO_PUP", Const, 0, ""},
+		{"IPPROTO_PVP", Const, 0, ""},
+		{"IPPROTO_RAW", Const, 0, ""},
+		{"IPPROTO_RCCMON", Const, 0, ""},
+		{"IPPROTO_RDP", Const, 0, ""},
+		{"IPPROTO_ROUTING", Const, 0, ""},
+		{"IPPROTO_RSVP", Const, 0, ""},
+		{"IPPROTO_RVD", Const, 0, ""},
+		{"IPPROTO_SATEXPAK", Const, 0, ""},
+		{"IPPROTO_SATMON", Const, 0, ""},
+		{"IPPROTO_SCCSP", Const, 0, ""},
+		{"IPPROTO_SCTP", Const, 0, ""},
+		{"IPPROTO_SDRP", Const, 0, ""},
+		{"IPPROTO_SEND", Const, 1, ""},
+		{"IPPROTO_SEP", Const, 0, ""},
+		{"IPPROTO_SKIP", Const, 0, ""},
+		{"IPPROTO_SPACER", Const, 0, ""},
+		{"IPPROTO_SRPC", Const, 0, ""},
+		{"IPPROTO_ST", Const, 0, ""},
+		{"IPPROTO_SVMTP", Const, 0, ""},
+		{"IPPROTO_SWIPE", Const, 0, ""},
+		{"IPPROTO_TCF", Const, 0, ""},
+		{"IPPROTO_TCP", Const, 0, ""},
+		{"IPPROTO_TLSP", Const, 0, ""},
+		{"IPPROTO_TP", Const, 0, ""},
+		{"IPPROTO_TPXX", Const, 0, ""},
+		{"IPPROTO_TRUNK1", Const, 0, ""},
+		{"IPPROTO_TRUNK2", Const, 0, ""},
+		{"IPPROTO_TTP", Const, 0, ""},
+		{"IPPROTO_UDP", Const, 0, ""},
+		{"IPPROTO_UDPLITE", Const, 0, ""},
+		{"IPPROTO_VINES", Const, 0, ""},
+		{"IPPROTO_VISA", Const, 0, ""},
+		{"IPPROTO_VMTP", Const, 0, ""},
+		{"IPPROTO_VRRP", Const, 1, ""},
+		{"IPPROTO_WBEXPAK", Const, 0, ""},
+		{"IPPROTO_WBMON", Const, 0, ""},
+		{"IPPROTO_WSN", Const, 0, ""},
+		{"IPPROTO_XNET", Const, 0, ""},
+		{"IPPROTO_XTP", Const, 0, ""},
+		{"IPV6_2292DSTOPTS", Const, 0, ""},
+		{"IPV6_2292HOPLIMIT", Const, 0, ""},
+		{"IPV6_2292HOPOPTS", Const, 0, ""},
+		{"IPV6_2292NEXTHOP", Const, 0, ""},
+		{"IPV6_2292PKTINFO", Const, 0, ""},
+		{"IPV6_2292PKTOPTIONS", Const, 0, ""},
+		{"IPV6_2292RTHDR", Const, 0, ""},
+		{"IPV6_ADDRFORM", Const, 0, ""},
+		{"IPV6_ADD_MEMBERSHIP", Const, 0, ""},
+		{"IPV6_AUTHHDR", Const, 0, ""},
+		{"IPV6_AUTH_LEVEL", Const, 1, ""},
+		{"IPV6_AUTOFLOWLABEL", Const, 0, ""},
+		{"IPV6_BINDANY", Const, 0, ""},
+		{"IPV6_BINDV6ONLY", Const, 0, ""},
+		{"IPV6_BOUND_IF", Const, 0, ""},
+		{"IPV6_CHECKSUM", Const, 0, ""},
+		{"IPV6_DEFAULT_MULTICAST_HOPS", Const, 0, ""},
+		{"IPV6_DEFAULT_MULTICAST_LOOP", Const, 0, ""},
+		{"IPV6_DEFHLIM", Const, 0, ""},
+		{"IPV6_DONTFRAG", Const, 0, ""},
+		{"IPV6_DROP_MEMBERSHIP", Const, 0, ""},
+		{"IPV6_DSTOPTS", Const, 0, ""},
+		{"IPV6_ESP_NETWORK_LEVEL", Const, 1, ""},
+		{"IPV6_ESP_TRANS_LEVEL", Const, 1, ""},
+		{"IPV6_FAITH", Const, 0, ""},
+		{"IPV6_FLOWINFO_MASK", Const, 0, ""},
+		{"IPV6_FLOWLABEL_MASK", Const, 0, ""},
+		{"IPV6_FRAGTTL", Const, 0, ""},
+		{"IPV6_FW_ADD", Const, 0, ""},
+		{"IPV6_FW_DEL", Const, 0, ""},
+		{"IPV6_FW_FLUSH", Const, 0, ""},
+		{"IPV6_FW_GET", Const, 0, ""},
+		{"IPV6_FW_ZERO", Const, 0, ""},
+		{"IPV6_HLIMDEC", Const, 0, ""},
+		{"IPV6_HOPLIMIT", Const, 0, ""},
+		{"IPV6_HOPOPTS", Const, 0, ""},
+		{"IPV6_IPCOMP_LEVEL", Const, 1, ""},
+		{"IPV6_IPSEC_POLICY", Const, 0, ""},
+		{"IPV6_JOIN_ANYCAST", Const, 0, ""},
+		{"IPV6_JOIN_GROUP", Const, 0, ""},
+		{"IPV6_LEAVE_ANYCAST", Const, 0, ""},
+		{"IPV6_LEAVE_GROUP", Const, 0, ""},
+		{"IPV6_MAXHLIM", Const, 0, ""},
+		{"IPV6_MAXOPTHDR", Const, 0, ""},
+		{"IPV6_MAXPACKET", Const, 0, ""},
+		{"IPV6_MAX_GROUP_SRC_FILTER", Const, 0, ""},
+		{"IPV6_MAX_MEMBERSHIPS", Const, 0, ""},
+		{"IPV6_MAX_SOCK_SRC_FILTER", Const, 0, ""},
+		{"IPV6_MIN_MEMBERSHIPS", Const, 0, ""},
+		{"IPV6_MMTU", Const, 0, ""},
+		{"IPV6_MSFILTER", Const, 0, ""},
+		{"IPV6_MTU", Const, 0, ""},
+		{"IPV6_MTU_DISCOVER", Const, 0, ""},
+		{"IPV6_MULTICAST_HOPS", Const, 0, ""},
+		{"IPV6_MULTICAST_IF", Const, 0, ""},
+		{"IPV6_MULTICAST_LOOP", Const, 0, ""},
+		{"IPV6_NEXTHOP", Const, 0, ""},
+		{"IPV6_OPTIONS", Const, 1, ""},
+		{"IPV6_PATHMTU", Const, 0, ""},
+		{"IPV6_PIPEX", Const, 1, ""},
+		{"IPV6_PKTINFO", Const, 0, ""},
+		{"IPV6_PMTUDISC_DO", Const, 0, ""},
+		{"IPV6_PMTUDISC_DONT", Const, 0, ""},
+		{"IPV6_PMTUDISC_PROBE", Const, 0, ""},
+		{"IPV6_PMTUDISC_WANT", Const, 0, ""},
+		{"IPV6_PORTRANGE", Const, 0, ""},
+		{"IPV6_PORTRANGE_DEFAULT", Const, 0, ""},
+		{"IPV6_PORTRANGE_HIGH", Const, 0, ""},
+		{"IPV6_PORTRANGE_LOW", Const, 0, ""},
+		{"IPV6_PREFER_TEMPADDR", Const, 0, ""},
+		{"IPV6_RECVDSTOPTS", Const, 0, ""},
+		{"IPV6_RECVDSTPORT", Const, 3, ""},
+		{"IPV6_RECVERR", Const, 0, ""},
+		{"IPV6_RECVHOPLIMIT", Const, 0, ""},
+		{"IPV6_RECVHOPOPTS", Const, 0, ""},
+		{"IPV6_RECVPATHMTU", Const, 0, ""},
+		{"IPV6_RECVPKTINFO", Const, 0, ""},
+		{"IPV6_RECVRTHDR", Const, 0, ""},
+		{"IPV6_RECVTCLASS", Const, 0, ""},
+		{"IPV6_ROUTER_ALERT", Const, 0, ""},
+		{"IPV6_RTABLE", Const, 1, ""},
+		{"IPV6_RTHDR", Const, 0, ""},
+		{"IPV6_RTHDRDSTOPTS", Const, 0, ""},
+		{"IPV6_RTHDR_LOOSE", Const, 0, ""},
+		{"IPV6_RTHDR_STRICT", Const, 0, ""},
+		{"IPV6_RTHDR_TYPE_0", Const, 0, ""},
+		{"IPV6_RXDSTOPTS", Const, 0, ""},
+		{"IPV6_RXHOPOPTS", Const, 0, ""},
+		{"IPV6_SOCKOPT_RESERVED1", Const, 0, ""},
+		{"IPV6_TCLASS", Const, 0, ""},
+		{"IPV6_UNICAST_HOPS", Const, 0, ""},
+		{"IPV6_USE_MIN_MTU", Const, 0, ""},
+		{"IPV6_V6ONLY", Const, 0, ""},
+		{"IPV6_VERSION", Const, 0, ""},
+		{"IPV6_VERSION_MASK", Const, 0, ""},
+		{"IPV6_XFRM_POLICY", Const, 0, ""},
+		{"IP_ADD_MEMBERSHIP", Const, 0, ""},
+		{"IP_ADD_SOURCE_MEMBERSHIP", Const, 0, ""},
+		{"IP_AUTH_LEVEL", Const, 1, ""},
+		{"IP_BINDANY", Const, 0, ""},
+		{"IP_BLOCK_SOURCE", Const, 0, ""},
+		{"IP_BOUND_IF", Const, 0, ""},
+		{"IP_DEFAULT_MULTICAST_LOOP", Const, 0, ""},
+		{"IP_DEFAULT_MULTICAST_TTL", Const, 0, ""},
+		{"IP_DF", Const, 0, ""},
+		{"IP_DIVERTFL", Const, 3, ""},
+		{"IP_DONTFRAG", Const, 0, ""},
+		{"IP_DROP_MEMBERSHIP", Const, 0, ""},
+		{"IP_DROP_SOURCE_MEMBERSHIP", Const, 0, ""},
+		{"IP_DUMMYNET3", Const, 0, ""},
+		{"IP_DUMMYNET_CONFIGURE", Const, 0, ""},
+		{"IP_DUMMYNET_DEL", Const, 0, ""},
+		{"IP_DUMMYNET_FLUSH", Const, 0, ""},
+		{"IP_DUMMYNET_GET", Const, 0, ""},
+		{"IP_EF", Const, 1, ""},
+		{"IP_ERRORMTU", Const, 1, ""},
+		{"IP_ESP_NETWORK_LEVEL", Const, 1, ""},
+		{"IP_ESP_TRANS_LEVEL", Const, 1, ""},
+		{"IP_FAITH", Const, 0, ""},
+		{"IP_FREEBIND", Const, 0, ""},
+		{"IP_FW3", Const, 0, ""},
+		{"IP_FW_ADD", Const, 0, ""},
+		{"IP_FW_DEL", Const, 0, ""},
+		{"IP_FW_FLUSH", Const, 0, ""},
+		{"IP_FW_GET", Const, 0, ""},
+		{"IP_FW_NAT_CFG", Const, 0, ""},
+		{"IP_FW_NAT_DEL", Const, 0, ""},
+		{"IP_FW_NAT_GET_CONFIG", Const, 0, ""},
+		{"IP_FW_NAT_GET_LOG", Const, 0, ""},
+		{"IP_FW_RESETLOG", Const, 0, ""},
+		{"IP_FW_TABLE_ADD", Const, 0, ""},
+		{"IP_FW_TABLE_DEL", Const, 0, ""},
+		{"IP_FW_TABLE_FLUSH", Const, 0, ""},
+		{"IP_FW_TABLE_GETSIZE", Const, 0, ""},
+		{"IP_FW_TABLE_LIST", Const, 0, ""},
+		{"IP_FW_ZERO", Const, 0, ""},
+		{"IP_HDRINCL", Const, 0, ""},
+		{"IP_IPCOMP_LEVEL", Const, 1, ""},
+		{"IP_IPSECFLOWINFO", Const, 1, ""},
+		{"IP_IPSEC_LOCAL_AUTH", Const, 1, ""},
+		{"IP_IPSEC_LOCAL_CRED", Const, 1, ""},
+		{"IP_IPSEC_LOCAL_ID", Const, 1, ""},
+		{"IP_IPSEC_POLICY", Const, 0, ""},
+		{"IP_IPSEC_REMOTE_AUTH", Const, 1, ""},
+		{"IP_IPSEC_REMOTE_CRED", Const, 1, ""},
+		{"IP_IPSEC_REMOTE_ID", Const, 1, ""},
+		{"IP_MAXPACKET", Const, 0, ""},
+		{"IP_MAX_GROUP_SRC_FILTER", Const, 0, ""},
+		{"IP_MAX_MEMBERSHIPS", Const, 0, ""},
+		{"IP_MAX_SOCK_MUTE_FILTER", Const, 0, ""},
+		{"IP_MAX_SOCK_SRC_FILTER", Const, 0, ""},
+		{"IP_MAX_SOURCE_FILTER", Const, 0, ""},
+		{"IP_MF", Const, 0, ""},
+		{"IP_MINFRAGSIZE", Const, 1, ""},
+		{"IP_MINTTL", Const, 0, ""},
+		{"IP_MIN_MEMBERSHIPS", Const, 0, ""},
+		{"IP_MSFILTER", Const, 0, ""},
+		{"IP_MSS", Const, 0, ""},
+		{"IP_MTU", Const, 0, ""},
+		{"IP_MTU_DISCOVER", Const, 0, ""},
+		{"IP_MULTICAST_IF", Const, 0, ""},
+		{"IP_MULTICAST_IFINDEX", Const, 0, ""},
+		{"IP_MULTICAST_LOOP", Const, 0, ""},
+		{"IP_MULTICAST_TTL", Const, 0, ""},
+		{"IP_MULTICAST_VIF", Const, 0, ""},
+		{"IP_NAT__XXX", Const, 0, ""},
+		{"IP_OFFMASK", Const, 0, ""},
+		{"IP_OLD_FW_ADD", Const, 0, ""},
+		{"IP_OLD_FW_DEL", Const, 0, ""},
+		{"IP_OLD_FW_FLUSH", Const, 0, ""},
+		{"IP_OLD_FW_GET", Const, 0, ""},
+		{"IP_OLD_FW_RESETLOG", Const, 0, ""},
+		{"IP_OLD_FW_ZERO", Const, 0, ""},
+		{"IP_ONESBCAST", Const, 0, ""},
+		{"IP_OPTIONS", Const, 0, ""},
+		{"IP_ORIGDSTADDR", Const, 0, ""},
+		{"IP_PASSSEC", Const, 0, ""},
+		{"IP_PIPEX", Const, 1, ""},
+		{"IP_PKTINFO", Const, 0, ""},
+		{"IP_PKTOPTIONS", Const, 0, ""},
+		{"IP_PMTUDISC", Const, 0, ""},
+		{"IP_PMTUDISC_DO", Const, 0, ""},
+		{"IP_PMTUDISC_DONT", Const, 0, ""},
+		{"IP_PMTUDISC_PROBE", Const, 0, ""},
+		{"IP_PMTUDISC_WANT", Const, 0, ""},
+		{"IP_PORTRANGE", Const, 0, ""},
+		{"IP_PORTRANGE_DEFAULT", Const, 0, ""},
+		{"IP_PORTRANGE_HIGH", Const, 0, ""},
+		{"IP_PORTRANGE_LOW", Const, 0, ""},
+		{"IP_RECVDSTADDR", Const, 0, ""},
+		{"IP_RECVDSTPORT", Const, 1, ""},
+		{"IP_RECVERR", Const, 0, ""},
+		{"IP_RECVIF", Const, 0, ""},
+		{"IP_RECVOPTS", Const, 0, ""},
+		{"IP_RECVORIGDSTADDR", Const, 0, ""},
+		{"IP_RECVPKTINFO", Const, 0, ""},
+		{"IP_RECVRETOPTS", Const, 0, ""},
+		{"IP_RECVRTABLE", Const, 1, ""},
+		{"IP_RECVTOS", Const, 0, ""},
+		{"IP_RECVTTL", Const, 0, ""},
+		{"IP_RETOPTS", Const, 0, ""},
+		{"IP_RF", Const, 0, ""},
+		{"IP_ROUTER_ALERT", Const, 0, ""},
+		{"IP_RSVP_OFF", Const, 0, ""},
+		{"IP_RSVP_ON", Const, 0, ""},
+		{"IP_RSVP_VIF_OFF", Const, 0, ""},
+		{"IP_RSVP_VIF_ON", Const, 0, ""},
+		{"IP_RTABLE", Const, 1, ""},
+		{"IP_SENDSRCADDR", Const, 0, ""},
+		{"IP_STRIPHDR", Const, 0, ""},
+		{"IP_TOS", Const, 0, ""},
+		{"IP_TRAFFIC_MGT_BACKGROUND", Const, 0, ""},
+		{"IP_TRANSPARENT", Const, 0, ""},
+		{"IP_TTL", Const, 0, ""},
+		{"IP_UNBLOCK_SOURCE", Const, 0, ""},
+		{"IP_XFRM_POLICY", Const, 0, ""},
+		{"IPv6MTUInfo", Type, 2, ""},
+		{"IPv6MTUInfo.Addr", Field, 2, ""},
+		{"IPv6MTUInfo.Mtu", Field, 2, ""},
+		{"IPv6Mreq", Type, 0, ""},
+		{"IPv6Mreq.Interface", Field, 0, ""},
+		{"IPv6Mreq.Multiaddr", Field, 0, ""},
+		{"ISIG", Const, 0, ""},
+		{"ISTRIP", Const, 0, ""},
+		{"IUCLC", Const, 0, ""},
+		{"IUTF8", Const, 0, ""},
+		{"IXANY", Const, 0, ""},
+		{"IXOFF", Const, 0, ""},
+		{"IXON", Const, 0, ""},
+		{"IfAddrmsg", Type, 0, ""},
+		{"IfAddrmsg.Family", Field, 0, ""},
+		{"IfAddrmsg.Flags", Field, 0, ""},
+		{"IfAddrmsg.Index", Field, 0, ""},
+		{"IfAddrmsg.Prefixlen", Field, 0, ""},
+		{"IfAddrmsg.Scope", Field, 0, ""},
+		{"IfAnnounceMsghdr", Type, 1, ""},
+		{"IfAnnounceMsghdr.Hdrlen", Field, 2, ""},
+		{"IfAnnounceMsghdr.Index", Field, 1, ""},
+		{"IfAnnounceMsghdr.Msglen", Field, 1, ""},
+		{"IfAnnounceMsghdr.Name", Field, 1, ""},
+		{"IfAnnounceMsghdr.Type", Field, 1, ""},
+		{"IfAnnounceMsghdr.Version", Field, 1, ""},
+		{"IfAnnounceMsghdr.What", Field, 1, ""},
+		{"IfData", Type, 0, ""},
+		{"IfData.Addrlen", Field, 0, ""},
+		{"IfData.Baudrate", Field, 0, ""},
+		{"IfData.Capabilities", Field, 2, ""},
+		{"IfData.Collisions", Field, 0, ""},
+		{"IfData.Datalen", Field, 0, ""},
+		{"IfData.Epoch", Field, 0, ""},
+		{"IfData.Hdrlen", Field, 0, ""},
+		{"IfData.Hwassist", Field, 0, ""},
+		{"IfData.Ibytes", Field, 0, ""},
+		{"IfData.Ierrors", Field, 0, ""},
+		{"IfData.Imcasts", Field, 0, ""},
+		{"IfData.Ipackets", Field, 0, ""},
+		{"IfData.Iqdrops", Field, 0, ""},
+		{"IfData.Lastchange", Field, 0, ""},
+		{"IfData.Link_state", Field, 0, ""},
+		{"IfData.Mclpool", Field, 2, ""},
+		{"IfData.Metric", Field, 0, ""},
+		{"IfData.Mtu", Field, 0, ""},
+		{"IfData.Noproto", Field, 0, ""},
+		{"IfData.Obytes", Field, 0, ""},
+		{"IfData.Oerrors", Field, 0, ""},
+		{"IfData.Omcasts", Field, 0, ""},
+		{"IfData.Opackets", Field, 0, ""},
+		{"IfData.Pad", Field, 2, ""},
+		{"IfData.Pad_cgo_0", Field, 2, ""},
+		{"IfData.Pad_cgo_1", Field, 2, ""},
+		{"IfData.Physical", Field, 0, ""},
+		{"IfData.Recvquota", Field, 0, ""},
+		{"IfData.Recvtiming", Field, 0, ""},
+		{"IfData.Reserved1", Field, 0, ""},
+		{"IfData.Reserved2", Field, 0, ""},
+		{"IfData.Spare_char1", Field, 0, ""},
+		{"IfData.Spare_char2", Field, 0, ""},
+		{"IfData.Type", Field, 0, ""},
+		{"IfData.Typelen", Field, 0, ""},
+		{"IfData.Unused1", Field, 0, ""},
+		{"IfData.Unused2", Field, 0, ""},
+		{"IfData.Xmitquota", Field, 0, ""},
+		{"IfData.Xmittiming", Field, 0, ""},
+		{"IfInfomsg", Type, 0, ""},
+		{"IfInfomsg.Change", Field, 0, ""},
+		{"IfInfomsg.Family", Field, 0, ""},
+		{"IfInfomsg.Flags", Field, 0, ""},
+		{"IfInfomsg.Index", Field, 0, ""},
+		{"IfInfomsg.Type", Field, 0, ""},
+		{"IfInfomsg.X__ifi_pad", Field, 0, ""},
+		{"IfMsghdr", Type, 0, ""},
+		{"IfMsghdr.Addrs", Field, 0, ""},
+		{"IfMsghdr.Data", Field, 0, ""},
+		{"IfMsghdr.Flags", Field, 0, ""},
+		{"IfMsghdr.Hdrlen", Field, 2, ""},
+		{"IfMsghdr.Index", Field, 0, ""},
+		{"IfMsghdr.Msglen", Field, 0, ""},
+		{"IfMsghdr.Pad1", Field, 2, ""},
+		{"IfMsghdr.Pad2", Field, 2, ""},
+		{"IfMsghdr.Pad_cgo_0", Field, 0, ""},
+		{"IfMsghdr.Pad_cgo_1", Field, 2, ""},
+		{"IfMsghdr.Tableid", Field, 2, ""},
+		{"IfMsghdr.Type", Field, 0, ""},
+		{"IfMsghdr.Version", Field, 0, ""},
+		{"IfMsghdr.Xflags", Field, 2, ""},
+		{"IfaMsghdr", Type, 0, ""},
+		{"IfaMsghdr.Addrs", Field, 0, ""},
+		{"IfaMsghdr.Flags", Field, 0, ""},
+		{"IfaMsghdr.Hdrlen", Field, 2, ""},
+		{"IfaMsghdr.Index", Field, 0, ""},
+		{"IfaMsghdr.Metric", Field, 0, ""},
+		{"IfaMsghdr.Msglen", Field, 0, ""},
+		{"IfaMsghdr.Pad1", Field, 2, ""},
+		{"IfaMsghdr.Pad2", Field, 2, ""},
+		{"IfaMsghdr.Pad_cgo_0", Field, 0, ""},
+		{"IfaMsghdr.Tableid", Field, 2, ""},
+		{"IfaMsghdr.Type", Field, 0, ""},
+		{"IfaMsghdr.Version", Field, 0, ""},
+		{"IfmaMsghdr", Type, 0, ""},
+		{"IfmaMsghdr.Addrs", Field, 0, ""},
+		{"IfmaMsghdr.Flags", Field, 0, ""},
+		{"IfmaMsghdr.Index", Field, 0, ""},
+		{"IfmaMsghdr.Msglen", Field, 0, ""},
+		{"IfmaMsghdr.Pad_cgo_0", Field, 0, ""},
+		{"IfmaMsghdr.Type", Field, 0, ""},
+		{"IfmaMsghdr.Version", Field, 0, ""},
+		{"IfmaMsghdr2", Type, 0, ""},
+		{"IfmaMsghdr2.Addrs", Field, 0, ""},
+		{"IfmaMsghdr2.Flags", Field, 0, ""},
+		{"IfmaMsghdr2.Index", Field, 0, ""},
+		{"IfmaMsghdr2.Msglen", Field, 0, ""},
+		{"IfmaMsghdr2.Pad_cgo_0", Field, 0, ""},
+		{"IfmaMsghdr2.Refcount", Field, 0, ""},
+		{"IfmaMsghdr2.Type", Field, 0, ""},
+		{"IfmaMsghdr2.Version", Field, 0, ""},
+		{"ImplementsGetwd", Const, 0, ""},
+		{"Inet4Pktinfo", Type, 0, ""},
+		{"Inet4Pktinfo.Addr", Field, 0, ""},
+		{"Inet4Pktinfo.Ifindex", Field, 0, ""},
+		{"Inet4Pktinfo.Spec_dst", Field, 0, ""},
+		{"Inet6Pktinfo", Type, 0, ""},
+		{"Inet6Pktinfo.Addr", Field, 0, ""},
+		{"Inet6Pktinfo.Ifindex", Field, 0, ""},
+		{"InotifyAddWatch", Func, 0, "func(fd int, pathname string, mask uint32) (watchdesc int, err error)"},
+		{"InotifyEvent", Type, 0, ""},
+		{"InotifyEvent.Cookie", Field, 0, ""},
+		{"InotifyEvent.Len", Field, 0, ""},
+		{"InotifyEvent.Mask", Field, 0, ""},
+		{"InotifyEvent.Name", Field, 0, ""},
+		{"InotifyEvent.Wd", Field, 0, ""},
+		{"InotifyInit", Func, 0, "func() (fd int, err error)"},
+		{"InotifyInit1", Func, 0, "func(flags int) (fd int, err error)"},
+		{"InotifyRmWatch", Func, 0, "func(fd int, watchdesc uint32) (success int, err error)"},
+		{"InterfaceAddrMessage", Type, 0, ""},
+		{"InterfaceAddrMessage.Data", Field, 0, ""},
+		{"InterfaceAddrMessage.Header", Field, 0, ""},
+		{"InterfaceAnnounceMessage", Type, 1, ""},
+		{"InterfaceAnnounceMessage.Header", Field, 1, ""},
+		{"InterfaceInfo", Type, 0, ""},
+		{"InterfaceInfo.Address", Field, 0, ""},
+		{"InterfaceInfo.BroadcastAddress", Field, 0, ""},
+		{"InterfaceInfo.Flags", Field, 0, ""},
+		{"InterfaceInfo.Netmask", Field, 0, ""},
+		{"InterfaceMessage", Type, 0, ""},
+		{"InterfaceMessage.Data", Field, 0, ""},
+		{"InterfaceMessage.Header", Field, 0, ""},
+		{"InterfaceMulticastAddrMessage", Type, 0, ""},
+		{"InterfaceMulticastAddrMessage.Data", Field, 0, ""},
+		{"InterfaceMulticastAddrMessage.Header", Field, 0, ""},
+		{"InvalidHandle", Const, 0, ""},
+		{"Ioperm", Func, 0, "func(from int, num int, on int) (err error)"},
+		{"Iopl", Func, 0, "func(level int) (err error)"},
+		{"Iovec", Type, 0, ""},
+		{"Iovec.Base", Field, 0, ""},
+		{"Iovec.Len", Field, 0, ""},
+		{"IpAdapterInfo", Type, 0, ""},
+		{"IpAdapterInfo.AdapterName", Field, 0, ""},
+		{"IpAdapterInfo.Address", Field, 0, ""},
+		{"IpAdapterInfo.AddressLength", Field, 0, ""},
+		{"IpAdapterInfo.ComboIndex", Field, 0, ""},
+		{"IpAdapterInfo.CurrentIpAddress", Field, 0, ""},
+		{"IpAdapterInfo.Description", Field, 0, ""},
+		{"IpAdapterInfo.DhcpEnabled", Field, 0, ""},
+		{"IpAdapterInfo.DhcpServer", Field, 0, ""},
+		{"IpAdapterInfo.GatewayList", Field, 0, ""},
+		{"IpAdapterInfo.HaveWins", Field, 0, ""},
+		{"IpAdapterInfo.Index", Field, 0, ""},
+		{"IpAdapterInfo.IpAddressList", Field, 0, ""},
+		{"IpAdapterInfo.LeaseExpires", Field, 0, ""},
+		{"IpAdapterInfo.LeaseObtained", Field, 0, ""},
+		{"IpAdapterInfo.Next", Field, 0, ""},
+		{"IpAdapterInfo.PrimaryWinsServer", Field, 0, ""},
+		{"IpAdapterInfo.SecondaryWinsServer", Field, 0, ""},
+		{"IpAdapterInfo.Type", Field, 0, ""},
+		{"IpAddrString", Type, 0, ""},
+		{"IpAddrString.Context", Field, 0, ""},
+		{"IpAddrString.IpAddress", Field, 0, ""},
+		{"IpAddrString.IpMask", Field, 0, ""},
+		{"IpAddrString.Next", Field, 0, ""},
+		{"IpAddressString", Type, 0, ""},
+		{"IpAddressString.String", Field, 0, ""},
+		{"IpMaskString", Type, 0, ""},
+		{"IpMaskString.String", Field, 2, ""},
+		{"Issetugid", Func, 0, ""},
+		{"KEY_ALL_ACCESS", Const, 0, ""},
+		{"KEY_CREATE_LINK", Const, 0, ""},
+		{"KEY_CREATE_SUB_KEY", Const, 0, ""},
+		{"KEY_ENUMERATE_SUB_KEYS", Const, 0, ""},
+		{"KEY_EXECUTE", Const, 0, ""},
+		{"KEY_NOTIFY", Const, 0, ""},
+		{"KEY_QUERY_VALUE", Const, 0, ""},
+		{"KEY_READ", Const, 0, ""},
+		{"KEY_SET_VALUE", Const, 0, ""},
+		{"KEY_WOW64_32KEY", Const, 0, ""},
+		{"KEY_WOW64_64KEY", Const, 0, ""},
+		{"KEY_WRITE", Const, 0, ""},
+		{"Kevent", Func, 0, ""},
+		{"Kevent_t", Type, 0, ""},
+		{"Kevent_t.Data", Field, 0, ""},
+		{"Kevent_t.Fflags", Field, 0, ""},
+		{"Kevent_t.Filter", Field, 0, ""},
+		{"Kevent_t.Flags", Field, 0, ""},
+		{"Kevent_t.Ident", Field, 0, ""},
+		{"Kevent_t.Pad_cgo_0", Field, 2, ""},
+		{"Kevent_t.Udata", Field, 0, ""},
+		{"Kill", Func, 0, "func(pid int, sig Signal) (err error)"},
+		{"Klogctl", Func, 0, "func(typ int, buf []byte) (n int, err error)"},
+		{"Kqueue", Func, 0, ""},
+		{"LANG_ENGLISH", Const, 0, ""},
+		{"LAYERED_PROTOCOL", Const, 2, ""},
+		{"LCNT_OVERLOAD_FLUSH", Const, 1, ""},
+		{"LINUX_REBOOT_CMD_CAD_OFF", Const, 0, ""},
+		{"LINUX_REBOOT_CMD_CAD_ON", Const, 0, ""},
+		{"LINUX_REBOOT_CMD_HALT", Const, 0, ""},
+		{"LINUX_REBOOT_CMD_KEXEC", Const, 0, ""},
+		{"LINUX_REBOOT_CMD_POWER_OFF", Const, 0, ""},
+		{"LINUX_REBOOT_CMD_RESTART", Const, 0, ""},
+		{"LINUX_REBOOT_CMD_RESTART2", Const, 0, ""},
+		{"LINUX_REBOOT_CMD_SW_SUSPEND", Const, 0, ""},
+		{"LINUX_REBOOT_MAGIC1", Const, 0, ""},
+		{"LINUX_REBOOT_MAGIC2", Const, 0, ""},
+		{"LOCK_EX", Const, 0, ""},
+		{"LOCK_NB", Const, 0, ""},
+		{"LOCK_SH", Const, 0, ""},
+		{"LOCK_UN", Const, 0, ""},
+		{"LazyDLL", Type, 0, ""},
+		{"LazyDLL.Name", Field, 0, ""},
+		{"LazyProc", Type, 0, ""},
+		{"LazyProc.Name", Field, 0, ""},
+		{"Lchown", Func, 0, "func(path string, uid int, gid int) (err error)"},
+		{"Linger", Type, 0, ""},
+		{"Linger.Linger", Field, 0, ""},
+		{"Linger.Onoff", Field, 0, ""},
+		{"Link", Func, 0, "func(oldpath string, newpath string) (err error)"},
+		{"Listen", Func, 0, "func(s int, n int) (err error)"},
+		{"Listxattr", Func, 1, "func(path string, dest []byte) (sz int, err error)"},
+		{"LoadCancelIoEx", Func, 1, ""},
+		{"LoadConnectEx", Func, 1, ""},
+		{"LoadCreateSymbolicLink", Func, 4, ""},
+		{"LoadDLL", Func, 0, ""},
+		{"LoadGetAddrInfo", Func, 1, ""},
+		{"LoadLibrary", Func, 0, ""},
+		{"LoadSetFileCompletionNotificationModes", Func, 2, ""},
+		{"LocalFree", Func, 0, ""},
+		{"Log2phys_t", Type, 0, ""},
+		{"Log2phys_t.Contigbytes", Field, 0, ""},
+		{"Log2phys_t.Devoffset", Field, 0, ""},
+		{"Log2phys_t.Flags", Field, 0, ""},
+		{"LookupAccountName", Func, 0, ""},
+		{"LookupAccountSid", Func, 0, ""},
+		{"LookupSID", Func, 0, ""},
+		{"LsfJump", Func, 0, "func(code int, k int, jt int, jf int) *SockFilter"},
+		{"LsfSocket", Func, 0, "func(ifindex int, proto int) (int, error)"},
+		{"LsfStmt", Func, 0, "func(code int, k int) *SockFilter"},
+		{"Lstat", Func, 0, "func(path string, stat *Stat_t) (err error)"},
+		{"MADV_AUTOSYNC", Const, 1, ""},
+		{"MADV_CAN_REUSE", Const, 0, ""},
+		{"MADV_CORE", Const, 1, ""},
+		{"MADV_DOFORK", Const, 0, ""},
+		{"MADV_DONTFORK", Const, 0, ""},
+		{"MADV_DONTNEED", Const, 0, ""},
+		{"MADV_FREE", Const, 0, ""},
+		{"MADV_FREE_REUSABLE", Const, 0, ""},
+		{"MADV_FREE_REUSE", Const, 0, ""},
+		{"MADV_HUGEPAGE", Const, 0, ""},
+		{"MADV_HWPOISON", Const, 0, ""},
+		{"MADV_MERGEABLE", Const, 0, ""},
+		{"MADV_NOCORE", Const, 1, ""},
+		{"MADV_NOHUGEPAGE", Const, 0, ""},
+		{"MADV_NORMAL", Const, 0, ""},
+		{"MADV_NOSYNC", Const, 1, ""},
+		{"MADV_PROTECT", Const, 1, ""},
+		{"MADV_RANDOM", Const, 0, ""},
+		{"MADV_REMOVE", Const, 0, ""},
+		{"MADV_SEQUENTIAL", Const, 0, ""},
+		{"MADV_SPACEAVAIL", Const, 3, ""},
+		{"MADV_UNMERGEABLE", Const, 0, ""},
+		{"MADV_WILLNEED", Const, 0, ""},
+		{"MADV_ZERO_WIRED_PAGES", Const, 0, ""},
+		{"MAP_32BIT", Const, 0, ""},
+		{"MAP_ALIGNED_SUPER", Const, 3, ""},
+		{"MAP_ALIGNMENT_16MB", Const, 3, ""},
+		{"MAP_ALIGNMENT_1TB", Const, 3, ""},
+		{"MAP_ALIGNMENT_256TB", Const, 3, ""},
+		{"MAP_ALIGNMENT_4GB", Const, 3, ""},
+		{"MAP_ALIGNMENT_64KB", Const, 3, ""},
+		{"MAP_ALIGNMENT_64PB", Const, 3, ""},
+		{"MAP_ALIGNMENT_MASK", Const, 3, ""},
+		{"MAP_ALIGNMENT_SHIFT", Const, 3, ""},
+		{"MAP_ANON", Const, 0, ""},
+		{"MAP_ANONYMOUS", Const, 0, ""},
+		{"MAP_COPY", Const, 0, ""},
+		{"MAP_DENYWRITE", Const, 0, ""},
+		{"MAP_EXECUTABLE", Const, 0, ""},
+		{"MAP_FILE", Const, 0, ""},
+		{"MAP_FIXED", Const, 0, ""},
+		{"MAP_FLAGMASK", Const, 3, ""},
+		{"MAP_GROWSDOWN", Const, 0, ""},
+		{"MAP_HASSEMAPHORE", Const, 0, ""},
+		{"MAP_HUGETLB", Const, 0, ""},
+		{"MAP_INHERIT", Const, 3, ""},
+		{"MAP_INHERIT_COPY", Const, 3, ""},
+		{"MAP_INHERIT_DEFAULT", Const, 3, ""},
+		{"MAP_INHERIT_DONATE_COPY", Const, 3, ""},
+		{"MAP_INHERIT_NONE", Const, 3, ""},
+		{"MAP_INHERIT_SHARE", Const, 3, ""},
+		{"MAP_JIT", Const, 0, ""},
+		{"MAP_LOCKED", Const, 0, ""},
+		{"MAP_NOCACHE", Const, 0, ""},
+		{"MAP_NOCORE", Const, 1, ""},
+		{"MAP_NOEXTEND", Const, 0, ""},
+		{"MAP_NONBLOCK", Const, 0, ""},
+		{"MAP_NORESERVE", Const, 0, ""},
+		{"MAP_NOSYNC", Const, 1, ""},
+		{"MAP_POPULATE", Const, 0, ""},
+		{"MAP_PREFAULT_READ", Const, 1, ""},
+		{"MAP_PRIVATE", Const, 0, ""},
+		{"MAP_RENAME", Const, 0, ""},
+		{"MAP_RESERVED0080", Const, 0, ""},
+		{"MAP_RESERVED0100", Const, 1, ""},
+		{"MAP_SHARED", Const, 0, ""},
+		{"MAP_STACK", Const, 0, ""},
+		{"MAP_TRYFIXED", Const, 3, ""},
+		{"MAP_TYPE", Const, 0, ""},
+		{"MAP_WIRED", Const, 3, ""},
+		{"MAXIMUM_REPARSE_DATA_BUFFER_SIZE", Const, 4, ""},
+		{"MAXLEN_IFDESCR", Const, 0, ""},
+		{"MAXLEN_PHYSADDR", Const, 0, ""},
+		{"MAX_ADAPTER_ADDRESS_LENGTH", Const, 0, ""},
+		{"MAX_ADAPTER_DESCRIPTION_LENGTH", Const, 0, ""},
+		{"MAX_ADAPTER_NAME_LENGTH", Const, 0, ""},
+		{"MAX_COMPUTERNAME_LENGTH", Const, 0, ""},
+		{"MAX_INTERFACE_NAME_LEN", Const, 0, ""},
+		{"MAX_LONG_PATH", Const, 0, ""},
+		{"MAX_PATH", Const, 0, ""},
+		{"MAX_PROTOCOL_CHAIN", Const, 2, ""},
+		{"MCL_CURRENT", Const, 0, ""},
+		{"MCL_FUTURE", Const, 0, ""},
+		{"MNT_DETACH", Const, 0, ""},
+		{"MNT_EXPIRE", Const, 0, ""},
+		{"MNT_FORCE", Const, 0, ""},
+		{"MSG_BCAST", Const, 1, ""},
+		{"MSG_CMSG_CLOEXEC", Const, 0, ""},
+		{"MSG_COMPAT", Const, 0, ""},
+		{"MSG_CONFIRM", Const, 0, ""},
+		{"MSG_CONTROLMBUF", Const, 1, ""},
+		{"MSG_CTRUNC", Const, 0, ""},
+		{"MSG_DONTROUTE", Const, 0, ""},
+		{"MSG_DONTWAIT", Const, 0, ""},
+		{"MSG_EOF", Const, 0, ""},
+		{"MSG_EOR", Const, 0, ""},
+		{"MSG_ERRQUEUE", Const, 0, ""},
+		{"MSG_FASTOPEN", Const, 1, ""},
+		{"MSG_FIN", Const, 0, ""},
+		{"MSG_FLUSH", Const, 0, ""},
+		{"MSG_HAVEMORE", Const, 0, ""},
+		{"MSG_HOLD", Const, 0, ""},
+		{"MSG_IOVUSRSPACE", Const, 1, ""},
+		{"MSG_LENUSRSPACE", Const, 1, ""},
+		{"MSG_MCAST", Const, 1, ""},
+		{"MSG_MORE", Const, 0, ""},
+		{"MSG_NAMEMBUF", Const, 1, ""},
+		{"MSG_NBIO", Const, 0, ""},
+		{"MSG_NEEDSA", Const, 0, ""},
+		{"MSG_NOSIGNAL", Const, 0, ""},
+		{"MSG_NOTIFICATION", Const, 0, ""},
+		{"MSG_OOB", Const, 0, ""},
+		{"MSG_PEEK", Const, 0, ""},
+		{"MSG_PROXY", Const, 0, ""},
+		{"MSG_RCVMORE", Const, 0, ""},
+		{"MSG_RST", Const, 0, ""},
+		{"MSG_SEND", Const, 0, ""},
+		{"MSG_SYN", Const, 0, ""},
+		{"MSG_TRUNC", Const, 0, ""},
+		{"MSG_TRYHARD", Const, 0, ""},
+		{"MSG_USERFLAGS", Const, 1, ""},
+		{"MSG_WAITALL", Const, 0, ""},
+		{"MSG_WAITFORONE", Const, 0, ""},
+		{"MSG_WAITSTREAM", Const, 0, ""},
+		{"MS_ACTIVE", Const, 0, ""},
+		{"MS_ASYNC", Const, 0, ""},
+		{"MS_BIND", Const, 0, ""},
+		{"MS_DEACTIVATE", Const, 0, ""},
+		{"MS_DIRSYNC", Const, 0, ""},
+		{"MS_INVALIDATE", Const, 0, ""},
+		{"MS_I_VERSION", Const, 0, ""},
+		{"MS_KERNMOUNT", Const, 0, ""},
+		{"MS_KILLPAGES", Const, 0, ""},
+		{"MS_MANDLOCK", Const, 0, ""},
+		{"MS_MGC_MSK", Const, 0, ""},
+		{"MS_MGC_VAL", Const, 0, ""},
+		{"MS_MOVE", Const, 0, ""},
+		{"MS_NOATIME", Const, 0, ""},
+		{"MS_NODEV", Const, 0, ""},
+		{"MS_NODIRATIME", Const, 0, ""},
+		{"MS_NOEXEC", Const, 0, ""},
+		{"MS_NOSUID", Const, 0, ""},
+		{"MS_NOUSER", Const, 0, ""},
+		{"MS_POSIXACL", Const, 0, ""},
+		{"MS_PRIVATE", Const, 0, ""},
+		{"MS_RDONLY", Const, 0, ""},
+		{"MS_REC", Const, 0, ""},
+		{"MS_RELATIME", Const, 0, ""},
+		{"MS_REMOUNT", Const, 0, ""},
+		{"MS_RMT_MASK", Const, 0, ""},
+		{"MS_SHARED", Const, 0, ""},
+		{"MS_SILENT", Const, 0, ""},
+		{"MS_SLAVE", Const, 0, ""},
+		{"MS_STRICTATIME", Const, 0, ""},
+		{"MS_SYNC", Const, 0, ""},
+		{"MS_SYNCHRONOUS", Const, 0, ""},
+		{"MS_UNBINDABLE", Const, 0, ""},
+		{"Madvise", Func, 0, "func(b []byte, advice int) (err error)"},
+		{"MapViewOfFile", Func, 0, ""},
+		{"MaxTokenInfoClass", Const, 0, ""},
+		{"Mclpool", Type, 2, ""},
+		{"Mclpool.Alive", Field, 2, ""},
+		{"Mclpool.Cwm", Field, 2, ""},
+		{"Mclpool.Grown", Field, 2, ""},
+		{"Mclpool.Hwm", Field, 2, ""},
+		{"Mclpool.Lwm", Field, 2, ""},
+		{"MibIfRow", Type, 0, ""},
+		{"MibIfRow.AdminStatus", Field, 0, ""},
+		{"MibIfRow.Descr", Field, 0, ""},
+		{"MibIfRow.DescrLen", Field, 0, ""},
+		{"MibIfRow.InDiscards", Field, 0, ""},
+		{"MibIfRow.InErrors", Field, 0, ""},
+		{"MibIfRow.InNUcastPkts", Field, 0, ""},
+		{"MibIfRow.InOctets", Field, 0, ""},
+		{"MibIfRow.InUcastPkts", Field, 0, ""},
+		{"MibIfRow.InUnknownProtos", Field, 0, ""},
+		{"MibIfRow.Index", Field, 0, ""},
+		{"MibIfRow.LastChange", Field, 0, ""},
+		{"MibIfRow.Mtu", Field, 0, ""},
+		{"MibIfRow.Name", Field, 0, ""},
+		{"MibIfRow.OperStatus", Field, 0, ""},
+		{"MibIfRow.OutDiscards", Field, 0, ""},
+		{"MibIfRow.OutErrors", Field, 0, ""},
+		{"MibIfRow.OutNUcastPkts", Field, 0, ""},
+		{"MibIfRow.OutOctets", Field, 0, ""},
+		{"MibIfRow.OutQLen", Field, 0, ""},
+		{"MibIfRow.OutUcastPkts", Field, 0, ""},
+		{"MibIfRow.PhysAddr", Field, 0, ""},
+		{"MibIfRow.PhysAddrLen", Field, 0, ""},
+		{"MibIfRow.Speed", Field, 0, ""},
+		{"MibIfRow.Type", Field, 0, ""},
+		{"Mkdir", Func, 0, "func(path string, mode uint32) (err error)"},
+		{"Mkdirat", Func, 0, "func(dirfd int, path string, mode uint32) (err error)"},
+		{"Mkfifo", Func, 0, "func(path string, mode uint32) (err error)"},
+		{"Mknod", Func, 0, "func(path string, mode uint32, dev int) (err error)"},
+		{"Mknodat", Func, 0, "func(dirfd int, path string, mode uint32, dev int) (err error)"},
+		{"Mlock", Func, 0, "func(b []byte) (err error)"},
+		{"Mlockall", Func, 0, "func(flags int) (err error)"},
+		{"Mmap", Func, 0, "func(fd int, offset int64, length int, prot int, flags int) (data []byte, err error)"},
+		{"Mount", Func, 0, "func(source string, target string, fstype string, flags uintptr, data string) (err error)"},
+		{"MoveFile", Func, 0, ""},
+		{"Mprotect", Func, 0, "func(b []byte, prot int) (err error)"},
+		{"Msghdr", Type, 0, ""},
+		{"Msghdr.Control", Field, 0, ""},
+		{"Msghdr.Controllen", Field, 0, ""},
+		{"Msghdr.Flags", Field, 0, ""},
+		{"Msghdr.Iov", Field, 0, ""},
+		{"Msghdr.Iovlen", Field, 0, ""},
+		{"Msghdr.Name", Field, 0, ""},
+		{"Msghdr.Namelen", Field, 0, ""},
+		{"Msghdr.Pad_cgo_0", Field, 0, ""},
+		{"Msghdr.Pad_cgo_1", Field, 0, ""},
+		{"Munlock", Func, 0, "func(b []byte) (err error)"},
+		{"Munlockall", Func, 0, "func() (err error)"},
+		{"Munmap", Func, 0, "func(b []byte) (err error)"},
+		{"MustLoadDLL", Func, 0, ""},
+		{"NAME_MAX", Const, 0, ""},
+		{"NETLINK_ADD_MEMBERSHIP", Const, 0, ""},
+		{"NETLINK_AUDIT", Const, 0, ""},
+		{"NETLINK_BROADCAST_ERROR", Const, 0, ""},
+		{"NETLINK_CONNECTOR", Const, 0, ""},
+		{"NETLINK_DNRTMSG", Const, 0, ""},
+		{"NETLINK_DROP_MEMBERSHIP", Const, 0, ""},
+		{"NETLINK_ECRYPTFS", Const, 0, ""},
+		{"NETLINK_FIB_LOOKUP", Const, 0, ""},
+		{"NETLINK_FIREWALL", Const, 0, ""},
+		{"NETLINK_GENERIC", Const, 0, ""},
+		{"NETLINK_INET_DIAG", Const, 0, ""},
+		{"NETLINK_IP6_FW", Const, 0, ""},
+		{"NETLINK_ISCSI", Const, 0, ""},
+		{"NETLINK_KOBJECT_UEVENT", Const, 0, ""},
+		{"NETLINK_NETFILTER", Const, 0, ""},
+		{"NETLINK_NFLOG", Const, 0, ""},
+		{"NETLINK_NO_ENOBUFS", Const, 0, ""},
+		{"NETLINK_PKTINFO", Const, 0, ""},
+		{"NETLINK_RDMA", Const, 0, ""},
+		{"NETLINK_ROUTE", Const, 0, ""},
+		{"NETLINK_SCSITRANSPORT", Const, 0, ""},
+		{"NETLINK_SELINUX", Const, 0, ""},
+		{"NETLINK_UNUSED", Const, 0, ""},
+		{"NETLINK_USERSOCK", Const, 0, ""},
+		{"NETLINK_XFRM", Const, 0, ""},
+		{"NET_RT_DUMP", Const, 0, ""},
+		{"NET_RT_DUMP2", Const, 0, ""},
+		{"NET_RT_FLAGS", Const, 0, ""},
+		{"NET_RT_IFLIST", Const, 0, ""},
+		{"NET_RT_IFLIST2", Const, 0, ""},
+		{"NET_RT_IFLISTL", Const, 1, ""},
+		{"NET_RT_IFMALIST", Const, 0, ""},
+		{"NET_RT_MAXID", Const, 0, ""},
+		{"NET_RT_OIFLIST", Const, 1, ""},
+		{"NET_RT_OOIFLIST", Const, 1, ""},
+		{"NET_RT_STAT", Const, 0, ""},
+		{"NET_RT_STATS", Const, 1, ""},
+		{"NET_RT_TABLE", Const, 1, ""},
+		{"NET_RT_TRASH", Const, 0, ""},
+		{"NLA_ALIGNTO", Const, 0, ""},
+		{"NLA_F_NESTED", Const, 0, ""},
+		{"NLA_F_NET_BYTEORDER", Const, 0, ""},
+		{"NLA_HDRLEN", Const, 0, ""},
+		{"NLMSG_ALIGNTO", Const, 0, ""},
+		{"NLMSG_DONE", Const, 0, ""},
+		{"NLMSG_ERROR", Const, 0, ""},
+		{"NLMSG_HDRLEN", Const, 0, ""},
+		{"NLMSG_MIN_TYPE", Const, 0, ""},
+		{"NLMSG_NOOP", Const, 0, ""},
+		{"NLMSG_OVERRUN", Const, 0, ""},
+		{"NLM_F_ACK", Const, 0, ""},
+		{"NLM_F_APPEND", Const, 0, ""},
+		{"NLM_F_ATOMIC", Const, 0, ""},
+		{"NLM_F_CREATE", Const, 0, ""},
+		{"NLM_F_DUMP", Const, 0, ""},
+		{"NLM_F_ECHO", Const, 0, ""},
+		{"NLM_F_EXCL", Const, 0, ""},
+		{"NLM_F_MATCH", Const, 0, ""},
+		{"NLM_F_MULTI", Const, 0, ""},
+		{"NLM_F_REPLACE", Const, 0, ""},
+		{"NLM_F_REQUEST", Const, 0, ""},
+		{"NLM_F_ROOT", Const, 0, ""},
+		{"NOFLSH", Const, 0, ""},
+		{"NOTE_ABSOLUTE", Const, 0, ""},
+		{"NOTE_ATTRIB", Const, 0, ""},
+		{"NOTE_BACKGROUND", Const, 16, ""},
+		{"NOTE_CHILD", Const, 0, ""},
+		{"NOTE_CRITICAL", Const, 16, ""},
+		{"NOTE_DELETE", Const, 0, ""},
+		{"NOTE_EOF", Const, 1, ""},
+		{"NOTE_EXEC", Const, 0, ""},
+		{"NOTE_EXIT", Const, 0, ""},
+		{"NOTE_EXITSTATUS", Const, 0, ""},
+		{"NOTE_EXIT_CSERROR", Const, 16, ""},
+		{"NOTE_EXIT_DECRYPTFAIL", Const, 16, ""},
+		{"NOTE_EXIT_DETAIL", Const, 16, ""},
+		{"NOTE_EXIT_DETAIL_MASK", Const, 16, ""},
+		{"NOTE_EXIT_MEMORY", Const, 16, ""},
+		{"NOTE_EXIT_REPARENTED", Const, 16, ""},
+		{"NOTE_EXTEND", Const, 0, ""},
+		{"NOTE_FFAND", Const, 0, ""},
+		{"NOTE_FFCOPY", Const, 0, ""},
+		{"NOTE_FFCTRLMASK", Const, 0, ""},
+		{"NOTE_FFLAGSMASK", Const, 0, ""},
+		{"NOTE_FFNOP", Const, 0, ""},
+		{"NOTE_FFOR", Const, 0, ""},
+		{"NOTE_FORK", Const, 0, ""},
+		{"NOTE_LEEWAY", Const, 16, ""},
+		{"NOTE_LINK", Const, 0, ""},
+		{"NOTE_LOWAT", Const, 0, ""},
+		{"NOTE_NONE", Const, 0, ""},
+		{"NOTE_NSECONDS", Const, 0, ""},
+		{"NOTE_PCTRLMASK", Const, 0, ""},
+		{"NOTE_PDATAMASK", Const, 0, ""},
+		{"NOTE_REAP", Const, 0, ""},
+		{"NOTE_RENAME", Const, 0, ""},
+		{"NOTE_RESOURCEEND", Const, 0, ""},
+		{"NOTE_REVOKE", Const, 0, ""},
+		{"NOTE_SECONDS", Const, 0, ""},
+		{"NOTE_SIGNAL", Const, 0, ""},
+		{"NOTE_TRACK", Const, 0, ""},
+		{"NOTE_TRACKERR", Const, 0, ""},
+		{"NOTE_TRIGGER", Const, 0, ""},
+		{"NOTE_TRUNCATE", Const, 1, ""},
+		{"NOTE_USECONDS", Const, 0, ""},
+		{"NOTE_VM_ERROR", Const, 0, ""},
+		{"NOTE_VM_PRESSURE", Const, 0, ""},
+		{"NOTE_VM_PRESSURE_SUDDEN_TERMINATE", Const, 0, ""},
+		{"NOTE_VM_PRESSURE_TERMINATE", Const, 0, ""},
+		{"NOTE_WRITE", Const, 0, ""},
+		{"NameCanonical", Const, 0, ""},
+		{"NameCanonicalEx", Const, 0, ""},
+		{"NameDisplay", Const, 0, ""},
+		{"NameDnsDomain", Const, 0, ""},
+		{"NameFullyQualifiedDN", Const, 0, ""},
+		{"NameSamCompatible", Const, 0, ""},
+		{"NameServicePrincipal", Const, 0, ""},
+		{"NameUniqueId", Const, 0, ""},
+		{"NameUnknown", Const, 0, ""},
+		{"NameUserPrincipal", Const, 0, ""},
+		{"Nanosleep", Func, 0, "func(time *Timespec, leftover *Timespec) (err error)"},
+		{"NetApiBufferFree", Func, 0, ""},
+		{"NetGetJoinInformation", Func, 2, ""},
+		{"NetSetupDomainName", Const, 2, ""},
+		{"NetSetupUnjoined", Const, 2, ""},
+		{"NetSetupUnknownStatus", Const, 2, ""},
+		{"NetSetupWorkgroupName", Const, 2, ""},
+		{"NetUserGetInfo", Func, 0, ""},
+		{"NetlinkMessage", Type, 0, ""},
+		{"NetlinkMessage.Data", Field, 0, ""},
+		{"NetlinkMessage.Header", Field, 0, ""},
+		{"NetlinkRIB", Func, 0, "func(proto int, family int) ([]byte, error)"},
+		{"NetlinkRouteAttr", Type, 0, ""},
+		{"NetlinkRouteAttr.Attr", Field, 0, ""},
+		{"NetlinkRouteAttr.Value", Field, 0, ""},
+		{"NetlinkRouteRequest", Type, 0, ""},
+		{"NetlinkRouteRequest.Data", Field, 0, ""},
+		{"NetlinkRouteRequest.Header", Field, 0, ""},
+		{"NewCallback", Func, 0, ""},
+		{"NewCallbackCDecl", Func, 3, ""},
+		{"NewLazyDLL", Func, 0, ""},
+		{"NlAttr", Type, 0, ""},
+		{"NlAttr.Len", Field, 0, ""},
+		{"NlAttr.Type", Field, 0, ""},
+		{"NlMsgerr", Type, 0, ""},
+		{"NlMsgerr.Error", Field, 0, ""},
+		{"NlMsgerr.Msg", Field, 0, ""},
+		{"NlMsghdr", Type, 0, ""},
+		{"NlMsghdr.Flags", Field, 0, ""},
+		{"NlMsghdr.Len", Field, 0, ""},
+		{"NlMsghdr.Pid", Field, 0, ""},
+		{"NlMsghdr.Seq", Field, 0, ""},
+		{"NlMsghdr.Type", Field, 0, ""},
+		{"NsecToFiletime", Func, 0, ""},
+		{"NsecToTimespec", Func, 0, "func(nsec int64) Timespec"},
+		{"NsecToTimeval", Func, 0, "func(nsec int64) Timeval"},
+		{"Ntohs", Func, 0, ""},
+		{"OCRNL", Const, 0, ""},
+		{"OFDEL", Const, 0, ""},
+		{"OFILL", Const, 0, ""},
+		{"OFIOGETBMAP", Const, 1, ""},
+		{"OID_PKIX_KP_SERVER_AUTH", Var, 0, ""},
+		{"OID_SERVER_GATED_CRYPTO", Var, 0, ""},
+		{"OID_SGC_NETSCAPE", Var, 0, ""},
+		{"OLCUC", Const, 0, ""},
+		{"ONLCR", Const, 0, ""},
+		{"ONLRET", Const, 0, ""},
+		{"ONOCR", Const, 0, ""},
+		{"ONOEOT", Const, 1, ""},
+		{"OPEN_ALWAYS", Const, 0, ""},
+		{"OPEN_EXISTING", Const, 0, ""},
+		{"OPOST", Const, 0, ""},
+		{"O_ACCMODE", Const, 0, ""},
+		{"O_ALERT", Const, 0, ""},
+		{"O_ALT_IO", Const, 1, ""},
+		{"O_APPEND", Const, 0, ""},
+		{"O_ASYNC", Const, 0, ""},
+		{"O_CLOEXEC", Const, 0, ""},
+		{"O_CREAT", Const, 0, ""},
+		{"O_DIRECT", Const, 0, ""},
+		{"O_DIRECTORY", Const, 0, ""},
+		{"O_DP_GETRAWENCRYPTED", Const, 16, ""},
+		{"O_DSYNC", Const, 0, ""},
+		{"O_EVTONLY", Const, 0, ""},
+		{"O_EXCL", Const, 0, ""},
+		{"O_EXEC", Const, 0, ""},
+		{"O_EXLOCK", Const, 0, ""},
+		{"O_FSYNC", Const, 0, ""},
+		{"O_LARGEFILE", Const, 0, ""},
+		{"O_NDELAY", Const, 0, ""},
+		{"O_NOATIME", Const, 0, ""},
+		{"O_NOCTTY", Const, 0, ""},
+		{"O_NOFOLLOW", Const, 0, ""},
+		{"O_NONBLOCK", Const, 0, ""},
+		{"O_NOSIGPIPE", Const, 1, ""},
+		{"O_POPUP", Const, 0, ""},
+		{"O_RDONLY", Const, 0, ""},
+		{"O_RDWR", Const, 0, ""},
+		{"O_RSYNC", Const, 0, ""},
+		{"O_SHLOCK", Const, 0, ""},
+		{"O_SYMLINK", Const, 0, ""},
+		{"O_SYNC", Const, 0, ""},
+		{"O_TRUNC", Const, 0, ""},
+		{"O_TTY_INIT", Const, 0, ""},
+		{"O_WRONLY", Const, 0, ""},
+		{"Open", Func, 0, "func(path string, mode int, perm uint32) (fd int, err error)"},
+		{"OpenCurrentProcessToken", Func, 0, ""},
+		{"OpenProcess", Func, 0, ""},
+		{"OpenProcessToken", Func, 0, ""},
+		{"Openat", Func, 0, "func(dirfd int, path string, flags int, mode uint32) (fd int, err error)"},
+		{"Overlapped", Type, 0, ""},
+		{"Overlapped.HEvent", Field, 0, ""},
+		{"Overlapped.Internal", Field, 0, ""},
+		{"Overlapped.InternalHigh", Field, 0, ""},
+		{"Overlapped.Offset", Field, 0, ""},
+		{"Overlapped.OffsetHigh", Field, 0, ""},
+		{"PACKET_ADD_MEMBERSHIP", Const, 0, ""},
+		{"PACKET_BROADCAST", Const, 0, ""},
+		{"PACKET_DROP_MEMBERSHIP", Const, 0, ""},
+		{"PACKET_FASTROUTE", Const, 0, ""},
+		{"PACKET_HOST", Const, 0, ""},
+		{"PACKET_LOOPBACK", Const, 0, ""},
+		{"PACKET_MR_ALLMULTI", Const, 0, ""},
+		{"PACKET_MR_MULTICAST", Const, 0, ""},
+		{"PACKET_MR_PROMISC", Const, 0, ""},
+		{"PACKET_MULTICAST", Const, 0, ""},
+		{"PACKET_OTHERHOST", Const, 0, ""},
+		{"PACKET_OUTGOING", Const, 0, ""},
+		{"PACKET_RECV_OUTPUT", Const, 0, ""},
+		{"PACKET_RX_RING", Const, 0, ""},
+		{"PACKET_STATISTICS", Const, 0, ""},
+		{"PAGE_EXECUTE_READ", Const, 0, ""},
+		{"PAGE_EXECUTE_READWRITE", Const, 0, ""},
+		{"PAGE_EXECUTE_WRITECOPY", Const, 0, ""},
+		{"PAGE_READONLY", Const, 0, ""},
+		{"PAGE_READWRITE", Const, 0, ""},
+		{"PAGE_WRITECOPY", Const, 0, ""},
+		{"PARENB", Const, 0, ""},
+		{"PARMRK", Const, 0, ""},
+		{"PARODD", Const, 0, ""},
+		{"PENDIN", Const, 0, ""},
+		{"PFL_HIDDEN", Const, 2, ""},
+		{"PFL_MATCHES_PROTOCOL_ZERO", Const, 2, ""},
+		{"PFL_MULTIPLE_PROTO_ENTRIES", Const, 2, ""},
+		{"PFL_NETWORKDIRECT_PROVIDER", Const, 2, ""},
+		{"PFL_RECOMMENDED_PROTO_ENTRY", Const, 2, ""},
+		{"PF_FLUSH", Const, 1, ""},
+		{"PKCS_7_ASN_ENCODING", Const, 0, ""},
+		{"PMC5_PIPELINE_FLUSH", Const, 1, ""},
+		{"PRIO_PGRP", Const, 2, ""},
+		{"PRIO_PROCESS", Const, 2, ""},
+		{"PRIO_USER", Const, 2, ""},
+		{"PRI_IOFLUSH", Const, 1, ""},
+		{"PROCESS_QUERY_INFORMATION", Const, 0, ""},
+		{"PROCESS_TERMINATE", Const, 2, ""},
+		{"PROT_EXEC", Const, 0, ""},
+		{"PROT_GROWSDOWN", Const, 0, ""},
+		{"PROT_GROWSUP", Const, 0, ""},
+		{"PROT_NONE", Const, 0, ""},
+		{"PROT_READ", Const, 0, ""},
+		{"PROT_WRITE", Const, 0, ""},
+		{"PROV_DH_SCHANNEL", Const, 0, ""},
+		{"PROV_DSS", Const, 0, ""},
+		{"PROV_DSS_DH", Const, 0, ""},
+		{"PROV_EC_ECDSA_FULL", Const, 0, ""},
+		{"PROV_EC_ECDSA_SIG", Const, 0, ""},
+		{"PROV_EC_ECNRA_FULL", Const, 0, ""},
+		{"PROV_EC_ECNRA_SIG", Const, 0, ""},
+		{"PROV_FORTEZZA", Const, 0, ""},
+		{"PROV_INTEL_SEC", Const, 0, ""},
+		{"PROV_MS_EXCHANGE", Const, 0, ""},
+		{"PROV_REPLACE_OWF", Const, 0, ""},
+		{"PROV_RNG", Const, 0, ""},
+		{"PROV_RSA_AES", Const, 0, ""},
+		{"PROV_RSA_FULL", Const, 0, ""},
+		{"PROV_RSA_SCHANNEL", Const, 0, ""},
+		{"PROV_RSA_SIG", Const, 0, ""},
+		{"PROV_SPYRUS_LYNKS", Const, 0, ""},
+		{"PROV_SSL", Const, 0, ""},
+		{"PR_CAPBSET_DROP", Const, 0, ""},
+		{"PR_CAPBSET_READ", Const, 0, ""},
+		{"PR_CLEAR_SECCOMP_FILTER", Const, 0, ""},
+		{"PR_ENDIAN_BIG", Const, 0, ""},
+		{"PR_ENDIAN_LITTLE", Const, 0, ""},
+		{"PR_ENDIAN_PPC_LITTLE", Const, 0, ""},
+		{"PR_FPEMU_NOPRINT", Const, 0, ""},
+		{"PR_FPEMU_SIGFPE", Const, 0, ""},
+		{"PR_FP_EXC_ASYNC", Const, 0, ""},
+		{"PR_FP_EXC_DISABLED", Const, 0, ""},
+		{"PR_FP_EXC_DIV", Const, 0, ""},
+		{"PR_FP_EXC_INV", Const, 0, ""},
+		{"PR_FP_EXC_NONRECOV", Const, 0, ""},
+		{"PR_FP_EXC_OVF", Const, 0, ""},
+		{"PR_FP_EXC_PRECISE", Const, 0, ""},
+		{"PR_FP_EXC_RES", Const, 0, ""},
+		{"PR_FP_EXC_SW_ENABLE", Const, 0, ""},
+		{"PR_FP_EXC_UND", Const, 0, ""},
+		{"PR_GET_DUMPABLE", Const, 0, ""},
+		{"PR_GET_ENDIAN", Const, 0, ""},
+		{"PR_GET_FPEMU", Const, 0, ""},
+		{"PR_GET_FPEXC", Const, 0, ""},
+		{"PR_GET_KEEPCAPS", Const, 0, ""},
+		{"PR_GET_NAME", Const, 0, ""},
+		{"PR_GET_PDEATHSIG", Const, 0, ""},
+		{"PR_GET_SECCOMP", Const, 0, ""},
+		{"PR_GET_SECCOMP_FILTER", Const, 0, ""},
+		{"PR_GET_SECUREBITS", Const, 0, ""},
+		{"PR_GET_TIMERSLACK", Const, 0, ""},
+		{"PR_GET_TIMING", Const, 0, ""},
+		{"PR_GET_TSC", Const, 0, ""},
+		{"PR_GET_UNALIGN", Const, 0, ""},
+		{"PR_MCE_KILL", Const, 0, ""},
+		{"PR_MCE_KILL_CLEAR", Const, 0, ""},
+		{"PR_MCE_KILL_DEFAULT", Const, 0, ""},
+		{"PR_MCE_KILL_EARLY", Const, 0, ""},
+		{"PR_MCE_KILL_GET", Const, 0, ""},
+		{"PR_MCE_KILL_LATE", Const, 0, ""},
+		{"PR_MCE_KILL_SET", Const, 0, ""},
+		{"PR_SECCOMP_FILTER_EVENT", Const, 0, ""},
+		{"PR_SECCOMP_FILTER_SYSCALL", Const, 0, ""},
+		{"PR_SET_DUMPABLE", Const, 0, ""},
+		{"PR_SET_ENDIAN", Const, 0, ""},
+		{"PR_SET_FPEMU", Const, 0, ""},
+		{"PR_SET_FPEXC", Const, 0, ""},
+		{"PR_SET_KEEPCAPS", Const, 0, ""},
+		{"PR_SET_NAME", Const, 0, ""},
+		{"PR_SET_PDEATHSIG", Const, 0, ""},
+		{"PR_SET_PTRACER", Const, 0, ""},
+		{"PR_SET_SECCOMP", Const, 0, ""},
+		{"PR_SET_SECCOMP_FILTER", Const, 0, ""},
+		{"PR_SET_SECUREBITS", Const, 0, ""},
+		{"PR_SET_TIMERSLACK", Const, 0, ""},
+		{"PR_SET_TIMING", Const, 0, ""},
+		{"PR_SET_TSC", Const, 0, ""},
+		{"PR_SET_UNALIGN", Const, 0, ""},
+		{"PR_TASK_PERF_EVENTS_DISABLE", Const, 0, ""},
+		{"PR_TASK_PERF_EVENTS_ENABLE", Const, 0, ""},
+		{"PR_TIMING_STATISTICAL", Const, 0, ""},
+		{"PR_TIMING_TIMESTAMP", Const, 0, ""},
+		{"PR_TSC_ENABLE", Const, 0, ""},
+		{"PR_TSC_SIGSEGV", Const, 0, ""},
+		{"PR_UNALIGN_NOPRINT", Const, 0, ""},
+		{"PR_UNALIGN_SIGBUS", Const, 0, ""},
+		{"PTRACE_ARCH_PRCTL", Const, 0, ""},
+		{"PTRACE_ATTACH", Const, 0, ""},
+		{"PTRACE_CONT", Const, 0, ""},
+		{"PTRACE_DETACH", Const, 0, ""},
+		{"PTRACE_EVENT_CLONE", Const, 0, ""},
+		{"PTRACE_EVENT_EXEC", Const, 0, ""},
+		{"PTRACE_EVENT_EXIT", Const, 0, ""},
+		{"PTRACE_EVENT_FORK", Const, 0, ""},
+		{"PTRACE_EVENT_VFORK", Const, 0, ""},
+		{"PTRACE_EVENT_VFORK_DONE", Const, 0, ""},
+		{"PTRACE_GETCRUNCHREGS", Const, 0, ""},
+		{"PTRACE_GETEVENTMSG", Const, 0, ""},
+		{"PTRACE_GETFPREGS", Const, 0, ""},
+		{"PTRACE_GETFPXREGS", Const, 0, ""},
+		{"PTRACE_GETHBPREGS", Const, 0, ""},
+		{"PTRACE_GETREGS", Const, 0, ""},
+		{"PTRACE_GETREGSET", Const, 0, ""},
+		{"PTRACE_GETSIGINFO", Const, 0, ""},
+		{"PTRACE_GETVFPREGS", Const, 0, ""},
+		{"PTRACE_GETWMMXREGS", Const, 0, ""},
+		{"PTRACE_GET_THREAD_AREA", Const, 0, ""},
+		{"PTRACE_KILL", Const, 0, ""},
+		{"PTRACE_OLDSETOPTIONS", Const, 0, ""},
+		{"PTRACE_O_MASK", Const, 0, ""},
+		{"PTRACE_O_TRACECLONE", Const, 0, ""},
+		{"PTRACE_O_TRACEEXEC", Const, 0, ""},
+		{"PTRACE_O_TRACEEXIT", Const, 0, ""},
+		{"PTRACE_O_TRACEFORK", Const, 0, ""},
+		{"PTRACE_O_TRACESYSGOOD", Const, 0, ""},
+		{"PTRACE_O_TRACEVFORK", Const, 0, ""},
+		{"PTRACE_O_TRACEVFORKDONE", Const, 0, ""},
+		{"PTRACE_PEEKDATA", Const, 0, ""},
+		{"PTRACE_PEEKTEXT", Const, 0, ""},
+		{"PTRACE_PEEKUSR", Const, 0, ""},
+		{"PTRACE_POKEDATA", Const, 0, ""},
+		{"PTRACE_POKETEXT", Const, 0, ""},
+		{"PTRACE_POKEUSR", Const, 0, ""},
+		{"PTRACE_SETCRUNCHREGS", Const, 0, ""},
+		{"PTRACE_SETFPREGS", Const, 0, ""},
+		{"PTRACE_SETFPXREGS", Const, 0, ""},
+		{"PTRACE_SETHBPREGS", Const, 0, ""},
+		{"PTRACE_SETOPTIONS", Const, 0, ""},
+		{"PTRACE_SETREGS", Const, 0, ""},
+		{"PTRACE_SETREGSET", Const, 0, ""},
+		{"PTRACE_SETSIGINFO", Const, 0, ""},
+		{"PTRACE_SETVFPREGS", Const, 0, ""},
+		{"PTRACE_SETWMMXREGS", Const, 0, ""},
+		{"PTRACE_SET_SYSCALL", Const, 0, ""},
+		{"PTRACE_SET_THREAD_AREA", Const, 0, ""},
+		{"PTRACE_SINGLEBLOCK", Const, 0, ""},
+		{"PTRACE_SINGLESTEP", Const, 0, ""},
+		{"PTRACE_SYSCALL", Const, 0, ""},
+		{"PTRACE_SYSEMU", Const, 0, ""},
+		{"PTRACE_SYSEMU_SINGLESTEP", Const, 0, ""},
+		{"PTRACE_TRACEME", Const, 0, ""},
+		{"PT_ATTACH", Const, 0, ""},
+		{"PT_ATTACHEXC", Const, 0, ""},
+		{"PT_CONTINUE", Const, 0, ""},
+		{"PT_DATA_ADDR", Const, 0, ""},
+		{"PT_DENY_ATTACH", Const, 0, ""},
+		{"PT_DETACH", Const, 0, ""},
+		{"PT_FIRSTMACH", Const, 0, ""},
+		{"PT_FORCEQUOTA", Const, 0, ""},
+		{"PT_KILL", Const, 0, ""},
+		{"PT_MASK", Const, 1, ""},
+		{"PT_READ_D", Const, 0, ""},
+		{"PT_READ_I", Const, 0, ""},
+		{"PT_READ_U", Const, 0, ""},
+		{"PT_SIGEXC", Const, 0, ""},
+		{"PT_STEP", Const, 0, ""},
+		{"PT_TEXT_ADDR", Const, 0, ""},
+		{"PT_TEXT_END_ADDR", Const, 0, ""},
+		{"PT_THUPDATE", Const, 0, ""},
+		{"PT_TRACE_ME", Const, 0, ""},
+		{"PT_WRITE_D", Const, 0, ""},
+		{"PT_WRITE_I", Const, 0, ""},
+		{"PT_WRITE_U", Const, 0, ""},
+		{"ParseDirent", Func, 0, "func(buf []byte, max int, names []string) (consumed int, count int, newnames []string)"},
+		{"ParseNetlinkMessage", Func, 0, "func(b []byte) ([]NetlinkMessage, error)"},
+		{"ParseNetlinkRouteAttr", Func, 0, "func(m *NetlinkMessage) ([]NetlinkRouteAttr, error)"},
+		{"ParseRoutingMessage", Func, 0, ""},
+		{"ParseRoutingSockaddr", Func, 0, ""},
+		{"ParseSocketControlMessage", Func, 0, "func(b []byte) ([]SocketControlMessage, error)"},
+		{"ParseUnixCredentials", Func, 0, "func(m *SocketControlMessage) (*Ucred, error)"},
+		{"ParseUnixRights", Func, 0, "func(m *SocketControlMessage) ([]int, error)"},
+		{"PathMax", Const, 0, ""},
+		{"Pathconf", Func, 0, ""},
+		{"Pause", Func, 0, "func() (err error)"},
+		{"Pipe", Func, 0, "func(p []int) error"},
+		{"Pipe2", Func, 1, "func(p []int, flags int) error"},
+		{"PivotRoot", Func, 0, "func(newroot string, putold string) (err error)"},
+		{"Pointer", Type, 11, ""},
+		{"PostQueuedCompletionStatus", Func, 0, ""},
+		{"Pread", Func, 0, "func(fd int, p []byte, offset int64) (n int, err error)"},
+		{"Proc", Type, 0, ""},
+		{"Proc.Dll", Field, 0, ""},
+		{"Proc.Name", Field, 0, ""},
+		{"ProcAttr", Type, 0, ""},
+		{"ProcAttr.Dir", Field, 0, ""},
+		{"ProcAttr.Env", Field, 0, ""},
+		{"ProcAttr.Files", Field, 0, ""},
+		{"ProcAttr.Sys", Field, 0, ""},
+		{"Process32First", Func, 4, ""},
+		{"Process32Next", Func, 4, ""},
+		{"ProcessEntry32", Type, 4, ""},
+		{"ProcessEntry32.DefaultHeapID", Field, 4, ""},
+		{"ProcessEntry32.ExeFile", Field, 4, ""},
+		{"ProcessEntry32.Flags", Field, 4, ""},
+		{"ProcessEntry32.ModuleID", Field, 4, ""},
+		{"ProcessEntry32.ParentProcessID", Field, 4, ""},
+		{"ProcessEntry32.PriClassBase", Field, 4, ""},
+		{"ProcessEntry32.ProcessID", Field, 4, ""},
+		{"ProcessEntry32.Size", Field, 4, ""},
+		{"ProcessEntry32.Threads", Field, 4, ""},
+		{"ProcessEntry32.Usage", Field, 4, ""},
+		{"ProcessInformation", Type, 0, ""},
+		{"ProcessInformation.Process", Field, 0, ""},
+		{"ProcessInformation.ProcessId", Field, 0, ""},
+		{"ProcessInformation.Thread", Field, 0, ""},
+		{"ProcessInformation.ThreadId", Field, 0, ""},
+		{"Protoent", Type, 0, ""},
+		{"Protoent.Aliases", Field, 0, ""},
+		{"Protoent.Name", Field, 0, ""},
+		{"Protoent.Proto", Field, 0, ""},
+		{"PtraceAttach", Func, 0, "func(pid int) (err error)"},
+		{"PtraceCont", Func, 0, "func(pid int, signal int) (err error)"},
+		{"PtraceDetach", Func, 0, "func(pid int) (err error)"},
+		{"PtraceGetEventMsg", Func, 0, "func(pid int) (msg uint, err error)"},
+		{"PtraceGetRegs", Func, 0, "func(pid int, regsout *PtraceRegs) (err error)"},
+		{"PtracePeekData", Func, 0, "func(pid int, addr uintptr, out []byte) (count int, err error)"},
+		{"PtracePeekText", Func, 0, "func(pid int, addr uintptr, out []byte) (count int, err error)"},
+		{"PtracePokeData", Func, 0, "func(pid int, addr uintptr, data []byte) (count int, err error)"},
+		{"PtracePokeText", Func, 0, "func(pid int, addr uintptr, data []byte) (count int, err error)"},
+		{"PtraceRegs", Type, 0, ""},
+		{"PtraceRegs.Cs", Field, 0, ""},
+		{"PtraceRegs.Ds", Field, 0, ""},
+		{"PtraceRegs.Eax", Field, 0, ""},
+		{"PtraceRegs.Ebp", Field, 0, ""},
+		{"PtraceRegs.Ebx", Field, 0, ""},
+		{"PtraceRegs.Ecx", Field, 0, ""},
+		{"PtraceRegs.Edi", Field, 0, ""},
+		{"PtraceRegs.Edx", Field, 0, ""},
+		{"PtraceRegs.Eflags", Field, 0, ""},
+		{"PtraceRegs.Eip", Field, 0, ""},
+		{"PtraceRegs.Es", Field, 0, ""},
+		{"PtraceRegs.Esi", Field, 0, ""},
+		{"PtraceRegs.Esp", Field, 0, ""},
+		{"PtraceRegs.Fs", Field, 0, ""},
+		{"PtraceRegs.Fs_base", Field, 0, ""},
+		{"PtraceRegs.Gs", Field, 0, ""},
+		{"PtraceRegs.Gs_base", Field, 0, ""},
+		{"PtraceRegs.Orig_eax", Field, 0, ""},
+		{"PtraceRegs.Orig_rax", Field, 0, ""},
+		{"PtraceRegs.R10", Field, 0, ""},
+		{"PtraceRegs.R11", Field, 0, ""},
+		{"PtraceRegs.R12", Field, 0, ""},
+		{"PtraceRegs.R13", Field, 0, ""},
+		{"PtraceRegs.R14", Field, 0, ""},
+		{"PtraceRegs.R15", Field, 0, ""},
+		{"PtraceRegs.R8", Field, 0, ""},
+		{"PtraceRegs.R9", Field, 0, ""},
+		{"PtraceRegs.Rax", Field, 0, ""},
+		{"PtraceRegs.Rbp", Field, 0, ""},
+		{"PtraceRegs.Rbx", Field, 0, ""},
+		{"PtraceRegs.Rcx", Field, 0, ""},
+		{"PtraceRegs.Rdi", Field, 0, ""},
+		{"PtraceRegs.Rdx", Field, 0, ""},
+		{"PtraceRegs.Rip", Field, 0, ""},
+		{"PtraceRegs.Rsi", Field, 0, ""},
+		{"PtraceRegs.Rsp", Field, 0, ""},
+		{"PtraceRegs.Ss", Field, 0, ""},
+		{"PtraceRegs.Uregs", Field, 0, ""},
+		{"PtraceRegs.Xcs", Field, 0, ""},
+		{"PtraceRegs.Xds", Field, 0, ""},
+		{"PtraceRegs.Xes", Field, 0, ""},
+		{"PtraceRegs.Xfs", Field, 0, ""},
+		{"PtraceRegs.Xgs", Field, 0, ""},
+		{"PtraceRegs.Xss", Field, 0, ""},
+		{"PtraceSetOptions", Func, 0, "func(pid int, options int) (err error)"},
+		{"PtraceSetRegs", Func, 0, "func(pid int, regs *PtraceRegs) (err error)"},
+		{"PtraceSingleStep", Func, 0, "func(pid int) (err error)"},
+		{"PtraceSyscall", Func, 1, "func(pid int, signal int) (err error)"},
+		{"Pwrite", Func, 0, "func(fd int, p []byte, offset int64) (n int, err error)"},
+		{"REG_BINARY", Const, 0, ""},
+		{"REG_DWORD", Const, 0, ""},
+		{"REG_DWORD_BIG_ENDIAN", Const, 0, ""},
+		{"REG_DWORD_LITTLE_ENDIAN", Const, 0, ""},
+		{"REG_EXPAND_SZ", Const, 0, ""},
+		{"REG_FULL_RESOURCE_DESCRIPTOR", Const, 0, ""},
+		{"REG_LINK", Const, 0, ""},
+		{"REG_MULTI_SZ", Const, 0, ""},
+		{"REG_NONE", Const, 0, ""},
+		{"REG_QWORD", Const, 0, ""},
+		{"REG_QWORD_LITTLE_ENDIAN", Const, 0, ""},
+		{"REG_RESOURCE_LIST", Const, 0, ""},
+		{"REG_RESOURCE_REQUIREMENTS_LIST", Const, 0, ""},
+		{"REG_SZ", Const, 0, ""},
+		{"RLIMIT_AS", Const, 0, ""},
+		{"RLIMIT_CORE", Const, 0, ""},
+		{"RLIMIT_CPU", Const, 0, ""},
+		{"RLIMIT_CPU_USAGE_MONITOR", Const, 16, ""},
+		{"RLIMIT_DATA", Const, 0, ""},
+		{"RLIMIT_FSIZE", Const, 0, ""},
+		{"RLIMIT_NOFILE", Const, 0, ""},
+		{"RLIMIT_STACK", Const, 0, ""},
+		{"RLIM_INFINITY", Const, 0, ""},
+		{"RTAX_ADVMSS", Const, 0, ""},
+		{"RTAX_AUTHOR", Const, 0, ""},
+		{"RTAX_BRD", Const, 0, ""},
+		{"RTAX_CWND", Const, 0, ""},
+		{"RTAX_DST", Const, 0, ""},
+		{"RTAX_FEATURES", Const, 0, ""},
+		{"RTAX_FEATURE_ALLFRAG", Const, 0, ""},
+		{"RTAX_FEATURE_ECN", Const, 0, ""},
+		{"RTAX_FEATURE_SACK", Const, 0, ""},
+		{"RTAX_FEATURE_TIMESTAMP", Const, 0, ""},
+		{"RTAX_GATEWAY", Const, 0, ""},
+		{"RTAX_GENMASK", Const, 0, ""},
+		{"RTAX_HOPLIMIT", Const, 0, ""},
+		{"RTAX_IFA", Const, 0, ""},
+		{"RTAX_IFP", Const, 0, ""},
+		{"RTAX_INITCWND", Const, 0, ""},
+		{"RTAX_INITRWND", Const, 0, ""},
+		{"RTAX_LABEL", Const, 1, ""},
+		{"RTAX_LOCK", Const, 0, ""},
+		{"RTAX_MAX", Const, 0, ""},
+		{"RTAX_MTU", Const, 0, ""},
+		{"RTAX_NETMASK", Const, 0, ""},
+		{"RTAX_REORDERING", Const, 0, ""},
+		{"RTAX_RTO_MIN", Const, 0, ""},
+		{"RTAX_RTT", Const, 0, ""},
+		{"RTAX_RTTVAR", Const, 0, ""},
+		{"RTAX_SRC", Const, 1, ""},
+		{"RTAX_SRCMASK", Const, 1, ""},
+		{"RTAX_SSTHRESH", Const, 0, ""},
+		{"RTAX_TAG", Const, 1, ""},
+		{"RTAX_UNSPEC", Const, 0, ""},
+		{"RTAX_WINDOW", Const, 0, ""},
+		{"RTA_ALIGNTO", Const, 0, ""},
+		{"RTA_AUTHOR", Const, 0, ""},
+		{"RTA_BRD", Const, 0, ""},
+		{"RTA_CACHEINFO", Const, 0, ""},
+		{"RTA_DST", Const, 0, ""},
+		{"RTA_FLOW", Const, 0, ""},
+		{"RTA_GATEWAY", Const, 0, ""},
+		{"RTA_GENMASK", Const, 0, ""},
+		{"RTA_IFA", Const, 0, ""},
+		{"RTA_IFP", Const, 0, ""},
+		{"RTA_IIF", Const, 0, ""},
+		{"RTA_LABEL", Const, 1, ""},
+		{"RTA_MAX", Const, 0, ""},
+		{"RTA_METRICS", Const, 0, ""},
+		{"RTA_MULTIPATH", Const, 0, ""},
+		{"RTA_NETMASK", Const, 0, ""},
+		{"RTA_OIF", Const, 0, ""},
+		{"RTA_PREFSRC", Const, 0, ""},
+		{"RTA_PRIORITY", Const, 0, ""},
+		{"RTA_SRC", Const, 0, ""},
+		{"RTA_SRCMASK", Const, 1, ""},
+		{"RTA_TABLE", Const, 0, ""},
+		{"RTA_TAG", Const, 1, ""},
+		{"RTA_UNSPEC", Const, 0, ""},
+		{"RTCF_DIRECTSRC", Const, 0, ""},
+		{"RTCF_DOREDIRECT", Const, 0, ""},
+		{"RTCF_LOG", Const, 0, ""},
+		{"RTCF_MASQ", Const, 0, ""},
+		{"RTCF_NAT", Const, 0, ""},
+		{"RTCF_VALVE", Const, 0, ""},
+		{"RTF_ADDRCLASSMASK", Const, 0, ""},
+		{"RTF_ADDRCONF", Const, 0, ""},
+		{"RTF_ALLONLINK", Const, 0, ""},
+		{"RTF_ANNOUNCE", Const, 1, ""},
+		{"RTF_BLACKHOLE", Const, 0, ""},
+		{"RTF_BROADCAST", Const, 0, ""},
+		{"RTF_CACHE", Const, 0, ""},
+		{"RTF_CLONED", Const, 1, ""},
+		{"RTF_CLONING", Const, 0, ""},
+		{"RTF_CONDEMNED", Const, 0, ""},
+		{"RTF_DEFAULT", Const, 0, ""},
+		{"RTF_DELCLONE", Const, 0, ""},
+		{"RTF_DONE", Const, 0, ""},
+		{"RTF_DYNAMIC", Const, 0, ""},
+		{"RTF_FLOW", Const, 0, ""},
+		{"RTF_FMASK", Const, 0, ""},
+		{"RTF_GATEWAY", Const, 0, ""},
+		{"RTF_GWFLAG_COMPAT", Const, 3, ""},
+		{"RTF_HOST", Const, 0, ""},
+		{"RTF_IFREF", Const, 0, ""},
+		{"RTF_IFSCOPE", Const, 0, ""},
+		{"RTF_INTERFACE", Const, 0, ""},
+		{"RTF_IRTT", Const, 0, ""},
+		{"RTF_LINKRT", Const, 0, ""},
+		{"RTF_LLDATA", Const, 0, ""},
+		{"RTF_LLINFO", Const, 0, ""},
+		{"RTF_LOCAL", Const, 0, ""},
+		{"RTF_MASK", Const, 1, ""},
+		{"RTF_MODIFIED", Const, 0, ""},
+		{"RTF_MPATH", Const, 1, ""},
+		{"RTF_MPLS", Const, 1, ""},
+		{"RTF_MSS", Const, 0, ""},
+		{"RTF_MTU", Const, 0, ""},
+		{"RTF_MULTICAST", Const, 0, ""},
+		{"RTF_NAT", Const, 0, ""},
+		{"RTF_NOFORWARD", Const, 0, ""},
+		{"RTF_NONEXTHOP", Const, 0, ""},
+		{"RTF_NOPMTUDISC", Const, 0, ""},
+		{"RTF_PERMANENT_ARP", Const, 1, ""},
+		{"RTF_PINNED", Const, 0, ""},
+		{"RTF_POLICY", Const, 0, ""},
+		{"RTF_PRCLONING", Const, 0, ""},
+		{"RTF_PROTO1", Const, 0, ""},
+		{"RTF_PROTO2", Const, 0, ""},
+		{"RTF_PROTO3", Const, 0, ""},
+		{"RTF_PROXY", Const, 16, ""},
+		{"RTF_REINSTATE", Const, 0, ""},
+		{"RTF_REJECT", Const, 0, ""},
+		{"RTF_RNH_LOCKED", Const, 0, ""},
+		{"RTF_ROUTER", Const, 16, ""},
+		{"RTF_SOURCE", Const, 1, ""},
+		{"RTF_SRC", Const, 1, ""},
+		{"RTF_STATIC", Const, 0, ""},
+		{"RTF_STICKY", Const, 0, ""},
+		{"RTF_THROW", Const, 0, ""},
+		{"RTF_TUNNEL", Const, 1, ""},
+		{"RTF_UP", Const, 0, ""},
+		{"RTF_USETRAILERS", Const, 1, ""},
+		{"RTF_WASCLONED", Const, 0, ""},
+		{"RTF_WINDOW", Const, 0, ""},
+		{"RTF_XRESOLVE", Const, 0, ""},
+		{"RTM_ADD", Const, 0, ""},
+		{"RTM_BASE", Const, 0, ""},
+		{"RTM_CHANGE", Const, 0, ""},
+		{"RTM_CHGADDR", Const, 1, ""},
+		{"RTM_DELACTION", Const, 0, ""},
+		{"RTM_DELADDR", Const, 0, ""},
+		{"RTM_DELADDRLABEL", Const, 0, ""},
+		{"RTM_DELETE", Const, 0, ""},
+		{"RTM_DELLINK", Const, 0, ""},
+		{"RTM_DELMADDR", Const, 0, ""},
+		{"RTM_DELNEIGH", Const, 0, ""},
+		{"RTM_DELQDISC", Const, 0, ""},
+		{"RTM_DELROUTE", Const, 0, ""},
+		{"RTM_DELRULE", Const, 0, ""},
+		{"RTM_DELTCLASS", Const, 0, ""},
+		{"RTM_DELTFILTER", Const, 0, ""},
+		{"RTM_DESYNC", Const, 1, ""},
+		{"RTM_F_CLONED", Const, 0, ""},
+		{"RTM_F_EQUALIZE", Const, 0, ""},
+		{"RTM_F_NOTIFY", Const, 0, ""},
+		{"RTM_F_PREFIX", Const, 0, ""},
+		{"RTM_GET", Const, 0, ""},
+		{"RTM_GET2", Const, 0, ""},
+		{"RTM_GETACTION", Const, 0, ""},
+		{"RTM_GETADDR", Const, 0, ""},
+		{"RTM_GETADDRLABEL", Const, 0, ""},
+		{"RTM_GETANYCAST", Const, 0, ""},
+		{"RTM_GETDCB", Const, 0, ""},
+		{"RTM_GETLINK", Const, 0, ""},
+		{"RTM_GETMULTICAST", Const, 0, ""},
+		{"RTM_GETNEIGH", Const, 0, ""},
+		{"RTM_GETNEIGHTBL", Const, 0, ""},
+		{"RTM_GETQDISC", Const, 0, ""},
+		{"RTM_GETROUTE", Const, 0, ""},
+		{"RTM_GETRULE", Const, 0, ""},
+		{"RTM_GETTCLASS", Const, 0, ""},
+		{"RTM_GETTFILTER", Const, 0, ""},
+		{"RTM_IEEE80211", Const, 0, ""},
+		{"RTM_IFANNOUNCE", Const, 0, ""},
+		{"RTM_IFINFO", Const, 0, ""},
+		{"RTM_IFINFO2", Const, 0, ""},
+		{"RTM_LLINFO_UPD", Const, 1, ""},
+		{"RTM_LOCK", Const, 0, ""},
+		{"RTM_LOSING", Const, 0, ""},
+		{"RTM_MAX", Const, 0, ""},
+		{"RTM_MAXSIZE", Const, 1, ""},
+		{"RTM_MISS", Const, 0, ""},
+		{"RTM_NEWACTION", Const, 0, ""},
+		{"RTM_NEWADDR", Const, 0, ""},
+		{"RTM_NEWADDRLABEL", Const, 0, ""},
+		{"RTM_NEWLINK", Const, 0, ""},
+		{"RTM_NEWMADDR", Const, 0, ""},
+		{"RTM_NEWMADDR2", Const, 0, ""},
+		{"RTM_NEWNDUSEROPT", Const, 0, ""},
+		{"RTM_NEWNEIGH", Const, 0, ""},
+		{"RTM_NEWNEIGHTBL", Const, 0, ""},
+		{"RTM_NEWPREFIX", Const, 0, ""},
+		{"RTM_NEWQDISC", Const, 0, ""},
+		{"RTM_NEWROUTE", Const, 0, ""},
+		{"RTM_NEWRULE", Const, 0, ""},
+		{"RTM_NEWTCLASS", Const, 0, ""},
+		{"RTM_NEWTFILTER", Const, 0, ""},
+		{"RTM_NR_FAMILIES", Const, 0, ""},
+		{"RTM_NR_MSGTYPES", Const, 0, ""},
+		{"RTM_OIFINFO", Const, 1, ""},
+		{"RTM_OLDADD", Const, 0, ""},
+		{"RTM_OLDDEL", Const, 0, ""},
+		{"RTM_OOIFINFO", Const, 1, ""},
+		{"RTM_REDIRECT", Const, 0, ""},
+		{"RTM_RESOLVE", Const, 0, ""},
+		{"RTM_RTTUNIT", Const, 0, ""},
+		{"RTM_SETDCB", Const, 0, ""},
+		{"RTM_SETGATE", Const, 1, ""},
+		{"RTM_SETLINK", Const, 0, ""},
+		{"RTM_SETNEIGHTBL", Const, 0, ""},
+		{"RTM_VERSION", Const, 0, ""},
+		{"RTNH_ALIGNTO", Const, 0, ""},
+		{"RTNH_F_DEAD", Const, 0, ""},
+		{"RTNH_F_ONLINK", Const, 0, ""},
+		{"RTNH_F_PERVASIVE", Const, 0, ""},
+		{"RTNLGRP_IPV4_IFADDR", Const, 1, ""},
+		{"RTNLGRP_IPV4_MROUTE", Const, 1, ""},
+		{"RTNLGRP_IPV4_ROUTE", Const, 1, ""},
+		{"RTNLGRP_IPV4_RULE", Const, 1, ""},
+		{"RTNLGRP_IPV6_IFADDR", Const, 1, ""},
+		{"RTNLGRP_IPV6_IFINFO", Const, 1, ""},
+		{"RTNLGRP_IPV6_MROUTE", Const, 1, ""},
+		{"RTNLGRP_IPV6_PREFIX", Const, 1, ""},
+		{"RTNLGRP_IPV6_ROUTE", Const, 1, ""},
+		{"RTNLGRP_IPV6_RULE", Const, 1, ""},
+		{"RTNLGRP_LINK", Const, 1, ""},
+		{"RTNLGRP_ND_USEROPT", Const, 1, ""},
+		{"RTNLGRP_NEIGH", Const, 1, ""},
+		{"RTNLGRP_NONE", Const, 1, ""},
+		{"RTNLGRP_NOTIFY", Const, 1, ""},
+		{"RTNLGRP_TC", Const, 1, ""},
+		{"RTN_ANYCAST", Const, 0, ""},
+		{"RTN_BLACKHOLE", Const, 0, ""},
+		{"RTN_BROADCAST", Const, 0, ""},
+		{"RTN_LOCAL", Const, 0, ""},
+		{"RTN_MAX", Const, 0, ""},
+		{"RTN_MULTICAST", Const, 0, ""},
+		{"RTN_NAT", Const, 0, ""},
+		{"RTN_PROHIBIT", Const, 0, ""},
+		{"RTN_THROW", Const, 0, ""},
+		{"RTN_UNICAST", Const, 0, ""},
+		{"RTN_UNREACHABLE", Const, 0, ""},
+		{"RTN_UNSPEC", Const, 0, ""},
+		{"RTN_XRESOLVE", Const, 0, ""},
+		{"RTPROT_BIRD", Const, 0, ""},
+		{"RTPROT_BOOT", Const, 0, ""},
+		{"RTPROT_DHCP", Const, 0, ""},
+		{"RTPROT_DNROUTED", Const, 0, ""},
+		{"RTPROT_GATED", Const, 0, ""},
+		{"RTPROT_KERNEL", Const, 0, ""},
+		{"RTPROT_MRT", Const, 0, ""},
+		{"RTPROT_NTK", Const, 0, ""},
+		{"RTPROT_RA", Const, 0, ""},
+		{"RTPROT_REDIRECT", Const, 0, ""},
+		{"RTPROT_STATIC", Const, 0, ""},
+		{"RTPROT_UNSPEC", Const, 0, ""},
+		{"RTPROT_XORP", Const, 0, ""},
+		{"RTPROT_ZEBRA", Const, 0, ""},
+		{"RTV_EXPIRE", Const, 0, ""},
+		{"RTV_HOPCOUNT", Const, 0, ""},
+		{"RTV_MTU", Const, 0, ""},
+		{"RTV_RPIPE", Const, 0, ""},
+		{"RTV_RTT", Const, 0, ""},
+		{"RTV_RTTVAR", Const, 0, ""},
+		{"RTV_SPIPE", Const, 0, ""},
+		{"RTV_SSTHRESH", Const, 0, ""},
+		{"RTV_WEIGHT", Const, 0, ""},
+		{"RT_CACHING_CONTEXT", Const, 1, ""},
+		{"RT_CLASS_DEFAULT", Const, 0, ""},
+		{"RT_CLASS_LOCAL", Const, 0, ""},
+		{"RT_CLASS_MAIN", Const, 0, ""},
+		{"RT_CLASS_MAX", Const, 0, ""},
+		{"RT_CLASS_UNSPEC", Const, 0, ""},
+		{"RT_DEFAULT_FIB", Const, 1, ""},
+		{"RT_NORTREF", Const, 1, ""},
+		{"RT_SCOPE_HOST", Const, 0, ""},
+		{"RT_SCOPE_LINK", Const, 0, ""},
+		{"RT_SCOPE_NOWHERE", Const, 0, ""},
+		{"RT_SCOPE_SITE", Const, 0, ""},
+		{"RT_SCOPE_UNIVERSE", Const, 0, ""},
+		{"RT_TABLEID_MAX", Const, 1, ""},
+		{"RT_TABLE_COMPAT", Const, 0, ""},
+		{"RT_TABLE_DEFAULT", Const, 0, ""},
+		{"RT_TABLE_LOCAL", Const, 0, ""},
+		{"RT_TABLE_MAIN", Const, 0, ""},
+		{"RT_TABLE_MAX", Const, 0, ""},
+		{"RT_TABLE_UNSPEC", Const, 0, ""},
+		{"RUSAGE_CHILDREN", Const, 0, ""},
+		{"RUSAGE_SELF", Const, 0, ""},
+		{"RUSAGE_THREAD", Const, 0, ""},
+		{"Radvisory_t", Type, 0, ""},
+		{"Radvisory_t.Count", Field, 0, ""},
+		{"Radvisory_t.Offset", Field, 0, ""},
+		{"Radvisory_t.Pad_cgo_0", Field, 0, ""},
+		{"RawConn", Type, 9, ""},
+		{"RawSockaddr", Type, 0, ""},
+		{"RawSockaddr.Data", Field, 0, ""},
+		{"RawSockaddr.Family", Field, 0, ""},
+		{"RawSockaddr.Len", Field, 0, ""},
+		{"RawSockaddrAny", Type, 0, ""},
+		{"RawSockaddrAny.Addr", Field, 0, ""},
+		{"RawSockaddrAny.Pad", Field, 0, ""},
+		{"RawSockaddrDatalink", Type, 0, ""},
+		{"RawSockaddrDatalink.Alen", Field, 0, ""},
+		{"RawSockaddrDatalink.Data", Field, 0, ""},
+		{"RawSockaddrDatalink.Family", Field, 0, ""},
+		{"RawSockaddrDatalink.Index", Field, 0, ""},
+		{"RawSockaddrDatalink.Len", Field, 0, ""},
+		{"RawSockaddrDatalink.Nlen", Field, 0, ""},
+		{"RawSockaddrDatalink.Pad_cgo_0", Field, 2, ""},
+		{"RawSockaddrDatalink.Slen", Field, 0, ""},
+		{"RawSockaddrDatalink.Type", Field, 0, ""},
+		{"RawSockaddrInet4", Type, 0, ""},
+		{"RawSockaddrInet4.Addr", Field, 0, ""},
+		{"RawSockaddrInet4.Family", Field, 0, ""},
+		{"RawSockaddrInet4.Len", Field, 0, ""},
+		{"RawSockaddrInet4.Port", Field, 0, ""},
+		{"RawSockaddrInet4.Zero", Field, 0, ""},
+		{"RawSockaddrInet6", Type, 0, ""},
+		{"RawSockaddrInet6.Addr", Field, 0, ""},
+		{"RawSockaddrInet6.Family", Field, 0, ""},
+		{"RawSockaddrInet6.Flowinfo", Field, 0, ""},
+		{"RawSockaddrInet6.Len", Field, 0, ""},
+		{"RawSockaddrInet6.Port", Field, 0, ""},
+		{"RawSockaddrInet6.Scope_id", Field, 0, ""},
+		{"RawSockaddrLinklayer", Type, 0, ""},
+		{"RawSockaddrLinklayer.Addr", Field, 0, ""},
+		{"RawSockaddrLinklayer.Family", Field, 0, ""},
+		{"RawSockaddrLinklayer.Halen", Field, 0, ""},
+		{"RawSockaddrLinklayer.Hatype", Field, 0, ""},
+		{"RawSockaddrLinklayer.Ifindex", Field, 0, ""},
+		{"RawSockaddrLinklayer.Pkttype", Field, 0, ""},
+		{"RawSockaddrLinklayer.Protocol", Field, 0, ""},
+		{"RawSockaddrNetlink", Type, 0, ""},
+		{"RawSockaddrNetlink.Family", Field, 0, ""},
+		{"RawSockaddrNetlink.Groups", Field, 0, ""},
+		{"RawSockaddrNetlink.Pad", Field, 0, ""},
+		{"RawSockaddrNetlink.Pid", Field, 0, ""},
+		{"RawSockaddrUnix", Type, 0, ""},
+		{"RawSockaddrUnix.Family", Field, 0, ""},
+		{"RawSockaddrUnix.Len", Field, 0, ""},
+		{"RawSockaddrUnix.Pad_cgo_0", Field, 2, ""},
+		{"RawSockaddrUnix.Path", Field, 0, ""},
+		{"RawSyscall", Func, 0, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err Errno)"},
+		{"RawSyscall6", Func, 0, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err Errno)"},
+		{"Read", Func, 0, "func(fd int, p []byte) (n int, err error)"},
+		{"ReadConsole", Func, 1, ""},
+		{"ReadDirectoryChanges", Func, 0, ""},
+		{"ReadDirent", Func, 0, "func(fd int, buf []byte) (n int, err error)"},
+		{"ReadFile", Func, 0, ""},
+		{"Readlink", Func, 0, "func(path string, buf []byte) (n int, err error)"},
+		{"Reboot", Func, 0, "func(cmd int) (err error)"},
+		{"Recvfrom", Func, 0, "func(fd int, p []byte, flags int) (n int, from Sockaddr, err error)"},
+		{"Recvmsg", Func, 0, "func(fd int, p []byte, oob []byte, flags int) (n int, oobn int, recvflags int, from Sockaddr, err error)"},
+		{"RegCloseKey", Func, 0, ""},
+		{"RegEnumKeyEx", Func, 0, ""},
+		{"RegOpenKeyEx", Func, 0, ""},
+		{"RegQueryInfoKey", Func, 0, ""},
+		{"RegQueryValueEx", Func, 0, ""},
+		{"RemoveDirectory", Func, 0, ""},
+		{"Removexattr", Func, 1, "func(path string, attr string) (err error)"},
+		{"Rename", Func, 0, "func(oldpath string, newpath string) (err error)"},
+		{"Renameat", Func, 0, "func(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)"},
+		{"Revoke", Func, 0, ""},
+		{"Rlimit", Type, 0, ""},
+		{"Rlimit.Cur", Field, 0, ""},
+		{"Rlimit.Max", Field, 0, ""},
+		{"Rmdir", Func, 0, "func(path string) error"},
+		{"RouteMessage", Type, 0, ""},
+		{"RouteMessage.Data", Field, 0, ""},
+		{"RouteMessage.Header", Field, 0, ""},
+		{"RouteRIB", Func, 0, ""},
+		{"RoutingMessage", Type, 14, ""},
+		{"RtAttr", Type, 0, ""},
+		{"RtAttr.Len", Field, 0, ""},
+		{"RtAttr.Type", Field, 0, ""},
+		{"RtGenmsg", Type, 0, ""},
+		{"RtGenmsg.Family", Field, 0, ""},
+		{"RtMetrics", Type, 0, ""},
+		{"RtMetrics.Expire", Field, 0, ""},
+		{"RtMetrics.Filler", Field, 0, ""},
+		{"RtMetrics.Hopcount", Field, 0, ""},
+		{"RtMetrics.Locks", Field, 0, ""},
+		{"RtMetrics.Mtu", Field, 0, ""},
+		{"RtMetrics.Pad", Field, 3, ""},
+		{"RtMetrics.Pksent", Field, 0, ""},
+		{"RtMetrics.Recvpipe", Field, 0, ""},
+		{"RtMetrics.Refcnt", Field, 2, ""},
+		{"RtMetrics.Rtt", Field, 0, ""},
+		{"RtMetrics.Rttvar", Field, 0, ""},
+		{"RtMetrics.Sendpipe", Field, 0, ""},
+		{"RtMetrics.Ssthresh", Field, 0, ""},
+		{"RtMetrics.Weight", Field, 0, ""},
+		{"RtMsg", Type, 0, ""},
+		{"RtMsg.Dst_len", Field, 0, ""},
+		{"RtMsg.Family", Field, 0, ""},
+		{"RtMsg.Flags", Field, 0, ""},
+		{"RtMsg.Protocol", Field, 0, ""},
+		{"RtMsg.Scope", Field, 0, ""},
+		{"RtMsg.Src_len", Field, 0, ""},
+		{"RtMsg.Table", Field, 0, ""},
+		{"RtMsg.Tos", Field, 0, ""},
+		{"RtMsg.Type", Field, 0, ""},
+		{"RtMsghdr", Type, 0, ""},
+		{"RtMsghdr.Addrs", Field, 0, ""},
+		{"RtMsghdr.Errno", Field, 0, ""},
+		{"RtMsghdr.Flags", Field, 0, ""},
+		{"RtMsghdr.Fmask", Field, 0, ""},
+		{"RtMsghdr.Hdrlen", Field, 2, ""},
+		{"RtMsghdr.Index", Field, 0, ""},
+		{"RtMsghdr.Inits", Field, 0, ""},
+		{"RtMsghdr.Mpls", Field, 2, ""},
+		{"RtMsghdr.Msglen", Field, 0, ""},
+		{"RtMsghdr.Pad_cgo_0", Field, 0, ""},
+		{"RtMsghdr.Pad_cgo_1", Field, 2, ""},
+		{"RtMsghdr.Pid", Field, 0, ""},
+		{"RtMsghdr.Priority", Field, 2, ""},
+		{"RtMsghdr.Rmx", Field, 0, ""},
+		{"RtMsghdr.Seq", Field, 0, ""},
+		{"RtMsghdr.Tableid", Field, 2, ""},
+		{"RtMsghdr.Type", Field, 0, ""},
+		{"RtMsghdr.Use", Field, 0, ""},
+		{"RtMsghdr.Version", Field, 0, ""},
+		{"RtNexthop", Type, 0, ""},
+		{"RtNexthop.Flags", Field, 0, ""},
+		{"RtNexthop.Hops", Field, 0, ""},
+		{"RtNexthop.Ifindex", Field, 0, ""},
+		{"RtNexthop.Len", Field, 0, ""},
+		{"Rusage", Type, 0, ""},
+		{"Rusage.CreationTime", Field, 0, ""},
+		{"Rusage.ExitTime", Field, 0, ""},
+		{"Rusage.Idrss", Field, 0, ""},
+		{"Rusage.Inblock", Field, 0, ""},
+		{"Rusage.Isrss", Field, 0, ""},
+		{"Rusage.Ixrss", Field, 0, ""},
+		{"Rusage.KernelTime", Field, 0, ""},
+		{"Rusage.Majflt", Field, 0, ""},
+		{"Rusage.Maxrss", Field, 0, ""},
+		{"Rusage.Minflt", Field, 0, ""},
+		{"Rusage.Msgrcv", Field, 0, ""},
+		{"Rusage.Msgsnd", Field, 0, ""},
+		{"Rusage.Nivcsw", Field, 0, ""},
+		{"Rusage.Nsignals", Field, 0, ""},
+		{"Rusage.Nswap", Field, 0, ""},
+		{"Rusage.Nvcsw", Field, 0, ""},
+		{"Rusage.Oublock", Field, 0, ""},
+		{"Rusage.Stime", Field, 0, ""},
+		{"Rusage.UserTime", Field, 0, ""},
+		{"Rusage.Utime", Field, 0, ""},
+		{"SCM_BINTIME", Const, 0, ""},
+		{"SCM_CREDENTIALS", Const, 0, ""},
+		{"SCM_CREDS", Const, 0, ""},
+		{"SCM_RIGHTS", Const, 0, ""},
+		{"SCM_TIMESTAMP", Const, 0, ""},
+		{"SCM_TIMESTAMPING", Const, 0, ""},
+		{"SCM_TIMESTAMPNS", Const, 0, ""},
+		{"SCM_TIMESTAMP_MONOTONIC", Const, 0, ""},
+		{"SHUT_RD", Const, 0, ""},
+		{"SHUT_RDWR", Const, 0, ""},
+		{"SHUT_WR", Const, 0, ""},
+		{"SID", Type, 0, ""},
+		{"SIDAndAttributes", Type, 0, ""},
+		{"SIDAndAttributes.Attributes", Field, 0, ""},
+		{"SIDAndAttributes.Sid", Field, 0, ""},
+		{"SIGABRT", Const, 0, ""},
+		{"SIGALRM", Const, 0, ""},
+		{"SIGBUS", Const, 0, ""},
+		{"SIGCHLD", Const, 0, ""},
+		{"SIGCLD", Const, 0, ""},
+		{"SIGCONT", Const, 0, ""},
+		{"SIGEMT", Const, 0, ""},
+		{"SIGFPE", Const, 0, ""},
+		{"SIGHUP", Const, 0, ""},
+		{"SIGILL", Const, 0, ""},
+		{"SIGINFO", Const, 0, ""},
+		{"SIGINT", Const, 0, ""},
+		{"SIGIO", Const, 0, ""},
+		{"SIGIOT", Const, 0, ""},
+		{"SIGKILL", Const, 0, ""},
+		{"SIGLIBRT", Const, 1, ""},
+		{"SIGLWP", Const, 0, ""},
+		{"SIGPIPE", Const, 0, ""},
+		{"SIGPOLL", Const, 0, ""},
+		{"SIGPROF", Const, 0, ""},
+		{"SIGPWR", Const, 0, ""},
+		{"SIGQUIT", Const, 0, ""},
+		{"SIGSEGV", Const, 0, ""},
+		{"SIGSTKFLT", Const, 0, ""},
+		{"SIGSTOP", Const, 0, ""},
+		{"SIGSYS", Const, 0, ""},
+		{"SIGTERM", Const, 0, ""},
+		{"SIGTHR", Const, 0, ""},
+		{"SIGTRAP", Const, 0, ""},
+		{"SIGTSTP", Const, 0, ""},
+		{"SIGTTIN", Const, 0, ""},
+		{"SIGTTOU", Const, 0, ""},
+		{"SIGUNUSED", Const, 0, ""},
+		{"SIGURG", Const, 0, ""},
+		{"SIGUSR1", Const, 0, ""},
+		{"SIGUSR2", Const, 0, ""},
+		{"SIGVTALRM", Const, 0, ""},
+		{"SIGWINCH", Const, 0, ""},
+		{"SIGXCPU", Const, 0, ""},
+		{"SIGXFSZ", Const, 0, ""},
+		{"SIOCADDDLCI", Const, 0, ""},
+		{"SIOCADDMULTI", Const, 0, ""},
+		{"SIOCADDRT", Const, 0, ""},
+		{"SIOCAIFADDR", Const, 0, ""},
+		{"SIOCAIFGROUP", Const, 0, ""},
+		{"SIOCALIFADDR", Const, 0, ""},
+		{"SIOCARPIPLL", Const, 0, ""},
+		{"SIOCATMARK", Const, 0, ""},
+		{"SIOCAUTOADDR", Const, 0, ""},
+		{"SIOCAUTONETMASK", Const, 0, ""},
+		{"SIOCBRDGADD", Const, 1, ""},
+		{"SIOCBRDGADDS", Const, 1, ""},
+		{"SIOCBRDGARL", Const, 1, ""},
+		{"SIOCBRDGDADDR", Const, 1, ""},
+		{"SIOCBRDGDEL", Const, 1, ""},
+		{"SIOCBRDGDELS", Const, 1, ""},
+		{"SIOCBRDGFLUSH", Const, 1, ""},
+		{"SIOCBRDGFRL", Const, 1, ""},
+		{"SIOCBRDGGCACHE", Const, 1, ""},
+		{"SIOCBRDGGFD", Const, 1, ""},
+		{"SIOCBRDGGHT", Const, 1, ""},
+		{"SIOCBRDGGIFFLGS", Const, 1, ""},
+		{"SIOCBRDGGMA", Const, 1, ""},
+		{"SIOCBRDGGPARAM", Const, 1, ""},
+		{"SIOCBRDGGPRI", Const, 1, ""},
+		{"SIOCBRDGGRL", Const, 1, ""},
+		{"SIOCBRDGGSIFS", Const, 1, ""},
+		{"SIOCBRDGGTO", Const, 1, ""},
+		{"SIOCBRDGIFS", Const, 1, ""},
+		{"SIOCBRDGRTS", Const, 1, ""},
+		{"SIOCBRDGSADDR", Const, 1, ""},
+		{"SIOCBRDGSCACHE", Const, 1, ""},
+		{"SIOCBRDGSFD", Const, 1, ""},
+		{"SIOCBRDGSHT", Const, 1, ""},
+		{"SIOCBRDGSIFCOST", Const, 1, ""},
+		{"SIOCBRDGSIFFLGS", Const, 1, ""},
+		{"SIOCBRDGSIFPRIO", Const, 1, ""},
+		{"SIOCBRDGSMA", Const, 1, ""},
+		{"SIOCBRDGSPRI", Const, 1, ""},
+		{"SIOCBRDGSPROTO", Const, 1, ""},
+		{"SIOCBRDGSTO", Const, 1, ""},
+		{"SIOCBRDGSTXHC", Const, 1, ""},
+		{"SIOCDARP", Const, 0, ""},
+		{"SIOCDELDLCI", Const, 0, ""},
+		{"SIOCDELMULTI", Const, 0, ""},
+		{"SIOCDELRT", Const, 0, ""},
+		{"SIOCDEVPRIVATE", Const, 0, ""},
+		{"SIOCDIFADDR", Const, 0, ""},
+		{"SIOCDIFGROUP", Const, 0, ""},
+		{"SIOCDIFPHYADDR", Const, 0, ""},
+		{"SIOCDLIFADDR", Const, 0, ""},
+		{"SIOCDRARP", Const, 0, ""},
+		{"SIOCGARP", Const, 0, ""},
+		{"SIOCGDRVSPEC", Const, 0, ""},
+		{"SIOCGETKALIVE", Const, 1, ""},
+		{"SIOCGETLABEL", Const, 1, ""},
+		{"SIOCGETPFLOW", Const, 1, ""},
+		{"SIOCGETPFSYNC", Const, 1, ""},
+		{"SIOCGETSGCNT", Const, 0, ""},
+		{"SIOCGETVIFCNT", Const, 0, ""},
+		{"SIOCGETVLAN", Const, 0, ""},
+		{"SIOCGHIWAT", Const, 0, ""},
+		{"SIOCGIFADDR", Const, 0, ""},
+		{"SIOCGIFADDRPREF", Const, 1, ""},
+		{"SIOCGIFALIAS", Const, 1, ""},
+		{"SIOCGIFALTMTU", Const, 0, ""},
+		{"SIOCGIFASYNCMAP", Const, 0, ""},
+		{"SIOCGIFBOND", Const, 0, ""},
+		{"SIOCGIFBR", Const, 0, ""},
+		{"SIOCGIFBRDADDR", Const, 0, ""},
+		{"SIOCGIFCAP", Const, 0, ""},
+		{"SIOCGIFCONF", Const, 0, ""},
+		{"SIOCGIFCOUNT", Const, 0, ""},
+		{"SIOCGIFDATA", Const, 1, ""},
+		{"SIOCGIFDESCR", Const, 0, ""},
+		{"SIOCGIFDEVMTU", Const, 0, ""},
+		{"SIOCGIFDLT", Const, 1, ""},
+		{"SIOCGIFDSTADDR", Const, 0, ""},
+		{"SIOCGIFENCAP", Const, 0, ""},
+		{"SIOCGIFFIB", Const, 1, ""},
+		{"SIOCGIFFLAGS", Const, 0, ""},
+		{"SIOCGIFGATTR", Const, 1, ""},
+		{"SIOCGIFGENERIC", Const, 0, ""},
+		{"SIOCGIFGMEMB", Const, 0, ""},
+		{"SIOCGIFGROUP", Const, 0, ""},
+		{"SIOCGIFHARDMTU", Const, 3, ""},
+		{"SIOCGIFHWADDR", Const, 0, ""},
+		{"SIOCGIFINDEX", Const, 0, ""},
+		{"SIOCGIFKPI", Const, 0, ""},
+		{"SIOCGIFMAC", Const, 0, ""},
+		{"SIOCGIFMAP", Const, 0, ""},
+		{"SIOCGIFMEDIA", Const, 0, ""},
+		{"SIOCGIFMEM", Const, 0, ""},
+		{"SIOCGIFMETRIC", Const, 0, ""},
+		{"SIOCGIFMTU", Const, 0, ""},
+		{"SIOCGIFNAME", Const, 0, ""},
+		{"SIOCGIFNETMASK", Const, 0, ""},
+		{"SIOCGIFPDSTADDR", Const, 0, ""},
+		{"SIOCGIFPFLAGS", Const, 0, ""},
+		{"SIOCGIFPHYS", Const, 0, ""},
+		{"SIOCGIFPRIORITY", Const, 1, ""},
+		{"SIOCGIFPSRCADDR", Const, 0, ""},
+		{"SIOCGIFRDOMAIN", Const, 1, ""},
+		{"SIOCGIFRTLABEL", Const, 1, ""},
+		{"SIOCGIFSLAVE", Const, 0, ""},
+		{"SIOCGIFSTATUS", Const, 0, ""},
+		{"SIOCGIFTIMESLOT", Const, 1, ""},
+		{"SIOCGIFTXQLEN", Const, 0, ""},
+		{"SIOCGIFVLAN", Const, 0, ""},
+		{"SIOCGIFWAKEFLAGS", Const, 0, ""},
+		{"SIOCGIFXFLAGS", Const, 1, ""},
+		{"SIOCGLIFADDR", Const, 0, ""},
+		{"SIOCGLIFPHYADDR", Const, 0, ""},
+		{"SIOCGLIFPHYRTABLE", Const, 1, ""},
+		{"SIOCGLIFPHYTTL", Const, 3, ""},
+		{"SIOCGLINKSTR", Const, 1, ""},
+		{"SIOCGLOWAT", Const, 0, ""},
+		{"SIOCGPGRP", Const, 0, ""},
+		{"SIOCGPRIVATE_0", Const, 0, ""},
+		{"SIOCGPRIVATE_1", Const, 0, ""},
+		{"SIOCGRARP", Const, 0, ""},
+		{"SIOCGSPPPPARAMS", Const, 3, ""},
+		{"SIOCGSTAMP", Const, 0, ""},
+		{"SIOCGSTAMPNS", Const, 0, ""},
+		{"SIOCGVH", Const, 1, ""},
+		{"SIOCGVNETID", Const, 3, ""},
+		{"SIOCIFCREATE", Const, 0, ""},
+		{"SIOCIFCREATE2", Const, 0, ""},
+		{"SIOCIFDESTROY", Const, 0, ""},
+		{"SIOCIFGCLONERS", Const, 0, ""},
+		{"SIOCINITIFADDR", Const, 1, ""},
+		{"SIOCPROTOPRIVATE", Const, 0, ""},
+		{"SIOCRSLVMULTI", Const, 0, ""},
+		{"SIOCRTMSG", Const, 0, ""},
+		{"SIOCSARP", Const, 0, ""},
+		{"SIOCSDRVSPEC", Const, 0, ""},
+		{"SIOCSETKALIVE", Const, 1, ""},
+		{"SIOCSETLABEL", Const, 1, ""},
+		{"SIOCSETPFLOW", Const, 1, ""},
+		{"SIOCSETPFSYNC", Const, 1, ""},
+		{"SIOCSETVLAN", Const, 0, ""},
+		{"SIOCSHIWAT", Const, 0, ""},
+		{"SIOCSIFADDR", Const, 0, ""},
+		{"SIOCSIFADDRPREF", Const, 1, ""},
+		{"SIOCSIFALTMTU", Const, 0, ""},
+		{"SIOCSIFASYNCMAP", Const, 0, ""},
+		{"SIOCSIFBOND", Const, 0, ""},
+		{"SIOCSIFBR", Const, 0, ""},
+		{"SIOCSIFBRDADDR", Const, 0, ""},
+		{"SIOCSIFCAP", Const, 0, ""},
+		{"SIOCSIFDESCR", Const, 0, ""},
+		{"SIOCSIFDSTADDR", Const, 0, ""},
+		{"SIOCSIFENCAP", Const, 0, ""},
+		{"SIOCSIFFIB", Const, 1, ""},
+		{"SIOCSIFFLAGS", Const, 0, ""},
+		{"SIOCSIFGATTR", Const, 1, ""},
+		{"SIOCSIFGENERIC", Const, 0, ""},
+		{"SIOCSIFHWADDR", Const, 0, ""},
+		{"SIOCSIFHWBROADCAST", Const, 0, ""},
+		{"SIOCSIFKPI", Const, 0, ""},
+		{"SIOCSIFLINK", Const, 0, ""},
+		{"SIOCSIFLLADDR", Const, 0, ""},
+		{"SIOCSIFMAC", Const, 0, ""},
+		{"SIOCSIFMAP", Const, 0, ""},
+		{"SIOCSIFMEDIA", Const, 0, ""},
+		{"SIOCSIFMEM", Const, 0, ""},
+		{"SIOCSIFMETRIC", Const, 0, ""},
+		{"SIOCSIFMTU", Const, 0, ""},
+		{"SIOCSIFNAME", Const, 0, ""},
+		{"SIOCSIFNETMASK", Const, 0, ""},
+		{"SIOCSIFPFLAGS", Const, 0, ""},
+		{"SIOCSIFPHYADDR", Const, 0, ""},
+		{"SIOCSIFPHYS", Const, 0, ""},
+		{"SIOCSIFPRIORITY", Const, 1, ""},
+		{"SIOCSIFRDOMAIN", Const, 1, ""},
+		{"SIOCSIFRTLABEL", Const, 1, ""},
+		{"SIOCSIFRVNET", Const, 0, ""},
+		{"SIOCSIFSLAVE", Const, 0, ""},
+		{"SIOCSIFTIMESLOT", Const, 1, ""},
+		{"SIOCSIFTXQLEN", Const, 0, ""},
+		{"SIOCSIFVLAN", Const, 0, ""},
+		{"SIOCSIFVNET", Const, 0, ""},
+		{"SIOCSIFXFLAGS", Const, 1, ""},
+		{"SIOCSLIFPHYADDR", Const, 0, ""},
+		{"SIOCSLIFPHYRTABLE", Const, 1, ""},
+		{"SIOCSLIFPHYTTL", Const, 3, ""},
+		{"SIOCSLINKSTR", Const, 1, ""},
+		{"SIOCSLOWAT", Const, 0, ""},
+		{"SIOCSPGRP", Const, 0, ""},
+		{"SIOCSRARP", Const, 0, ""},
+		{"SIOCSSPPPPARAMS", Const, 3, ""},
+		{"SIOCSVH", Const, 1, ""},
+		{"SIOCSVNETID", Const, 3, ""},
+		{"SIOCZIFDATA", Const, 1, ""},
+		{"SIO_GET_EXTENSION_FUNCTION_POINTER", Const, 1, ""},
+		{"SIO_GET_INTERFACE_LIST", Const, 0, ""},
+		{"SIO_KEEPALIVE_VALS", Const, 3, ""},
+		{"SIO_UDP_CONNRESET", Const, 4, ""},
+		{"SOCK_CLOEXEC", Const, 0, ""},
+		{"SOCK_DCCP", Const, 0, ""},
+		{"SOCK_DGRAM", Const, 0, ""},
+		{"SOCK_FLAGS_MASK", Const, 1, ""},
+		{"SOCK_MAXADDRLEN", Const, 0, ""},
+		{"SOCK_NONBLOCK", Const, 0, ""},
+		{"SOCK_NOSIGPIPE", Const, 1, ""},
+		{"SOCK_PACKET", Const, 0, ""},
+		{"SOCK_RAW", Const, 0, ""},
+		{"SOCK_RDM", Const, 0, ""},
+		{"SOCK_SEQPACKET", Const, 0, ""},
+		{"SOCK_STREAM", Const, 0, ""},
+		{"SOL_AAL", Const, 0, ""},
+		{"SOL_ATM", Const, 0, ""},
+		{"SOL_DECNET", Const, 0, ""},
+		{"SOL_ICMPV6", Const, 0, ""},
+		{"SOL_IP", Const, 0, ""},
+		{"SOL_IPV6", Const, 0, ""},
+		{"SOL_IRDA", Const, 0, ""},
+		{"SOL_PACKET", Const, 0, ""},
+		{"SOL_RAW", Const, 0, ""},
+		{"SOL_SOCKET", Const, 0, ""},
+		{"SOL_TCP", Const, 0, ""},
+		{"SOL_X25", Const, 0, ""},
+		{"SOMAXCONN", Const, 0, ""},
+		{"SO_ACCEPTCONN", Const, 0, ""},
+		{"SO_ACCEPTFILTER", Const, 0, ""},
+		{"SO_ATTACH_FILTER", Const, 0, ""},
+		{"SO_BINDANY", Const, 1, ""},
+		{"SO_BINDTODEVICE", Const, 0, ""},
+		{"SO_BINTIME", Const, 0, ""},
+		{"SO_BROADCAST", Const, 0, ""},
+		{"SO_BSDCOMPAT", Const, 0, ""},
+		{"SO_DEBUG", Const, 0, ""},
+		{"SO_DETACH_FILTER", Const, 0, ""},
+		{"SO_DOMAIN", Const, 0, ""},
+		{"SO_DONTROUTE", Const, 0, ""},
+		{"SO_DONTTRUNC", Const, 0, ""},
+		{"SO_ERROR", Const, 0, ""},
+		{"SO_KEEPALIVE", Const, 0, ""},
+		{"SO_LABEL", Const, 0, ""},
+		{"SO_LINGER", Const, 0, ""},
+		{"SO_LINGER_SEC", Const, 0, ""},
+		{"SO_LISTENINCQLEN", Const, 0, ""},
+		{"SO_LISTENQLEN", Const, 0, ""},
+		{"SO_LISTENQLIMIT", Const, 0, ""},
+		{"SO_MARK", Const, 0, ""},
+		{"SO_NETPROC", Const, 1, ""},
+		{"SO_NKE", Const, 0, ""},
+		{"SO_NOADDRERR", Const, 0, ""},
+		{"SO_NOHEADER", Const, 1, ""},
+		{"SO_NOSIGPIPE", Const, 0, ""},
+		{"SO_NOTIFYCONFLICT", Const, 0, ""},
+		{"SO_NO_CHECK", Const, 0, ""},
+		{"SO_NO_DDP", Const, 0, ""},
+		{"SO_NO_OFFLOAD", Const, 0, ""},
+		{"SO_NP_EXTENSIONS", Const, 0, ""},
+		{"SO_NREAD", Const, 0, ""},
+		{"SO_NUMRCVPKT", Const, 16, ""},
+		{"SO_NWRITE", Const, 0, ""},
+		{"SO_OOBINLINE", Const, 0, ""},
+		{"SO_OVERFLOWED", Const, 1, ""},
+		{"SO_PASSCRED", Const, 0, ""},
+		{"SO_PASSSEC", Const, 0, ""},
+		{"SO_PEERCRED", Const, 0, ""},
+		{"SO_PEERLABEL", Const, 0, ""},
+		{"SO_PEERNAME", Const, 0, ""},
+		{"SO_PEERSEC", Const, 0, ""},
+		{"SO_PRIORITY", Const, 0, ""},
+		{"SO_PROTOCOL", Const, 0, ""},
+		{"SO_PROTOTYPE", Const, 1, ""},
+		{"SO_RANDOMPORT", Const, 0, ""},
+		{"SO_RCVBUF", Const, 0, ""},
+		{"SO_RCVBUFFORCE", Const, 0, ""},
+		{"SO_RCVLOWAT", Const, 0, ""},
+		{"SO_RCVTIMEO", Const, 0, ""},
+		{"SO_RESTRICTIONS", Const, 0, ""},
+		{"SO_RESTRICT_DENYIN", Const, 0, ""},
+		{"SO_RESTRICT_DENYOUT", Const, 0, ""},
+		{"SO_RESTRICT_DENYSET", Const, 0, ""},
+		{"SO_REUSEADDR", Const, 0, ""},
+		{"SO_REUSEPORT", Const, 0, ""},
+		{"SO_REUSESHAREUID", Const, 0, ""},
+		{"SO_RTABLE", Const, 1, ""},
+		{"SO_RXQ_OVFL", Const, 0, ""},
+		{"SO_SECURITY_AUTHENTICATION", Const, 0, ""},
+		{"SO_SECURITY_ENCRYPTION_NETWORK", Const, 0, ""},
+		{"SO_SECURITY_ENCRYPTION_TRANSPORT", Const, 0, ""},
+		{"SO_SETFIB", Const, 0, ""},
+		{"SO_SNDBUF", Const, 0, ""},
+		{"SO_SNDBUFFORCE", Const, 0, ""},
+		{"SO_SNDLOWAT", Const, 0, ""},
+		{"SO_SNDTIMEO", Const, 0, ""},
+		{"SO_SPLICE", Const, 1, ""},
+		{"SO_TIMESTAMP", Const, 0, ""},
+		{"SO_TIMESTAMPING", Const, 0, ""},
+		{"SO_TIMESTAMPNS", Const, 0, ""},
+		{"SO_TIMESTAMP_MONOTONIC", Const, 0, ""},
+		{"SO_TYPE", Const, 0, ""},
+		{"SO_UPCALLCLOSEWAIT", Const, 0, ""},
+		{"SO_UPDATE_ACCEPT_CONTEXT", Const, 0, ""},
+		{"SO_UPDATE_CONNECT_CONTEXT", Const, 1, ""},
+		{"SO_USELOOPBACK", Const, 0, ""},
+		{"SO_USER_COOKIE", Const, 1, ""},
+		{"SO_VENDOR", Const, 3, ""},
+		{"SO_WANTMORE", Const, 0, ""},
+		{"SO_WANTOOBFLAG", Const, 0, ""},
+		{"SSLExtraCertChainPolicyPara", Type, 0, ""},
+		{"SSLExtraCertChainPolicyPara.AuthType", Field, 0, ""},
+		{"SSLExtraCertChainPolicyPara.Checks", Field, 0, ""},
+		{"SSLExtraCertChainPolicyPara.ServerName", Field, 0, ""},
+		{"SSLExtraCertChainPolicyPara.Size", Field, 0, ""},
+		{"STANDARD_RIGHTS_ALL", Const, 0, ""},
+		{"STANDARD_RIGHTS_EXECUTE", Const, 0, ""},
+		{"STANDARD_RIGHTS_READ", Const, 0, ""},
+		{"STANDARD_RIGHTS_REQUIRED", Const, 0, ""},
+		{"STANDARD_RIGHTS_WRITE", Const, 0, ""},
+		{"STARTF_USESHOWWINDOW", Const, 0, ""},
+		{"STARTF_USESTDHANDLES", Const, 0, ""},
+		{"STD_ERROR_HANDLE", Const, 0, ""},
+		{"STD_INPUT_HANDLE", Const, 0, ""},
+		{"STD_OUTPUT_HANDLE", Const, 0, ""},
+		{"SUBLANG_ENGLISH_US", Const, 0, ""},
+		{"SW_FORCEMINIMIZE", Const, 0, ""},
+		{"SW_HIDE", Const, 0, ""},
+		{"SW_MAXIMIZE", Const, 0, ""},
+		{"SW_MINIMIZE", Const, 0, ""},
+		{"SW_NORMAL", Const, 0, ""},
+		{"SW_RESTORE", Const, 0, ""},
+		{"SW_SHOW", Const, 0, ""},
+		{"SW_SHOWDEFAULT", Const, 0, ""},
+		{"SW_SHOWMAXIMIZED", Const, 0, ""},
+		{"SW_SHOWMINIMIZED", Const, 0, ""},
+		{"SW_SHOWMINNOACTIVE", Const, 0, ""},
+		{"SW_SHOWNA", Const, 0, ""},
+		{"SW_SHOWNOACTIVATE", Const, 0, ""},
+		{"SW_SHOWNORMAL", Const, 0, ""},
+		{"SYMBOLIC_LINK_FLAG_DIRECTORY", Const, 4, ""},
+		{"SYNCHRONIZE", Const, 0, ""},
+		{"SYSCTL_VERSION", Const, 1, ""},
+		{"SYSCTL_VERS_0", Const, 1, ""},
+		{"SYSCTL_VERS_1", Const, 1, ""},
+		{"SYSCTL_VERS_MASK", Const, 1, ""},
+		{"SYS_ABORT2", Const, 0, ""},
+		{"SYS_ACCEPT", Const, 0, ""},
+		{"SYS_ACCEPT4", Const, 0, ""},
+		{"SYS_ACCEPT_NOCANCEL", Const, 0, ""},
+		{"SYS_ACCESS", Const, 0, ""},
+		{"SYS_ACCESS_EXTENDED", Const, 0, ""},
+		{"SYS_ACCT", Const, 0, ""},
+		{"SYS_ADD_KEY", Const, 0, ""},
+		{"SYS_ADD_PROFIL", Const, 0, ""},
+		{"SYS_ADJFREQ", Const, 1, ""},
+		{"SYS_ADJTIME", Const, 0, ""},
+		{"SYS_ADJTIMEX", Const, 0, ""},
+		{"SYS_AFS_SYSCALL", Const, 0, ""},
+		{"SYS_AIO_CANCEL", Const, 0, ""},
+		{"SYS_AIO_ERROR", Const, 0, ""},
+		{"SYS_AIO_FSYNC", Const, 0, ""},
+		{"SYS_AIO_MLOCK", Const, 14, ""},
+		{"SYS_AIO_READ", Const, 0, ""},
+		{"SYS_AIO_RETURN", Const, 0, ""},
+		{"SYS_AIO_SUSPEND", Const, 0, ""},
+		{"SYS_AIO_SUSPEND_NOCANCEL", Const, 0, ""},
+		{"SYS_AIO_WAITCOMPLETE", Const, 14, ""},
+		{"SYS_AIO_WRITE", Const, 0, ""},
+		{"SYS_ALARM", Const, 0, ""},
+		{"SYS_ARCH_PRCTL", Const, 0, ""},
+		{"SYS_ARM_FADVISE64_64", Const, 0, ""},
+		{"SYS_ARM_SYNC_FILE_RANGE", Const, 0, ""},
+		{"SYS_ATGETMSG", Const, 0, ""},
+		{"SYS_ATPGETREQ", Const, 0, ""},
+		{"SYS_ATPGETRSP", Const, 0, ""},
+		{"SYS_ATPSNDREQ", Const, 0, ""},
+		{"SYS_ATPSNDRSP", Const, 0, ""},
+		{"SYS_ATPUTMSG", Const, 0, ""},
+		{"SYS_ATSOCKET", Const, 0, ""},
+		{"SYS_AUDIT", Const, 0, ""},
+		{"SYS_AUDITCTL", Const, 0, ""},
+		{"SYS_AUDITON", Const, 0, ""},
+		{"SYS_AUDIT_SESSION_JOIN", Const, 0, ""},
+		{"SYS_AUDIT_SESSION_PORT", Const, 0, ""},
+		{"SYS_AUDIT_SESSION_SELF", Const, 0, ""},
+		{"SYS_BDFLUSH", Const, 0, ""},
+		{"SYS_BIND", Const, 0, ""},
+		{"SYS_BINDAT", Const, 3, ""},
+		{"SYS_BREAK", Const, 0, ""},
+		{"SYS_BRK", Const, 0, ""},
+		{"SYS_BSDTHREAD_CREATE", Const, 0, ""},
+		{"SYS_BSDTHREAD_REGISTER", Const, 0, ""},
+		{"SYS_BSDTHREAD_TERMINATE", Const, 0, ""},
+		{"SYS_CAPGET", Const, 0, ""},
+		{"SYS_CAPSET", Const, 0, ""},
+		{"SYS_CAP_ENTER", Const, 0, ""},
+		{"SYS_CAP_FCNTLS_GET", Const, 1, ""},
+		{"SYS_CAP_FCNTLS_LIMIT", Const, 1, ""},
+		{"SYS_CAP_GETMODE", Const, 0, ""},
+		{"SYS_CAP_GETRIGHTS", Const, 0, ""},
+		{"SYS_CAP_IOCTLS_GET", Const, 1, ""},
+		{"SYS_CAP_IOCTLS_LIMIT", Const, 1, ""},
+		{"SYS_CAP_NEW", Const, 0, ""},
+		{"SYS_CAP_RIGHTS_GET", Const, 1, ""},
+		{"SYS_CAP_RIGHTS_LIMIT", Const, 1, ""},
+		{"SYS_CHDIR", Const, 0, ""},
+		{"SYS_CHFLAGS", Const, 0, ""},
+		{"SYS_CHFLAGSAT", Const, 3, ""},
+		{"SYS_CHMOD", Const, 0, ""},
+		{"SYS_CHMOD_EXTENDED", Const, 0, ""},
+		{"SYS_CHOWN", Const, 0, ""},
+		{"SYS_CHOWN32", Const, 0, ""},
+		{"SYS_CHROOT", Const, 0, ""},
+		{"SYS_CHUD", Const, 0, ""},
+		{"SYS_CLOCK_ADJTIME", Const, 0, ""},
+		{"SYS_CLOCK_GETCPUCLOCKID2", Const, 1, ""},
+		{"SYS_CLOCK_GETRES", Const, 0, ""},
+		{"SYS_CLOCK_GETTIME", Const, 0, ""},
+		{"SYS_CLOCK_NANOSLEEP", Const, 0, ""},
+		{"SYS_CLOCK_SETTIME", Const, 0, ""},
+		{"SYS_CLONE", Const, 0, ""},
+		{"SYS_CLOSE", Const, 0, ""},
+		{"SYS_CLOSEFROM", Const, 0, ""},
+		{"SYS_CLOSE_NOCANCEL", Const, 0, ""},
+		{"SYS_CONNECT", Const, 0, ""},
+		{"SYS_CONNECTAT", Const, 3, ""},
+		{"SYS_CONNECT_NOCANCEL", Const, 0, ""},
+		{"SYS_COPYFILE", Const, 0, ""},
+		{"SYS_CPUSET", Const, 0, ""},
+		{"SYS_CPUSET_GETAFFINITY", Const, 0, ""},
+		{"SYS_CPUSET_GETID", Const, 0, ""},
+		{"SYS_CPUSET_SETAFFINITY", Const, 0, ""},
+		{"SYS_CPUSET_SETID", Const, 0, ""},
+		{"SYS_CREAT", Const, 0, ""},
+		{"SYS_CREATE_MODULE", Const, 0, ""},
+		{"SYS_CSOPS", Const, 0, ""},
+		{"SYS_CSOPS_AUDITTOKEN", Const, 16, ""},
+		{"SYS_DELETE", Const, 0, ""},
+		{"SYS_DELETE_MODULE", Const, 0, ""},
+		{"SYS_DUP", Const, 0, ""},
+		{"SYS_DUP2", Const, 0, ""},
+		{"SYS_DUP3", Const, 0, ""},
+		{"SYS_EACCESS", Const, 0, ""},
+		{"SYS_EPOLL_CREATE", Const, 0, ""},
+		{"SYS_EPOLL_CREATE1", Const, 0, ""},
+		{"SYS_EPOLL_CTL", Const, 0, ""},
+		{"SYS_EPOLL_CTL_OLD", Const, 0, ""},
+		{"SYS_EPOLL_PWAIT", Const, 0, ""},
+		{"SYS_EPOLL_WAIT", Const, 0, ""},
+		{"SYS_EPOLL_WAIT_OLD", Const, 0, ""},
+		{"SYS_EVENTFD", Const, 0, ""},
+		{"SYS_EVENTFD2", Const, 0, ""},
+		{"SYS_EXCHANGEDATA", Const, 0, ""},
+		{"SYS_EXECVE", Const, 0, ""},
+		{"SYS_EXIT", Const, 0, ""},
+		{"SYS_EXIT_GROUP", Const, 0, ""},
+		{"SYS_EXTATTRCTL", Const, 0, ""},
+		{"SYS_EXTATTR_DELETE_FD", Const, 0, ""},
+		{"SYS_EXTATTR_DELETE_FILE", Const, 0, ""},
+		{"SYS_EXTATTR_DELETE_LINK", Const, 0, ""},
+		{"SYS_EXTATTR_GET_FD", Const, 0, ""},
+		{"SYS_EXTATTR_GET_FILE", Const, 0, ""},
+		{"SYS_EXTATTR_GET_LINK", Const, 0, ""},
+		{"SYS_EXTATTR_LIST_FD", Const, 0, ""},
+		{"SYS_EXTATTR_LIST_FILE", Const, 0, ""},
+		{"SYS_EXTATTR_LIST_LINK", Const, 0, ""},
+		{"SYS_EXTATTR_SET_FD", Const, 0, ""},
+		{"SYS_EXTATTR_SET_FILE", Const, 0, ""},
+		{"SYS_EXTATTR_SET_LINK", Const, 0, ""},
+		{"SYS_FACCESSAT", Const, 0, ""},
+		{"SYS_FADVISE64", Const, 0, ""},
+		{"SYS_FADVISE64_64", Const, 0, ""},
+		{"SYS_FALLOCATE", Const, 0, ""},
+		{"SYS_FANOTIFY_INIT", Const, 0, ""},
+		{"SYS_FANOTIFY_MARK", Const, 0, ""},
+		{"SYS_FCHDIR", Const, 0, ""},
+		{"SYS_FCHFLAGS", Const, 0, ""},
+		{"SYS_FCHMOD", Const, 0, ""},
+		{"SYS_FCHMODAT", Const, 0, ""},
+		{"SYS_FCHMOD_EXTENDED", Const, 0, ""},
+		{"SYS_FCHOWN", Const, 0, ""},
+		{"SYS_FCHOWN32", Const, 0, ""},
+		{"SYS_FCHOWNAT", Const, 0, ""},
+		{"SYS_FCHROOT", Const, 1, ""},
+		{"SYS_FCNTL", Const, 0, ""},
+		{"SYS_FCNTL64", Const, 0, ""},
+		{"SYS_FCNTL_NOCANCEL", Const, 0, ""},
+		{"SYS_FDATASYNC", Const, 0, ""},
+		{"SYS_FEXECVE", Const, 0, ""},
+		{"SYS_FFCLOCK_GETCOUNTER", Const, 0, ""},
+		{"SYS_FFCLOCK_GETESTIMATE", Const, 0, ""},
+		{"SYS_FFCLOCK_SETESTIMATE", Const, 0, ""},
+		{"SYS_FFSCTL", Const, 0, ""},
+		{"SYS_FGETATTRLIST", Const, 0, ""},
+		{"SYS_FGETXATTR", Const, 0, ""},
+		{"SYS_FHOPEN", Const, 0, ""},
+		{"SYS_FHSTAT", Const, 0, ""},
+		{"SYS_FHSTATFS", Const, 0, ""},
+		{"SYS_FILEPORT_MAKEFD", Const, 0, ""},
+		{"SYS_FILEPORT_MAKEPORT", Const, 0, ""},
+		{"SYS_FKTRACE", Const, 1, ""},
+		{"SYS_FLISTXATTR", Const, 0, ""},
+		{"SYS_FLOCK", Const, 0, ""},
+		{"SYS_FORK", Const, 0, ""},
+		{"SYS_FPATHCONF", Const, 0, ""},
+		{"SYS_FREEBSD6_FTRUNCATE", Const, 0, ""},
+		{"SYS_FREEBSD6_LSEEK", Const, 0, ""},
+		{"SYS_FREEBSD6_MMAP", Const, 0, ""},
+		{"SYS_FREEBSD6_PREAD", Const, 0, ""},
+		{"SYS_FREEBSD6_PWRITE", Const, 0, ""},
+		{"SYS_FREEBSD6_TRUNCATE", Const, 0, ""},
+		{"SYS_FREMOVEXATTR", Const, 0, ""},
+		{"SYS_FSCTL", Const, 0, ""},
+		{"SYS_FSETATTRLIST", Const, 0, ""},
+		{"SYS_FSETXATTR", Const, 0, ""},
+		{"SYS_FSGETPATH", Const, 0, ""},
+		{"SYS_FSTAT", Const, 0, ""},
+		{"SYS_FSTAT64", Const, 0, ""},
+		{"SYS_FSTAT64_EXTENDED", Const, 0, ""},
+		{"SYS_FSTATAT", Const, 0, ""},
+		{"SYS_FSTATAT64", Const, 0, ""},
+		{"SYS_FSTATFS", Const, 0, ""},
+		{"SYS_FSTATFS64", Const, 0, ""},
+		{"SYS_FSTATV", Const, 0, ""},
+		{"SYS_FSTATVFS1", Const, 1, ""},
+		{"SYS_FSTAT_EXTENDED", Const, 0, ""},
+		{"SYS_FSYNC", Const, 0, ""},
+		{"SYS_FSYNC_NOCANCEL", Const, 0, ""},
+		{"SYS_FSYNC_RANGE", Const, 1, ""},
+		{"SYS_FTIME", Const, 0, ""},
+		{"SYS_FTRUNCATE", Const, 0, ""},
+		{"SYS_FTRUNCATE64", Const, 0, ""},
+		{"SYS_FUTEX", Const, 0, ""},
+		{"SYS_FUTIMENS", Const, 1, ""},
+		{"SYS_FUTIMES", Const, 0, ""},
+		{"SYS_FUTIMESAT", Const, 0, ""},
+		{"SYS_GETATTRLIST", Const, 0, ""},
+		{"SYS_GETAUDIT", Const, 0, ""},
+		{"SYS_GETAUDIT_ADDR", Const, 0, ""},
+		{"SYS_GETAUID", Const, 0, ""},
+		{"SYS_GETCONTEXT", Const, 0, ""},
+		{"SYS_GETCPU", Const, 0, ""},
+		{"SYS_GETCWD", Const, 0, ""},
+		{"SYS_GETDENTS", Const, 0, ""},
+		{"SYS_GETDENTS64", Const, 0, ""},
+		{"SYS_GETDIRENTRIES", Const, 0, ""},
+		{"SYS_GETDIRENTRIES64", Const, 0, ""},
+		{"SYS_GETDIRENTRIESATTR", Const, 0, ""},
+		{"SYS_GETDTABLECOUNT", Const, 1, ""},
+		{"SYS_GETDTABLESIZE", Const, 0, ""},
+		{"SYS_GETEGID", Const, 0, ""},
+		{"SYS_GETEGID32", Const, 0, ""},
+		{"SYS_GETEUID", Const, 0, ""},
+		{"SYS_GETEUID32", Const, 0, ""},
+		{"SYS_GETFH", Const, 0, ""},
+		{"SYS_GETFSSTAT", Const, 0, ""},
+		{"SYS_GETFSSTAT64", Const, 0, ""},
+		{"SYS_GETGID", Const, 0, ""},
+		{"SYS_GETGID32", Const, 0, ""},
+		{"SYS_GETGROUPS", Const, 0, ""},
+		{"SYS_GETGROUPS32", Const, 0, ""},
+		{"SYS_GETHOSTUUID", Const, 0, ""},
+		{"SYS_GETITIMER", Const, 0, ""},
+		{"SYS_GETLCID", Const, 0, ""},
+		{"SYS_GETLOGIN", Const, 0, ""},
+		{"SYS_GETLOGINCLASS", Const, 0, ""},
+		{"SYS_GETPEERNAME", Const, 0, ""},
+		{"SYS_GETPGID", Const, 0, ""},
+		{"SYS_GETPGRP", Const, 0, ""},
+		{"SYS_GETPID", Const, 0, ""},
+		{"SYS_GETPMSG", Const, 0, ""},
+		{"SYS_GETPPID", Const, 0, ""},
+		{"SYS_GETPRIORITY", Const, 0, ""},
+		{"SYS_GETRESGID", Const, 0, ""},
+		{"SYS_GETRESGID32", Const, 0, ""},
+		{"SYS_GETRESUID", Const, 0, ""},
+		{"SYS_GETRESUID32", Const, 0, ""},
+		{"SYS_GETRLIMIT", Const, 0, ""},
+		{"SYS_GETRTABLE", Const, 1, ""},
+		{"SYS_GETRUSAGE", Const, 0, ""},
+		{"SYS_GETSGROUPS", Const, 0, ""},
+		{"SYS_GETSID", Const, 0, ""},
+		{"SYS_GETSOCKNAME", Const, 0, ""},
+		{"SYS_GETSOCKOPT", Const, 0, ""},
+		{"SYS_GETTHRID", Const, 1, ""},
+		{"SYS_GETTID", Const, 0, ""},
+		{"SYS_GETTIMEOFDAY", Const, 0, ""},
+		{"SYS_GETUID", Const, 0, ""},
+		{"SYS_GETUID32", Const, 0, ""},
+		{"SYS_GETVFSSTAT", Const, 1, ""},
+		{"SYS_GETWGROUPS", Const, 0, ""},
+		{"SYS_GETXATTR", Const, 0, ""},
+		{"SYS_GET_KERNEL_SYMS", Const, 0, ""},
+		{"SYS_GET_MEMPOLICY", Const, 0, ""},
+		{"SYS_GET_ROBUST_LIST", Const, 0, ""},
+		{"SYS_GET_THREAD_AREA", Const, 0, ""},
+		{"SYS_GSSD_SYSCALL", Const, 14, ""},
+		{"SYS_GTTY", Const, 0, ""},
+		{"SYS_IDENTITYSVC", Const, 0, ""},
+		{"SYS_IDLE", Const, 0, ""},
+		{"SYS_INITGROUPS", Const, 0, ""},
+		{"SYS_INIT_MODULE", Const, 0, ""},
+		{"SYS_INOTIFY_ADD_WATCH", Const, 0, ""},
+		{"SYS_INOTIFY_INIT", Const, 0, ""},
+		{"SYS_INOTIFY_INIT1", Const, 0, ""},
+		{"SYS_INOTIFY_RM_WATCH", Const, 0, ""},
+		{"SYS_IOCTL", Const, 0, ""},
+		{"SYS_IOPERM", Const, 0, ""},
+		{"SYS_IOPL", Const, 0, ""},
+		{"SYS_IOPOLICYSYS", Const, 0, ""},
+		{"SYS_IOPRIO_GET", Const, 0, ""},
+		{"SYS_IOPRIO_SET", Const, 0, ""},
+		{"SYS_IO_CANCEL", Const, 0, ""},
+		{"SYS_IO_DESTROY", Const, 0, ""},
+		{"SYS_IO_GETEVENTS", Const, 0, ""},
+		{"SYS_IO_SETUP", Const, 0, ""},
+		{"SYS_IO_SUBMIT", Const, 0, ""},
+		{"SYS_IPC", Const, 0, ""},
+		{"SYS_ISSETUGID", Const, 0, ""},
+		{"SYS_JAIL", Const, 0, ""},
+		{"SYS_JAIL_ATTACH", Const, 0, ""},
+		{"SYS_JAIL_GET", Const, 0, ""},
+		{"SYS_JAIL_REMOVE", Const, 0, ""},
+		{"SYS_JAIL_SET", Const, 0, ""},
+		{"SYS_KAS_INFO", Const, 16, ""},
+		{"SYS_KDEBUG_TRACE", Const, 0, ""},
+		{"SYS_KENV", Const, 0, ""},
+		{"SYS_KEVENT", Const, 0, ""},
+		{"SYS_KEVENT64", Const, 0, ""},
+		{"SYS_KEXEC_LOAD", Const, 0, ""},
+		{"SYS_KEYCTL", Const, 0, ""},
+		{"SYS_KILL", Const, 0, ""},
+		{"SYS_KLDFIND", Const, 0, ""},
+		{"SYS_KLDFIRSTMOD", Const, 0, ""},
+		{"SYS_KLDLOAD", Const, 0, ""},
+		{"SYS_KLDNEXT", Const, 0, ""},
+		{"SYS_KLDSTAT", Const, 0, ""},
+		{"SYS_KLDSYM", Const, 0, ""},
+		{"SYS_KLDUNLOAD", Const, 0, ""},
+		{"SYS_KLDUNLOADF", Const, 0, ""},
+		{"SYS_KMQ_NOTIFY", Const, 14, ""},
+		{"SYS_KMQ_OPEN", Const, 14, ""},
+		{"SYS_KMQ_SETATTR", Const, 14, ""},
+		{"SYS_KMQ_TIMEDRECEIVE", Const, 14, ""},
+		{"SYS_KMQ_TIMEDSEND", Const, 14, ""},
+		{"SYS_KMQ_UNLINK", Const, 14, ""},
+		{"SYS_KQUEUE", Const, 0, ""},
+		{"SYS_KQUEUE1", Const, 1, ""},
+		{"SYS_KSEM_CLOSE", Const, 14, ""},
+		{"SYS_KSEM_DESTROY", Const, 14, ""},
+		{"SYS_KSEM_GETVALUE", Const, 14, ""},
+		{"SYS_KSEM_INIT", Const, 14, ""},
+		{"SYS_KSEM_OPEN", Const, 14, ""},
+		{"SYS_KSEM_POST", Const, 14, ""},
+		{"SYS_KSEM_TIMEDWAIT", Const, 14, ""},
+		{"SYS_KSEM_TRYWAIT", Const, 14, ""},
+		{"SYS_KSEM_UNLINK", Const, 14, ""},
+		{"SYS_KSEM_WAIT", Const, 14, ""},
+		{"SYS_KTIMER_CREATE", Const, 0, ""},
+		{"SYS_KTIMER_DELETE", Const, 0, ""},
+		{"SYS_KTIMER_GETOVERRUN", Const, 0, ""},
+		{"SYS_KTIMER_GETTIME", Const, 0, ""},
+		{"SYS_KTIMER_SETTIME", Const, 0, ""},
+		{"SYS_KTRACE", Const, 0, ""},
+		{"SYS_LCHFLAGS", Const, 0, ""},
+		{"SYS_LCHMOD", Const, 0, ""},
+		{"SYS_LCHOWN", Const, 0, ""},
+		{"SYS_LCHOWN32", Const, 0, ""},
+		{"SYS_LEDGER", Const, 16, ""},
+		{"SYS_LGETFH", Const, 0, ""},
+		{"SYS_LGETXATTR", Const, 0, ""},
+		{"SYS_LINK", Const, 0, ""},
+		{"SYS_LINKAT", Const, 0, ""},
+		{"SYS_LIO_LISTIO", Const, 0, ""},
+		{"SYS_LISTEN", Const, 0, ""},
+		{"SYS_LISTXATTR", Const, 0, ""},
+		{"SYS_LLISTXATTR", Const, 0, ""},
+		{"SYS_LOCK", Const, 0, ""},
+		{"SYS_LOOKUP_DCOOKIE", Const, 0, ""},
+		{"SYS_LPATHCONF", Const, 0, ""},
+		{"SYS_LREMOVEXATTR", Const, 0, ""},
+		{"SYS_LSEEK", Const, 0, ""},
+		{"SYS_LSETXATTR", Const, 0, ""},
+		{"SYS_LSTAT", Const, 0, ""},
+		{"SYS_LSTAT64", Const, 0, ""},
+		{"SYS_LSTAT64_EXTENDED", Const, 0, ""},
+		{"SYS_LSTATV", Const, 0, ""},
+		{"SYS_LSTAT_EXTENDED", Const, 0, ""},
+		{"SYS_LUTIMES", Const, 0, ""},
+		{"SYS_MAC_SYSCALL", Const, 0, ""},
+		{"SYS_MADVISE", Const, 0, ""},
+		{"SYS_MADVISE1", Const, 0, ""},
+		{"SYS_MAXSYSCALL", Const, 0, ""},
+		{"SYS_MBIND", Const, 0, ""},
+		{"SYS_MIGRATE_PAGES", Const, 0, ""},
+		{"SYS_MINCORE", Const, 0, ""},
+		{"SYS_MINHERIT", Const, 0, ""},
+		{"SYS_MKCOMPLEX", Const, 0, ""},
+		{"SYS_MKDIR", Const, 0, ""},
+		{"SYS_MKDIRAT", Const, 0, ""},
+		{"SYS_MKDIR_EXTENDED", Const, 0, ""},
+		{"SYS_MKFIFO", Const, 0, ""},
+		{"SYS_MKFIFOAT", Const, 0, ""},
+		{"SYS_MKFIFO_EXTENDED", Const, 0, ""},
+		{"SYS_MKNOD", Const, 0, ""},
+		{"SYS_MKNODAT", Const, 0, ""},
+		{"SYS_MLOCK", Const, 0, ""},
+		{"SYS_MLOCKALL", Const, 0, ""},
+		{"SYS_MMAP", Const, 0, ""},
+		{"SYS_MMAP2", Const, 0, ""},
+		{"SYS_MODCTL", Const, 1, ""},
+		{"SYS_MODFIND", Const, 0, ""},
+		{"SYS_MODFNEXT", Const, 0, ""},
+		{"SYS_MODIFY_LDT", Const, 0, ""},
+		{"SYS_MODNEXT", Const, 0, ""},
+		{"SYS_MODSTAT", Const, 0, ""},
+		{"SYS_MODWATCH", Const, 0, ""},
+		{"SYS_MOUNT", Const, 0, ""},
+		{"SYS_MOVE_PAGES", Const, 0, ""},
+		{"SYS_MPROTECT", Const, 0, ""},
+		{"SYS_MPX", Const, 0, ""},
+		{"SYS_MQUERY", Const, 1, ""},
+		{"SYS_MQ_GETSETATTR", Const, 0, ""},
+		{"SYS_MQ_NOTIFY", Const, 0, ""},
+		{"SYS_MQ_OPEN", Const, 0, ""},
+		{"SYS_MQ_TIMEDRECEIVE", Const, 0, ""},
+		{"SYS_MQ_TIMEDSEND", Const, 0, ""},
+		{"SYS_MQ_UNLINK", Const, 0, ""},
+		{"SYS_MREMAP", Const, 0, ""},
+		{"SYS_MSGCTL", Const, 0, ""},
+		{"SYS_MSGGET", Const, 0, ""},
+		{"SYS_MSGRCV", Const, 0, ""},
+		{"SYS_MSGRCV_NOCANCEL", Const, 0, ""},
+		{"SYS_MSGSND", Const, 0, ""},
+		{"SYS_MSGSND_NOCANCEL", Const, 0, ""},
+		{"SYS_MSGSYS", Const, 0, ""},
+		{"SYS_MSYNC", Const, 0, ""},
+		{"SYS_MSYNC_NOCANCEL", Const, 0, ""},
+		{"SYS_MUNLOCK", Const, 0, ""},
+		{"SYS_MUNLOCKALL", Const, 0, ""},
+		{"SYS_MUNMAP", Const, 0, ""},
+		{"SYS_NAME_TO_HANDLE_AT", Const, 0, ""},
+		{"SYS_NANOSLEEP", Const, 0, ""},
+		{"SYS_NEWFSTATAT", Const, 0, ""},
+		{"SYS_NFSCLNT", Const, 0, ""},
+		{"SYS_NFSSERVCTL", Const, 0, ""},
+		{"SYS_NFSSVC", Const, 0, ""},
+		{"SYS_NFSTAT", Const, 0, ""},
+		{"SYS_NICE", Const, 0, ""},
+		{"SYS_NLM_SYSCALL", Const, 14, ""},
+		{"SYS_NLSTAT", Const, 0, ""},
+		{"SYS_NMOUNT", Const, 0, ""},
+		{"SYS_NSTAT", Const, 0, ""},
+		{"SYS_NTP_ADJTIME", Const, 0, ""},
+		{"SYS_NTP_GETTIME", Const, 0, ""},
+		{"SYS_NUMA_GETAFFINITY", Const, 14, ""},
+		{"SYS_NUMA_SETAFFINITY", Const, 14, ""},
+		{"SYS_OABI_SYSCALL_BASE", Const, 0, ""},
+		{"SYS_OBREAK", Const, 0, ""},
+		{"SYS_OLDFSTAT", Const, 0, ""},
+		{"SYS_OLDLSTAT", Const, 0, ""},
+		{"SYS_OLDOLDUNAME", Const, 0, ""},
+		{"SYS_OLDSTAT", Const, 0, ""},
+		{"SYS_OLDUNAME", Const, 0, ""},
+		{"SYS_OPEN", Const, 0, ""},
+		{"SYS_OPENAT", Const, 0, ""},
+		{"SYS_OPENBSD_POLL", Const, 0, ""},
+		{"SYS_OPEN_BY_HANDLE_AT", Const, 0, ""},
+		{"SYS_OPEN_DPROTECTED_NP", Const, 16, ""},
+		{"SYS_OPEN_EXTENDED", Const, 0, ""},
+		{"SYS_OPEN_NOCANCEL", Const, 0, ""},
+		{"SYS_OVADVISE", Const, 0, ""},
+		{"SYS_PACCEPT", Const, 1, ""},
+		{"SYS_PATHCONF", Const, 0, ""},
+		{"SYS_PAUSE", Const, 0, ""},
+		{"SYS_PCICONFIG_IOBASE", Const, 0, ""},
+		{"SYS_PCICONFIG_READ", Const, 0, ""},
+		{"SYS_PCICONFIG_WRITE", Const, 0, ""},
+		{"SYS_PDFORK", Const, 0, ""},
+		{"SYS_PDGETPID", Const, 0, ""},
+		{"SYS_PDKILL", Const, 0, ""},
+		{"SYS_PERF_EVENT_OPEN", Const, 0, ""},
+		{"SYS_PERSONALITY", Const, 0, ""},
+		{"SYS_PID_HIBERNATE", Const, 0, ""},
+		{"SYS_PID_RESUME", Const, 0, ""},
+		{"SYS_PID_SHUTDOWN_SOCKETS", Const, 0, ""},
+		{"SYS_PID_SUSPEND", Const, 0, ""},
+		{"SYS_PIPE", Const, 0, ""},
+		{"SYS_PIPE2", Const, 0, ""},
+		{"SYS_PIVOT_ROOT", Const, 0, ""},
+		{"SYS_PMC_CONTROL", Const, 1, ""},
+		{"SYS_PMC_GET_INFO", Const, 1, ""},
+		{"SYS_POLL", Const, 0, ""},
+		{"SYS_POLLTS", Const, 1, ""},
+		{"SYS_POLL_NOCANCEL", Const, 0, ""},
+		{"SYS_POSIX_FADVISE", Const, 0, ""},
+		{"SYS_POSIX_FALLOCATE", Const, 0, ""},
+		{"SYS_POSIX_OPENPT", Const, 0, ""},
+		{"SYS_POSIX_SPAWN", Const, 0, ""},
+		{"SYS_PPOLL", Const, 0, ""},
+		{"SYS_PRCTL", Const, 0, ""},
+		{"SYS_PREAD", Const, 0, ""},
+		{"SYS_PREAD64", Const, 0, ""},
+		{"SYS_PREADV", Const, 0, ""},
+		{"SYS_PREAD_NOCANCEL", Const, 0, ""},
+		{"SYS_PRLIMIT64", Const, 0, ""},
+		{"SYS_PROCCTL", Const, 3, ""},
+		{"SYS_PROCESS_POLICY", Const, 0, ""},
+		{"SYS_PROCESS_VM_READV", Const, 0, ""},
+		{"SYS_PROCESS_VM_WRITEV", Const, 0, ""},
+		{"SYS_PROC_INFO", Const, 0, ""},
+		{"SYS_PROF", Const, 0, ""},
+		{"SYS_PROFIL", Const, 0, ""},
+		{"SYS_PSELECT", Const, 0, ""},
+		{"SYS_PSELECT6", Const, 0, ""},
+		{"SYS_PSET_ASSIGN", Const, 1, ""},
+		{"SYS_PSET_CREATE", Const, 1, ""},
+		{"SYS_PSET_DESTROY", Const, 1, ""},
+		{"SYS_PSYNCH_CVBROAD", Const, 0, ""},
+		{"SYS_PSYNCH_CVCLRPREPOST", Const, 0, ""},
+		{"SYS_PSYNCH_CVSIGNAL", Const, 0, ""},
+		{"SYS_PSYNCH_CVWAIT", Const, 0, ""},
+		{"SYS_PSYNCH_MUTEXDROP", Const, 0, ""},
+		{"SYS_PSYNCH_MUTEXWAIT", Const, 0, ""},
+		{"SYS_PSYNCH_RW_DOWNGRADE", Const, 0, ""},
+		{"SYS_PSYNCH_RW_LONGRDLOCK", Const, 0, ""},
+		{"SYS_PSYNCH_RW_RDLOCK", Const, 0, ""},
+		{"SYS_PSYNCH_RW_UNLOCK", Const, 0, ""},
+		{"SYS_PSYNCH_RW_UNLOCK2", Const, 0, ""},
+		{"SYS_PSYNCH_RW_UPGRADE", Const, 0, ""},
+		{"SYS_PSYNCH_RW_WRLOCK", Const, 0, ""},
+		{"SYS_PSYNCH_RW_YIELDWRLOCK", Const, 0, ""},
+		{"SYS_PTRACE", Const, 0, ""},
+		{"SYS_PUTPMSG", Const, 0, ""},
+		{"SYS_PWRITE", Const, 0, ""},
+		{"SYS_PWRITE64", Const, 0, ""},
+		{"SYS_PWRITEV", Const, 0, ""},
+		{"SYS_PWRITE_NOCANCEL", Const, 0, ""},
+		{"SYS_QUERY_MODULE", Const, 0, ""},
+		{"SYS_QUOTACTL", Const, 0, ""},
+		{"SYS_RASCTL", Const, 1, ""},
+		{"SYS_RCTL_ADD_RULE", Const, 0, ""},
+		{"SYS_RCTL_GET_LIMITS", Const, 0, ""},
+		{"SYS_RCTL_GET_RACCT", Const, 0, ""},
+		{"SYS_RCTL_GET_RULES", Const, 0, ""},
+		{"SYS_RCTL_REMOVE_RULE", Const, 0, ""},
+		{"SYS_READ", Const, 0, ""},
+		{"SYS_READAHEAD", Const, 0, ""},
+		{"SYS_READDIR", Const, 0, ""},
+		{"SYS_READLINK", Const, 0, ""},
+		{"SYS_READLINKAT", Const, 0, ""},
+		{"SYS_READV", Const, 0, ""},
+		{"SYS_READV_NOCANCEL", Const, 0, ""},
+		{"SYS_READ_NOCANCEL", Const, 0, ""},
+		{"SYS_REBOOT", Const, 0, ""},
+		{"SYS_RECV", Const, 0, ""},
+		{"SYS_RECVFROM", Const, 0, ""},
+		{"SYS_RECVFROM_NOCANCEL", Const, 0, ""},
+		{"SYS_RECVMMSG", Const, 0, ""},
+		{"SYS_RECVMSG", Const, 0, ""},
+		{"SYS_RECVMSG_NOCANCEL", Const, 0, ""},
+		{"SYS_REMAP_FILE_PAGES", Const, 0, ""},
+		{"SYS_REMOVEXATTR", Const, 0, ""},
+		{"SYS_RENAME", Const, 0, ""},
+		{"SYS_RENAMEAT", Const, 0, ""},
+		{"SYS_REQUEST_KEY", Const, 0, ""},
+		{"SYS_RESTART_SYSCALL", Const, 0, ""},
+		{"SYS_REVOKE", Const, 0, ""},
+		{"SYS_RFORK", Const, 0, ""},
+		{"SYS_RMDIR", Const, 0, ""},
+		{"SYS_RTPRIO", Const, 0, ""},
+		{"SYS_RTPRIO_THREAD", Const, 0, ""},
+		{"SYS_RT_SIGACTION", Const, 0, ""},
+		{"SYS_RT_SIGPENDING", Const, 0, ""},
+		{"SYS_RT_SIGPROCMASK", Const, 0, ""},
+		{"SYS_RT_SIGQUEUEINFO", Const, 0, ""},
+		{"SYS_RT_SIGRETURN", Const, 0, ""},
+		{"SYS_RT_SIGSUSPEND", Const, 0, ""},
+		{"SYS_RT_SIGTIMEDWAIT", Const, 0, ""},
+		{"SYS_RT_TGSIGQUEUEINFO", Const, 0, ""},
+		{"SYS_SBRK", Const, 0, ""},
+		{"SYS_SCHED_GETAFFINITY", Const, 0, ""},
+		{"SYS_SCHED_GETPARAM", Const, 0, ""},
+		{"SYS_SCHED_GETSCHEDULER", Const, 0, ""},
+		{"SYS_SCHED_GET_PRIORITY_MAX", Const, 0, ""},
+		{"SYS_SCHED_GET_PRIORITY_MIN", Const, 0, ""},
+		{"SYS_SCHED_RR_GET_INTERVAL", Const, 0, ""},
+		{"SYS_SCHED_SETAFFINITY", Const, 0, ""},
+		{"SYS_SCHED_SETPARAM", Const, 0, ""},
+		{"SYS_SCHED_SETSCHEDULER", Const, 0, ""},
+		{"SYS_SCHED_YIELD", Const, 0, ""},
+		{"SYS_SCTP_GENERIC_RECVMSG", Const, 0, ""},
+		{"SYS_SCTP_GENERIC_SENDMSG", Const, 0, ""},
+		{"SYS_SCTP_GENERIC_SENDMSG_IOV", Const, 0, ""},
+		{"SYS_SCTP_PEELOFF", Const, 0, ""},
+		{"SYS_SEARCHFS", Const, 0, ""},
+		{"SYS_SECURITY", Const, 0, ""},
+		{"SYS_SELECT", Const, 0, ""},
+		{"SYS_SELECT_NOCANCEL", Const, 0, ""},
+		{"SYS_SEMCONFIG", Const, 1, ""},
+		{"SYS_SEMCTL", Const, 0, ""},
+		{"SYS_SEMGET", Const, 0, ""},
+		{"SYS_SEMOP", Const, 0, ""},
+		{"SYS_SEMSYS", Const, 0, ""},
+		{"SYS_SEMTIMEDOP", Const, 0, ""},
+		{"SYS_SEM_CLOSE", Const, 0, ""},
+		{"SYS_SEM_DESTROY", Const, 0, ""},
+		{"SYS_SEM_GETVALUE", Const, 0, ""},
+		{"SYS_SEM_INIT", Const, 0, ""},
+		{"SYS_SEM_OPEN", Const, 0, ""},
+		{"SYS_SEM_POST", Const, 0, ""},
+		{"SYS_SEM_TRYWAIT", Const, 0, ""},
+		{"SYS_SEM_UNLINK", Const, 0, ""},
+		{"SYS_SEM_WAIT", Const, 0, ""},
+		{"SYS_SEM_WAIT_NOCANCEL", Const, 0, ""},
+		{"SYS_SEND", Const, 0, ""},
+		{"SYS_SENDFILE", Const, 0, ""},
+		{"SYS_SENDFILE64", Const, 0, ""},
+		{"SYS_SENDMMSG", Const, 0, ""},
+		{"SYS_SENDMSG", Const, 0, ""},
+		{"SYS_SENDMSG_NOCANCEL", Const, 0, ""},
+		{"SYS_SENDTO", Const, 0, ""},
+		{"SYS_SENDTO_NOCANCEL", Const, 0, ""},
+		{"SYS_SETATTRLIST", Const, 0, ""},
+		{"SYS_SETAUDIT", Const, 0, ""},
+		{"SYS_SETAUDIT_ADDR", Const, 0, ""},
+		{"SYS_SETAUID", Const, 0, ""},
+		{"SYS_SETCONTEXT", Const, 0, ""},
+		{"SYS_SETDOMAINNAME", Const, 0, ""},
+		{"SYS_SETEGID", Const, 0, ""},
+		{"SYS_SETEUID", Const, 0, ""},
+		{"SYS_SETFIB", Const, 0, ""},
+		{"SYS_SETFSGID", Const, 0, ""},
+		{"SYS_SETFSGID32", Const, 0, ""},
+		{"SYS_SETFSUID", Const, 0, ""},
+		{"SYS_SETFSUID32", Const, 0, ""},
+		{"SYS_SETGID", Const, 0, ""},
+		{"SYS_SETGID32", Const, 0, ""},
+		{"SYS_SETGROUPS", Const, 0, ""},
+		{"SYS_SETGROUPS32", Const, 0, ""},
+		{"SYS_SETHOSTNAME", Const, 0, ""},
+		{"SYS_SETITIMER", Const, 0, ""},
+		{"SYS_SETLCID", Const, 0, ""},
+		{"SYS_SETLOGIN", Const, 0, ""},
+		{"SYS_SETLOGINCLASS", Const, 0, ""},
+		{"SYS_SETNS", Const, 0, ""},
+		{"SYS_SETPGID", Const, 0, ""},
+		{"SYS_SETPRIORITY", Const, 0, ""},
+		{"SYS_SETPRIVEXEC", Const, 0, ""},
+		{"SYS_SETREGID", Const, 0, ""},
+		{"SYS_SETREGID32", Const, 0, ""},
+		{"SYS_SETRESGID", Const, 0, ""},
+		{"SYS_SETRESGID32", Const, 0, ""},
+		{"SYS_SETRESUID", Const, 0, ""},
+		{"SYS_SETRESUID32", Const, 0, ""},
+		{"SYS_SETREUID", Const, 0, ""},
+		{"SYS_SETREUID32", Const, 0, ""},
+		{"SYS_SETRLIMIT", Const, 0, ""},
+		{"SYS_SETRTABLE", Const, 1, ""},
+		{"SYS_SETSGROUPS", Const, 0, ""},
+		{"SYS_SETSID", Const, 0, ""},
+		{"SYS_SETSOCKOPT", Const, 0, ""},
+		{"SYS_SETTID", Const, 0, ""},
+		{"SYS_SETTID_WITH_PID", Const, 0, ""},
+		{"SYS_SETTIMEOFDAY", Const, 0, ""},
+		{"SYS_SETUID", Const, 0, ""},
+		{"SYS_SETUID32", Const, 0, ""},
+		{"SYS_SETWGROUPS", Const, 0, ""},
+		{"SYS_SETXATTR", Const, 0, ""},
+		{"SYS_SET_MEMPOLICY", Const, 0, ""},
+		{"SYS_SET_ROBUST_LIST", Const, 0, ""},
+		{"SYS_SET_THREAD_AREA", Const, 0, ""},
+		{"SYS_SET_TID_ADDRESS", Const, 0, ""},
+		{"SYS_SGETMASK", Const, 0, ""},
+		{"SYS_SHARED_REGION_CHECK_NP", Const, 0, ""},
+		{"SYS_SHARED_REGION_MAP_AND_SLIDE_NP", Const, 0, ""},
+		{"SYS_SHMAT", Const, 0, ""},
+		{"SYS_SHMCTL", Const, 0, ""},
+		{"SYS_SHMDT", Const, 0, ""},
+		{"SYS_SHMGET", Const, 0, ""},
+		{"SYS_SHMSYS", Const, 0, ""},
+		{"SYS_SHM_OPEN", Const, 0, ""},
+		{"SYS_SHM_UNLINK", Const, 0, ""},
+		{"SYS_SHUTDOWN", Const, 0, ""},
+		{"SYS_SIGACTION", Const, 0, ""},
+		{"SYS_SIGALTSTACK", Const, 0, ""},
+		{"SYS_SIGNAL", Const, 0, ""},
+		{"SYS_SIGNALFD", Const, 0, ""},
+		{"SYS_SIGNALFD4", Const, 0, ""},
+		{"SYS_SIGPENDING", Const, 0, ""},
+		{"SYS_SIGPROCMASK", Const, 0, ""},
+		{"SYS_SIGQUEUE", Const, 0, ""},
+		{"SYS_SIGQUEUEINFO", Const, 1, ""},
+		{"SYS_SIGRETURN", Const, 0, ""},
+		{"SYS_SIGSUSPEND", Const, 0, ""},
+		{"SYS_SIGSUSPEND_NOCANCEL", Const, 0, ""},
+		{"SYS_SIGTIMEDWAIT", Const, 0, ""},
+		{"SYS_SIGWAIT", Const, 0, ""},
+		{"SYS_SIGWAITINFO", Const, 0, ""},
+		{"SYS_SOCKET", Const, 0, ""},
+		{"SYS_SOCKETCALL", Const, 0, ""},
+		{"SYS_SOCKETPAIR", Const, 0, ""},
+		{"SYS_SPLICE", Const, 0, ""},
+		{"SYS_SSETMASK", Const, 0, ""},
+		{"SYS_SSTK", Const, 0, ""},
+		{"SYS_STACK_SNAPSHOT", Const, 0, ""},
+		{"SYS_STAT", Const, 0, ""},
+		{"SYS_STAT64", Const, 0, ""},
+		{"SYS_STAT64_EXTENDED", Const, 0, ""},
+		{"SYS_STATFS", Const, 0, ""},
+		{"SYS_STATFS64", Const, 0, ""},
+		{"SYS_STATV", Const, 0, ""},
+		{"SYS_STATVFS1", Const, 1, ""},
+		{"SYS_STAT_EXTENDED", Const, 0, ""},
+		{"SYS_STIME", Const, 0, ""},
+		{"SYS_STTY", Const, 0, ""},
+		{"SYS_SWAPCONTEXT", Const, 0, ""},
+		{"SYS_SWAPCTL", Const, 1, ""},
+		{"SYS_SWAPOFF", Const, 0, ""},
+		{"SYS_SWAPON", Const, 0, ""},
+		{"SYS_SYMLINK", Const, 0, ""},
+		{"SYS_SYMLINKAT", Const, 0, ""},
+		{"SYS_SYNC", Const, 0, ""},
+		{"SYS_SYNCFS", Const, 0, ""},
+		{"SYS_SYNC_FILE_RANGE", Const, 0, ""},
+		{"SYS_SYSARCH", Const, 0, ""},
+		{"SYS_SYSCALL", Const, 0, ""},
+		{"SYS_SYSCALL_BASE", Const, 0, ""},
+		{"SYS_SYSFS", Const, 0, ""},
+		{"SYS_SYSINFO", Const, 0, ""},
+		{"SYS_SYSLOG", Const, 0, ""},
+		{"SYS_TEE", Const, 0, ""},
+		{"SYS_TGKILL", Const, 0, ""},
+		{"SYS_THREAD_SELFID", Const, 0, ""},
+		{"SYS_THR_CREATE", Const, 0, ""},
+		{"SYS_THR_EXIT", Const, 0, ""},
+		{"SYS_THR_KILL", Const, 0, ""},
+		{"SYS_THR_KILL2", Const, 0, ""},
+		{"SYS_THR_NEW", Const, 0, ""},
+		{"SYS_THR_SELF", Const, 0, ""},
+		{"SYS_THR_SET_NAME", Const, 0, ""},
+		{"SYS_THR_SUSPEND", Const, 0, ""},
+		{"SYS_THR_WAKE", Const, 0, ""},
+		{"SYS_TIME", Const, 0, ""},
+		{"SYS_TIMERFD_CREATE", Const, 0, ""},
+		{"SYS_TIMERFD_GETTIME", Const, 0, ""},
+		{"SYS_TIMERFD_SETTIME", Const, 0, ""},
+		{"SYS_TIMER_CREATE", Const, 0, ""},
+		{"SYS_TIMER_DELETE", Const, 0, ""},
+		{"SYS_TIMER_GETOVERRUN", Const, 0, ""},
+		{"SYS_TIMER_GETTIME", Const, 0, ""},
+		{"SYS_TIMER_SETTIME", Const, 0, ""},
+		{"SYS_TIMES", Const, 0, ""},
+		{"SYS_TKILL", Const, 0, ""},
+		{"SYS_TRUNCATE", Const, 0, ""},
+		{"SYS_TRUNCATE64", Const, 0, ""},
+		{"SYS_TUXCALL", Const, 0, ""},
+		{"SYS_UGETRLIMIT", Const, 0, ""},
+		{"SYS_ULIMIT", Const, 0, ""},
+		{"SYS_UMASK", Const, 0, ""},
+		{"SYS_UMASK_EXTENDED", Const, 0, ""},
+		{"SYS_UMOUNT", Const, 0, ""},
+		{"SYS_UMOUNT2", Const, 0, ""},
+		{"SYS_UNAME", Const, 0, ""},
+		{"SYS_UNDELETE", Const, 0, ""},
+		{"SYS_UNLINK", Const, 0, ""},
+		{"SYS_UNLINKAT", Const, 0, ""},
+		{"SYS_UNMOUNT", Const, 0, ""},
+		{"SYS_UNSHARE", Const, 0, ""},
+		{"SYS_USELIB", Const, 0, ""},
+		{"SYS_USTAT", Const, 0, ""},
+		{"SYS_UTIME", Const, 0, ""},
+		{"SYS_UTIMENSAT", Const, 0, ""},
+		{"SYS_UTIMES", Const, 0, ""},
+		{"SYS_UTRACE", Const, 0, ""},
+		{"SYS_UUIDGEN", Const, 0, ""},
+		{"SYS_VADVISE", Const, 1, ""},
+		{"SYS_VFORK", Const, 0, ""},
+		{"SYS_VHANGUP", Const, 0, ""},
+		{"SYS_VM86", Const, 0, ""},
+		{"SYS_VM86OLD", Const, 0, ""},
+		{"SYS_VMSPLICE", Const, 0, ""},
+		{"SYS_VM_PRESSURE_MONITOR", Const, 0, ""},
+		{"SYS_VSERVER", Const, 0, ""},
+		{"SYS_WAIT4", Const, 0, ""},
+		{"SYS_WAIT4_NOCANCEL", Const, 0, ""},
+		{"SYS_WAIT6", Const, 1, ""},
+		{"SYS_WAITEVENT", Const, 0, ""},
+		{"SYS_WAITID", Const, 0, ""},
+		{"SYS_WAITID_NOCANCEL", Const, 0, ""},
+		{"SYS_WAITPID", Const, 0, ""},
+		{"SYS_WATCHEVENT", Const, 0, ""},
+		{"SYS_WORKQ_KERNRETURN", Const, 0, ""},
+		{"SYS_WORKQ_OPEN", Const, 0, ""},
+		{"SYS_WRITE", Const, 0, ""},
+		{"SYS_WRITEV", Const, 0, ""},
+		{"SYS_WRITEV_NOCANCEL", Const, 0, ""},
+		{"SYS_WRITE_NOCANCEL", Const, 0, ""},
+		{"SYS_YIELD", Const, 0, ""},
+		{"SYS__LLSEEK", Const, 0, ""},
+		{"SYS__LWP_CONTINUE", Const, 1, ""},
+		{"SYS__LWP_CREATE", Const, 1, ""},
+		{"SYS__LWP_CTL", Const, 1, ""},
+		{"SYS__LWP_DETACH", Const, 1, ""},
+		{"SYS__LWP_EXIT", Const, 1, ""},
+		{"SYS__LWP_GETNAME", Const, 1, ""},
+		{"SYS__LWP_GETPRIVATE", Const, 1, ""},
+		{"SYS__LWP_KILL", Const, 1, ""},
+		{"SYS__LWP_PARK", Const, 1, ""},
+		{"SYS__LWP_SELF", Const, 1, ""},
+		{"SYS__LWP_SETNAME", Const, 1, ""},
+		{"SYS__LWP_SETPRIVATE", Const, 1, ""},
+		{"SYS__LWP_SUSPEND", Const, 1, ""},
+		{"SYS__LWP_UNPARK", Const, 1, ""},
+		{"SYS__LWP_UNPARK_ALL", Const, 1, ""},
+		{"SYS__LWP_WAIT", Const, 1, ""},
+		{"SYS__LWP_WAKEUP", Const, 1, ""},
+		{"SYS__NEWSELECT", Const, 0, ""},
+		{"SYS__PSET_BIND", Const, 1, ""},
+		{"SYS__SCHED_GETAFFINITY", Const, 1, ""},
+		{"SYS__SCHED_GETPARAM", Const, 1, ""},
+		{"SYS__SCHED_SETAFFINITY", Const, 1, ""},
+		{"SYS__SCHED_SETPARAM", Const, 1, ""},
+		{"SYS__SYSCTL", Const, 0, ""},
+		{"SYS__UMTX_LOCK", Const, 0, ""},
+		{"SYS__UMTX_OP", Const, 0, ""},
+		{"SYS__UMTX_UNLOCK", Const, 0, ""},
+		{"SYS___ACL_ACLCHECK_FD", Const, 0, ""},
+		{"SYS___ACL_ACLCHECK_FILE", Const, 0, ""},
+		{"SYS___ACL_ACLCHECK_LINK", Const, 0, ""},
+		{"SYS___ACL_DELETE_FD", Const, 0, ""},
+		{"SYS___ACL_DELETE_FILE", Const, 0, ""},
+		{"SYS___ACL_DELETE_LINK", Const, 0, ""},
+		{"SYS___ACL_GET_FD", Const, 0, ""},
+		{"SYS___ACL_GET_FILE", Const, 0, ""},
+		{"SYS___ACL_GET_LINK", Const, 0, ""},
+		{"SYS___ACL_SET_FD", Const, 0, ""},
+		{"SYS___ACL_SET_FILE", Const, 0, ""},
+		{"SYS___ACL_SET_LINK", Const, 0, ""},
+		{"SYS___CAP_RIGHTS_GET", Const, 14, ""},
+		{"SYS___CLONE", Const, 1, ""},
+		{"SYS___DISABLE_THREADSIGNAL", Const, 0, ""},
+		{"SYS___GETCWD", Const, 0, ""},
+		{"SYS___GETLOGIN", Const, 1, ""},
+		{"SYS___GET_TCB", Const, 1, ""},
+		{"SYS___MAC_EXECVE", Const, 0, ""},
+		{"SYS___MAC_GETFSSTAT", Const, 0, ""},
+		{"SYS___MAC_GET_FD", Const, 0, ""},
+		{"SYS___MAC_GET_FILE", Const, 0, ""},
+		{"SYS___MAC_GET_LCID", Const, 0, ""},
+		{"SYS___MAC_GET_LCTX", Const, 0, ""},
+		{"SYS___MAC_GET_LINK", Const, 0, ""},
+		{"SYS___MAC_GET_MOUNT", Const, 0, ""},
+		{"SYS___MAC_GET_PID", Const, 0, ""},
+		{"SYS___MAC_GET_PROC", Const, 0, ""},
+		{"SYS___MAC_MOUNT", Const, 0, ""},
+		{"SYS___MAC_SET_FD", Const, 0, ""},
+		{"SYS___MAC_SET_FILE", Const, 0, ""},
+		{"SYS___MAC_SET_LCTX", Const, 0, ""},
+		{"SYS___MAC_SET_LINK", Const, 0, ""},
+		{"SYS___MAC_SET_PROC", Const, 0, ""},
+		{"SYS___MAC_SYSCALL", Const, 0, ""},
+		{"SYS___OLD_SEMWAIT_SIGNAL", Const, 0, ""},
+		{"SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL", Const, 0, ""},
+		{"SYS___POSIX_CHOWN", Const, 1, ""},
+		{"SYS___POSIX_FCHOWN", Const, 1, ""},
+		{"SYS___POSIX_LCHOWN", Const, 1, ""},
+		{"SYS___POSIX_RENAME", Const, 1, ""},
+		{"SYS___PTHREAD_CANCELED", Const, 0, ""},
+		{"SYS___PTHREAD_CHDIR", Const, 0, ""},
+		{"SYS___PTHREAD_FCHDIR", Const, 0, ""},
+		{"SYS___PTHREAD_KILL", Const, 0, ""},
+		{"SYS___PTHREAD_MARKCANCEL", Const, 0, ""},
+		{"SYS___PTHREAD_SIGMASK", Const, 0, ""},
+		{"SYS___QUOTACTL", Const, 1, ""},
+		{"SYS___SEMCTL", Const, 1, ""},
+		{"SYS___SEMWAIT_SIGNAL", Const, 0, ""},
+		{"SYS___SEMWAIT_SIGNAL_NOCANCEL", Const, 0, ""},
+		{"SYS___SETLOGIN", Const, 1, ""},
+		{"SYS___SETUGID", Const, 0, ""},
+		{"SYS___SET_TCB", Const, 1, ""},
+		{"SYS___SIGACTION_SIGTRAMP", Const, 1, ""},
+		{"SYS___SIGTIMEDWAIT", Const, 1, ""},
+		{"SYS___SIGWAIT", Const, 0, ""},
+		{"SYS___SIGWAIT_NOCANCEL", Const, 0, ""},
+		{"SYS___SYSCTL", Const, 0, ""},
+		{"SYS___TFORK", Const, 1, ""},
+		{"SYS___THREXIT", Const, 1, ""},
+		{"SYS___THRSIGDIVERT", Const, 1, ""},
+		{"SYS___THRSLEEP", Const, 1, ""},
+		{"SYS___THRWAKEUP", Const, 1, ""},
+		{"S_ARCH1", Const, 1, ""},
+		{"S_ARCH2", Const, 1, ""},
+		{"S_BLKSIZE", Const, 0, ""},
+		{"S_IEXEC", Const, 0, ""},
+		{"S_IFBLK", Const, 0, ""},
+		{"S_IFCHR", Const, 0, ""},
+		{"S_IFDIR", Const, 0, ""},
+		{"S_IFIFO", Const, 0, ""},
+		{"S_IFLNK", Const, 0, ""},
+		{"S_IFMT", Const, 0, ""},
+		{"S_IFREG", Const, 0, ""},
+		{"S_IFSOCK", Const, 0, ""},
+		{"S_IFWHT", Const, 0, ""},
+		{"S_IREAD", Const, 0, ""},
+		{"S_IRGRP", Const, 0, ""},
+		{"S_IROTH", Const, 0, ""},
+		{"S_IRUSR", Const, 0, ""},
+		{"S_IRWXG", Const, 0, ""},
+		{"S_IRWXO", Const, 0, ""},
+		{"S_IRWXU", Const, 0, ""},
+		{"S_ISGID", Const, 0, ""},
+		{"S_ISTXT", Const, 0, ""},
+		{"S_ISUID", Const, 0, ""},
+		{"S_ISVTX", Const, 0, ""},
+		{"S_IWGRP", Const, 0, ""},
+		{"S_IWOTH", Const, 0, ""},
+		{"S_IWRITE", Const, 0, ""},
+		{"S_IWUSR", Const, 0, ""},
+		{"S_IXGRP", Const, 0, ""},
+		{"S_IXOTH", Const, 0, ""},
+		{"S_IXUSR", Const, 0, ""},
+		{"S_LOGIN_SET", Const, 1, ""},
+		{"SecurityAttributes", Type, 0, ""},
+		{"SecurityAttributes.InheritHandle", Field, 0, ""},
+		{"SecurityAttributes.Length", Field, 0, ""},
+		{"SecurityAttributes.SecurityDescriptor", Field, 0, ""},
+		{"Seek", Func, 0, "func(fd int, offset int64, whence int) (off int64, err error)"},
+		{"Select", Func, 0, "func(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)"},
+		{"Sendfile", Func, 0, "func(outfd int, infd int, offset *int64, count int) (written int, err error)"},
+		{"Sendmsg", Func, 0, "func(fd int, p []byte, oob []byte, to Sockaddr, flags int) (err error)"},
+		{"SendmsgN", Func, 3, "func(fd int, p []byte, oob []byte, to Sockaddr, flags int) (n int, err error)"},
+		{"Sendto", Func, 0, "func(fd int, p []byte, flags int, to Sockaddr) (err error)"},
+		{"Servent", Type, 0, ""},
+		{"Servent.Aliases", Field, 0, ""},
+		{"Servent.Name", Field, 0, ""},
+		{"Servent.Port", Field, 0, ""},
+		{"Servent.Proto", Field, 0, ""},
+		{"SetBpf", Func, 0, ""},
+		{"SetBpfBuflen", Func, 0, ""},
+		{"SetBpfDatalink", Func, 0, ""},
+		{"SetBpfHeadercmpl", Func, 0, ""},
+		{"SetBpfImmediate", Func, 0, ""},
+		{"SetBpfInterface", Func, 0, ""},
+		{"SetBpfPromisc", Func, 0, ""},
+		{"SetBpfTimeout", Func, 0, ""},
+		{"SetCurrentDirectory", Func, 0, ""},
+		{"SetEndOfFile", Func, 0, ""},
+		{"SetEnvironmentVariable", Func, 0, ""},
+		{"SetFileAttributes", Func, 0, ""},
+		{"SetFileCompletionNotificationModes", Func, 2, ""},
+		{"SetFilePointer", Func, 0, ""},
+		{"SetFileTime", Func, 0, ""},
+		{"SetHandleInformation", Func, 0, ""},
+		{"SetKevent", Func, 0, ""},
+		{"SetLsfPromisc", Func, 0, "func(name string, m bool) error"},
+		{"SetNonblock", Func, 0, "func(fd int, nonblocking bool) (err error)"},
+		{"Setdomainname", Func, 0, "func(p []byte) (err error)"},
+		{"Setegid", Func, 0, "func(egid int) (err error)"},
+		{"Setenv", Func, 0, "func(key string, value string) error"},
+		{"Seteuid", Func, 0, "func(euid int) (err error)"},
+		{"Setfsgid", Func, 0, "func(gid int) (err error)"},
+		{"Setfsuid", Func, 0, "func(uid int) (err error)"},
+		{"Setgid", Func, 0, "func(gid int) (err error)"},
+		{"Setgroups", Func, 0, "func(gids []int) (err error)"},
+		{"Sethostname", Func, 0, "func(p []byte) (err error)"},
+		{"Setlogin", Func, 0, ""},
+		{"Setpgid", Func, 0, "func(pid int, pgid int) (err error)"},
+		{"Setpriority", Func, 0, "func(which int, who int, prio int) (err error)"},
+		{"Setprivexec", Func, 0, ""},
+		{"Setregid", Func, 0, "func(rgid int, egid int) (err error)"},
+		{"Setresgid", Func, 0, "func(rgid int, egid int, sgid int) (err error)"},
+		{"Setresuid", Func, 0, "func(ruid int, euid int, suid int) (err error)"},
+		{"Setreuid", Func, 0, "func(ruid int, euid int) (err error)"},
+		{"Setrlimit", Func, 0, "func(resource int, rlim *Rlimit) error"},
+		{"Setsid", Func, 0, "func() (pid int, err error)"},
+		{"Setsockopt", Func, 0, ""},
+		{"SetsockoptByte", Func, 0, "func(fd int, level int, opt int, value byte) (err error)"},
+		{"SetsockoptICMPv6Filter", Func, 2, "func(fd int, level int, opt int, filter *ICMPv6Filter) error"},
+		{"SetsockoptIPMreq", Func, 0, "func(fd int, level int, opt int, mreq *IPMreq) (err error)"},
+		{"SetsockoptIPMreqn", Func, 0, "func(fd int, level int, opt int, mreq *IPMreqn) (err error)"},
+		{"SetsockoptIPv6Mreq", Func, 0, "func(fd int, level int, opt int, mreq *IPv6Mreq) (err error)"},
+		{"SetsockoptInet4Addr", Func, 0, "func(fd int, level int, opt int, value [4]byte) (err error)"},
+		{"SetsockoptInt", Func, 0, "func(fd int, level int, opt int, value int) (err error)"},
+		{"SetsockoptLinger", Func, 0, "func(fd int, level int, opt int, l *Linger) (err error)"},
+		{"SetsockoptString", Func, 0, "func(fd int, level int, opt int, s string) (err error)"},
+		{"SetsockoptTimeval", Func, 0, "func(fd int, level int, opt int, tv *Timeval) (err error)"},
+		{"Settimeofday", Func, 0, "func(tv *Timeval) (err error)"},
+		{"Setuid", Func, 0, "func(uid int) (err error)"},
+		{"Setxattr", Func, 1, "func(path string, attr string, data []byte, flags int) (err error)"},
+		{"Shutdown", Func, 0, "func(fd int, how int) (err error)"},
+		{"SidTypeAlias", Const, 0, ""},
+		{"SidTypeComputer", Const, 0, ""},
+		{"SidTypeDeletedAccount", Const, 0, ""},
+		{"SidTypeDomain", Const, 0, ""},
+		{"SidTypeGroup", Const, 0, ""},
+		{"SidTypeInvalid", Const, 0, ""},
+		{"SidTypeLabel", Const, 0, ""},
+		{"SidTypeUnknown", Const, 0, ""},
+		{"SidTypeUser", Const, 0, ""},
+		{"SidTypeWellKnownGroup", Const, 0, ""},
+		{"Signal", Type, 0, ""},
+		{"SizeofBpfHdr", Const, 0, ""},
+		{"SizeofBpfInsn", Const, 0, ""},
+		{"SizeofBpfProgram", Const, 0, ""},
+		{"SizeofBpfStat", Const, 0, ""},
+		{"SizeofBpfVersion", Const, 0, ""},
+		{"SizeofBpfZbuf", Const, 0, ""},
+		{"SizeofBpfZbufHeader", Const, 0, ""},
+		{"SizeofCmsghdr", Const, 0, ""},
+		{"SizeofICMPv6Filter", Const, 2, ""},
+		{"SizeofIPMreq", Const, 0, ""},
+		{"SizeofIPMreqn", Const, 0, ""},
+		{"SizeofIPv6MTUInfo", Const, 2, ""},
+		{"SizeofIPv6Mreq", Const, 0, ""},
+		{"SizeofIfAddrmsg", Const, 0, ""},
+		{"SizeofIfAnnounceMsghdr", Const, 1, ""},
+		{"SizeofIfData", Const, 0, ""},
+		{"SizeofIfInfomsg", Const, 0, ""},
+		{"SizeofIfMsghdr", Const, 0, ""},
+		{"SizeofIfaMsghdr", Const, 0, ""},
+		{"SizeofIfmaMsghdr", Const, 0, ""},
+		{"SizeofIfmaMsghdr2", Const, 0, ""},
+		{"SizeofInet4Pktinfo", Const, 0, ""},
+		{"SizeofInet6Pktinfo", Const, 0, ""},
+		{"SizeofInotifyEvent", Const, 0, ""},
+		{"SizeofLinger", Const, 0, ""},
+		{"SizeofMsghdr", Const, 0, ""},
+		{"SizeofNlAttr", Const, 0, ""},
+		{"SizeofNlMsgerr", Const, 0, ""},
+		{"SizeofNlMsghdr", Const, 0, ""},
+		{"SizeofRtAttr", Const, 0, ""},
+		{"SizeofRtGenmsg", Const, 0, ""},
+		{"SizeofRtMetrics", Const, 0, ""},
+		{"SizeofRtMsg", Const, 0, ""},
+		{"SizeofRtMsghdr", Const, 0, ""},
+		{"SizeofRtNexthop", Const, 0, ""},
+		{"SizeofSockFilter", Const, 0, ""},
+		{"SizeofSockFprog", Const, 0, ""},
+		{"SizeofSockaddrAny", Const, 0, ""},
+		{"SizeofSockaddrDatalink", Const, 0, ""},
+		{"SizeofSockaddrInet4", Const, 0, ""},
+		{"SizeofSockaddrInet6", Const, 0, ""},
+		{"SizeofSockaddrLinklayer", Const, 0, ""},
+		{"SizeofSockaddrNetlink", Const, 0, ""},
+		{"SizeofSockaddrUnix", Const, 0, ""},
+		{"SizeofTCPInfo", Const, 1, ""},
+		{"SizeofUcred", Const, 0, ""},
+		{"SlicePtrFromStrings", Func, 1, "func(ss []string) ([]*byte, error)"},
+		{"SockFilter", Type, 0, ""},
+		{"SockFilter.Code", Field, 0, ""},
+		{"SockFilter.Jf", Field, 0, ""},
+		{"SockFilter.Jt", Field, 0, ""},
+		{"SockFilter.K", Field, 0, ""},
+		{"SockFprog", Type, 0, ""},
+		{"SockFprog.Filter", Field, 0, ""},
+		{"SockFprog.Len", Field, 0, ""},
+		{"SockFprog.Pad_cgo_0", Field, 0, ""},
+		{"SockaddrDatalink", Type, 0, ""},
+		{"SockaddrDatalink.Alen", Field, 0, ""},
+		{"SockaddrDatalink.Data", Field, 0, ""},
+		{"SockaddrDatalink.Family", Field, 0, ""},
+		{"SockaddrDatalink.Index", Field, 0, ""},
+		{"SockaddrDatalink.Len", Field, 0, ""},
+		{"SockaddrDatalink.Nlen", Field, 0, ""},
+		{"SockaddrDatalink.Slen", Field, 0, ""},
+		{"SockaddrDatalink.Type", Field, 0, ""},
+		{"SockaddrGen", Type, 0, ""},
+		{"SockaddrInet4", Type, 0, ""},
+		{"SockaddrInet4.Addr", Field, 0, ""},
+		{"SockaddrInet4.Port", Field, 0, ""},
+		{"SockaddrInet6", Type, 0, ""},
+		{"SockaddrInet6.Addr", Field, 0, ""},
+		{"SockaddrInet6.Port", Field, 0, ""},
+		{"SockaddrInet6.ZoneId", Field, 0, ""},
+		{"SockaddrLinklayer", Type, 0, ""},
+		{"SockaddrLinklayer.Addr", Field, 0, ""},
+		{"SockaddrLinklayer.Halen", Field, 0, ""},
+		{"SockaddrLinklayer.Hatype", Field, 0, ""},
+		{"SockaddrLinklayer.Ifindex", Field, 0, ""},
+		{"SockaddrLinklayer.Pkttype", Field, 0, ""},
+		{"SockaddrLinklayer.Protocol", Field, 0, ""},
+		{"SockaddrNetlink", Type, 0, ""},
+		{"SockaddrNetlink.Family", Field, 0, ""},
+		{"SockaddrNetlink.Groups", Field, 0, ""},
+		{"SockaddrNetlink.Pad", Field, 0, ""},
+		{"SockaddrNetlink.Pid", Field, 0, ""},
+		{"SockaddrUnix", Type, 0, ""},
+		{"SockaddrUnix.Name", Field, 0, ""},
+		{"Socket", Func, 0, "func(domain int, typ int, proto int) (fd int, err error)"},
+		{"SocketControlMessage", Type, 0, ""},
+		{"SocketControlMessage.Data", Field, 0, ""},
+		{"SocketControlMessage.Header", Field, 0, ""},
+		{"SocketDisableIPv6", Var, 0, ""},
+		{"Socketpair", Func, 0, "func(domain int, typ int, proto int) (fd [2]int, err error)"},
+		{"Splice", Func, 0, "func(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)"},
+		{"StartProcess", Func, 0, "func(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error)"},
+		{"StartupInfo", Type, 0, ""},
+		{"StartupInfo.Cb", Field, 0, ""},
+		{"StartupInfo.Desktop", Field, 0, ""},
+		{"StartupInfo.FillAttribute", Field, 0, ""},
+		{"StartupInfo.Flags", Field, 0, ""},
+		{"StartupInfo.ShowWindow", Field, 0, ""},
+		{"StartupInfo.StdErr", Field, 0, ""},
+		{"StartupInfo.StdInput", Field, 0, ""},
+		{"StartupInfo.StdOutput", Field, 0, ""},
+		{"StartupInfo.Title", Field, 0, ""},
+		{"StartupInfo.X", Field, 0, ""},
+		{"StartupInfo.XCountChars", Field, 0, ""},
+		{"StartupInfo.XSize", Field, 0, ""},
+		{"StartupInfo.Y", Field, 0, ""},
+		{"StartupInfo.YCountChars", Field, 0, ""},
+		{"StartupInfo.YSize", Field, 0, ""},
+		{"Stat", Func, 0, "func(path string, stat *Stat_t) (err error)"},
+		{"Stat_t", Type, 0, ""},
+		{"Stat_t.Atim", Field, 0, ""},
+		{"Stat_t.Atim_ext", Field, 12, ""},
+		{"Stat_t.Atimespec", Field, 0, ""},
+		{"Stat_t.Birthtimespec", Field, 0, ""},
+		{"Stat_t.Blksize", Field, 0, ""},
+		{"Stat_t.Blocks", Field, 0, ""},
+		{"Stat_t.Btim_ext", Field, 12, ""},
+		{"Stat_t.Ctim", Field, 0, ""},
+		{"Stat_t.Ctim_ext", Field, 12, ""},
+		{"Stat_t.Ctimespec", Field, 0, ""},
+		{"Stat_t.Dev", Field, 0, ""},
+		{"Stat_t.Flags", Field, 0, ""},
+		{"Stat_t.Gen", Field, 0, ""},
+		{"Stat_t.Gid", Field, 0, ""},
+		{"Stat_t.Ino", Field, 0, ""},
+		{"Stat_t.Lspare", Field, 0, ""},
+		{"Stat_t.Lspare0", Field, 2, ""},
+		{"Stat_t.Lspare1", Field, 2, ""},
+		{"Stat_t.Mode", Field, 0, ""},
+		{"Stat_t.Mtim", Field, 0, ""},
+		{"Stat_t.Mtim_ext", Field, 12, ""},
+		{"Stat_t.Mtimespec", Field, 0, ""},
+		{"Stat_t.Nlink", Field, 0, ""},
+		{"Stat_t.Pad_cgo_0", Field, 0, ""},
+		{"Stat_t.Pad_cgo_1", Field, 0, ""},
+		{"Stat_t.Pad_cgo_2", Field, 0, ""},
+		{"Stat_t.Padding0", Field, 12, ""},
+		{"Stat_t.Padding1", Field, 12, ""},
+		{"Stat_t.Qspare", Field, 0, ""},
+		{"Stat_t.Rdev", Field, 0, ""},
+		{"Stat_t.Size", Field, 0, ""},
+		{"Stat_t.Spare", Field, 2, ""},
+		{"Stat_t.Uid", Field, 0, ""},
+		{"Stat_t.X__pad0", Field, 0, ""},
+		{"Stat_t.X__pad1", Field, 0, ""},
+		{"Stat_t.X__pad2", Field, 0, ""},
+		{"Stat_t.X__st_birthtim", Field, 2, ""},
+		{"Stat_t.X__st_ino", Field, 0, ""},
+		{"Stat_t.X__unused", Field, 0, ""},
+		{"Statfs", Func, 0, "func(path string, buf *Statfs_t) (err error)"},
+		{"Statfs_t", Type, 0, ""},
+		{"Statfs_t.Asyncreads", Field, 0, ""},
+		{"Statfs_t.Asyncwrites", Field, 0, ""},
+		{"Statfs_t.Bavail", Field, 0, ""},
+		{"Statfs_t.Bfree", Field, 0, ""},
+		{"Statfs_t.Blocks", Field, 0, ""},
+		{"Statfs_t.Bsize", Field, 0, ""},
+		{"Statfs_t.Charspare", Field, 0, ""},
+		{"Statfs_t.F_asyncreads", Field, 2, ""},
+		{"Statfs_t.F_asyncwrites", Field, 2, ""},
+		{"Statfs_t.F_bavail", Field, 2, ""},
+		{"Statfs_t.F_bfree", Field, 2, ""},
+		{"Statfs_t.F_blocks", Field, 2, ""},
+		{"Statfs_t.F_bsize", Field, 2, ""},
+		{"Statfs_t.F_ctime", Field, 2, ""},
+		{"Statfs_t.F_favail", Field, 2, ""},
+		{"Statfs_t.F_ffree", Field, 2, ""},
+		{"Statfs_t.F_files", Field, 2, ""},
+		{"Statfs_t.F_flags", Field, 2, ""},
+		{"Statfs_t.F_fsid", Field, 2, ""},
+		{"Statfs_t.F_fstypename", Field, 2, ""},
+		{"Statfs_t.F_iosize", Field, 2, ""},
+		{"Statfs_t.F_mntfromname", Field, 2, ""},
+		{"Statfs_t.F_mntfromspec", Field, 3, ""},
+		{"Statfs_t.F_mntonname", Field, 2, ""},
+		{"Statfs_t.F_namemax", Field, 2, ""},
+		{"Statfs_t.F_owner", Field, 2, ""},
+		{"Statfs_t.F_spare", Field, 2, ""},
+		{"Statfs_t.F_syncreads", Field, 2, ""},
+		{"Statfs_t.F_syncwrites", Field, 2, ""},
+		{"Statfs_t.Ffree", Field, 0, ""},
+		{"Statfs_t.Files", Field, 0, ""},
+		{"Statfs_t.Flags", Field, 0, ""},
+		{"Statfs_t.Frsize", Field, 0, ""},
+		{"Statfs_t.Fsid", Field, 0, ""},
+		{"Statfs_t.Fssubtype", Field, 0, ""},
+		{"Statfs_t.Fstypename", Field, 0, ""},
+		{"Statfs_t.Iosize", Field, 0, ""},
+		{"Statfs_t.Mntfromname", Field, 0, ""},
+		{"Statfs_t.Mntonname", Field, 0, ""},
+		{"Statfs_t.Mount_info", Field, 2, ""},
+		{"Statfs_t.Namelen", Field, 0, ""},
+		{"Statfs_t.Namemax", Field, 0, ""},
+		{"Statfs_t.Owner", Field, 0, ""},
+		{"Statfs_t.Pad_cgo_0", Field, 0, ""},
+		{"Statfs_t.Pad_cgo_1", Field, 2, ""},
+		{"Statfs_t.Reserved", Field, 0, ""},
+		{"Statfs_t.Spare", Field, 0, ""},
+		{"Statfs_t.Syncreads", Field, 0, ""},
+		{"Statfs_t.Syncwrites", Field, 0, ""},
+		{"Statfs_t.Type", Field, 0, ""},
+		{"Statfs_t.Version", Field, 0, ""},
+		{"Stderr", Var, 0, ""},
+		{"Stdin", Var, 0, ""},
+		{"Stdout", Var, 0, ""},
+		{"StringBytePtr", Func, 0, "func(s string) *byte"},
+		{"StringByteSlice", Func, 0, "func(s string) []byte"},
+		{"StringSlicePtr", Func, 0, "func(ss []string) []*byte"},
+		{"StringToSid", Func, 0, ""},
+		{"StringToUTF16", Func, 0, ""},
+		{"StringToUTF16Ptr", Func, 0, ""},
+		{"Symlink", Func, 0, "func(oldpath string, newpath string) (err error)"},
+		{"Sync", Func, 0, "func()"},
+		{"SyncFileRange", Func, 0, "func(fd int, off int64, n int64, flags int) (err error)"},
+		{"SysProcAttr", Type, 0, ""},
+		{"SysProcAttr.AdditionalInheritedHandles", Field, 17, ""},
+		{"SysProcAttr.AmbientCaps", Field, 9, ""},
+		{"SysProcAttr.CgroupFD", Field, 20, ""},
+		{"SysProcAttr.Chroot", Field, 0, ""},
+		{"SysProcAttr.Cloneflags", Field, 2, ""},
+		{"SysProcAttr.CmdLine", Field, 0, ""},
+		{"SysProcAttr.CreationFlags", Field, 1, ""},
+		{"SysProcAttr.Credential", Field, 0, ""},
+		{"SysProcAttr.Ctty", Field, 1, ""},
+		{"SysProcAttr.Foreground", Field, 5, ""},
+		{"SysProcAttr.GidMappings", Field, 4, ""},
+		{"SysProcAttr.GidMappingsEnableSetgroups", Field, 5, ""},
+		{"SysProcAttr.HideWindow", Field, 0, ""},
+		{"SysProcAttr.Jail", Field, 21, ""},
+		{"SysProcAttr.NoInheritHandles", Field, 16, ""},
+		{"SysProcAttr.Noctty", Field, 0, ""},
+		{"SysProcAttr.ParentProcess", Field, 17, ""},
+		{"SysProcAttr.Pdeathsig", Field, 0, ""},
+		{"SysProcAttr.Pgid", Field, 5, ""},
+		{"SysProcAttr.PidFD", Field, 22, ""},
+		{"SysProcAttr.ProcessAttributes", Field, 13, ""},
+		{"SysProcAttr.Ptrace", Field, 0, ""},
+		{"SysProcAttr.Setctty", Field, 0, ""},
+		{"SysProcAttr.Setpgid", Field, 0, ""},
+		{"SysProcAttr.Setsid", Field, 0, ""},
+		{"SysProcAttr.ThreadAttributes", Field, 13, ""},
+		{"SysProcAttr.Token", Field, 10, ""},
+		{"SysProcAttr.UidMappings", Field, 4, ""},
+		{"SysProcAttr.Unshareflags", Field, 7, ""},
+		{"SysProcAttr.UseCgroupFD", Field, 20, ""},
+		{"SysProcIDMap", Type, 4, ""},
+		{"SysProcIDMap.ContainerID", Field, 4, ""},
+		{"SysProcIDMap.HostID", Field, 4, ""},
+		{"SysProcIDMap.Size", Field, 4, ""},
+		{"Syscall", Func, 0, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err Errno)"},
+		{"Syscall12", Func, 0, ""},
+		{"Syscall15", Func, 0, ""},
+		{"Syscall18", Func, 12, ""},
+		{"Syscall6", Func, 0, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err Errno)"},
+		{"Syscall9", Func, 0, ""},
+		{"SyscallN", Func, 18, ""},
+		{"Sysctl", Func, 0, ""},
+		{"SysctlUint32", Func, 0, ""},
+		{"Sysctlnode", Type, 2, ""},
+		{"Sysctlnode.Flags", Field, 2, ""},
+		{"Sysctlnode.Name", Field, 2, ""},
+		{"Sysctlnode.Num", Field, 2, ""},
+		{"Sysctlnode.Un", Field, 2, ""},
+		{"Sysctlnode.Ver", Field, 2, ""},
+		{"Sysctlnode.X__rsvd", Field, 2, ""},
+		{"Sysctlnode.X_sysctl_desc", Field, 2, ""},
+		{"Sysctlnode.X_sysctl_func", Field, 2, ""},
+		{"Sysctlnode.X_sysctl_parent", Field, 2, ""},
+		{"Sysctlnode.X_sysctl_size", Field, 2, ""},
+		{"Sysinfo", Func, 0, "func(info *Sysinfo_t) (err error)"},
+		{"Sysinfo_t", Type, 0, ""},
+		{"Sysinfo_t.Bufferram", Field, 0, ""},
+		{"Sysinfo_t.Freehigh", Field, 0, ""},
+		{"Sysinfo_t.Freeram", Field, 0, ""},
+		{"Sysinfo_t.Freeswap", Field, 0, ""},
+		{"Sysinfo_t.Loads", Field, 0, ""},
+		{"Sysinfo_t.Pad", Field, 0, ""},
+		{"Sysinfo_t.Pad_cgo_0", Field, 0, ""},
+		{"Sysinfo_t.Pad_cgo_1", Field, 0, ""},
+		{"Sysinfo_t.Procs", Field, 0, ""},
+		{"Sysinfo_t.Sharedram", Field, 0, ""},
+		{"Sysinfo_t.Totalhigh", Field, 0, ""},
+		{"Sysinfo_t.Totalram", Field, 0, ""},
+		{"Sysinfo_t.Totalswap", Field, 0, ""},
+		{"Sysinfo_t.Unit", Field, 0, ""},
+		{"Sysinfo_t.Uptime", Field, 0, ""},
+		{"Sysinfo_t.X_f", Field, 0, ""},
+		{"Systemtime", Type, 0, ""},
+		{"Systemtime.Day", Field, 0, ""},
+		{"Systemtime.DayOfWeek", Field, 0, ""},
+		{"Systemtime.Hour", Field, 0, ""},
+		{"Systemtime.Milliseconds", Field, 0, ""},
+		{"Systemtime.Minute", Field, 0, ""},
+		{"Systemtime.Month", Field, 0, ""},
+		{"Systemtime.Second", Field, 0, ""},
+		{"Systemtime.Year", Field, 0, ""},
+		{"TCGETS", Const, 0, ""},
+		{"TCIFLUSH", Const, 1, ""},
+		{"TCIOFLUSH", Const, 1, ""},
+		{"TCOFLUSH", Const, 1, ""},
+		{"TCPInfo", Type, 1, ""},
+		{"TCPInfo.Advmss", Field, 1, ""},
+		{"TCPInfo.Ato", Field, 1, ""},
+		{"TCPInfo.Backoff", Field, 1, ""},
+		{"TCPInfo.Ca_state", Field, 1, ""},
+		{"TCPInfo.Fackets", Field, 1, ""},
+		{"TCPInfo.Last_ack_recv", Field, 1, ""},
+		{"TCPInfo.Last_ack_sent", Field, 1, ""},
+		{"TCPInfo.Last_data_recv", Field, 1, ""},
+		{"TCPInfo.Last_data_sent", Field, 1, ""},
+		{"TCPInfo.Lost", Field, 1, ""},
+		{"TCPInfo.Options", Field, 1, ""},
+		{"TCPInfo.Pad_cgo_0", Field, 1, ""},
+		{"TCPInfo.Pmtu", Field, 1, ""},
+		{"TCPInfo.Probes", Field, 1, ""},
+		{"TCPInfo.Rcv_mss", Field, 1, ""},
+		{"TCPInfo.Rcv_rtt", Field, 1, ""},
+		{"TCPInfo.Rcv_space", Field, 1, ""},
+		{"TCPInfo.Rcv_ssthresh", Field, 1, ""},
+		{"TCPInfo.Reordering", Field, 1, ""},
+		{"TCPInfo.Retrans", Field, 1, ""},
+		{"TCPInfo.Retransmits", Field, 1, ""},
+		{"TCPInfo.Rto", Field, 1, ""},
+		{"TCPInfo.Rtt", Field, 1, ""},
+		{"TCPInfo.Rttvar", Field, 1, ""},
+		{"TCPInfo.Sacked", Field, 1, ""},
+		{"TCPInfo.Snd_cwnd", Field, 1, ""},
+		{"TCPInfo.Snd_mss", Field, 1, ""},
+		{"TCPInfo.Snd_ssthresh", Field, 1, ""},
+		{"TCPInfo.State", Field, 1, ""},
+		{"TCPInfo.Total_retrans", Field, 1, ""},
+		{"TCPInfo.Unacked", Field, 1, ""},
+		{"TCPKeepalive", Type, 3, ""},
+		{"TCPKeepalive.Interval", Field, 3, ""},
+		{"TCPKeepalive.OnOff", Field, 3, ""},
+		{"TCPKeepalive.Time", Field, 3, ""},
+		{"TCP_CA_NAME_MAX", Const, 0, ""},
+		{"TCP_CONGCTL", Const, 1, ""},
+		{"TCP_CONGESTION", Const, 0, ""},
+		{"TCP_CONNECTIONTIMEOUT", Const, 0, ""},
+		{"TCP_CORK", Const, 0, ""},
+		{"TCP_DEFER_ACCEPT", Const, 0, ""},
+		{"TCP_ENABLE_ECN", Const, 16, ""},
+		{"TCP_INFO", Const, 0, ""},
+		{"TCP_KEEPALIVE", Const, 0, ""},
+		{"TCP_KEEPCNT", Const, 0, ""},
+		{"TCP_KEEPIDLE", Const, 0, ""},
+		{"TCP_KEEPINIT", Const, 1, ""},
+		{"TCP_KEEPINTVL", Const, 0, ""},
+		{"TCP_LINGER2", Const, 0, ""},
+		{"TCP_MAXBURST", Const, 0, ""},
+		{"TCP_MAXHLEN", Const, 0, ""},
+		{"TCP_MAXOLEN", Const, 0, ""},
+		{"TCP_MAXSEG", Const, 0, ""},
+		{"TCP_MAXWIN", Const, 0, ""},
+		{"TCP_MAX_SACK", Const, 0, ""},
+		{"TCP_MAX_WINSHIFT", Const, 0, ""},
+		{"TCP_MD5SIG", Const, 0, ""},
+		{"TCP_MD5SIG_MAXKEYLEN", Const, 0, ""},
+		{"TCP_MINMSS", Const, 0, ""},
+		{"TCP_MINMSSOVERLOAD", Const, 0, ""},
+		{"TCP_MSS", Const, 0, ""},
+		{"TCP_NODELAY", Const, 0, ""},
+		{"TCP_NOOPT", Const, 0, ""},
+		{"TCP_NOPUSH", Const, 0, ""},
+		{"TCP_NOTSENT_LOWAT", Const, 16, ""},
+		{"TCP_NSTATES", Const, 1, ""},
+		{"TCP_QUICKACK", Const, 0, ""},
+		{"TCP_RXT_CONNDROPTIME", Const, 0, ""},
+		{"TCP_RXT_FINDROP", Const, 0, ""},
+		{"TCP_SACK_ENABLE", Const, 1, ""},
+		{"TCP_SENDMOREACKS", Const, 16, ""},
+		{"TCP_SYNCNT", Const, 0, ""},
+		{"TCP_VENDOR", Const, 3, ""},
+		{"TCP_WINDOW_CLAMP", Const, 0, ""},
+		{"TCSAFLUSH", Const, 1, ""},
+		{"TCSETS", Const, 0, ""},
+		{"TF_DISCONNECT", Const, 0, ""},
+		{"TF_REUSE_SOCKET", Const, 0, ""},
+		{"TF_USE_DEFAULT_WORKER", Const, 0, ""},
+		{"TF_USE_KERNEL_APC", Const, 0, ""},
+		{"TF_USE_SYSTEM_THREAD", Const, 0, ""},
+		{"TF_WRITE_BEHIND", Const, 0, ""},
+		{"TH32CS_INHERIT", Const, 4, ""},
+		{"TH32CS_SNAPALL", Const, 4, ""},
+		{"TH32CS_SNAPHEAPLIST", Const, 4, ""},
+		{"TH32CS_SNAPMODULE", Const, 4, ""},
+		{"TH32CS_SNAPMODULE32", Const, 4, ""},
+		{"TH32CS_SNAPPROCESS", Const, 4, ""},
+		{"TH32CS_SNAPTHREAD", Const, 4, ""},
+		{"TIME_ZONE_ID_DAYLIGHT", Const, 0, ""},
+		{"TIME_ZONE_ID_STANDARD", Const, 0, ""},
+		{"TIME_ZONE_ID_UNKNOWN", Const, 0, ""},
+		{"TIOCCBRK", Const, 0, ""},
+		{"TIOCCDTR", Const, 0, ""},
+		{"TIOCCONS", Const, 0, ""},
+		{"TIOCDCDTIMESTAMP", Const, 0, ""},
+		{"TIOCDRAIN", Const, 0, ""},
+		{"TIOCDSIMICROCODE", Const, 0, ""},
+		{"TIOCEXCL", Const, 0, ""},
+		{"TIOCEXT", Const, 0, ""},
+		{"TIOCFLAG_CDTRCTS", Const, 1, ""},
+		{"TIOCFLAG_CLOCAL", Const, 1, ""},
+		{"TIOCFLAG_CRTSCTS", Const, 1, ""},
+		{"TIOCFLAG_MDMBUF", Const, 1, ""},
+		{"TIOCFLAG_PPS", Const, 1, ""},
+		{"TIOCFLAG_SOFTCAR", Const, 1, ""},
+		{"TIOCFLUSH", Const, 0, ""},
+		{"TIOCGDEV", Const, 0, ""},
+		{"TIOCGDRAINWAIT", Const, 0, ""},
+		{"TIOCGETA", Const, 0, ""},
+		{"TIOCGETD", Const, 0, ""},
+		{"TIOCGFLAGS", Const, 1, ""},
+		{"TIOCGICOUNT", Const, 0, ""},
+		{"TIOCGLCKTRMIOS", Const, 0, ""},
+		{"TIOCGLINED", Const, 1, ""},
+		{"TIOCGPGRP", Const, 0, ""},
+		{"TIOCGPTN", Const, 0, ""},
+		{"TIOCGQSIZE", Const, 1, ""},
+		{"TIOCGRANTPT", Const, 1, ""},
+		{"TIOCGRS485", Const, 0, ""},
+		{"TIOCGSERIAL", Const, 0, ""},
+		{"TIOCGSID", Const, 0, ""},
+		{"TIOCGSIZE", Const, 1, ""},
+		{"TIOCGSOFTCAR", Const, 0, ""},
+		{"TIOCGTSTAMP", Const, 1, ""},
+		{"TIOCGWINSZ", Const, 0, ""},
+		{"TIOCINQ", Const, 0, ""},
+		{"TIOCIXOFF", Const, 0, ""},
+		{"TIOCIXON", Const, 0, ""},
+		{"TIOCLINUX", Const, 0, ""},
+		{"TIOCMBIC", Const, 0, ""},
+		{"TIOCMBIS", Const, 0, ""},
+		{"TIOCMGDTRWAIT", Const, 0, ""},
+		{"TIOCMGET", Const, 0, ""},
+		{"TIOCMIWAIT", Const, 0, ""},
+		{"TIOCMODG", Const, 0, ""},
+		{"TIOCMODS", Const, 0, ""},
+		{"TIOCMSDTRWAIT", Const, 0, ""},
+		{"TIOCMSET", Const, 0, ""},
+		{"TIOCM_CAR", Const, 0, ""},
+		{"TIOCM_CD", Const, 0, ""},
+		{"TIOCM_CTS", Const, 0, ""},
+		{"TIOCM_DCD", Const, 0, ""},
+		{"TIOCM_DSR", Const, 0, ""},
+		{"TIOCM_DTR", Const, 0, ""},
+		{"TIOCM_LE", Const, 0, ""},
+		{"TIOCM_RI", Const, 0, ""},
+		{"TIOCM_RNG", Const, 0, ""},
+		{"TIOCM_RTS", Const, 0, ""},
+		{"TIOCM_SR", Const, 0, ""},
+		{"TIOCM_ST", Const, 0, ""},
+		{"TIOCNOTTY", Const, 0, ""},
+		{"TIOCNXCL", Const, 0, ""},
+		{"TIOCOUTQ", Const, 0, ""},
+		{"TIOCPKT", Const, 0, ""},
+		{"TIOCPKT_DATA", Const, 0, ""},
+		{"TIOCPKT_DOSTOP", Const, 0, ""},
+		{"TIOCPKT_FLUSHREAD", Const, 0, ""},
+		{"TIOCPKT_FLUSHWRITE", Const, 0, ""},
+		{"TIOCPKT_IOCTL", Const, 0, ""},
+		{"TIOCPKT_NOSTOP", Const, 0, ""},
+		{"TIOCPKT_START", Const, 0, ""},
+		{"TIOCPKT_STOP", Const, 0, ""},
+		{"TIOCPTMASTER", Const, 0, ""},
+		{"TIOCPTMGET", Const, 1, ""},
+		{"TIOCPTSNAME", Const, 1, ""},
+		{"TIOCPTYGNAME", Const, 0, ""},
+		{"TIOCPTYGRANT", Const, 0, ""},
+		{"TIOCPTYUNLK", Const, 0, ""},
+		{"TIOCRCVFRAME", Const, 1, ""},
+		{"TIOCREMOTE", Const, 0, ""},
+		{"TIOCSBRK", Const, 0, ""},
+		{"TIOCSCONS", Const, 0, ""},
+		{"TIOCSCTTY", Const, 0, ""},
+		{"TIOCSDRAINWAIT", Const, 0, ""},
+		{"TIOCSDTR", Const, 0, ""},
+		{"TIOCSERCONFIG", Const, 0, ""},
+		{"TIOCSERGETLSR", Const, 0, ""},
+		{"TIOCSERGETMULTI", Const, 0, ""},
+		{"TIOCSERGSTRUCT", Const, 0, ""},
+		{"TIOCSERGWILD", Const, 0, ""},
+		{"TIOCSERSETMULTI", Const, 0, ""},
+		{"TIOCSERSWILD", Const, 0, ""},
+		{"TIOCSER_TEMT", Const, 0, ""},
+		{"TIOCSETA", Const, 0, ""},
+		{"TIOCSETAF", Const, 0, ""},
+		{"TIOCSETAW", Const, 0, ""},
+		{"TIOCSETD", Const, 0, ""},
+		{"TIOCSFLAGS", Const, 1, ""},
+		{"TIOCSIG", Const, 0, ""},
+		{"TIOCSLCKTRMIOS", Const, 0, ""},
+		{"TIOCSLINED", Const, 1, ""},
+		{"TIOCSPGRP", Const, 0, ""},
+		{"TIOCSPTLCK", Const, 0, ""},
+		{"TIOCSQSIZE", Const, 1, ""},
+		{"TIOCSRS485", Const, 0, ""},
+		{"TIOCSSERIAL", Const, 0, ""},
+		{"TIOCSSIZE", Const, 1, ""},
+		{"TIOCSSOFTCAR", Const, 0, ""},
+		{"TIOCSTART", Const, 0, ""},
+		{"TIOCSTAT", Const, 0, ""},
+		{"TIOCSTI", Const, 0, ""},
+		{"TIOCSTOP", Const, 0, ""},
+		{"TIOCSTSTAMP", Const, 1, ""},
+		{"TIOCSWINSZ", Const, 0, ""},
+		{"TIOCTIMESTAMP", Const, 0, ""},
+		{"TIOCUCNTL", Const, 0, ""},
+		{"TIOCVHANGUP", Const, 0, ""},
+		{"TIOCXMTFRAME", Const, 1, ""},
+		{"TOKEN_ADJUST_DEFAULT", Const, 0, ""},
+		{"TOKEN_ADJUST_GROUPS", Const, 0, ""},
+		{"TOKEN_ADJUST_PRIVILEGES", Const, 0, ""},
+		{"TOKEN_ADJUST_SESSIONID", Const, 11, ""},
+		{"TOKEN_ALL_ACCESS", Const, 0, ""},
+		{"TOKEN_ASSIGN_PRIMARY", Const, 0, ""},
+		{"TOKEN_DUPLICATE", Const, 0, ""},
+		{"TOKEN_EXECUTE", Const, 0, ""},
+		{"TOKEN_IMPERSONATE", Const, 0, ""},
+		{"TOKEN_QUERY", Const, 0, ""},
+		{"TOKEN_QUERY_SOURCE", Const, 0, ""},
+		{"TOKEN_READ", Const, 0, ""},
+		{"TOKEN_WRITE", Const, 0, ""},
+		{"TOSTOP", Const, 0, ""},
+		{"TRUNCATE_EXISTING", Const, 0, ""},
+		{"TUNATTACHFILTER", Const, 0, ""},
+		{"TUNDETACHFILTER", Const, 0, ""},
+		{"TUNGETFEATURES", Const, 0, ""},
+		{"TUNGETIFF", Const, 0, ""},
+		{"TUNGETSNDBUF", Const, 0, ""},
+		{"TUNGETVNETHDRSZ", Const, 0, ""},
+		{"TUNSETDEBUG", Const, 0, ""},
+		{"TUNSETGROUP", Const, 0, ""},
+		{"TUNSETIFF", Const, 0, ""},
+		{"TUNSETLINK", Const, 0, ""},
+		{"TUNSETNOCSUM", Const, 0, ""},
+		{"TUNSETOFFLOAD", Const, 0, ""},
+		{"TUNSETOWNER", Const, 0, ""},
+		{"TUNSETPERSIST", Const, 0, ""},
+		{"TUNSETSNDBUF", Const, 0, ""},
+		{"TUNSETTXFILTER", Const, 0, ""},
+		{"TUNSETVNETHDRSZ", Const, 0, ""},
+		{"Tee", Func, 0, "func(rfd int, wfd int, len int, flags int) (n int64, err error)"},
+		{"TerminateProcess", Func, 0, ""},
+		{"Termios", Type, 0, ""},
+		{"Termios.Cc", Field, 0, ""},
+		{"Termios.Cflag", Field, 0, ""},
+		{"Termios.Iflag", Field, 0, ""},
+		{"Termios.Ispeed", Field, 0, ""},
+		{"Termios.Lflag", Field, 0, ""},
+		{"Termios.Line", Field, 0, ""},
+		{"Termios.Oflag", Field, 0, ""},
+		{"Termios.Ospeed", Field, 0, ""},
+		{"Termios.Pad_cgo_0", Field, 0, ""},
+		{"Tgkill", Func, 0, "func(tgid int, tid int, sig Signal) (err error)"},
+		{"Time", Func, 0, "func(t *Time_t) (tt Time_t, err error)"},
+		{"Time_t", Type, 0, ""},
+		{"Times", Func, 0, "func(tms *Tms) (ticks uintptr, err error)"},
+		{"Timespec", Type, 0, ""},
+		{"Timespec.Nsec", Field, 0, ""},
+		{"Timespec.Pad_cgo_0", Field, 2, ""},
+		{"Timespec.Sec", Field, 0, ""},
+		{"TimespecToNsec", Func, 0, "func(ts Timespec) int64"},
+		{"Timeval", Type, 0, ""},
+		{"Timeval.Pad_cgo_0", Field, 0, ""},
+		{"Timeval.Sec", Field, 0, ""},
+		{"Timeval.Usec", Field, 0, ""},
+		{"Timeval32", Type, 0, ""},
+		{"Timeval32.Sec", Field, 0, ""},
+		{"Timeval32.Usec", Field, 0, ""},
+		{"TimevalToNsec", Func, 0, "func(tv Timeval) int64"},
+		{"Timex", Type, 0, ""},
+		{"Timex.Calcnt", Field, 0, ""},
+		{"Timex.Constant", Field, 0, ""},
+		{"Timex.Errcnt", Field, 0, ""},
+		{"Timex.Esterror", Field, 0, ""},
+		{"Timex.Freq", Field, 0, ""},
+		{"Timex.Jitcnt", Field, 0, ""},
+		{"Timex.Jitter", Field, 0, ""},
+		{"Timex.Maxerror", Field, 0, ""},
+		{"Timex.Modes", Field, 0, ""},
+		{"Timex.Offset", Field, 0, ""},
+		{"Timex.Pad_cgo_0", Field, 0, ""},
+		{"Timex.Pad_cgo_1", Field, 0, ""},
+		{"Timex.Pad_cgo_2", Field, 0, ""},
+		{"Timex.Pad_cgo_3", Field, 0, ""},
+		{"Timex.Ppsfreq", Field, 0, ""},
+		{"Timex.Precision", Field, 0, ""},
+		{"Timex.Shift", Field, 0, ""},
+		{"Timex.Stabil", Field, 0, ""},
+		{"Timex.Status", Field, 0, ""},
+		{"Timex.Stbcnt", Field, 0, ""},
+		{"Timex.Tai", Field, 0, ""},
+		{"Timex.Tick", Field, 0, ""},
+		{"Timex.Time", Field, 0, ""},
+		{"Timex.Tolerance", Field, 0, ""},
+		{"Timezoneinformation", Type, 0, ""},
+		{"Timezoneinformation.Bias", Field, 0, ""},
+		{"Timezoneinformation.DaylightBias", Field, 0, ""},
+		{"Timezoneinformation.DaylightDate", Field, 0, ""},
+		{"Timezoneinformation.DaylightName", Field, 0, ""},
+		{"Timezoneinformation.StandardBias", Field, 0, ""},
+		{"Timezoneinformation.StandardDate", Field, 0, ""},
+		{"Timezoneinformation.StandardName", Field, 0, ""},
+		{"Tms", Type, 0, ""},
+		{"Tms.Cstime", Field, 0, ""},
+		{"Tms.Cutime", Field, 0, ""},
+		{"Tms.Stime", Field, 0, ""},
+		{"Tms.Utime", Field, 0, ""},
+		{"Token", Type, 0, ""},
+		{"TokenAccessInformation", Const, 0, ""},
+		{"TokenAuditPolicy", Const, 0, ""},
+		{"TokenDefaultDacl", Const, 0, ""},
+		{"TokenElevation", Const, 0, ""},
+		{"TokenElevationType", Const, 0, ""},
+		{"TokenGroups", Const, 0, ""},
+		{"TokenGroupsAndPrivileges", Const, 0, ""},
+		{"TokenHasRestrictions", Const, 0, ""},
+		{"TokenImpersonationLevel", Const, 0, ""},
+		{"TokenIntegrityLevel", Const, 0, ""},
+		{"TokenLinkedToken", Const, 0, ""},
+		{"TokenLogonSid", Const, 0, ""},
+		{"TokenMandatoryPolicy", Const, 0, ""},
+		{"TokenOrigin", Const, 0, ""},
+		{"TokenOwner", Const, 0, ""},
+		{"TokenPrimaryGroup", Const, 0, ""},
+		{"TokenPrivileges", Const, 0, ""},
+		{"TokenRestrictedSids", Const, 0, ""},
+		{"TokenSandBoxInert", Const, 0, ""},
+		{"TokenSessionId", Const, 0, ""},
+		{"TokenSessionReference", Const, 0, ""},
+		{"TokenSource", Const, 0, ""},
+		{"TokenStatistics", Const, 0, ""},
+		{"TokenType", Const, 0, ""},
+		{"TokenUIAccess", Const, 0, ""},
+		{"TokenUser", Const, 0, ""},
+		{"TokenVirtualizationAllowed", Const, 0, ""},
+		{"TokenVirtualizationEnabled", Const, 0, ""},
+		{"Tokenprimarygroup", Type, 0, ""},
+		{"Tokenprimarygroup.PrimaryGroup", Field, 0, ""},
+		{"Tokenuser", Type, 0, ""},
+		{"Tokenuser.User", Field, 0, ""},
+		{"TranslateAccountName", Func, 0, ""},
+		{"TranslateName", Func, 0, ""},
+		{"TransmitFile", Func, 0, ""},
+		{"TransmitFileBuffers", Type, 0, ""},
+		{"TransmitFileBuffers.Head", Field, 0, ""},
+		{"TransmitFileBuffers.HeadLength", Field, 0, ""},
+		{"TransmitFileBuffers.Tail", Field, 0, ""},
+		{"TransmitFileBuffers.TailLength", Field, 0, ""},
+		{"Truncate", Func, 0, "func(path string, length int64) (err error)"},
+		{"UNIX_PATH_MAX", Const, 12, ""},
+		{"USAGE_MATCH_TYPE_AND", Const, 0, ""},
+		{"USAGE_MATCH_TYPE_OR", Const, 0, ""},
+		{"UTF16FromString", Func, 1, ""},
+		{"UTF16PtrFromString", Func, 1, ""},
+		{"UTF16ToString", Func, 0, ""},
+		{"Ucred", Type, 0, ""},
+		{"Ucred.Gid", Field, 0, ""},
+		{"Ucred.Pid", Field, 0, ""},
+		{"Ucred.Uid", Field, 0, ""},
+		{"Umask", Func, 0, "func(mask int) (oldmask int)"},
+		{"Uname", Func, 0, "func(buf *Utsname) (err error)"},
+		{"Undelete", Func, 0, ""},
+		{"UnixCredentials", Func, 0, "func(ucred *Ucred) []byte"},
+		{"UnixRights", Func, 0, "func(fds ...int) []byte"},
+		{"Unlink", Func, 0, "func(path string) error"},
+		{"Unlinkat", Func, 0, "func(dirfd int, path string) error"},
+		{"UnmapViewOfFile", Func, 0, ""},
+		{"Unmount", Func, 0, "func(target string, flags int) (err error)"},
+		{"Unsetenv", Func, 4, "func(key string) error"},
+		{"Unshare", Func, 0, "func(flags int) (err error)"},
+		{"UserInfo10", Type, 0, ""},
+		{"UserInfo10.Comment", Field, 0, ""},
+		{"UserInfo10.FullName", Field, 0, ""},
+		{"UserInfo10.Name", Field, 0, ""},
+		{"UserInfo10.UsrComment", Field, 0, ""},
+		{"Ustat", Func, 0, "func(dev int, ubuf *Ustat_t) (err error)"},
+		{"Ustat_t", Type, 0, ""},
+		{"Ustat_t.Fname", Field, 0, ""},
+		{"Ustat_t.Fpack", Field, 0, ""},
+		{"Ustat_t.Pad_cgo_0", Field, 0, ""},
+		{"Ustat_t.Pad_cgo_1", Field, 0, ""},
+		{"Ustat_t.Tfree", Field, 0, ""},
+		{"Ustat_t.Tinode", Field, 0, ""},
+		{"Utimbuf", Type, 0, ""},
+		{"Utimbuf.Actime", Field, 0, ""},
+		{"Utimbuf.Modtime", Field, 0, ""},
+		{"Utime", Func, 0, "func(path string, buf *Utimbuf) (err error)"},
+		{"Utimes", Func, 0, "func(path string, tv []Timeval) (err error)"},
+		{"UtimesNano", Func, 1, "func(path string, ts []Timespec) (err error)"},
+		{"Utsname", Type, 0, ""},
+		{"Utsname.Domainname", Field, 0, ""},
+		{"Utsname.Machine", Field, 0, ""},
+		{"Utsname.Nodename", Field, 0, ""},
+		{"Utsname.Release", Field, 0, ""},
+		{"Utsname.Sysname", Field, 0, ""},
+		{"Utsname.Version", Field, 0, ""},
+		{"VDISCARD", Const, 0, ""},
+		{"VDSUSP", Const, 1, ""},
+		{"VEOF", Const, 0, ""},
+		{"VEOL", Const, 0, ""},
+		{"VEOL2", Const, 0, ""},
+		{"VERASE", Const, 0, ""},
+		{"VERASE2", Const, 1, ""},
+		{"VINTR", Const, 0, ""},
+		{"VKILL", Const, 0, ""},
+		{"VLNEXT", Const, 0, ""},
+		{"VMIN", Const, 0, ""},
+		{"VQUIT", Const, 0, ""},
+		{"VREPRINT", Const, 0, ""},
+		{"VSTART", Const, 0, ""},
+		{"VSTATUS", Const, 1, ""},
+		{"VSTOP", Const, 0, ""},
+		{"VSUSP", Const, 0, ""},
+		{"VSWTC", Const, 0, ""},
+		{"VT0", Const, 1, ""},
+		{"VT1", Const, 1, ""},
+		{"VTDLY", Const, 1, ""},
+		{"VTIME", Const, 0, ""},
+		{"VWERASE", Const, 0, ""},
+		{"VirtualLock", Func, 0, ""},
+		{"VirtualUnlock", Func, 0, ""},
+		{"WAIT_ABANDONED", Const, 0, ""},
+		{"WAIT_FAILED", Const, 0, ""},
+		{"WAIT_OBJECT_0", Const, 0, ""},
+		{"WAIT_TIMEOUT", Const, 0, ""},
+		{"WALL", Const, 0, ""},
+		{"WALLSIG", Const, 1, ""},
+		{"WALTSIG", Const, 1, ""},
+		{"WCLONE", Const, 0, ""},
+		{"WCONTINUED", Const, 0, ""},
+		{"WCOREFLAG", Const, 0, ""},
+		{"WEXITED", Const, 0, ""},
+		{"WLINUXCLONE", Const, 0, ""},
+		{"WNOHANG", Const, 0, ""},
+		{"WNOTHREAD", Const, 0, ""},
+		{"WNOWAIT", Const, 0, ""},
+		{"WNOZOMBIE", Const, 1, ""},
+		{"WOPTSCHECKED", Const, 1, ""},
+		{"WORDSIZE", Const, 0, ""},
+		{"WSABuf", Type, 0, ""},
+		{"WSABuf.Buf", Field, 0, ""},
+		{"WSABuf.Len", Field, 0, ""},
+		{"WSACleanup", Func, 0, ""},
+		{"WSADESCRIPTION_LEN", Const, 0, ""},
+		{"WSAData", Type, 0, ""},
+		{"WSAData.Description", Field, 0, ""},
+		{"WSAData.HighVersion", Field, 0, ""},
+		{"WSAData.MaxSockets", Field, 0, ""},
+		{"WSAData.MaxUdpDg", Field, 0, ""},
+		{"WSAData.SystemStatus", Field, 0, ""},
+		{"WSAData.VendorInfo", Field, 0, ""},
+		{"WSAData.Version", Field, 0, ""},
+		{"WSAEACCES", Const, 2, ""},
+		{"WSAECONNABORTED", Const, 9, ""},
+		{"WSAECONNRESET", Const, 3, ""},
+		{"WSAENOPROTOOPT", Const, 23, ""},
+		{"WSAEnumProtocols", Func, 2, ""},
+		{"WSAID_CONNECTEX", Var, 1, ""},
+		{"WSAIoctl", Func, 0, ""},
+		{"WSAPROTOCOL_LEN", Const, 2, ""},
+		{"WSAProtocolChain", Type, 2, ""},
+		{"WSAProtocolChain.ChainEntries", Field, 2, ""},
+		{"WSAProtocolChain.ChainLen", Field, 2, ""},
+		{"WSAProtocolInfo", Type, 2, ""},
+		{"WSAProtocolInfo.AddressFamily", Field, 2, ""},
+		{"WSAProtocolInfo.CatalogEntryId", Field, 2, ""},
+		{"WSAProtocolInfo.MaxSockAddr", Field, 2, ""},
+		{"WSAProtocolInfo.MessageSize", Field, 2, ""},
+		{"WSAProtocolInfo.MinSockAddr", Field, 2, ""},
+		{"WSAProtocolInfo.NetworkByteOrder", Field, 2, ""},
+		{"WSAProtocolInfo.Protocol", Field, 2, ""},
+		{"WSAProtocolInfo.ProtocolChain", Field, 2, ""},
+		{"WSAProtocolInfo.ProtocolMaxOffset", Field, 2, ""},
+		{"WSAProtocolInfo.ProtocolName", Field, 2, ""},
+		{"WSAProtocolInfo.ProviderFlags", Field, 2, ""},
+		{"WSAProtocolInfo.ProviderId", Field, 2, ""},
+		{"WSAProtocolInfo.ProviderReserved", Field, 2, ""},
+		{"WSAProtocolInfo.SecurityScheme", Field, 2, ""},
+		{"WSAProtocolInfo.ServiceFlags1", Field, 2, ""},
+		{"WSAProtocolInfo.ServiceFlags2", Field, 2, ""},
+		{"WSAProtocolInfo.ServiceFlags3", Field, 2, ""},
+		{"WSAProtocolInfo.ServiceFlags4", Field, 2, ""},
+		{"WSAProtocolInfo.SocketType", Field, 2, ""},
+		{"WSAProtocolInfo.Version", Field, 2, ""},
+		{"WSARecv", Func, 0, ""},
+		{"WSARecvFrom", Func, 0, ""},
+		{"WSASYS_STATUS_LEN", Const, 0, ""},
+		{"WSASend", Func, 0, ""},
+		{"WSASendTo", Func, 0, ""},
+		{"WSASendto", Func, 0, ""},
+		{"WSAStartup", Func, 0, ""},
+		{"WSTOPPED", Const, 0, ""},
+		{"WTRAPPED", Const, 1, ""},
+		{"WUNTRACED", Const, 0, ""},
+		{"Wait4", Func, 0, "func(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error)"},
+		{"WaitForSingleObject", Func, 0, ""},
+		{"WaitStatus", Type, 0, ""},
+		{"WaitStatus.ExitCode", Field, 0, ""},
+		{"Win32FileAttributeData", Type, 0, ""},
+		{"Win32FileAttributeData.CreationTime", Field, 0, ""},
+		{"Win32FileAttributeData.FileAttributes", Field, 0, ""},
+		{"Win32FileAttributeData.FileSizeHigh", Field, 0, ""},
+		{"Win32FileAttributeData.FileSizeLow", Field, 0, ""},
+		{"Win32FileAttributeData.LastAccessTime", Field, 0, ""},
+		{"Win32FileAttributeData.LastWriteTime", Field, 0, ""},
+		{"Win32finddata", Type, 0, ""},
+		{"Win32finddata.AlternateFileName", Field, 0, ""},
+		{"Win32finddata.CreationTime", Field, 0, ""},
+		{"Win32finddata.FileAttributes", Field, 0, ""},
+		{"Win32finddata.FileName", Field, 0, ""},
+		{"Win32finddata.FileSizeHigh", Field, 0, ""},
+		{"Win32finddata.FileSizeLow", Field, 0, ""},
+		{"Win32finddata.LastAccessTime", Field, 0, ""},
+		{"Win32finddata.LastWriteTime", Field, 0, ""},
+		{"Win32finddata.Reserved0", Field, 0, ""},
+		{"Win32finddata.Reserved1", Field, 0, ""},
+		{"Write", Func, 0, "func(fd int, p []byte) (n int, err error)"},
+		{"WriteConsole", Func, 1, ""},
+		{"WriteFile", Func, 0, ""},
+		{"X509_ASN_ENCODING", Const, 0, ""},
+		{"XCASE", Const, 0, ""},
+		{"XP1_CONNECTIONLESS", Const, 2, ""},
+		{"XP1_CONNECT_DATA", Const, 2, ""},
+		{"XP1_DISCONNECT_DATA", Const, 2, ""},
+		{"XP1_EXPEDITED_DATA", Const, 2, ""},
+		{"XP1_GRACEFUL_CLOSE", Const, 2, ""},
+		{"XP1_GUARANTEED_DELIVERY", Const, 2, ""},
+		{"XP1_GUARANTEED_ORDER", Const, 2, ""},
+		{"XP1_IFS_HANDLES", Const, 2, ""},
+		{"XP1_MESSAGE_ORIENTED", Const, 2, ""},
+		{"XP1_MULTIPOINT_CONTROL_PLANE", Const, 2, ""},
+		{"XP1_MULTIPOINT_DATA_PLANE", Const, 2, ""},
+		{"XP1_PARTIAL_MESSAGE", Const, 2, ""},
+		{"XP1_PSEUDO_STREAM", Const, 2, ""},
+		{"XP1_QOS_SUPPORTED", Const, 2, ""},
+		{"XP1_SAN_SUPPORT_SDP", Const, 2, ""},
+		{"XP1_SUPPORT_BROADCAST", Const, 2, ""},
+		{"XP1_SUPPORT_MULTIPOINT", Const, 2, ""},
+		{"XP1_UNI_RECV", Const, 2, ""},
+		{"XP1_UNI_SEND", Const, 2, ""},
+	},
+	"syscall/js": {
+		{"CopyBytesToGo", Func, 0, ""},
+		{"CopyBytesToJS", Func, 0, ""},
+		{"Error", Type, 0, ""},
+		{"Func", Type, 0, ""},
+		{"FuncOf", Func, 0, ""},
+		{"Global", Func, 0, ""},
+		{"Null", Func, 0, ""},
+		{"Type", Type, 0, ""},
+		{"TypeBoolean", Const, 0, ""},
+		{"TypeFunction", Const, 0, ""},
+		{"TypeNull", Const, 0, ""},
+		{"TypeNumber", Const, 0, ""},
+		{"TypeObject", Const, 0, ""},
+		{"TypeString", Const, 0, ""},
+		{"TypeSymbol", Const, 0, ""},
+		{"TypeUndefined", Const, 0, ""},
+		{"Undefined", Func, 0, ""},
+		{"Value", Type, 0, ""},
+		{"ValueError", Type, 0, ""},
+		{"ValueOf", Func, 0, ""},
+	},
+	"testing": {
+		{"(*B).ArtifactDir", Method, 26, ""},
+		{"(*B).Attr", Method, 25, ""},
+		{"(*B).Chdir", Method, 24, ""},
+		{"(*B).Cleanup", Method, 14, ""},
+		{"(*B).Context", Method, 24, ""},
+		{"(*B).Elapsed", Method, 20, ""},
+		{"(*B).Error", Method, 0, ""},
+		{"(*B).Errorf", Method, 0, ""},
+		{"(*B).Fail", Method, 0, ""},
+		{"(*B).FailNow", Method, 0, ""},
+		{"(*B).Failed", Method, 0, ""},
+		{"(*B).Fatal", Method, 0, ""},
+		{"(*B).Fatalf", Method, 0, ""},
+		{"(*B).Helper", Method, 9, ""},
+		{"(*B).Log", Method, 0, ""},
+		{"(*B).Logf", Method, 0, ""},
+		{"(*B).Loop", Method, 24, ""},
+		{"(*B).Name", Method, 8, ""},
+		{"(*B).Output", Method, 25, ""},
+		{"(*B).ReportAllocs", Method, 1, ""},
+		{"(*B).ReportMetric", Method, 13, ""},
+		{"(*B).ResetTimer", Method, 0, ""},
+		{"(*B).Run", Method, 7, ""},
+		{"(*B).RunParallel", Method, 3, ""},
+		{"(*B).SetBytes", Method, 0, ""},
+		{"(*B).SetParallelism", Method, 3, ""},
+		{"(*B).Setenv", Method, 17, ""},
+		{"(*B).Skip", Method, 1, ""},
+		{"(*B).SkipNow", Method, 1, ""},
+		{"(*B).Skipf", Method, 1, ""},
+		{"(*B).Skipped", Method, 1, ""},
+		{"(*B).StartTimer", Method, 0, ""},
+		{"(*B).StopTimer", Method, 0, ""},
+		{"(*B).TempDir", Method, 15, ""},
+		{"(*F).Add", Method, 18, ""},
+		{"(*F).ArtifactDir", Method, 26, ""},
+		{"(*F).Attr", Method, 25, ""},
+		{"(*F).Chdir", Method, 24, ""},
+		{"(*F).Cleanup", Method, 18, ""},
+		{"(*F).Context", Method, 24, ""},
+		{"(*F).Error", Method, 18, ""},
+		{"(*F).Errorf", Method, 18, ""},
+		{"(*F).Fail", Method, 18, ""},
+		{"(*F).FailNow", Method, 18, ""},
+		{"(*F).Failed", Method, 18, ""},
+		{"(*F).Fatal", Method, 18, ""},
+		{"(*F).Fatalf", Method, 18, ""},
+		{"(*F).Fuzz", Method, 18, ""},
+		{"(*F).Helper", Method, 18, ""},
+		{"(*F).Log", Method, 18, ""},
+		{"(*F).Logf", Method, 18, ""},
+		{"(*F).Name", Method, 18, ""},
+		{"(*F).Output", Method, 25, ""},
+		{"(*F).Setenv", Method, 18, ""},
+		{"(*F).Skip", Method, 18, ""},
+		{"(*F).SkipNow", Method, 18, ""},
+		{"(*F).Skipf", Method, 18, ""},
+		{"(*F).Skipped", Method, 18, ""},
+		{"(*F).TempDir", Method, 18, ""},
+		{"(*M).Run", Method, 4, ""},
+		{"(*PB).Next", Method, 3, ""},
+		{"(*T).ArtifactDir", Method, 26, ""},
+		{"(*T).Attr", Method, 25, ""},
+		{"(*T).Chdir", Method, 24, ""},
+		{"(*T).Cleanup", Method, 14, ""},
+		{"(*T).Context", Method, 24, ""},
+		{"(*T).Deadline", Method, 15, ""},
+		{"(*T).Error", Method, 0, ""},
+		{"(*T).Errorf", Method, 0, ""},
+		{"(*T).Fail", Method, 0, ""},
+		{"(*T).FailNow", Method, 0, ""},
+		{"(*T).Failed", Method, 0, ""},
+		{"(*T).Fatal", Method, 0, ""},
+		{"(*T).Fatalf", Method, 0, ""},
+		{"(*T).Helper", Method, 9, ""},
+		{"(*T).Log", Method, 0, ""},
+		{"(*T).Logf", Method, 0, ""},
+		{"(*T).Name", Method, 8, ""},
+		{"(*T).Output", Method, 25, ""},
+		{"(*T).Parallel", Method, 0, ""},
+		{"(*T).Run", Method, 7, ""},
+		{"(*T).Setenv", Method, 17, ""},
+		{"(*T).Skip", Method, 1, ""},
+		{"(*T).SkipNow", Method, 1, ""},
+		{"(*T).Skipf", Method, 1, ""},
+		{"(*T).Skipped", Method, 1, ""},
+		{"(*T).TempDir", Method, 15, ""},
+		{"(BenchmarkResult).AllocedBytesPerOp", Method, 1, ""},
+		{"(BenchmarkResult).AllocsPerOp", Method, 1, ""},
+		{"(BenchmarkResult).MemString", Method, 1, ""},
+		{"(BenchmarkResult).NsPerOp", Method, 0, ""},
+		{"(BenchmarkResult).String", Method, 0, ""},
+		{"(TB).ArtifactDir", Method, 26, ""},
+		{"(TB).Attr", Method, 25, ""},
+		{"(TB).Chdir", Method, 24, ""},
+		{"(TB).Cleanup", Method, 14, ""},
+		{"(TB).Context", Method, 24, ""},
+		{"(TB).Error", Method, 2, ""},
+		{"(TB).Errorf", Method, 2, ""},
+		{"(TB).Fail", Method, 2, ""},
+		{"(TB).FailNow", Method, 2, ""},
+		{"(TB).Failed", Method, 2, ""},
+		{"(TB).Fatal", Method, 2, ""},
+		{"(TB).Fatalf", Method, 2, ""},
+		{"(TB).Helper", Method, 9, ""},
+		{"(TB).Log", Method, 2, ""},
+		{"(TB).Logf", Method, 2, ""},
+		{"(TB).Name", Method, 8, ""},
+		{"(TB).Output", Method, 25, ""},
+		{"(TB).Setenv", Method, 17, ""},
+		{"(TB).Skip", Method, 2, ""},
+		{"(TB).SkipNow", Method, 2, ""},
+		{"(TB).Skipf", Method, 2, ""},
+		{"(TB).Skipped", Method, 2, ""},
+		{"(TB).TempDir", Method, 15, ""},
+		{"AllocsPerRun", Func, 1, "func(runs int, f func()) (avg float64)"},
+		{"B", Type, 0, ""},
+		{"B.N", Field, 0, ""},
+		{"Benchmark", Func, 0, "func(f func(b *B)) BenchmarkResult"},
+		{"BenchmarkResult", Type, 0, ""},
+		{"BenchmarkResult.Bytes", Field, 0, ""},
+		{"BenchmarkResult.Extra", Field, 13, ""},
+		{"BenchmarkResult.MemAllocs", Field, 1, ""},
+		{"BenchmarkResult.MemBytes", Field, 1, ""},
+		{"BenchmarkResult.N", Field, 0, ""},
+		{"BenchmarkResult.T", Field, 0, ""},
+		{"Cover", Type, 2, ""},
+		{"Cover.Blocks", Field, 2, ""},
+		{"Cover.Counters", Field, 2, ""},
+		{"Cover.CoveredPackages", Field, 2, ""},
+		{"Cover.Mode", Field, 2, ""},
+		{"CoverBlock", Type, 2, ""},
+		{"CoverBlock.Col0", Field, 2, ""},
+		{"CoverBlock.Col1", Field, 2, ""},
+		{"CoverBlock.Line0", Field, 2, ""},
+		{"CoverBlock.Line1", Field, 2, ""},
+		{"CoverBlock.Stmts", Field, 2, ""},
+		{"CoverMode", Func, 8, "func() string"},
+		{"Coverage", Func, 4, "func() float64"},
+		{"F", Type, 18, ""},
+		{"Init", Func, 13, "func()"},
+		{"InternalBenchmark", Type, 0, ""},
+		{"InternalBenchmark.F", Field, 0, ""},
+		{"InternalBenchmark.Name", Field, 0, ""},
+		{"InternalExample", Type, 0, ""},
+		{"InternalExample.F", Field, 0, ""},
+		{"InternalExample.Name", Field, 0, ""},
+		{"InternalExample.Output", Field, 0, ""},
+		{"InternalExample.Unordered", Field, 7, ""},
+		{"InternalFuzzTarget", Type, 18, ""},
+		{"InternalFuzzTarget.Fn", Field, 18, ""},
+		{"InternalFuzzTarget.Name", Field, 18, ""},
+		{"InternalTest", Type, 0, ""},
+		{"InternalTest.F", Field, 0, ""},
+		{"InternalTest.Name", Field, 0, ""},
+		{"M", Type, 4, ""},
+		{"Main", Func, 0, "func(matchString func(pat string, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample)"},
+		{"MainStart", Func, 4, "func(deps testDeps, tests []InternalTest, benchmarks []InternalBenchmark, fuzzTargets []InternalFuzzTarget, examples []InternalExample) *M"},
+		{"PB", Type, 3, ""},
+		{"RegisterCover", Func, 2, "func(c Cover)"},
+		{"RunBenchmarks", Func, 0, "func(matchString func(pat string, str string) (bool, error), benchmarks []InternalBenchmark)"},
+		{"RunExamples", Func, 0, "func(matchString func(pat string, str string) (bool, error), examples []InternalExample) (ok bool)"},
+		{"RunTests", Func, 0, "func(matchString func(pat string, str string) (bool, error), tests []InternalTest) (ok bool)"},
+		{"Short", Func, 0, "func() bool"},
+		{"T", Type, 0, ""},
+		{"Testing", Func, 21, "func() bool"},
+		{"Verbose", Func, 1, "func() bool"},
+	},
+	"testing/cryptotest": {
+		{"SetGlobalRandom", Func, 26, "func(t *testing.T, seed uint64)"},
+	},
+	"testing/fstest": {
+		{"(MapFS).Glob", Method, 16, ""},
+		{"(MapFS).Lstat", Method, 25, ""},
+		{"(MapFS).Open", Method, 16, ""},
+		{"(MapFS).ReadDir", Method, 16, ""},
+		{"(MapFS).ReadFile", Method, 16, ""},
+		{"(MapFS).ReadLink", Method, 25, ""},
+		{"(MapFS).Stat", Method, 16, ""},
+		{"(MapFS).Sub", Method, 16, ""},
+		{"MapFS", Type, 16, ""},
+		{"MapFile", Type, 16, ""},
+		{"MapFile.Data", Field, 16, ""},
+		{"MapFile.ModTime", Field, 16, ""},
+		{"MapFile.Mode", Field, 16, ""},
+		{"MapFile.Sys", Field, 16, ""},
+		{"TestFS", Func, 16, "func(fsys fs.FS, expected ...string) error"},
+	},
+	"testing/iotest": {
+		{"DataErrReader", Func, 0, "func(r io.Reader) io.Reader"},
+		{"ErrReader", Func, 16, "func(err error) io.Reader"},
+		{"ErrTimeout", Var, 0, ""},
+		{"HalfReader", Func, 0, "func(r io.Reader) io.Reader"},
+		{"NewReadLogger", Func, 0, "func(prefix string, r io.Reader) io.Reader"},
+		{"NewWriteLogger", Func, 0, "func(prefix string, w io.Writer) io.Writer"},
+		{"OneByteReader", Func, 0, "func(r io.Reader) io.Reader"},
+		{"TestReader", Func, 16, "func(r io.Reader, content []byte) error"},
+		{"TimeoutReader", Func, 0, "func(r io.Reader) io.Reader"},
+		{"TruncateWriter", Func, 0, "func(w io.Writer, n int64) io.Writer"},
+	},
+	"testing/quick": {
+		{"(*CheckEqualError).Error", Method, 0, ""},
+		{"(*CheckError).Error", Method, 0, ""},
+		{"(Generator).Generate", Method, 0, ""},
+		{"(SetupError).Error", Method, 0, ""},
+		{"Check", Func, 0, "func(f any, config *Config) error"},
+		{"CheckEqual", Func, 0, "func(f any, g any, config *Config) error"},
+		{"CheckEqualError", Type, 0, ""},
+		{"CheckEqualError.CheckError", Field, 0, ""},
+		{"CheckEqualError.Out1", Field, 0, ""},
+		{"CheckEqualError.Out2", Field, 0, ""},
+		{"CheckError", Type, 0, ""},
+		{"CheckError.Count", Field, 0, ""},
+		{"CheckError.In", Field, 0, ""},
+		{"Config", Type, 0, ""},
+		{"Config.MaxCount", Field, 0, ""},
+		{"Config.MaxCountScale", Field, 0, ""},
+		{"Config.Rand", Field, 0, ""},
+		{"Config.Values", Field, 0, ""},
+		{"Generator", Type, 0, ""},
+		{"SetupError", Type, 0, ""},
+		{"Value", Func, 0, "func(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool)"},
+	},
+	"testing/slogtest": {
+		{"Run", Func, 22, "func(t *testing.T, newHandler func(*testing.T) slog.Handler, result func(*testing.T) map[string]any)"},
+		{"TestHandler", Func, 21, "func(h slog.Handler, results func() []map[string]any) error"},
+	},
+	"testing/synctest": {
+		{"Sleep", Func, 27, "func(d time.Duration)"},
+		{"Test", Func, 25, "func(t *testing.T, f func(*testing.T))"},
+		{"Wait", Func, 25, "func()"},
+	},
+	"text/scanner": {
+		{"(*Position).IsValid", Method, 0, ""},
+		{"(*Scanner).Init", Method, 0, ""},
+		{"(*Scanner).IsValid", Method, 0, ""},
+		{"(*Scanner).Next", Method, 0, ""},
+		{"(*Scanner).Peek", Method, 0, ""},
+		{"(*Scanner).Pos", Method, 0, ""},
+		{"(*Scanner).Scan", Method, 0, ""},
+		{"(*Scanner).TokenText", Method, 0, ""},
+		{"(Position).String", Method, 0, ""},
+		{"(Scanner).String", Method, 0, ""},
+		{"Char", Const, 0, ""},
+		{"Comment", Const, 0, ""},
+		{"EOF", Const, 0, ""},
+		{"Float", Const, 0, ""},
+		{"GoTokens", Const, 0, ""},
+		{"GoWhitespace", Const, 0, ""},
+		{"Ident", Const, 0, ""},
+		{"Int", Const, 0, ""},
+		{"Position", Type, 0, ""},
+		{"Position.Column", Field, 0, ""},
+		{"Position.Filename", Field, 0, ""},
+		{"Position.Line", Field, 0, ""},
+		{"Position.Offset", Field, 0, ""},
+		{"RawString", Const, 0, ""},
+		{"ScanChars", Const, 0, ""},
+		{"ScanComments", Const, 0, ""},
+		{"ScanFloats", Const, 0, ""},
+		{"ScanIdents", Const, 0, ""},
+		{"ScanInts", Const, 0, ""},
+		{"ScanRawStrings", Const, 0, ""},
+		{"ScanStrings", Const, 0, ""},
+		{"Scanner", Type, 0, ""},
+		{"Scanner.Error", Field, 0, ""},
+		{"Scanner.ErrorCount", Field, 0, ""},
+		{"Scanner.IsIdentRune", Field, 4, ""},
+		{"Scanner.Mode", Field, 0, ""},
+		{"Scanner.Position", Field, 0, ""},
+		{"Scanner.Whitespace", Field, 0, ""},
+		{"SkipComments", Const, 0, ""},
+		{"String", Const, 0, ""},
+		{"TokenString", Func, 0, "func(tok rune) string"},
+	},
+	"text/tabwriter": {
+		{"(*Writer).Flush", Method, 0, ""},
+		{"(*Writer).Init", Method, 0, ""},
+		{"(*Writer).Write", Method, 0, ""},
+		{"AlignRight", Const, 0, ""},
+		{"Debug", Const, 0, ""},
+		{"DiscardEmptyColumns", Const, 0, ""},
+		{"Escape", Const, 0, ""},
+		{"FilterHTML", Const, 0, ""},
+		{"NewWriter", Func, 0, "func(output io.Writer, minwidth int, tabwidth int, padding int, padchar byte, flags uint) *Writer"},
+		{"StripEscape", Const, 0, ""},
+		{"TabIndent", Const, 0, ""},
+		{"Writer", Type, 0, ""},
+	},
+	"text/template": {
+		{"(*Template).AddParseTree", Method, 0, ""},
+		{"(*Template).Clone", Method, 0, ""},
+		{"(*Template).DefinedTemplates", Method, 5, ""},
+		{"(*Template).Delims", Method, 0, ""},
+		{"(*Template).Execute", Method, 0, ""},
+		{"(*Template).ExecuteTemplate", Method, 0, ""},
+		{"(*Template).Funcs", Method, 0, ""},
+		{"(*Template).Lookup", Method, 0, ""},
+		{"(*Template).Name", Method, 0, ""},
+		{"(*Template).New", Method, 0, ""},
+		{"(*Template).Option", Method, 5, ""},
+		{"(*Template).Parse", Method, 0, ""},
+		{"(*Template).ParseFS", Method, 16, ""},
+		{"(*Template).ParseFiles", Method, 0, ""},
+		{"(*Template).ParseGlob", Method, 0, ""},
+		{"(*Template).Templates", Method, 0, ""},
+		{"(ExecError).Error", Method, 6, ""},
+		{"(ExecError).Unwrap", Method, 13, ""},
+		{"(Template).Copy", Method, 2, ""},
+		{"(Template).ErrorContext", Method, 1, ""},
+		{"ExecError", Type, 6, ""},
+		{"ExecError.Err", Field, 6, ""},
+		{"ExecError.Name", Field, 6, ""},
+		{"FuncMap", Type, 0, ""},
+		{"HTMLEscape", Func, 0, "func(w io.Writer, b []byte)"},
+		{"HTMLEscapeString", Func, 0, "func(s string) string"},
+		{"HTMLEscaper", Func, 0, "func(args ...any) string"},
+		{"IsTrue", Func, 6, "func(val any) (truth bool, ok bool)"},
+		{"JSEscape", Func, 0, "func(w io.Writer, b []byte)"},
+		{"JSEscapeString", Func, 0, "func(s string) string"},
+		{"JSEscaper", Func, 0, "func(args ...any) string"},
+		{"Must", Func, 0, "func(t *Template, err error) *Template"},
+		{"New", Func, 0, "func(name string) *Template"},
+		{"ParseFS", Func, 16, "func(fsys fs.FS, patterns ...string) (*Template, error)"},
+		{"ParseFiles", Func, 0, "func(filenames ...string) (*Template, error)"},
+		{"ParseGlob", Func, 0, "func(pattern string) (*Template, error)"},
+		{"Template", Type, 0, ""},
+		{"Template.Tree", Field, 0, ""},
+		{"URLQueryEscaper", Func, 0, "func(args ...any) string"},
+	},
+	"text/template/parse": {
+		{"(*ActionNode).Copy", Method, 0, ""},
+		{"(*ActionNode).String", Method, 0, ""},
+		{"(*BoolNode).Copy", Method, 0, ""},
+		{"(*BoolNode).String", Method, 0, ""},
+		{"(*BranchNode).Copy", Method, 4, ""},
+		{"(*BranchNode).String", Method, 0, ""},
+		{"(*BreakNode).Copy", Method, 18, ""},
+		{"(*BreakNode).String", Method, 18, ""},
+		{"(*ChainNode).Add", Method, 1, ""},
+		{"(*ChainNode).Copy", Method, 1, ""},
+		{"(*ChainNode).String", Method, 1, ""},
+		{"(*CommandNode).Copy", Method, 0, ""},
+		{"(*CommandNode).String", Method, 0, ""},
+		{"(*CommentNode).Copy", Method, 16, ""},
+		{"(*CommentNode).String", Method, 16, ""},
+		{"(*ContinueNode).Copy", Method, 18, ""},
+		{"(*ContinueNode).String", Method, 18, ""},
+		{"(*DotNode).Copy", Method, 0, ""},
+		{"(*DotNode).String", Method, 0, ""},
+		{"(*DotNode).Type", Method, 0, ""},
+		{"(*FieldNode).Copy", Method, 0, ""},
+		{"(*FieldNode).String", Method, 0, ""},
+		{"(*IdentifierNode).Copy", Method, 0, ""},
+		{"(*IdentifierNode).SetPos", Method, 1, ""},
+		{"(*IdentifierNode).SetTree", Method, 4, ""},
+		{"(*IdentifierNode).String", Method, 0, ""},
+		{"(*IfNode).Copy", Method, 0, ""},
+		{"(*IfNode).String", Method, 0, ""},
+		{"(*ListNode).Copy", Method, 0, ""},
+		{"(*ListNode).CopyList", Method, 0, ""},
+		{"(*ListNode).String", Method, 0, ""},
+		{"(*NilNode).Copy", Method, 1, ""},
+		{"(*NilNode).String", Method, 1, ""},
+		{"(*NilNode).Type", Method, 1, ""},
+		{"(*NumberNode).Copy", Method, 0, ""},
+		{"(*NumberNode).String", Method, 0, ""},
+		{"(*PipeNode).Copy", Method, 0, ""},
+		{"(*PipeNode).CopyPipe", Method, 0, ""},
+		{"(*PipeNode).String", Method, 0, ""},
+		{"(*RangeNode).Copy", Method, 0, ""},
+		{"(*RangeNode).String", Method, 0, ""},
+		{"(*StringNode).Copy", Method, 0, ""},
+		{"(*StringNode).String", Method, 0, ""},
+		{"(*TemplateNode).Copy", Method, 0, ""},
+		{"(*TemplateNode).String", Method, 0, ""},
+		{"(*TextNode).Copy", Method, 0, ""},
+		{"(*TextNode).String", Method, 0, ""},
+		{"(*Tree).Copy", Method, 2, ""},
+		{"(*Tree).ErrorContext", Method, 1, ""},
+		{"(*Tree).Parse", Method, 0, ""},
+		{"(*VariableNode).Copy", Method, 0, ""},
+		{"(*VariableNode).String", Method, 0, ""},
+		{"(*WithNode).Copy", Method, 0, ""},
+		{"(*WithNode).String", Method, 0, ""},
+		{"(ActionNode).Position", Method, 1, ""},
+		{"(ActionNode).Type", Method, 0, ""},
+		{"(BoolNode).Position", Method, 1, ""},
+		{"(BoolNode).Type", Method, 0, ""},
+		{"(BranchNode).Position", Method, 1, ""},
+		{"(BranchNode).Type", Method, 0, ""},
+		{"(BreakNode).Position", Method, 18, ""},
+		{"(BreakNode).Type", Method, 18, ""},
+		{"(ChainNode).Position", Method, 1, ""},
+		{"(ChainNode).Type", Method, 1, ""},
+		{"(CommandNode).Position", Method, 1, ""},
+		{"(CommandNode).Type", Method, 0, ""},
+		{"(CommentNode).Position", Method, 16, ""},
+		{"(CommentNode).Type", Method, 16, ""},
+		{"(ContinueNode).Position", Method, 18, ""},
+		{"(ContinueNode).Type", Method, 18, ""},
+		{"(DotNode).Position", Method, 1, ""},
+		{"(FieldNode).Position", Method, 1, ""},
+		{"(FieldNode).Type", Method, 0, ""},
+		{"(IdentifierNode).Position", Method, 1, ""},
+		{"(IdentifierNode).Type", Method, 0, ""},
+		{"(IfNode).Position", Method, 1, ""},
+		{"(IfNode).Type", Method, 0, ""},
+		{"(ListNode).Position", Method, 1, ""},
+		{"(ListNode).Type", Method, 0, ""},
+		{"(NilNode).Position", Method, 1, ""},
+		{"(Node).Copy", Method, 0, ""},
+		{"(Node).Position", Method, 1, ""},
+		{"(Node).String", Method, 0, ""},
+		{"(Node).Type", Method, 0, ""},
+		{"(NodeType).Type", Method, 0, ""},
+		{"(NumberNode).Position", Method, 1, ""},
+		{"(NumberNode).Type", Method, 0, ""},
+		{"(PipeNode).Position", Method, 1, ""},
+		{"(PipeNode).Type", Method, 0, ""},
+		{"(Pos).Position", Method, 1, ""},
+		{"(RangeNode).Position", Method, 1, ""},
+		{"(RangeNode).Type", Method, 0, ""},
+		{"(StringNode).Position", Method, 1, ""},
+		{"(StringNode).Type", Method, 0, ""},
+		{"(TemplateNode).Position", Method, 1, ""},
+		{"(TemplateNode).Type", Method, 0, ""},
+		{"(TextNode).Position", Method, 1, ""},
+		{"(TextNode).Type", Method, 0, ""},
+		{"(VariableNode).Position", Method, 1, ""},
+		{"(VariableNode).Type", Method, 0, ""},
+		{"(WithNode).Position", Method, 1, ""},
+		{"(WithNode).Type", Method, 0, ""},
+		{"ActionNode", Type, 0, ""},
+		{"ActionNode.Line", Field, 0, ""},
+		{"ActionNode.NodeType", Field, 0, ""},
+		{"ActionNode.Pipe", Field, 0, ""},
+		{"ActionNode.Pos", Field, 1, ""},
+		{"BoolNode", Type, 0, ""},
+		{"BoolNode.NodeType", Field, 0, ""},
+		{"BoolNode.Pos", Field, 1, ""},
+		{"BoolNode.True", Field, 0, ""},
+		{"BranchNode", Type, 0, ""},
+		{"BranchNode.ElseList", Field, 0, ""},
+		{"BranchNode.Line", Field, 0, ""},
+		{"BranchNode.List", Field, 0, ""},
+		{"BranchNode.NodeType", Field, 0, ""},
+		{"BranchNode.Pipe", Field, 0, ""},
+		{"BranchNode.Pos", Field, 1, ""},
+		{"BreakNode", Type, 18, ""},
+		{"BreakNode.Line", Field, 18, ""},
+		{"BreakNode.NodeType", Field, 18, ""},
+		{"BreakNode.Pos", Field, 18, ""},
+		{"ChainNode", Type, 1, ""},
+		{"ChainNode.Field", Field, 1, ""},
+		{"ChainNode.Node", Field, 1, ""},
+		{"ChainNode.NodeType", Field, 1, ""},
+		{"ChainNode.Pos", Field, 1, ""},
+		{"CommandNode", Type, 0, ""},
+		{"CommandNode.Args", Field, 0, ""},
+		{"CommandNode.NodeType", Field, 0, ""},
+		{"CommandNode.Pos", Field, 1, ""},
+		{"CommentNode", Type, 16, ""},
+		{"CommentNode.NodeType", Field, 16, ""},
+		{"CommentNode.Pos", Field, 16, ""},
+		{"CommentNode.Text", Field, 16, ""},
+		{"ContinueNode", Type, 18, ""},
+		{"ContinueNode.Line", Field, 18, ""},
+		{"ContinueNode.NodeType", Field, 18, ""},
+		{"ContinueNode.Pos", Field, 18, ""},
+		{"DotNode", Type, 0, ""},
+		{"DotNode.NodeType", Field, 4, ""},
+		{"DotNode.Pos", Field, 1, ""},
+		{"FieldNode", Type, 0, ""},
+		{"FieldNode.Ident", Field, 0, ""},
+		{"FieldNode.NodeType", Field, 0, ""},
+		{"FieldNode.Pos", Field, 1, ""},
+		{"IdentifierNode", Type, 0, ""},
+		{"IdentifierNode.Ident", Field, 0, ""},
+		{"IdentifierNode.NodeType", Field, 0, ""},
+		{"IdentifierNode.Pos", Field, 1, ""},
+		{"IfNode", Type, 0, ""},
+		{"IfNode.BranchNode", Field, 0, ""},
+		{"IsEmptyTree", Func, 0, "func(n Node) bool"},
+		{"ListNode", Type, 0, ""},
+		{"ListNode.NodeType", Field, 0, ""},
+		{"ListNode.Nodes", Field, 0, ""},
+		{"ListNode.Pos", Field, 1, ""},
+		{"Mode", Type, 16, ""},
+		{"New", Func, 0, "func(name string, funcs ...map[string]any) *Tree"},
+		{"NewIdentifier", Func, 0, "func(ident string) *IdentifierNode"},
+		{"NilNode", Type, 1, ""},
+		{"NilNode.NodeType", Field, 4, ""},
+		{"NilNode.Pos", Field, 1, ""},
+		{"Node", Type, 0, ""},
+		{"NodeAction", Const, 0, ""},
+		{"NodeBool", Const, 0, ""},
+		{"NodeBreak", Const, 18, ""},
+		{"NodeChain", Const, 1, ""},
+		{"NodeCommand", Const, 0, ""},
+		{"NodeComment", Const, 16, ""},
+		{"NodeContinue", Const, 18, ""},
+		{"NodeDot", Const, 0, ""},
+		{"NodeField", Const, 0, ""},
+		{"NodeIdentifier", Const, 0, ""},
+		{"NodeIf", Const, 0, ""},
+		{"NodeList", Const, 0, ""},
+		{"NodeNil", Const, 1, ""},
+		{"NodeNumber", Const, 0, ""},
+		{"NodePipe", Const, 0, ""},
+		{"NodeRange", Const, 0, ""},
+		{"NodeString", Const, 0, ""},
+		{"NodeTemplate", Const, 0, ""},
+		{"NodeText", Const, 0, ""},
+		{"NodeType", Type, 0, ""},
+		{"NodeVariable", Const, 0, ""},
+		{"NodeWith", Const, 0, ""},
+		{"NumberNode", Type, 0, ""},
+		{"NumberNode.Complex128", Field, 0, ""},
+		{"NumberNode.Float64", Field, 0, ""},
+		{"NumberNode.Int64", Field, 0, ""},
+		{"NumberNode.IsComplex", Field, 0, ""},
+		{"NumberNode.IsFloat", Field, 0, ""},
+		{"NumberNode.IsInt", Field, 0, ""},
+		{"NumberNode.IsUint", Field, 0, ""},
+		{"NumberNode.NodeType", Field, 0, ""},
+		{"NumberNode.Pos", Field, 1, ""},
+		{"NumberNode.Text", Field, 0, ""},
+		{"NumberNode.Uint64", Field, 0, ""},
+		{"Parse", Func, 0, "func(name string, text string, leftDelim string, rightDelim string, funcs ...map[string]any) (map[string]*Tree, error)"},
+		{"ParseComments", Const, 16, ""},
+		{"PipeNode", Type, 0, ""},
+		{"PipeNode.Cmds", Field, 0, ""},
+		{"PipeNode.Decl", Field, 0, ""},
+		{"PipeNode.IsAssign", Field, 11, ""},
+		{"PipeNode.Line", Field, 0, ""},
+		{"PipeNode.NodeType", Field, 0, ""},
+		{"PipeNode.Pos", Field, 1, ""},
+		{"Pos", Type, 1, ""},
+		{"RangeNode", Type, 0, ""},
+		{"RangeNode.BranchNode", Field, 0, ""},
+		{"SkipFuncCheck", Const, 17, ""},
+		{"StringNode", Type, 0, ""},
+		{"StringNode.NodeType", Field, 0, ""},
+		{"StringNode.Pos", Field, 1, ""},
+		{"StringNode.Quoted", Field, 0, ""},
+		{"StringNode.Text", Field, 0, ""},
+		{"TemplateNode", Type, 0, ""},
+		{"TemplateNode.Line", Field, 0, ""},
+		{"TemplateNode.Name", Field, 0, ""},
+		{"TemplateNode.NodeType", Field, 0, ""},
+		{"TemplateNode.Pipe", Field, 0, ""},
+		{"TemplateNode.Pos", Field, 1, ""},
+		{"TextNode", Type, 0, ""},
+		{"TextNode.NodeType", Field, 0, ""},
+		{"TextNode.Pos", Field, 1, ""},
+		{"TextNode.Text", Field, 0, ""},
+		{"Tree", Type, 0, ""},
+		{"Tree.Mode", Field, 16, ""},
+		{"Tree.Name", Field, 0, ""},
+		{"Tree.ParseName", Field, 1, ""},
+		{"Tree.Root", Field, 0, ""},
+		{"VariableNode", Type, 0, ""},
+		{"VariableNode.Ident", Field, 0, ""},
+		{"VariableNode.NodeType", Field, 0, ""},
+		{"VariableNode.Pos", Field, 1, ""},
+		{"WithNode", Type, 0, ""},
+		{"WithNode.BranchNode", Field, 0, ""},
+	},
+	"time": {
+		{"(*Location).String", Method, 0, ""},
+		{"(*ParseError).Error", Method, 0, ""},
+		{"(*Ticker).Reset", Method, 15, ""},
+		{"(*Ticker).Stop", Method, 0, ""},
+		{"(*Time).GobDecode", Method, 0, ""},
+		{"(*Time).UnmarshalBinary", Method, 2, ""},
+		{"(*Time).UnmarshalJSON", Method, 0, ""},
+		{"(*Time).UnmarshalText", Method, 2, ""},
+		{"(*Timer).Reset", Method, 1, ""},
+		{"(*Timer).Stop", Method, 0, ""},
+		{"(Duration).Abs", Method, 19, ""},
+		{"(Duration).Hours", Method, 0, ""},
+		{"(Duration).Microseconds", Method, 13, ""},
+		{"(Duration).Milliseconds", Method, 13, ""},
+		{"(Duration).Minutes", Method, 0, ""},
+		{"(Duration).Nanoseconds", Method, 0, ""},
+		{"(Duration).Round", Method, 9, ""},
+		{"(Duration).Seconds", Method, 0, ""},
+		{"(Duration).String", Method, 0, ""},
+		{"(Duration).Truncate", Method, 9, ""},
+		{"(Month).String", Method, 0, ""},
+		{"(Time).Add", Method, 0, ""},
+		{"(Time).AddDate", Method, 0, ""},
+		{"(Time).After", Method, 0, ""},
+		{"(Time).AppendBinary", Method, 24, ""},
+		{"(Time).AppendFormat", Method, 5, ""},
+		{"(Time).AppendText", Method, 24, ""},
+		{"(Time).Before", Method, 0, ""},
+		{"(Time).Clock", Method, 0, ""},
+		{"(Time).Compare", Method, 20, ""},
+		{"(Time).Date", Method, 0, ""},
+		{"(Time).Day", Method, 0, ""},
+		{"(Time).Equal", Method, 0, ""},
+		{"(Time).Format", Method, 0, ""},
+		{"(Time).GoString", Method, 17, ""},
+		{"(Time).GobEncode", Method, 0, ""},
+		{"(Time).Hour", Method, 0, ""},
+		{"(Time).ISOWeek", Method, 0, ""},
+		{"(Time).In", Method, 0, ""},
+		{"(Time).IsDST", Method, 17, ""},
+		{"(Time).IsZero", Method, 0, ""},
+		{"(Time).Local", Method, 0, ""},
+		{"(Time).Location", Method, 0, ""},
+		{"(Time).MarshalBinary", Method, 2, ""},
+		{"(Time).MarshalJSON", Method, 0, ""},
+		{"(Time).MarshalText", Method, 2, ""},
+		{"(Time).Minute", Method, 0, ""},
+		{"(Time).Month", Method, 0, ""},
+		{"(Time).Nanosecond", Method, 0, ""},
+		{"(Time).Round", Method, 1, ""},
+		{"(Time).Second", Method, 0, ""},
+		{"(Time).String", Method, 0, ""},
+		{"(Time).Sub", Method, 0, ""},
+		{"(Time).Truncate", Method, 1, ""},
+		{"(Time).UTC", Method, 0, ""},
+		{"(Time).Unix", Method, 0, ""},
+		{"(Time).UnixMicro", Method, 17, ""},
+		{"(Time).UnixMilli", Method, 17, ""},
+		{"(Time).UnixNano", Method, 0, ""},
+		{"(Time).Weekday", Method, 0, ""},
+		{"(Time).Year", Method, 0, ""},
+		{"(Time).YearDay", Method, 1, ""},
+		{"(Time).Zone", Method, 0, ""},
+		{"(Time).ZoneBounds", Method, 19, ""},
+		{"(Weekday).String", Method, 0, ""},
+		{"ANSIC", Const, 0, ""},
+		{"After", Func, 0, "func(d Duration) <-chan Time"},
+		{"AfterFunc", Func, 0, "func(d Duration, f func()) *Timer"},
+		{"April", Const, 0, ""},
+		{"August", Const, 0, ""},
+		{"Date", Func, 0, "func(year int, month Month, day int, hour int, min int, sec int, nsec int, loc *Location) Time"},
+		{"DateOnly", Const, 20, ""},
+		{"DateTime", Const, 20, ""},
+		{"December", Const, 0, ""},
+		{"Duration", Type, 0, ""},
+		{"February", Const, 0, ""},
+		{"FixedZone", Func, 0, "func(name string, offset int) *Location"},
+		{"Friday", Const, 0, ""},
+		{"Hour", Const, 0, ""},
+		{"January", Const, 0, ""},
+		{"July", Const, 0, ""},
+		{"June", Const, 0, ""},
+		{"Kitchen", Const, 0, ""},
+		{"Layout", Const, 17, ""},
+		{"LoadLocation", Func, 0, "func(name string) (*Location, error)"},
+		{"LoadLocationFromTZData", Func, 10, "func(name string, data []byte) (*Location, error)"},
+		{"Local", Var, 0, ""},
+		{"Location", Type, 0, ""},
+		{"March", Const, 0, ""},
+		{"May", Const, 0, ""},
+		{"Microsecond", Const, 0, ""},
+		{"Millisecond", Const, 0, ""},
+		{"Minute", Const, 0, ""},
+		{"Monday", Const, 0, ""},
+		{"Month", Type, 0, ""},
+		{"Nanosecond", Const, 0, ""},
+		{"NewTicker", Func, 0, "func(d Duration) *Ticker"},
+		{"NewTimer", Func, 0, "func(d Duration) *Timer"},
+		{"November", Const, 0, ""},
+		{"Now", Func, 0, "func() Time"},
+		{"October", Const, 0, ""},
+		{"Parse", Func, 0, "func(layout string, value string) (Time, error)"},
+		{"ParseDuration", Func, 0, "func(s string) (Duration, error)"},
+		{"ParseError", Type, 0, ""},
+		{"ParseError.Layout", Field, 0, ""},
+		{"ParseError.LayoutElem", Field, 0, ""},
+		{"ParseError.Message", Field, 0, ""},
+		{"ParseError.Value", Field, 0, ""},
+		{"ParseError.ValueElem", Field, 0, ""},
+		{"ParseInLocation", Func, 1, "func(layout string, value string, loc *Location) (Time, error)"},
+		{"RFC1123", Const, 0, ""},
+		{"RFC1123Z", Const, 0, ""},
+		{"RFC3339", Const, 0, ""},
+		{"RFC3339Nano", Const, 0, ""},
+		{"RFC822", Const, 0, ""},
+		{"RFC822Z", Const, 0, ""},
+		{"RFC850", Const, 0, ""},
+		{"RubyDate", Const, 0, ""},
+		{"Saturday", Const, 0, ""},
+		{"Second", Const, 0, ""},
+		{"September", Const, 0, ""},
+		{"Since", Func, 0, "func(t Time) Duration"},
+		{"Sleep", Func, 0, "func(d Duration)"},
+		{"Stamp", Const, 0, ""},
+		{"StampMicro", Const, 0, ""},
+		{"StampMilli", Const, 0, ""},
+		{"StampNano", Const, 0, ""},
+		{"Sunday", Const, 0, ""},
+		{"Thursday", Const, 0, ""},
+		{"Tick", Func, 0, "func(d Duration) <-chan Time"},
+		{"Ticker", Type, 0, ""},
+		{"Ticker.C", Field, 0, ""},
+		{"Time", Type, 0, ""},
+		{"TimeOnly", Const, 20, ""},
+		{"Timer", Type, 0, ""},
+		{"Timer.C", Field, 0, ""},
+		{"Tuesday", Const, 0, ""},
+		{"UTC", Var, 0, ""},
+		{"Unix", Func, 0, "func(sec int64, nsec int64) Time"},
+		{"UnixDate", Const, 0, ""},
+		{"UnixMicro", Func, 17, "func(usec int64) Time"},
+		{"UnixMilli", Func, 17, "func(msec int64) Time"},
+		{"Until", Func, 8, "func(t Time) Duration"},
+		{"Wednesday", Const, 0, ""},
+		{"Weekday", Type, 0, ""},
+	},
+	"unicode": {
+		{"(SpecialCase).ToLower", Method, 0, ""},
+		{"(SpecialCase).ToTitle", Method, 0, ""},
+		{"(SpecialCase).ToUpper", Method, 0, ""},
+		{"ASCII_Hex_Digit", Var, 0, ""},
+		{"Adlam", Var, 7, ""},
+		{"Ahom", Var, 5, ""},
+		{"Anatolian_Hieroglyphs", Var, 5, ""},
+		{"Arabic", Var, 0, ""},
+		{"Armenian", Var, 0, ""},
+		{"Avestan", Var, 0, ""},
+		{"AzeriCase", Var, 0, ""},
+		{"Balinese", Var, 0, ""},
+		{"Bamum", Var, 0, ""},
+		{"Bassa_Vah", Var, 4, ""},
+		{"Batak", Var, 0, ""},
+		{"Bengali", Var, 0, ""},
+		{"Beria_Erfe", Var, 27, ""},
+		{"Bhaiksuki", Var, 7, ""},
+		{"Bidi_Control", Var, 0, ""},
+		{"Bopomofo", Var, 0, ""},
+		{"Brahmi", Var, 0, ""},
+		{"Braille", Var, 0, ""},
+		{"Buginese", Var, 0, ""},
+		{"Buhid", Var, 0, ""},
+		{"C", Var, 0, ""},
+		{"Canadian_Aboriginal", Var, 0, ""},
+		{"Carian", Var, 0, ""},
+		{"CaseRange", Type, 0, ""},
+		{"CaseRange.Delta", Field, 0, ""},
+		{"CaseRange.Hi", Field, 0, ""},
+		{"CaseRange.Lo", Field, 0, ""},
+		{"CaseRanges", Var, 0, ""},
+		{"Categories", Var, 0, ""},
+		{"CategoryAliases", Var, 25, ""},
+		{"Caucasian_Albanian", Var, 4, ""},
+		{"Cc", Var, 0, ""},
+		{"Cf", Var, 0, ""},
+		{"Chakma", Var, 1, ""},
+		{"Cham", Var, 0, ""},
+		{"Cherokee", Var, 0, ""},
+		{"Chorasmian", Var, 16, ""},
+		{"Cn", Var, 25, ""},
+		{"Co", Var, 0, ""},
+		{"Common", Var, 0, ""},
+		{"Coptic", Var, 0, ""},
+		{"Cs", Var, 0, ""},
+		{"Cuneiform", Var, 0, ""},
+		{"Cypriot", Var, 0, ""},
+		{"Cypro_Minoan", Var, 21, ""},
+		{"Cyrillic", Var, 0, ""},
+		{"Dash", Var, 0, ""},
+		{"Deprecated", Var, 0, ""},
+		{"Deseret", Var, 0, ""},
+		{"Devanagari", Var, 0, ""},
+		{"Diacritic", Var, 0, ""},
+		{"Digit", Var, 0, ""},
+		{"Dives_Akuru", Var, 16, ""},
+		{"Dogra", Var, 13, ""},
+		{"Duployan", Var, 4, ""},
+		{"Egyptian_Hieroglyphs", Var, 0, ""},
+		{"Elbasan", Var, 4, ""},
+		{"Elymaic", Var, 14, ""},
+		{"Ethiopic", Var, 0, ""},
+		{"Extender", Var, 0, ""},
+		{"FoldCategory", Var, 0, ""},
+		{"FoldScript", Var, 0, ""},
+		{"Garay", Var, 27, ""},
+		{"Georgian", Var, 0, ""},
+		{"Glagolitic", Var, 0, ""},
+		{"Gothic", Var, 0, ""},
+		{"Grantha", Var, 4, ""},
+		{"GraphicRanges", Var, 0, ""},
+		{"Greek", Var, 0, ""},
+		{"Gujarati", Var, 0, ""},
+		{"Gunjala_Gondi", Var, 13, ""},
+		{"Gurmukhi", Var, 0, ""},
+		{"Gurung_Khema", Var, 27, ""},
+		{"Han", Var, 0, ""},
+		{"Hangul", Var, 0, ""},
+		{"Hanifi_Rohingya", Var, 13, ""},
+		{"Hanunoo", Var, 0, ""},
+		{"Hatran", Var, 5, ""},
+		{"Hebrew", Var, 0, ""},
+		{"Hex_Digit", Var, 0, ""},
+		{"Hiragana", Var, 0, ""},
+		{"Hyphen", Var, 0, ""},
+		{"IDS_Binary_Operator", Var, 0, ""},
+		{"IDS_Trinary_Operator", Var, 0, ""},
+		{"IDS_Unary_Operator", Var, 27, ""},
+		{"ID_Compat_Math_Continue", Var, 27, ""},
+		{"ID_Compat_Math_Start", Var, 27, ""},
+		{"Ideographic", Var, 0, ""},
+		{"Imperial_Aramaic", Var, 0, ""},
+		{"In", Func, 2, "func(r rune, ranges ...*RangeTable) bool"},
+		{"Inherited", Var, 0, ""},
+		{"Inscriptional_Pahlavi", Var, 0, ""},
+		{"Inscriptional_Parthian", Var, 0, ""},
+		{"Is", Func, 0, "func(rangeTab *RangeTable, r rune) bool"},
+		{"IsControl", Func, 0, "func(r rune) bool"},
+		{"IsDigit", Func, 0, "func(r rune) bool"},
+		{"IsGraphic", Func, 0, "func(r rune) bool"},
+		{"IsLetter", Func, 0, "func(r rune) bool"},
+		{"IsLower", Func, 0, "func(r rune) bool"},
+		{"IsMark", Func, 0, "func(r rune) bool"},
+		{"IsNumber", Func, 0, "func(r rune) bool"},
+		{"IsOneOf", Func, 0, "func(ranges []*RangeTable, r rune) bool"},
+		{"IsPrint", Func, 0, "func(r rune) bool"},
+		{"IsPunct", Func, 0, "func(r rune) bool"},
+		{"IsSpace", Func, 0, "func(r rune) bool"},
+		{"IsSymbol", Func, 0, "func(r rune) bool"},
+		{"IsTitle", Func, 0, "func(r rune) bool"},
+		{"IsUpper", Func, 0, "func(r rune) bool"},
+		{"Javanese", Var, 0, ""},
+		{"Join_Control", Var, 0, ""},
+		{"Kaithi", Var, 0, ""},
+		{"Kannada", Var, 0, ""},
+		{"Katakana", Var, 0, ""},
+		{"Kawi", Var, 21, ""},
+		{"Kayah_Li", Var, 0, ""},
+		{"Kharoshthi", Var, 0, ""},
+		{"Khitan_Small_Script", Var, 16, ""},
+		{"Khmer", Var, 0, ""},
+		{"Khojki", Var, 4, ""},
+		{"Khudawadi", Var, 4, ""},
+		{"Kirat_Rai", Var, 27, ""},
+		{"L", Var, 0, ""},
+		{"LC", Var, 25, ""},
+		{"Lao", Var, 0, ""},
+		{"Latin", Var, 0, ""},
+		{"Lepcha", Var, 0, ""},
+		{"Letter", Var, 0, ""},
+		{"Limbu", Var, 0, ""},
+		{"Linear_A", Var, 4, ""},
+		{"Linear_B", Var, 0, ""},
+		{"Lisu", Var, 0, ""},
+		{"Ll", Var, 0, ""},
+		{"Lm", Var, 0, ""},
+		{"Lo", Var, 0, ""},
+		{"Logical_Order_Exception", Var, 0, ""},
+		{"Lower", Var, 0, ""},
+		{"LowerCase", Const, 0, ""},
+		{"Lt", Var, 0, ""},
+		{"Lu", Var, 0, ""},
+		{"Lycian", Var, 0, ""},
+		{"Lydian", Var, 0, ""},
+		{"M", Var, 0, ""},
+		{"Mahajani", Var, 4, ""},
+		{"Makasar", Var, 13, ""},
+		{"Malayalam", Var, 0, ""},
+		{"Mandaic", Var, 0, ""},
+		{"Manichaean", Var, 4, ""},
+		{"Marchen", Var, 7, ""},
+		{"Mark", Var, 0, ""},
+		{"Masaram_Gondi", Var, 10, ""},
+		{"MaxASCII", Const, 0, ""},
+		{"MaxCase", Const, 0, ""},
+		{"MaxLatin1", Const, 0, ""},
+		{"MaxRune", Const, 0, ""},
+		{"Mc", Var, 0, ""},
+		{"Me", Var, 0, ""},
+		{"Medefaidrin", Var, 13, ""},
+		{"Meetei_Mayek", Var, 0, ""},
+		{"Mende_Kikakui", Var, 4, ""},
+		{"Meroitic_Cursive", Var, 1, ""},
+		{"Meroitic_Hieroglyphs", Var, 1, ""},
+		{"Miao", Var, 1, ""},
+		{"Mn", Var, 0, ""},
+		{"Modi", Var, 4, ""},
+		{"Modifier_Combining_Mark", Var, 27, ""},
+		{"Mongolian", Var, 0, ""},
+		{"Mro", Var, 4, ""},
+		{"Multani", Var, 5, ""},
+		{"Myanmar", Var, 0, ""},
+		{"N", Var, 0, ""},
+		{"Nabataean", Var, 4, ""},
+		{"Nag_Mundari", Var, 21, ""},
+		{"Nandinagari", Var, 14, ""},
+		{"Nd", Var, 0, ""},
+		{"New_Tai_Lue", Var, 0, ""},
+		{"Newa", Var, 7, ""},
+		{"Nko", Var, 0, ""},
+		{"Nl", Var, 0, ""},
+		{"No", Var, 0, ""},
+		{"Noncharacter_Code_Point", Var, 0, ""},
+		{"Number", Var, 0, ""},
+		{"Nushu", Var, 10, ""},
+		{"Nyiakeng_Puachue_Hmong", Var, 14, ""},
+		{"Ogham", Var, 0, ""},
+		{"Ol_Chiki", Var, 0, ""},
+		{"Ol_Onal", Var, 27, ""},
+		{"Old_Hungarian", Var, 5, ""},
+		{"Old_Italic", Var, 0, ""},
+		{"Old_North_Arabian", Var, 4, ""},
+		{"Old_Permic", Var, 4, ""},
+		{"Old_Persian", Var, 0, ""},
+		{"Old_Sogdian", Var, 13, ""},
+		{"Old_South_Arabian", Var, 0, ""},
+		{"Old_Turkic", Var, 0, ""},
+		{"Old_Uyghur", Var, 21, ""},
+		{"Oriya", Var, 0, ""},
+		{"Osage", Var, 7, ""},
+		{"Osmanya", Var, 0, ""},
+		{"Other", Var, 0, ""},
+		{"Other_Alphabetic", Var, 0, ""},
+		{"Other_Default_Ignorable_Code_Point", Var, 0, ""},
+		{"Other_Grapheme_Extend", Var, 0, ""},
+		{"Other_ID_Continue", Var, 0, ""},
+		{"Other_ID_Start", Var, 0, ""},
+		{"Other_Lowercase", Var, 0, ""},
+		{"Other_Math", Var, 0, ""},
+		{"Other_Uppercase", Var, 0, ""},
+		{"P", Var, 0, ""},
+		{"Pahawh_Hmong", Var, 4, ""},
+		{"Palmyrene", Var, 4, ""},
+		{"Pattern_Syntax", Var, 0, ""},
+		{"Pattern_White_Space", Var, 0, ""},
+		{"Pau_Cin_Hau", Var, 4, ""},
+		{"Pc", Var, 0, ""},
+		{"Pd", Var, 0, ""},
+		{"Pe", Var, 0, ""},
+		{"Pf", Var, 0, ""},
+		{"Phags_Pa", Var, 0, ""},
+		{"Phoenician", Var, 0, ""},
+		{"Pi", Var, 0, ""},
+		{"Po", Var, 0, ""},
+		{"Prepended_Concatenation_Mark", Var, 7, ""},
+		{"PrintRanges", Var, 0, ""},
+		{"Properties", Var, 0, ""},
+		{"Ps", Var, 0, ""},
+		{"Psalter_Pahlavi", Var, 4, ""},
+		{"Punct", Var, 0, ""},
+		{"Quotation_Mark", Var, 0, ""},
+		{"Radical", Var, 0, ""},
+		{"Range16", Type, 0, ""},
+		{"Range16.Hi", Field, 0, ""},
+		{"Range16.Lo", Field, 0, ""},
+		{"Range16.Stride", Field, 0, ""},
+		{"Range32", Type, 0, ""},
+		{"Range32.Hi", Field, 0, ""},
+		{"Range32.Lo", Field, 0, ""},
+		{"Range32.Stride", Field, 0, ""},
+		{"RangeTable", Type, 0, ""},
+		{"RangeTable.LatinOffset", Field, 1, ""},
+		{"RangeTable.R16", Field, 0, ""},
+		{"RangeTable.R32", Field, 0, ""},
+		{"Regional_Indicator", Var, 10, ""},
+		{"Rejang", Var, 0, ""},
+		{"ReplacementChar", Const, 0, ""},
+		{"Runic", Var, 0, ""},
+		{"S", Var, 0, ""},
+		{"STerm", Var, 0, ""},
+		{"Samaritan", Var, 0, ""},
+		{"Saurashtra", Var, 0, ""},
+		{"Sc", Var, 0, ""},
+		{"Scripts", Var, 0, ""},
+		{"Sentence_Terminal", Var, 7, ""},
+		{"Sharada", Var, 1, ""},
+		{"Shavian", Var, 0, ""},
+		{"Siddham", Var, 4, ""},
+		{"Sidetic", Var, 27, ""},
+		{"SignWriting", Var, 5, ""},
+		{"SimpleFold", Func, 0, "func(r rune) rune"},
+		{"Sinhala", Var, 0, ""},
+		{"Sk", Var, 0, ""},
+		{"Sm", Var, 0, ""},
+		{"So", Var, 0, ""},
+		{"Soft_Dotted", Var, 0, ""},
+		{"Sogdian", Var, 13, ""},
+		{"Sora_Sompeng", Var, 1, ""},
+		{"Soyombo", Var, 10, ""},
+		{"Space", Var, 0, ""},
+		{"SpecialCase", Type, 0, ""},
+		{"Sundanese", Var, 0, ""},
+		{"Sunuwar", Var, 27, ""},
+		{"Syloti_Nagri", Var, 0, ""},
+		{"Symbol", Var, 0, ""},
+		{"Syriac", Var, 0, ""},
+		{"Tagalog", Var, 0, ""},
+		{"Tagbanwa", Var, 0, ""},
+		{"Tai_Le", Var, 0, ""},
+		{"Tai_Tham", Var, 0, ""},
+		{"Tai_Viet", Var, 0, ""},
+		{"Tai_Yo", Var, 27, ""},
+		{"Takri", Var, 1, ""},
+		{"Tamil", Var, 0, ""},
+		{"Tangsa", Var, 21, ""},
+		{"Tangut", Var, 7, ""},
+		{"Telugu", Var, 0, ""},
+		{"Terminal_Punctuation", Var, 0, ""},
+		{"Thaana", Var, 0, ""},
+		{"Thai", Var, 0, ""},
+		{"Tibetan", Var, 0, ""},
+		{"Tifinagh", Var, 0, ""},
+		{"Tirhuta", Var, 4, ""},
+		{"Title", Var, 0, ""},
+		{"TitleCase", Const, 0, ""},
+		{"To", Func, 0, "func(_case int, r rune) rune"},
+		{"ToLower", Func, 0, "func(r rune) rune"},
+		{"ToTitle", Func, 0, "func(r rune) rune"},
+		{"ToUpper", Func, 0, "func(r rune) rune"},
+		{"Todhri", Var, 27, ""},
+		{"Tolong_Siki", Var, 27, ""},
+		{"Toto", Var, 21, ""},
+		{"Tulu_Tigalari", Var, 27, ""},
+		{"TurkishCase", Var, 0, ""},
+		{"Ugaritic", Var, 0, ""},
+		{"Unified_Ideograph", Var, 0, ""},
+		{"Upper", Var, 0, ""},
+		{"UpperCase", Const, 0, ""},
+		{"UpperLower", Const, 0, ""},
+		{"Vai", Var, 0, ""},
+		{"Variation_Selector", Var, 0, ""},
+		{"Version", Const, 0, ""},
+		{"Vithkuqi", Var, 21, ""},
+		{"Wancho", Var, 14, ""},
+		{"Warang_Citi", Var, 4, ""},
+		{"White_Space", Var, 0, ""},
+		{"Yezidi", Var, 16, ""},
+		{"Yi", Var, 0, ""},
+		{"Z", Var, 0, ""},
+		{"Zanabazar_Square", Var, 10, ""},
+		{"Zl", Var, 0, ""},
+		{"Zp", Var, 0, ""},
+		{"Zs", Var, 0, ""},
+	},
+	"unicode/utf16": {
+		{"AppendRune", Func, 20, "func(a []uint16, r rune) []uint16"},
+		{"Decode", Func, 0, "func(s []uint16) []rune"},
+		{"DecodeRune", Func, 0, "func(r1 rune, r2 rune) rune"},
+		{"Encode", Func, 0, "func(s []rune) []uint16"},
+		{"EncodeRune", Func, 0, "func(r rune) (r1 rune, r2 rune)"},
+		{"IsSurrogate", Func, 0, "func(r rune) bool"},
+		{"RuneLen", Func, 23, "func(r rune) int"},
+	},
+	"unicode/utf8": {
+		{"AppendRune", Func, 18, "func(p []byte, r rune) []byte"},
+		{"DecodeLastRune", Func, 0, "func(p []byte) (r rune, size int)"},
+		{"DecodeLastRuneInString", Func, 0, "func(s string) (r rune, size int)"},
+		{"DecodeRune", Func, 0, "func(p []byte) (r rune, size int)"},
+		{"DecodeRuneInString", Func, 0, "func(s string) (r rune, size int)"},
+		{"EncodeRune", Func, 0, "func(p []byte, r rune) int"},
+		{"FullRune", Func, 0, "func(p []byte) bool"},
+		{"FullRuneInString", Func, 0, "func(s string) bool"},
+		{"MaxRune", Const, 0, ""},
+		{"RuneCount", Func, 0, "func(p []byte) int"},
+		{"RuneCountInString", Func, 0, "func(s string) (n int)"},
+		{"RuneError", Const, 0, ""},
+		{"RuneLen", Func, 0, "func(r rune) int"},
+		{"RuneSelf", Const, 0, ""},
+		{"RuneStart", Func, 0, "func(b byte) bool"},
+		{"UTFMax", Const, 0, ""},
+		{"Valid", Func, 0, "func(p []byte) bool"},
+		{"ValidRune", Func, 1, "func(r rune) bool"},
+		{"ValidString", Func, 0, "func(s string) bool"},
+	},
+	"unique": {
+		{"(Handle).Value", Method, 23, ""},
+		{"Handle", Type, 23, ""},
+		{"Make", Func, 23, "func[T comparable](value T) Handle[T]"},
+	},
+	"unsafe": {
+		{"Add", Func, 0, ""},
+		{"Alignof", Func, 0, ""},
+		{"Offsetof", Func, 0, ""},
+		{"Pointer", Type, 0, ""},
+		{"Sizeof", Func, 0, ""},
+		{"Slice", Func, 0, ""},
+		{"SliceData", Func, 0, ""},
+		{"String", Func, 0, ""},
+		{"StringData", Func, 0, ""},
+	},
+	"uuid": {
+		{"(*UUID).UnmarshalText", Method, 27, ""},
+		{"(UUID).AppendText", Method, 27, ""},
+		{"(UUID).Compare", Method, 27, ""},
+		{"(UUID).MarshalText", Method, 27, ""},
+		{"(UUID).String", Method, 27, ""},
+		{"Max", Func, 27, "func() UUID"},
+		{"MustParse", Func, 27, "func(s string) UUID"},
+		{"New", Func, 27, "func() UUID"},
+		{"NewV4", Func, 27, "func() UUID"},
+		{"NewV7", Func, 27, "func() UUID"},
+		{"Nil", Func, 27, "func() UUID"},
+		{"Parse", Func, 27, "func(s string) (UUID, error)"},
+		{"UUID", Type, 27, ""},
+	},
+	"weak": {
+		{"(Pointer).Value", Method, 24, ""},
+		{"Make", Func, 24, "func[T any](ptr *T) Pointer[T]"},
+		{"Pointer", Type, 24, ""},
+	},
+}
diff --git a/vendor/golang.org/x/tools/internal/stdlib/stdlib.go b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go
new file mode 100644
index 0000000..59a5de3
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go
@@ -0,0 +1,105 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run generate.go
+
+// Package stdlib provides a table of all exported symbols in the
+// standard library, along with the version at which they first
+// appeared. It also provides the import graph of std packages.
+package stdlib
+
+import (
+	"fmt"
+	"strings"
+)
+
+type Symbol struct {
+	Name    string
+	Kind    Kind
+	Version Version // Go version that first included the symbol
+	// Signature provides the type of a function (defined only for Kind=Func).
+	// Imported types are denoted as pkg.T; pkg is not fully qualified.
+	// TODO(adonovan): use an unambiguous encoding that is parseable.
+	//
+	// Example2:
+	//    func[M ~map[K]V, K comparable, V any](m M) M
+	//    func(fi fs.FileInfo, link string) (*Header, error)
+	Signature string // if Kind == stdlib.Func
+}
+
+// A Kind indicates the kind of a symbol:
+// function, variable, constant, type, and so on.
+type Kind int8
+
+const (
+	Invalid Kind = iota // Example name:
+	Type                // "Buffer"
+	Func                // "Println"
+	Var                 // "EOF"
+	Const               // "Pi"
+	Field               // "Point.X"
+	Method              // "(*Buffer).Grow" or "(Reader).Read"
+)
+
+func (kind Kind) String() string {
+	return [...]string{
+		Invalid: "invalid",
+		Type:    "type",
+		Func:    "func",
+		Var:     "var",
+		Const:   "const",
+		Field:   "field",
+		Method:  "method",
+	}[kind]
+}
+
+// A Version represents a version of Go of the form "go1.%d".
+type Version int8
+
+// String returns a version string of the form "go1.23", without allocating.
+func (v Version) String() string { return versions[v] }
+
+var versions [30]string // (increase constant as needed)
+
+func init() {
+	for i := range versions {
+		versions[i] = fmt.Sprintf("go1.%d", i)
+	}
+}
+
+// HasPackage reports whether the specified package path is part of
+// the standard library's public API.
+func HasPackage(path string) bool {
+	_, ok := PackageSymbols[path]
+	return ok
+}
+
+// SplitField splits the field symbol name into type and field
+// components. It must be called only on Field symbols.
+//
+// Example: "File.Package" -> ("File", "Package")
+func (sym *Symbol) SplitField() (typename, name string) {
+	if sym.Kind != Field {
+		panic("not a field")
+	}
+	typename, name, _ = strings.Cut(sym.Name, ".")
+	return
+}
+
+// SplitMethod splits the method symbol name into pointer, receiver,
+// and method components. It must be called only on Method symbols.
+//
+// Example: "(*Buffer).Grow" -> (true, "Buffer", "Grow")
+func (sym *Symbol) SplitMethod() (ptr bool, recv, name string) {
+	if sym.Kind != Method {
+		panic("not a method")
+	}
+	recv, name, _ = strings.Cut(sym.Name, ".")
+	recv = recv[len("(") : len(recv)-len(")")]
+	ptr = recv[0] == '*'
+	if ptr {
+		recv = recv[len("*"):]
+	}
+	return
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/common.go b/vendor/golang.org/x/tools/internal/typeparams/common.go
new file mode 100644
index 0000000..cdae2b8
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/common.go
@@ -0,0 +1,68 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package typeparams contains common utilities for writing tools that
+// interact with generic Go code, as introduced with Go 1.18. It
+// supplements the standard library APIs. Notably, the StructuralTerms
+// API computes a minimal representation of the structural
+// restrictions on a type parameter.
+//
+// An external version of these APIs is available in the
+// golang.org/x/exp/typeparams module.
+package typeparams
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+)
+
+// UnpackIndexExpr extracts data from AST nodes that represent index
+// expressions.
+//
+// For an ast.IndexExpr, the resulting indices slice will contain exactly one
+// index expression. For an ast.IndexListExpr (go1.18+), it may have a variable
+// number of index expressions.
+//
+// For nodes that don't represent index expressions, the first return value of
+// UnpackIndexExpr will be nil.
+func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) {
+	switch e := n.(type) {
+	case *ast.IndexExpr:
+		return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack
+	case *ast.IndexListExpr:
+		return e.X, e.Lbrack, e.Indices, e.Rbrack
+	}
+	return nil, token.NoPos, nil, token.NoPos
+}
+
+// PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on
+// the cardinality of indices. Calling PackIndexExpr with len(indices) == 0
+// will panic.
+func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr {
+	switch len(indices) {
+	case 0:
+		panic("empty indices")
+	case 1:
+		return &ast.IndexExpr{
+			X:      x,
+			Lbrack: lbrack,
+			Index:  indices[0],
+			Rbrack: rbrack,
+		}
+	default:
+		return &ast.IndexListExpr{
+			X:       x,
+			Lbrack:  lbrack,
+			Indices: indices,
+			Rbrack:  rbrack,
+		}
+	}
+}
+
+// IsTypeParam reports whether t is a type parameter (or an alias of one).
+func IsTypeParam(t types.Type) bool {
+	_, ok := types.Unalias(t).(*types.TypeParam)
+	return ok
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/vendor/golang.org/x/tools/internal/typeparams/coretype.go
new file mode 100644
index 0000000..2e05de4
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/coretype.go
@@ -0,0 +1,157 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeparams
+
+import (
+	"fmt"
+	"go/types"
+)
+
+// CoreType returns the core type of T or nil if T does not have a core type.
+//
+// As of Go1.25, the notion of a core type has been removed from the language spec.
+// See https://go.dev/blog/coretypes for more details.
+// TODO(mkalil): We should eventually consider removing all uses of CoreType.
+func CoreType(T types.Type) types.Type {
+	U := T.Underlying()
+	if _, ok := U.(*types.Interface); !ok {
+		return U // for non-interface types,
+	}
+
+	terms, err := NormalTerms(U)
+	if len(terms) == 0 || err != nil {
+		// len(terms) -> empty type set of interface.
+		// err != nil => U is invalid, exceeds complexity bounds, or has an empty type set.
+		return nil // no core type.
+	}
+
+	U = terms[0].Type().Underlying()
+	var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying())
+	for identical = 1; identical < len(terms); identical++ {
+		if !types.Identical(U, terms[identical].Type().Underlying()) {
+			break
+		}
+	}
+
+	if identical == len(terms) {
+		// From the deprecated core types spec:
+		// "There is a single type U which is the underlying type of all types in the type set of T"
+		return U
+	}
+	ch, ok := U.(*types.Chan)
+	if !ok {
+		return nil // no core type as identical < len(terms) and U is not a channel.
+	}
+	// From the deprecated core types spec:
+	// "the type chan E if T contains only bidirectional channels, or the type chan<- E or
+	// <-chan E depending on the direction of the directional channels present."
+	for chans := identical; chans < len(terms); chans++ {
+		curr, ok := terms[chans].Type().Underlying().(*types.Chan)
+		if !ok {
+			return nil
+		}
+		if !types.Identical(ch.Elem(), curr.Elem()) {
+			return nil // channel elements are not identical.
+		}
+		if ch.Dir() == types.SendRecv {
+			// ch is bidirectional. We can safely always use curr's direction.
+			ch = curr
+		} else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() {
+			// ch and curr are not bidirectional and not the same direction.
+			return nil
+		}
+	}
+	return ch
+}
+
+// NormalTerms returns a slice of terms representing the normalized structural
+// type restrictions of a type, if any.
+//
+// For all types other than *types.TypeParam, *types.Interface, and
+// *types.Union, this is just a single term with Tilde() == false and
+// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see
+// below.
+//
+// Structural type restrictions of a type parameter are created via
+// non-interface types embedded in its constraint interface (directly, or via a
+// chain of interface embeddings). For example, in the declaration type
+// T[P interface{~int; m()}] int the structural restriction of the type
+// parameter P is ~int.
+//
+// With interface embedding and unions, the specification of structural type
+// restrictions may be arbitrarily complex. For example, consider the
+// following:
+//
+//	type A interface{ ~string|~[]byte }
+//
+//	type B interface{ int|string }
+//
+//	type C interface { ~string|~int }
+//
+//	type T[P interface{ A|B; C }] int
+//
+// In this example, the structural type restriction of P is ~string|int: A|B
+// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
+// which when intersected with C (~string|~int) yields ~string|int.
+//
+// NormalTerms computes these expansions and reductions, producing a
+// "normalized" form of the embeddings. A structural restriction is normalized
+// if it is a single union containing no interface terms, and is minimal in the
+// sense that removing any term changes the set of types satisfying the
+// constraint. It is left as a proof for the reader that, modulo sorting, there
+// is exactly one such normalized form.
+//
+// Because the minimal representation always takes this form, NormalTerms
+// returns a slice of tilde terms corresponding to the terms of the union in
+// the normalized structural restriction. An error is returned if the type is
+// invalid, exceeds complexity bounds, or has an empty type set. In the latter
+// case, NormalTerms returns ErrEmptyTypeSet.
+//
+// NormalTerms makes no guarantees about the order of terms, except that it
+// is deterministic.
+func NormalTerms(T types.Type) ([]*types.Term, error) {
+	// typeSetOf(T) == typeSetOf(Unalias(T))
+	typ := types.Unalias(T)
+	if named, ok := typ.(*types.Named); ok {
+		typ = named.Underlying()
+	}
+	switch typ := typ.(type) {
+	case *types.TypeParam:
+		return StructuralTerms(typ)
+	case *types.Union:
+		return UnionTermSet(typ)
+	case *types.Interface:
+		return InterfaceTermSet(typ)
+	default:
+		return []*types.Term{types.NewTerm(false, T)}, nil
+	}
+}
+
+// Deref returns the type of the variable pointed to by t,
+// if t's core type is a pointer; otherwise it returns t.
+//
+// Do not assume that Deref(T)==T implies T is not a pointer:
+// consider "type T *T", for example.
+//
+// TODO(adonovan): ideally this would live in typesinternal, but that
+// creates an import cycle. Move there when we melt this package down.
+func Deref(t types.Type) types.Type {
+	if ptr, ok := CoreType(t).(*types.Pointer); ok {
+		return ptr.Elem()
+	}
+	return t
+}
+
+// MustDeref returns the type of the variable pointed to by t.
+// It panics if t's core type is not a pointer.
+//
+// TODO(adonovan): ideally this would live in typesinternal, but that
+// creates an import cycle. Move there when we melt this package down.
+func MustDeref(t types.Type) types.Type {
+	if ptr, ok := CoreType(t).(*types.Pointer); ok {
+		return ptr.Elem()
+	}
+	panic(fmt.Sprintf("%v is not a pointer", t))
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/free.go b/vendor/golang.org/x/tools/internal/typeparams/free.go
new file mode 100644
index 0000000..4c39187
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/free.go
@@ -0,0 +1,129 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeparams
+
+import (
+	"go/types"
+)
+
+// Free is a memoization of the set of free type parameters within a
+// type. It makes a sequence of calls to [Free.Has] for overlapping
+// types more efficient. The zero value is ready for use.
+//
+// NOTE: Adapted from go/types/infer.go. If it is later exported, factor.
+type Free struct {
+	seen map[types.Type]bool
+}
+
+// Has reports whether the specified type has a free type parameter.
+func (w *Free) Has(typ types.Type) (res bool) {
+	// detect cycles
+	if x, ok := w.seen[typ]; ok {
+		return x
+	}
+	if w.seen == nil {
+		w.seen = make(map[types.Type]bool)
+	}
+	w.seen[typ] = false
+	defer func() {
+		w.seen[typ] = res
+	}()
+
+	switch t := typ.(type) {
+	case nil, *types.Basic: // TODO(gri) should nil be handled here?
+		break
+
+	case *types.Alias:
+		if t.TypeParams().Len() > t.TypeArgs().Len() {
+			return true // This is an uninstantiated Alias.
+		}
+		// The expansion of an alias can have free type parameters,
+		// whether or not the alias itself has type parameters:
+		//
+		//   func _[K comparable]() {
+		//     type Set      = map[K]bool // free(Set)      = {K}
+		//     type MapTo[V] = map[K]V    // free(Map[foo]) = {V}
+		//   }
+		//
+		// So, we must Unalias.
+		return w.Has(types.Unalias(t))
+
+	case *types.Array:
+		return w.Has(t.Elem())
+
+	case *types.Slice:
+		return w.Has(t.Elem())
+
+	case *types.Struct:
+		for i, n := 0, t.NumFields(); i < n; i++ {
+			if w.Has(t.Field(i).Type()) {
+				return true
+			}
+		}
+
+	case *types.Pointer:
+		return w.Has(t.Elem())
+
+	case *types.Tuple:
+		n := t.Len()
+		for i := range n {
+			if w.Has(t.At(i).Type()) {
+				return true
+			}
+		}
+
+	case *types.Signature:
+		// t.tparams may not be nil if we are looking at a signature
+		// of a generic function type (or an interface method) that is
+		// part of the type we're testing. We don't care about these type
+		// parameters.
+		// Similarly, the receiver of a method may declare (rather than
+		// use) type parameters, we don't care about those either.
+		// Thus, we only need to look at the input and result parameters.
+		return w.Has(t.Params()) || w.Has(t.Results())
+
+	case *types.Interface:
+		for i, n := 0, t.NumMethods(); i < n; i++ {
+			if w.Has(t.Method(i).Type()) {
+				return true
+			}
+		}
+		terms, err := InterfaceTermSet(t)
+		if err != nil {
+			return false // ill typed
+		}
+		for _, term := range terms {
+			if w.Has(term.Type()) {
+				return true
+			}
+		}
+
+	case *types.Map:
+		return w.Has(t.Key()) || w.Has(t.Elem())
+
+	case *types.Chan:
+		return w.Has(t.Elem())
+
+	case *types.Named:
+		args := t.TypeArgs()
+		if params := t.TypeParams(); params.Len() > args.Len() {
+			return true // this is an uninstantiated named type.
+		}
+		for i, n := 0, args.Len(); i < n; i++ {
+			if w.Has(args.At(i)) {
+				return true
+			}
+		}
+		return w.Has(t.Underlying()) // recurse for types local to parameterized functions
+
+	case *types.TypeParam:
+		return true
+
+	default:
+		panic(t) // unreachable
+	}
+
+	return false
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/normalize.go b/vendor/golang.org/x/tools/internal/typeparams/normalize.go
new file mode 100644
index 0000000..8d13f12
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/normalize.go
@@ -0,0 +1,216 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeparams
+
+import (
+	"errors"
+	"fmt"
+	"go/types"
+	"os"
+	"strings"
+)
+
+//go:generate go run copytermlist.go
+
+const debug = false
+
+var ErrEmptyTypeSet = errors.New("empty type set")
+
+// StructuralTerms returns a slice of terms representing the normalized
+// structural type restrictions of a type parameter, if any.
+//
+// Structural type restrictions of a type parameter are created via
+// non-interface types embedded in its constraint interface (directly, or via a
+// chain of interface embeddings). For example, in the declaration
+//
+//	type T[P interface{~int; m()}] int
+//
+// the structural restriction of the type parameter P is ~int.
+//
+// With interface embedding and unions, the specification of structural type
+// restrictions may be arbitrarily complex. For example, consider the
+// following:
+//
+//	type A interface{ ~string|~[]byte }
+//
+//	type B interface{ int|string }
+//
+//	type C interface { ~string|~int }
+//
+//	type T[P interface{ A|B; C }] int
+//
+// In this example, the structural type restriction of P is ~string|int: A|B
+// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
+// which when intersected with C (~string|~int) yields ~string|int.
+//
+// StructuralTerms computes these expansions and reductions, producing a
+// "normalized" form of the embeddings. A structural restriction is normalized
+// if it is a single union containing no interface terms, and is minimal in the
+// sense that removing any term changes the set of types satisfying the
+// constraint. It is left as a proof for the reader that, modulo sorting, there
+// is exactly one such normalized form.
+//
+// Because the minimal representation always takes this form, StructuralTerms
+// returns a slice of tilde terms corresponding to the terms of the union in
+// the normalized structural restriction. An error is returned if the
+// constraint interface is invalid, exceeds complexity bounds, or has an empty
+// type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet.
+//
+// StructuralTerms makes no guarantees about the order of terms, except that it
+// is deterministic.
+func StructuralTerms(tparam *types.TypeParam) ([]*types.Term, error) {
+	constraint := tparam.Constraint()
+	if constraint == nil {
+		return nil, fmt.Errorf("%s has nil constraint", tparam)
+	}
+	iface, _ := constraint.Underlying().(*types.Interface)
+	if iface == nil {
+		return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying())
+	}
+	return InterfaceTermSet(iface)
+}
+
+// InterfaceTermSet computes the normalized terms for a constraint interface,
+// returning an error if the term set cannot be computed or is empty. In the
+// latter case, the error will be ErrEmptyTypeSet.
+//
+// See the documentation of StructuralTerms for more information on
+// normalization.
+func InterfaceTermSet(iface *types.Interface) ([]*types.Term, error) {
+	return computeTermSet(iface)
+}
+
+// UnionTermSet computes the normalized terms for a union, returning an error
+// if the term set cannot be computed or is empty. In the latter case, the
+// error will be ErrEmptyTypeSet.
+//
+// See the documentation of StructuralTerms for more information on
+// normalization.
+func UnionTermSet(union *types.Union) ([]*types.Term, error) {
+	return computeTermSet(union)
+}
+
+func computeTermSet(typ types.Type) ([]*types.Term, error) {
+	tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0)
+	if err != nil {
+		return nil, err
+	}
+	if tset.terms.isEmpty() {
+		return nil, ErrEmptyTypeSet
+	}
+	if tset.terms.isAll() {
+		return nil, nil
+	}
+	var terms []*types.Term
+	for _, term := range tset.terms {
+		terms = append(terms, types.NewTerm(term.tilde, term.typ))
+	}
+	return terms, nil
+}
+
+// A termSet holds the normalized set of terms for a given type.
+//
+// The name termSet is intentionally distinct from 'type set': a type set is
+// all types that implement a type (and includes method restrictions), whereas
+// a term set just represents the structural restrictions on a type.
+type termSet struct {
+	complete bool
+	terms    termlist
+}
+
+func indentf(depth int, format string, args ...any) {
+	fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...)
+}
+
+func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) {
+	if t == nil {
+		panic("nil type")
+	}
+
+	if debug {
+		indentf(depth, "%s", t.String())
+		defer func() {
+			if err != nil {
+				indentf(depth, "=> %s", err)
+			} else {
+				indentf(depth, "=> %s", res.terms.String())
+			}
+		}()
+	}
+
+	const maxTermCount = 100
+	if tset, ok := seen[t]; ok {
+		if !tset.complete {
+			return nil, fmt.Errorf("cycle detected in the declaration of %s", t)
+		}
+		return tset, nil
+	}
+
+	// Mark the current type as seen to avoid infinite recursion.
+	tset := new(termSet)
+	defer func() {
+		tset.complete = true
+	}()
+	seen[t] = tset
+
+	switch u := t.Underlying().(type) {
+	case *types.Interface:
+		// The term set of an interface is the intersection of the term sets of its
+		// embedded types.
+		tset.terms = allTermlist
+		for embedded := range u.EmbeddedTypes() {
+			if _, ok := embedded.Underlying().(*types.TypeParam); ok {
+				return nil, fmt.Errorf("invalid embedded type %T", embedded)
+			}
+			tset2, err := computeTermSetInternal(embedded, seen, depth+1)
+			if err != nil {
+				return nil, err
+			}
+			tset.terms = tset.terms.intersect(tset2.terms)
+		}
+	case *types.Union:
+		// The term set of a union is the union of term sets of its terms.
+		tset.terms = nil
+		for t := range u.Terms() {
+			var terms termlist
+			switch t.Type().Underlying().(type) {
+			case *types.Interface:
+				tset2, err := computeTermSetInternal(t.Type(), seen, depth+1)
+				if err != nil {
+					return nil, err
+				}
+				terms = tset2.terms
+			case *types.TypeParam, *types.Union:
+				// A stand-alone type parameter or union is not permitted as union
+				// term.
+				return nil, fmt.Errorf("invalid union term %T", t)
+			default:
+				if t.Type() == types.Typ[types.Invalid] {
+					continue
+				}
+				terms = termlist{{t.Tilde(), t.Type()}}
+			}
+			tset.terms = tset.terms.union(terms)
+			if len(tset.terms) > maxTermCount {
+				return nil, fmt.Errorf("exceeded max term count %d", maxTermCount)
+			}
+		}
+	case *types.TypeParam:
+		panic("unreachable")
+	default:
+		// For all other types, the term set is just a single non-tilde term
+		// holding the type itself.
+		if u != types.Typ[types.Invalid] {
+			tset.terms = termlist{{false, t}}
+		}
+	}
+	return tset, nil
+}
+
+// under is a facade for the go/types internal function of the same name. It is
+// used by typeterm.go.
+func under(t types.Type) types.Type {
+	return t.Underlying()
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/termlist.go b/vendor/golang.org/x/tools/internal/typeparams/termlist.go
new file mode 100644
index 0000000..9bc2914
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/termlist.go
@@ -0,0 +1,169 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+// Source: ../../cmd/compile/internal/types2/termlist.go
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by copytermlist.go DO NOT EDIT.
+
+package typeparams
+
+import (
+	"go/types"
+	"strings"
+)
+
+// A termlist represents the type set represented by the union
+// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn.
+// A termlist is in normal form if all terms are disjoint.
+// termlist operations don't require the operands to be in
+// normal form.
+type termlist []*term
+
+// allTermlist represents the set of all types.
+// It is in normal form.
+var allTermlist = termlist{new(term)}
+
+// termSep is the separator used between individual terms.
+const termSep = " | "
+
+// String prints the termlist exactly (without normalization).
+func (xl termlist) String() string {
+	if len(xl) == 0 {
+		return "∅"
+	}
+	var buf strings.Builder
+	for i, x := range xl {
+		if i > 0 {
+			buf.WriteString(termSep)
+		}
+		buf.WriteString(x.String())
+	}
+	return buf.String()
+}
+
+// isEmpty reports whether the termlist xl represents the empty set of types.
+func (xl termlist) isEmpty() bool {
+	// If there's a non-nil term, the entire list is not empty.
+	// If the termlist is in normal form, this requires at most
+	// one iteration.
+	for _, x := range xl {
+		if x != nil {
+			return false
+		}
+	}
+	return true
+}
+
+// isAll reports whether the termlist xl represents the set of all types.
+func (xl termlist) isAll() bool {
+	// If there's a 𝓤 term, the entire list is 𝓤.
+	// If the termlist is in normal form, this requires at most
+	// one iteration.
+	for _, x := range xl {
+		if x != nil && x.typ == nil {
+			return true
+		}
+	}
+	return false
+}
+
+// norm returns the normal form of xl.
+func (xl termlist) norm() termlist {
+	// Quadratic algorithm, but good enough for now.
+	// TODO(gri) fix asymptotic performance
+	used := make([]bool, len(xl))
+	var rl termlist
+	for i, xi := range xl {
+		if xi == nil || used[i] {
+			continue
+		}
+		for j := i + 1; j < len(xl); j++ {
+			xj := xl[j]
+			if xj == nil || used[j] {
+				continue
+			}
+			if u1, u2 := xi.union(xj); u2 == nil {
+				// If we encounter a 𝓤 term, the entire list is 𝓤.
+				// Exit early.
+				// (Note that this is not just an optimization;
+				// if we continue, we may end up with a 𝓤 term
+				// and other terms and the result would not be
+				// in normal form.)
+				if u1.typ == nil {
+					return allTermlist
+				}
+				xi = u1
+				used[j] = true // xj is now unioned into xi - ignore it in future iterations
+			}
+		}
+		rl = append(rl, xi)
+	}
+	return rl
+}
+
+// union returns the union xl ∪ yl.
+func (xl termlist) union(yl termlist) termlist {
+	return append(xl, yl...).norm()
+}
+
+// intersect returns the intersection xl ∩ yl.
+func (xl termlist) intersect(yl termlist) termlist {
+	if xl.isEmpty() || yl.isEmpty() {
+		return nil
+	}
+
+	// Quadratic algorithm, but good enough for now.
+	// TODO(gri) fix asymptotic performance
+	var rl termlist
+	for _, x := range xl {
+		for _, y := range yl {
+			if r := x.intersect(y); r != nil {
+				rl = append(rl, r)
+			}
+		}
+	}
+	return rl.norm()
+}
+
+// equal reports whether xl and yl represent the same type set.
+func (xl termlist) equal(yl termlist) bool {
+	// TODO(gri) this should be more efficient
+	return xl.subsetOf(yl) && yl.subsetOf(xl)
+}
+
+// includes reports whether t ∈ xl.
+func (xl termlist) includes(t types.Type) bool {
+	for _, x := range xl {
+		if x.includes(t) {
+			return true
+		}
+	}
+	return false
+}
+
+// supersetOf reports whether y ⊆ xl.
+func (xl termlist) supersetOf(y *term) bool {
+	for _, x := range xl {
+		if y.subsetOf(x) {
+			return true
+		}
+	}
+	return false
+}
+
+// subsetOf reports whether xl ⊆ yl.
+func (xl termlist) subsetOf(yl termlist) bool {
+	if yl.isEmpty() {
+		return xl.isEmpty()
+	}
+
+	// each term x of xl must be a subset of yl
+	for _, x := range xl {
+		if !yl.supersetOf(x) {
+			return false // x is not a subset yl
+		}
+	}
+	return true
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go b/vendor/golang.org/x/tools/internal/typeparams/typeterm.go
new file mode 100644
index 0000000..fa758cd
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/typeterm.go
@@ -0,0 +1,172 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+// Source: ../../cmd/compile/internal/types2/typeterm.go
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by copytermlist.go DO NOT EDIT.
+
+package typeparams
+
+import "go/types"
+
+// A term describes elementary type sets:
+//
+//	 ∅:  (*term)(nil)     == ∅                      // set of no types (empty set)
+//	 𝓤:  &term{}          == 𝓤                      // set of all types (𝓤niverse)
+//	 T:  &term{false, T}  == {T}                    // set of type T
+//	~t:  &term{true, t}   == {t' | under(t') == t}  // set of types with underlying type t
+type term struct {
+	tilde bool // valid if typ != nil
+	typ   types.Type
+}
+
+func (x *term) String() string {
+	switch {
+	case x == nil:
+		return "∅"
+	case x.typ == nil:
+		return "𝓤"
+	case x.tilde:
+		return "~" + x.typ.String()
+	default:
+		return x.typ.String()
+	}
+}
+
+// equal reports whether x and y represent the same type set.
+func (x *term) equal(y *term) bool {
+	// easy cases
+	switch {
+	case x == nil || y == nil:
+		return x == y
+	case x.typ == nil || y.typ == nil:
+		return x.typ == y.typ
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	return x.tilde == y.tilde && types.Identical(x.typ, y.typ)
+}
+
+// union returns the union x ∪ y: zero, one, or two non-nil terms.
+func (x *term) union(y *term) (_, _ *term) {
+	// easy cases
+	switch {
+	case x == nil && y == nil:
+		return nil, nil // ∅ ∪ ∅ == ∅
+	case x == nil:
+		return y, nil // ∅ ∪ y == y
+	case y == nil:
+		return x, nil // x ∪ ∅ == x
+	case x.typ == nil:
+		return x, nil // 𝓤 ∪ y == 𝓤
+	case y.typ == nil:
+		return y, nil // x ∪ 𝓤 == 𝓤
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	if x.disjoint(y) {
+		return x, y // x ∪ y == (x, y) if x ∩ y == ∅
+	}
+	// x.typ == y.typ
+
+	// ~t ∪ ~t == ~t
+	// ~t ∪  T == ~t
+	//  T ∪ ~t == ~t
+	//  T ∪  T ==  T
+	if x.tilde || !y.tilde {
+		return x, nil
+	}
+	return y, nil
+}
+
+// intersect returns the intersection x ∩ y.
+func (x *term) intersect(y *term) *term {
+	// easy cases
+	switch {
+	case x == nil || y == nil:
+		return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅
+	case x.typ == nil:
+		return y // 𝓤 ∩ y == y
+	case y.typ == nil:
+		return x // x ∩ 𝓤 == x
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	if x.disjoint(y) {
+		return nil // x ∩ y == ∅ if x ∩ y == ∅
+	}
+	// x.typ == y.typ
+
+	// ~t ∩ ~t == ~t
+	// ~t ∩  T ==  T
+	//  T ∩ ~t ==  T
+	//  T ∩  T ==  T
+	if !x.tilde || y.tilde {
+		return x
+	}
+	return y
+}
+
+// includes reports whether t ∈ x.
+func (x *term) includes(t types.Type) bool {
+	// easy cases
+	switch {
+	case x == nil:
+		return false // t ∈ ∅ == false
+	case x.typ == nil:
+		return true // t ∈ 𝓤 == true
+	}
+	// ∅ ⊂ x ⊂ 𝓤
+
+	u := t
+	if x.tilde {
+		u = under(u)
+	}
+	return types.Identical(x.typ, u)
+}
+
+// subsetOf reports whether x ⊆ y.
+func (x *term) subsetOf(y *term) bool {
+	// easy cases
+	switch {
+	case x == nil:
+		return true // ∅ ⊆ y == true
+	case y == nil:
+		return false // x ⊆ ∅ == false since x != ∅
+	case y.typ == nil:
+		return true // x ⊆ 𝓤 == true
+	case x.typ == nil:
+		return false // 𝓤 ⊆ y == false since y != 𝓤
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	if x.disjoint(y) {
+		return false // x ⊆ y == false if x ∩ y == ∅
+	}
+	// x.typ == y.typ
+
+	// ~t ⊆ ~t == true
+	// ~t ⊆ T == false
+	//  T ⊆ ~t == true
+	//  T ⊆  T == true
+	return !x.tilde || y.tilde
+}
+
+// disjoint reports whether x ∩ y == ∅.
+// x.typ and y.typ must not be nil.
+func (x *term) disjoint(y *term) bool {
+	if debug && (x.typ == nil || y.typ == nil) {
+		panic("invalid argument(s)")
+	}
+	ux := x.typ
+	if y.tilde {
+		ux = under(ux)
+	}
+	uy := y.typ
+	if x.tilde {
+		uy = under(uy)
+	}
+	return !types.Identical(ux, uy)
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go b/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go
new file mode 100644
index 0000000..4b5d488
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go
@@ -0,0 +1,128 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+
+	"golang.org/x/tools/go/ast/edge"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+// IsAssignedOrAddressTaken reports whether the expression cur denotes a
+// variable and appears in a context that assigns it or that takes its address,
+// potentially leading to indirect assignment.
+//
+// These examples cause IsAssignedOrAddressTaken on the identifier for x to
+// return true:
+//
+//		x = 1
+//		x++
+//		x[i] = 1	   (assume x is an array)
+//		x.a[i] = 1	 (assume x.a is a non-pointer struct field)
+//	  use(&x)
+//
+// whereas these cause it to return false:
+//
+//	y = x
+//	f(x)
+//	use(x.a[i])
+//	use(*x)
+//
+// The expression may itself be a compound, for example:
+//
+//	use(&(*ptr))  => IsAssignedOrAddressTaken("*ptr") = true
+//	x.a[i] = 1    => IsAssignedOrAddressTaken("x.a")  = true
+//	_ = x.a[i]    => IsAssignedOrAddressTaken("x.a")  = false
+//
+// A variable's declaration is not considered to be an assignment:
+//
+//	var x int     => IsAssignedOrAddressTaken(x) = false
+//	x := 1        => IsAssignedOrAddressTaken(x) = false
+//
+// TODO(adonovan): revisit the surprising behavior for declarations.
+func IsAssignedOrAddressTaken(info *types.Info, cur inspector.Cursor) bool {
+	// Unfortunately we can't simply use info.Types[e].Assignable()
+	// as it is always true for a variable even when that variable is
+	// used only as an r-value. So we must inspect enclosing syntax.
+outer:
+	// Ascend to outermost aggregate of which
+	// original cur is a part:
+	//    x -> (x) | x.f | x[i] | x[i:j]
+	for cur = range cur.Enclosing() {
+		switch cur.ParentEdgeKind() {
+		case edge.ParenExpr_X:
+			// If x is an lvalue, then (x) is an lvalue.
+		case edge.SelectorExpr_X:
+			// If x is an lvalue, then x.f is an lvalue iff
+			// the selection does not traverse a pointer.
+			sel := cur.Parent().Node().(*ast.SelectorExpr)
+			if seln, ok := info.Selections[sel]; ok {
+				// Note: there is a bug in Indirect() where it spuriously returns true
+				// when both the selection receiver and parameter are pointers. However,
+				// it's okay in this case because there is no address taken when a
+				// pointer receiver method is called on a pointer type.
+				if seln.Indirect() {
+					return false
+				}
+				if seln.Kind() == types.MethodVal {
+					sig := seln.Obj().Type().(*types.Signature)
+					if is[*types.Pointer](sig.Recv().Type().Underlying()) {
+						t := seln.Recv()
+						// The receiver may be an embedded field, so we need
+						// to get the inner-most type (right before the method
+						// call in seln.Index())
+						for field := range ImplicitFieldSelections(seln) {
+							t = field.Type()
+						}
+						if !is[*types.Pointer](t.Underlying()) {
+							return true // takes address of receiver
+						}
+					}
+					return false
+				}
+			}
+		case edge.IndexExpr_X, edge.SliceExpr_X:
+			// If x[i] or x[i:j] is an lvalue,
+			// then x is an lvalue iff x is an array.
+			if !is[*types.Array](info.TypeOf(cur.Node().(ast.Expr)).Underlying()) {
+				return false
+			}
+		default:
+			break outer
+		}
+	}
+	switch cur.ParentEdgeKind() {
+	case edge.AssignStmt_Lhs:
+		assign := cur.Parent().Node().(*ast.AssignStmt)
+		if assign.Tok != token.DEFINE {
+			return true // x = j or x += j
+		}
+		id := cur.Node().(*ast.Ident)
+		// Re-assigned identifiers are recorded in the Uses map.
+		if _, ok := info.Uses[id]; ok {
+			return true // reassignment of x (x, y := 1, 2)
+		}
+	case edge.RangeStmt_Key, edge.RangeStmt_Value:
+		rng := cur.Parent().Node().(*ast.RangeStmt)
+		if rng.Tok == token.ASSIGN {
+			return true // "for k, v = range x" is like an AssignStmt to k, v
+		}
+	case edge.IncDecStmt_X:
+		return true // x++, x--
+	case edge.UnaryExpr_X:
+		if cur.Parent().Node().(*ast.UnaryExpr).Op == token.AND {
+			return true // &x
+		}
+	}
+	return false
+}
+
+func is[T any](x any) bool {
+	_, ok := x.(T)
+	return ok
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go b/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go
new file mode 100644
index 0000000..d5c40a2
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go
@@ -0,0 +1,198 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+)
+
+// CallKind describes the function position of an [*ast.CallExpr].
+type CallKind int
+
+const (
+	CallStatic     CallKind = iota // static call to known function
+	CallInterface                  // dynamic call through an interface method
+	CallDynamic                    // dynamic call of a func value
+	CallBuiltin                    // call to a builtin function
+	CallConversion                 // a conversion (not a call)
+)
+
+var callKindNames = []string{
+	"CallStatic",
+	"CallInterface",
+	"CallDynamic",
+	"CallBuiltin",
+	"CallConversion",
+}
+
+func (k CallKind) String() string {
+	if i := int(k); i >= 0 && i < len(callKindNames) {
+		return callKindNames[i]
+	}
+	return fmt.Sprintf("typeutil.CallKind(%d)", k)
+}
+
+// ClassifyCall classifies the function position of a call expression ([*ast.CallExpr]).
+// It distinguishes among true function calls, calls to builtins, and type conversions,
+// and further classifies function calls as static calls (where the function is known),
+// dynamic interface calls, and other dynamic calls.
+//
+// For the declarations:
+//
+//	func f() {}
+//	func g[T any]() {}
+//	var v func()
+//	var s []func()
+//	type I interface { M() }
+//	var i I
+//
+// ClassifyCall returns the following:
+//
+//	f()           CallStatic
+//	g[int]()      CallStatic
+//	i.M()         CallInterface
+//	min(1, 2)     CallBuiltin
+//	v()           CallDynamic
+//	s[0]()        CallDynamic
+//	int(x)        CallConversion
+//	[]byte("")    CallConversion
+func ClassifyCall(info *types.Info, call *ast.CallExpr) CallKind {
+	if info.Types == nil {
+		panic("ClassifyCall: info.Types is nil")
+	}
+	tv := info.Types[call.Fun]
+	if tv.IsType() {
+		return CallConversion
+	}
+	if tv.IsBuiltin() {
+		return CallBuiltin
+	}
+	id := UsedIdent(info, call.Fun)
+	if id == nil {
+		return CallDynamic
+	}
+	obj := info.Uses[id]
+	// Classify the call by the type of the object, if any.
+	switch obj := obj.(type) {
+	case *types.Func:
+		if isInterfaceMethod(obj) {
+			return CallInterface
+		}
+		return CallStatic
+	default:
+		return CallDynamic
+	}
+}
+
+// UsedIdent returns the identifier such that info.Uses[UsedIdent(info, e)]
+// is the [types.Object] used by e, if any.
+//
+// If e is one of various forms of reference:
+//
+//	f, c, v, T           lexical reference
+//	pkg.X                qualified identifier
+//	f[T] or pkg.F[K,V]   instantiations of the above kinds
+//	expr.f               field or method value selector
+//	T.f                  method expression selector
+//
+// UsedIdent returns the identifier whose is associated value in [types.Info.Uses]
+// is the object to which it refers.
+//
+// For the declarations:
+//
+//	func F[T any] {...}
+//	type I interface { M() }
+//	var (
+//	  x int
+//	  s struct { f  int }
+//	  a []int
+//	  i I
+//	)
+//
+// UsedIdent returns the following:
+//
+//	Expr          UsedIdent
+//	x             x
+//	s.f           f
+//	F[int]        F
+//	i.M           M
+//	I.M           M
+//	min           min
+//	int           int
+//	1             nil
+//	a[0]          nil
+//	[]byte        nil
+//
+// Note: if e is an instantiated function or method, UsedIdent returns
+// the corresponding generic function or method on the generic type.
+func UsedIdent(info *types.Info, e ast.Expr) *ast.Ident {
+	if info.Types == nil || info.Uses == nil {
+		panic("one of info.Types or info.Uses is nil; both must be populated")
+	}
+	// Look through type instantiation if necessary.
+	switch d := ast.Unparen(e).(type) {
+	case *ast.IndexExpr:
+		if info.Types[d.Index].IsType() {
+			e = d.X
+		}
+	case *ast.IndexListExpr:
+		e = d.X
+	}
+
+	switch e := ast.Unparen(e).(type) {
+	// info.Uses always has the object we want, even for selector expressions.
+	// We don't need info.Selections.
+	// See go/types/recording.go:recordSelection.
+	case *ast.Ident:
+		return e
+	case *ast.SelectorExpr:
+		return e.Sel
+	}
+	return nil
+}
+
+// See [golang.org/x/tools/go/types/typeutil.Callee].
+func Callee(info *types.Info, call *ast.CallExpr) types.Object {
+	id := UsedIdent(info, call.Fun)
+	if id == nil {
+		return nil
+	}
+	obj := info.Uses[id]
+	if obj == nil {
+		return nil
+	}
+	if _, ok := obj.(*types.TypeName); ok {
+		return nil
+	}
+	if fn, ok := obj.(*types.Func); ok {
+		return fn.Origin()
+	}
+	return obj
+}
+
+// See [golang.org/x/tools/go/types/typeutil.StaticCallee].
+func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func {
+	id := UsedIdent(info, call.Fun)
+	if id == nil {
+		return nil
+	}
+	obj := info.Uses[id]
+	if obj == nil {
+		return nil
+	}
+	fn, _ := obj.(*types.Func)
+	if fn == nil || isInterfaceMethod(fn) {
+		return nil
+	}
+	return fn.Origin()
+}
+
+// isInterfaceMethod reports whether its argument is a method of an interface.
+func isInterfaceMethod(f *types.Func) bool {
+	recv := f.Signature().Recv()
+	return recv != nil && types.IsInterface(recv.Type())
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/element.go b/vendor/golang.org/x/tools/internal/typesinternal/element.go
new file mode 100644
index 0000000..bab37fb
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/element.go
@@ -0,0 +1,134 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"fmt"
+	"go/types"
+)
+
+// ForEachElement calls f for type T and each type reachable from its
+// type through reflection. It does this by recursively stripping off
+// type constructors; in addition, for each named type N, the type *N
+// is added to the result as it may have additional methods.
+//
+// The access argument passed to f indicates whether the type is
+// inaccessible to reflection (for example, intermediate tuple types
+// or underlying types of named types).
+//
+// The result of f indicates whether the caller has seen this type
+// already, so we can prune the traversal.
+//
+// methodSetOf abstracts (*typeutil.MethodSetCache).MethodSet,
+// avoiding an import cycle.
+func ForEachElement(methodSetOf func(types.Type) *types.MethodSet, T types.Type, f func(T types.Type, access bool) bool) {
+	var visit func(T types.Type, access bool)
+	visit = func(T types.Type, access bool) {
+		if f(T, access) {
+			return // duplicate; prune descent
+		}
+
+		// Recursion over signatures of each method.
+		tmset := methodSetOf(T)
+		for method := range tmset.Methods() {
+			sig := method.Type().(*types.Signature)
+			if sig.TypeParams() != nil {
+				continue // skip type-parameterized methods
+			}
+
+			// It is tempting to call visit(sig, false)
+			// but, as noted in golang.org/cl/65450043,
+			// the Signature.Recv field is ignored by
+			// types.Identical and typeutil.Map, which
+			// is confusing at best.
+			//
+			// More importantly, the true signature rtype
+			// reachable from a method using reflection
+			// has no receiver but an extra ordinary parameter.
+			// For the Read method of io.Reader we want:
+			//   func(Reader, []byte) (int, error)
+			// but here sig is:
+			//   func([]byte) (int, error)
+			// with .Recv = Reader (though it is hard to
+			// notice because it doesn't affect Signature.String
+			// or types.Identical).
+			//
+			// TODO(adonovan): construct and visit the correct
+			// non-method signature with an extra parameter
+			// (though since unnamed func types have no methods
+			// there is essentially no actual demand for this).
+			//
+			// TODO(adonovan): document whether or not it is
+			// safe to skip non-exported methods (as RTA does).
+			visit(sig.Params(), false)  // the Tuple is inaccessible
+			visit(sig.Results(), false) // the Tuple is inaccessible
+		}
+
+		switch T := T.(type) {
+		case *types.Alias:
+			visit(types.Unalias(T), access) // emulates the pre-Alias behavior
+
+		case *types.Basic:
+			// nop
+
+		case *types.Interface:
+			// nop---handled by recursion over method set.
+
+		case *types.Pointer:
+			visit(T.Elem(), true)
+
+		case *types.Slice:
+			visit(T.Elem(), true)
+
+		case *types.Chan:
+			visit(T.Elem(), true)
+
+		case *types.Map:
+			visit(T.Key(), true)
+			visit(T.Elem(), true)
+
+		case *types.Signature:
+			if T.Recv() != nil {
+				panic(fmt.Sprintf("Signature %s has Recv %s", T, T.Recv()))
+			}
+			visit(T.Params(), false)  // the Tuple is inaccessible
+			visit(T.Results(), false) // the Tuple is inaccessible
+
+		case *types.Named:
+			// A pointer-to-named type can be derived from a named
+			// type via reflection.  It may have methods too.
+			visit(types.NewPointer(T), true)
+
+			// Consider 'type T struct{S}' where S has methods.
+			// Reflection provides no way to get from T to struct{S},
+			// only to S, so the method set of struct{S} is unwanted,
+			// so mark it inaccessible during recursion.
+			visit(T.Underlying(), false) // skip the unnamed type
+
+		case *types.Array:
+			visit(T.Elem(), true)
+
+		case *types.Struct:
+			for i, n := 0, T.NumFields(); i < n; i++ {
+				// TODO(adonovan): document whether or not
+				// it is safe to skip non-exported fields.
+				visit(T.Field(i).Type(), true)
+			}
+
+		case *types.Tuple:
+			for i, n := 0, T.Len(); i < n; i++ {
+				visit(T.At(i).Type(), true)
+			}
+
+		case *types.TypeParam, *types.Union:
+			// forEachReachable must not be called on parameterized types.
+			panic(fmt.Sprintf("ForEachElement called on type containing %T", T))
+
+		default:
+			panic(fmt.Sprintf("ForEachElement called on unexpected type %T", T))
+		}
+	}
+	visit(T, true)
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go
new file mode 100644
index 0000000..235a6de
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go
@@ -0,0 +1,1560 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+//go:generate stringer -type=ErrorCode
+
+type ErrorCode int
+
+// This file defines the error codes that can be produced during type-checking.
+// Collectively, these codes provide an identifier that may be used to
+// implement special handling for certain types of errors.
+//
+// Error codes should be fine-grained enough that the exact nature of the error
+// can be easily determined, but coarse enough that they are not an
+// implementation detail of the type checking algorithm. As a rule-of-thumb,
+// errors should be considered equivalent if there is a theoretical refactoring
+// of the type checker in which they are emitted in exactly one place. For
+// example, the type checker emits different error messages for "too many
+// arguments" and "too few arguments", but one can imagine an alternative type
+// checker where this check instead just emits a single "wrong number of
+// arguments", so these errors should have the same code.
+//
+// Error code names should be as brief as possible while retaining accuracy and
+// distinctiveness. In most cases names should start with an adjective
+// describing the nature of the error (e.g. "invalid", "unused", "misplaced"),
+// and end with a noun identifying the relevant language object. For example,
+// "DuplicateDecl" or "InvalidSliceExpr". For brevity, naming follows the
+// convention that "bad" implies a problem with syntax, and "invalid" implies a
+// problem with types.
+
+const (
+	// InvalidSyntaxTree occurs if an invalid syntax tree is provided
+	// to the type checker. It should never happen.
+	InvalidSyntaxTree ErrorCode = -1
+)
+
+const (
+	_ ErrorCode = iota
+
+	// Test is reserved for errors that only apply while in self-test mode.
+	Test
+
+	/* package names */
+
+	// BlankPkgName occurs when a package name is the blank identifier "_".
+	//
+	// Per the spec:
+	//  "The PackageName must not be the blank identifier."
+	BlankPkgName
+
+	// MismatchedPkgName occurs when a file's package name doesn't match the
+	// package name already established by other files.
+	MismatchedPkgName
+
+	// InvalidPkgUse occurs when a package identifier is used outside of a
+	// selector expression.
+	//
+	// Example:
+	//  import "fmt"
+	//
+	//  var _ = fmt
+	InvalidPkgUse
+
+	/* imports */
+
+	// BadImportPath occurs when an import path is not valid.
+	BadImportPath
+
+	// BrokenImport occurs when importing a package fails.
+	//
+	// Example:
+	//  import "amissingpackage"
+	BrokenImport
+
+	// ImportCRenamed occurs when the special import "C" is renamed. "C" is a
+	// pseudo-package, and must not be renamed.
+	//
+	// Example:
+	//  import _ "C"
+	ImportCRenamed
+
+	// UnusedImport occurs when an import is unused.
+	//
+	// Example:
+	//  import "fmt"
+	//
+	//  func main() {}
+	UnusedImport
+
+	/* initialization */
+
+	// InvalidInitCycle occurs when an invalid cycle is detected within the
+	// initialization graph.
+	//
+	// Example:
+	//  var x int = f()
+	//
+	//  func f() int { return x }
+	InvalidInitCycle
+
+	/* decls */
+
+	// DuplicateDecl occurs when an identifier is declared multiple times.
+	//
+	// Example:
+	//  var x = 1
+	//  var x = 2
+	DuplicateDecl
+
+	// InvalidDeclCycle occurs when a declaration cycle is not valid.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type T struct {
+	//  	a [n]int
+	//  }
+	//
+	//  var n = unsafe.Sizeof(T{})
+	InvalidDeclCycle
+
+	// InvalidTypeCycle occurs when a cycle in type definitions results in a
+	// type that is not well-defined.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type T [unsafe.Sizeof(T{})]int
+	InvalidTypeCycle
+
+	/* decls > const */
+
+	// InvalidConstInit occurs when a const declaration has a non-constant
+	// initializer.
+	//
+	// Example:
+	//  var x int
+	//  const _ = x
+	InvalidConstInit
+
+	// InvalidConstVal occurs when a const value cannot be converted to its
+	// target type.
+	//
+	// TODO(findleyr): this error code and example are not very clear. Consider
+	// removing it.
+	//
+	// Example:
+	//  const _ = 1 << "hello"
+	InvalidConstVal
+
+	// InvalidConstType occurs when the underlying type in a const declaration
+	// is not a valid constant type.
+	//
+	// Example:
+	//  const c *int = 4
+	InvalidConstType
+
+	/* decls > var (+ other variable assignment codes) */
+
+	// UntypedNilUse occurs when the predeclared (untyped) value nil is used to
+	// initialize a variable declared without an explicit type.
+	//
+	// Example:
+	//  var x = nil
+	UntypedNilUse
+
+	// WrongAssignCount occurs when the number of values on the right-hand side
+	// of an assignment or initialization expression does not match the number
+	// of variables on the left-hand side.
+	//
+	// Example:
+	//  var x = 1, 2
+	WrongAssignCount
+
+	// UnassignableOperand occurs when the left-hand side of an assignment is
+	// not assignable.
+	//
+	// Example:
+	//  func f() {
+	//  	const c = 1
+	//  	c = 2
+	//  }
+	UnassignableOperand
+
+	// NoNewVar occurs when a short variable declaration (':=') does not declare
+	// new variables.
+	//
+	// Example:
+	//  func f() {
+	//  	x := 1
+	//  	x := 2
+	//  }
+	NoNewVar
+
+	// MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does
+	// not have single-valued left-hand or right-hand side.
+	//
+	// Per the spec:
+	//  "In assignment operations, both the left- and right-hand expression lists
+	//  must contain exactly one single-valued expression"
+	//
+	// Example:
+	//  func f() int {
+	//  	x, y := 1, 2
+	//  	x, y += 1
+	//  	return x + y
+	//  }
+	MultiValAssignOp
+
+	// InvalidIfaceAssign occurs when a value of type T is used as an
+	// interface, but T does not implement a method of the expected interface.
+	//
+	// Example:
+	//  type I interface {
+	//  	f()
+	//  }
+	//
+	//  type T int
+	//
+	//  var x I = T(1)
+	InvalidIfaceAssign
+
+	// InvalidChanAssign occurs when a chan assignment is invalid.
+	//
+	// Per the spec, a value x is assignable to a channel type T if:
+	//  "x is a bidirectional channel value, T is a channel type, x's type V and
+	//  T have identical element types, and at least one of V or T is not a
+	//  defined type."
+	//
+	// Example:
+	//  type T1 chan int
+	//  type T2 chan int
+	//
+	//  var x T1
+	//  // Invalid assignment because both types are named
+	//  var _ T2 = x
+	InvalidChanAssign
+
+	// IncompatibleAssign occurs when the type of the right-hand side expression
+	// in an assignment cannot be assigned to the type of the variable being
+	// assigned.
+	//
+	// Example:
+	//  var x []int
+	//  var _ int = x
+	IncompatibleAssign
+
+	// UnaddressableFieldAssign occurs when trying to assign to a struct field
+	// in a map value.
+	//
+	// Example:
+	//  func f() {
+	//  	m := make(map[string]struct{i int})
+	//  	m["foo"].i = 42
+	//  }
+	UnaddressableFieldAssign
+
+	/* decls > type (+ other type expression codes) */
+
+	// NotAType occurs when the identifier used as the underlying type in a type
+	// declaration or the right-hand side of a type alias does not denote a type.
+	//
+	// Example:
+	//  var S = 2
+	//
+	//  type T S
+	NotAType
+
+	// InvalidArrayLen occurs when an array length is not a constant value.
+	//
+	// Example:
+	//  var n = 3
+	//  var _ = [n]int{}
+	InvalidArrayLen
+
+	// BlankIfaceMethod occurs when a method name is '_'.
+	//
+	// Per the spec:
+	//  "The name of each explicitly specified method must be unique and not
+	//  blank."
+	//
+	// Example:
+	//  type T interface {
+	//  	_(int)
+	//  }
+	BlankIfaceMethod
+
+	// IncomparableMapKey occurs when a map key type does not support the == and
+	// != operators.
+	//
+	// Per the spec:
+	//  "The comparison operators == and != must be fully defined for operands of
+	//  the key type; thus the key type must not be a function, map, or slice."
+	//
+	// Example:
+	//  var x map[T]int
+	//
+	//  type T []int
+	IncomparableMapKey
+
+	// InvalidIfaceEmbed occurs when a non-interface type is embedded in an
+	// interface.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func (T) m()
+	//
+	//  type I interface {
+	//  	T
+	//  }
+	InvalidIfaceEmbed
+
+	// InvalidPtrEmbed occurs when an embedded field is of the pointer form *T,
+	// and T itself is itself a pointer, an unsafe.Pointer, or an interface.
+	//
+	// Per the spec:
+	//  "An embedded field must be specified as a type name T or as a pointer to
+	//  a non-interface type name *T, and T itself may not be a pointer type."
+	//
+	// Example:
+	//  type T *int
+	//
+	//  type S struct {
+	//  	*T
+	//  }
+	InvalidPtrEmbed
+
+	/* decls > func and method */
+
+	// BadRecv occurs when a method declaration does not have exactly one
+	// receiver parameter.
+	//
+	// Example:
+	//  func () _() {}
+	BadRecv
+
+	// InvalidRecv occurs when a receiver type expression is not of the form T
+	// or *T, or T is a pointer type.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func (**T) m() {}
+	InvalidRecv
+
+	// DuplicateFieldAndMethod occurs when an identifier appears as both a field
+	// and method name.
+	//
+	// Example:
+	//  type T struct {
+	//  	m int
+	//  }
+	//
+	//  func (T) m() {}
+	DuplicateFieldAndMethod
+
+	// DuplicateMethod occurs when two methods on the same receiver type have
+	// the same name.
+	//
+	// Example:
+	//  type T struct {}
+	//  func (T) m() {}
+	//  func (T) m(i int) int { return i }
+	DuplicateMethod
+
+	/* decls > special */
+
+	// InvalidBlank occurs when a blank identifier is used as a value or type.
+	//
+	// Per the spec:
+	//  "The blank identifier may appear as an operand only on the left-hand side
+	//  of an assignment."
+	//
+	// Example:
+	//  var x = _
+	InvalidBlank
+
+	// InvalidIota occurs when the predeclared identifier iota is used outside
+	// of a constant declaration.
+	//
+	// Example:
+	//  var x = iota
+	InvalidIota
+
+	// MissingInitBody occurs when an init function is missing its body.
+	//
+	// Example:
+	//  func init()
+	MissingInitBody
+
+	// InvalidInitSig occurs when an init function declares parameters or
+	// results.
+	//
+	// Example:
+	//  func init() int { return 1 }
+	InvalidInitSig
+
+	// InvalidInitDecl occurs when init is declared as anything other than a
+	// function.
+	//
+	// Example:
+	//  var init = 1
+	InvalidInitDecl
+
+	// InvalidMainDecl occurs when main is declared as anything other than a
+	// function, in a main package.
+	InvalidMainDecl
+
+	/* exprs */
+
+	// TooManyValues occurs when a function returns too many values for the
+	// expression context in which it is used.
+	//
+	// Example:
+	//  func ReturnTwo() (int, int) {
+	//  	return 1, 2
+	//  }
+	//
+	//  var x = ReturnTwo()
+	TooManyValues
+
+	// NotAnExpr occurs when a type expression is used where a value expression
+	// is expected.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func f() {
+	//  	T
+	//  }
+	NotAnExpr
+
+	/* exprs > const */
+
+	// TruncatedFloat occurs when a float constant is truncated to an integer
+	// value.
+	//
+	// Example:
+	//  var _ int = 98.6
+	TruncatedFloat
+
+	// NumericOverflow occurs when a numeric constant overflows its target type.
+	//
+	// Example:
+	//  var x int8 = 1000
+	NumericOverflow
+
+	/* exprs > operation */
+
+	// UndefinedOp occurs when an operator is not defined for the type(s) used
+	// in an operation.
+	//
+	// Example:
+	//  var c = "a" - "b"
+	UndefinedOp
+
+	// MismatchedTypes occurs when operand types are incompatible in a binary
+	// operation.
+	//
+	// Example:
+	//  var a = "hello"
+	//  var b = 1
+	//  var c = a - b
+	MismatchedTypes
+
+	// DivByZero occurs when a division operation is provable at compile
+	// time to be a division by zero.
+	//
+	// Example:
+	//  const divisor = 0
+	//  var x int = 1/divisor
+	DivByZero
+
+	// NonNumericIncDec occurs when an increment or decrement operator is
+	// applied to a non-numeric value.
+	//
+	// Example:
+	//  func f() {
+	//  	var c = "c"
+	//  	c++
+	//  }
+	NonNumericIncDec
+
+	/* exprs > ptr */
+
+	// UnaddressableOperand occurs when the & operator is applied to an
+	// unaddressable expression.
+	//
+	// Example:
+	//  var x = &1
+	UnaddressableOperand
+
+	// InvalidIndirection occurs when a non-pointer value is indirected via the
+	// '*' operator.
+	//
+	// Example:
+	//  var x int
+	//  var y = *x
+	InvalidIndirection
+
+	/* exprs > [] */
+
+	// NonIndexableOperand occurs when an index operation is applied to a value
+	// that cannot be indexed.
+	//
+	// Example:
+	//  var x = 1
+	//  var y = x[1]
+	NonIndexableOperand
+
+	// InvalidIndex occurs when an index argument is not of integer type,
+	// negative, or out-of-bounds.
+	//
+	// Example:
+	//  var s = [...]int{1,2,3}
+	//  var x = s[5]
+	//
+	// Example:
+	//  var s = []int{1,2,3}
+	//  var _ = s[-1]
+	//
+	// Example:
+	//  var s = []int{1,2,3}
+	//  var i string
+	//  var _ = s[i]
+	InvalidIndex
+
+	// SwappedSliceIndices occurs when constant indices in a slice expression
+	// are decreasing in value.
+	//
+	// Example:
+	//  var _ = []int{1,2,3}[2:1]
+	SwappedSliceIndices
+
+	/* operators > slice */
+
+	// NonSliceableOperand occurs when a slice operation is applied to a value
+	// whose type is not sliceable, or is unaddressable.
+	//
+	// Example:
+	//  var x = [...]int{1, 2, 3}[:1]
+	//
+	// Example:
+	//  var x = 1
+	//  var y = 1[:1]
+	NonSliceableOperand
+
+	// InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is
+	// applied to a string.
+	//
+	// Example:
+	//  var s = "hello"
+	//  var x = s[1:2:3]
+	InvalidSliceExpr
+
+	/* exprs > shift */
+
+	// InvalidShiftCount occurs when the right-hand side of a shift operation is
+	// either non-integer, negative, or too large.
+	//
+	// Example:
+	//  var (
+	//  	x string
+	//  	y int = 1 << x
+	//  )
+	InvalidShiftCount
+
+	// InvalidShiftOperand occurs when the shifted operand is not an integer.
+	//
+	// Example:
+	//  var s = "hello"
+	//  var x = s << 2
+	InvalidShiftOperand
+
+	/* exprs > chan */
+
+	// InvalidReceive occurs when there is a channel receive from a value that
+	// is either not a channel, or is a send-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x = 1
+	//  	<-x
+	//  }
+	InvalidReceive
+
+	// InvalidSend occurs when there is a channel send to a value that is not a
+	// channel, or is a receive-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x = 1
+	//  	x <- "hello!"
+	//  }
+	InvalidSend
+
+	/* exprs > literal */
+
+	// DuplicateLitKey occurs when an index is duplicated in a slice, array, or
+	// map literal.
+	//
+	// Example:
+	//  var _ = []int{0:1, 0:2}
+	//
+	// Example:
+	//  var _ = map[string]int{"a": 1, "a": 2}
+	DuplicateLitKey
+
+	// MissingLitKey occurs when a map literal is missing a key expression.
+	//
+	// Example:
+	//  var _ = map[string]int{1}
+	MissingLitKey
+
+	// InvalidLitIndex occurs when the key in a key-value element of a slice or
+	// array literal is not an integer constant.
+	//
+	// Example:
+	//  var i = 0
+	//  var x = []string{i: "world"}
+	InvalidLitIndex
+
+	// OversizeArrayLit occurs when an array literal exceeds its length.
+	//
+	// Example:
+	//  var _ = [2]int{1,2,3}
+	OversizeArrayLit
+
+	// MixedStructLit occurs when a struct literal contains a mix of positional
+	// and named elements.
+	//
+	// Example:
+	//  var _ = struct{i, j int}{i: 1, 2}
+	MixedStructLit
+
+	// InvalidStructLit occurs when a positional struct literal has an incorrect
+	// number of values.
+	//
+	// Example:
+	//  var _ = struct{i, j int}{1,2,3}
+	InvalidStructLit
+
+	// MissingLitField occurs when a struct literal refers to a field that does
+	// not exist on the struct type.
+	//
+	// Example:
+	//  var _ = struct{i int}{j: 2}
+	MissingLitField
+
+	// DuplicateLitField occurs when a struct literal contains duplicated
+	// fields.
+	//
+	// Example:
+	//  var _ = struct{i int}{i: 1, i: 2}
+	DuplicateLitField
+
+	// UnexportedLitField occurs when a positional struct literal implicitly
+	// assigns an unexported field of an imported type.
+	UnexportedLitField
+
+	// InvalidLitField occurs when a field name is not a valid identifier.
+	//
+	// Example:
+	//  var _ = struct{i int}{1: 1}
+	InvalidLitField
+
+	// UntypedLit occurs when a composite literal omits a required type
+	// identifier.
+	//
+	// Example:
+	//  type outer struct{
+	//  	inner struct { i int }
+	//  }
+	//
+	//  var _ = outer{inner: {1}}
+	UntypedLit
+
+	// InvalidLit occurs when a composite literal expression does not match its
+	// type.
+	//
+	// Example:
+	//  type P *struct{
+	//  	x int
+	//  }
+	//  var _ = P {}
+	InvalidLit
+
+	/* exprs > selector */
+
+	// AmbiguousSelector occurs when a selector is ambiguous.
+	//
+	// Example:
+	//  type E1 struct { i int }
+	//  type E2 struct { i int }
+	//  type T struct { E1; E2 }
+	//
+	//  var x T
+	//  var _ = x.i
+	AmbiguousSelector
+
+	// UndeclaredImportedName occurs when a package-qualified identifier is
+	// undeclared by the imported package.
+	//
+	// Example:
+	//  import "go/types"
+	//
+	//  var _ = types.NotAnActualIdentifier
+	UndeclaredImportedName
+
+	// UnexportedName occurs when a selector refers to an unexported identifier
+	// of an imported package.
+	//
+	// Example:
+	//  import "reflect"
+	//
+	//  type _ reflect.flag
+	UnexportedName
+
+	// UndeclaredName occurs when an identifier is not declared in the current
+	// scope.
+	//
+	// Example:
+	//  var x T
+	UndeclaredName
+
+	// MissingFieldOrMethod occurs when a selector references a field or method
+	// that does not exist.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  var x = T{}.f
+	MissingFieldOrMethod
+
+	/* exprs > ... */
+
+	// BadDotDotDotSyntax occurs when a "..." occurs in a context where it is
+	// not valid.
+	//
+	// Example:
+	//  var _ = map[int][...]int{0: {}}
+	BadDotDotDotSyntax
+
+	// NonVariadicDotDotDot occurs when a "..." is used on the final argument to
+	// a non-variadic function.
+	//
+	// Example:
+	//  func printArgs(s []string) {
+	//  	for _, a := range s {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func f() {
+	//  	s := []string{"a", "b", "c"}
+	//  	printArgs(s...)
+	//  }
+	NonVariadicDotDotDot
+
+	// MisplacedDotDotDot occurs when a "..." is used somewhere other than the
+	// final argument to a function call.
+	//
+	// Example:
+	//  func printArgs(args ...int) {
+	//  	for _, a := range args {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func f() {
+	//  	a := []int{1,2,3}
+	//  	printArgs(0, a...)
+	//  }
+	MisplacedDotDotDot
+
+	// InvalidDotDotDotOperand occurs when a "..." operator is applied to a
+	// single-valued operand.
+	//
+	// Example:
+	//  func printArgs(args ...int) {
+	//  	for _, a := range args {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func f() {
+	//  	a := 1
+	//  	printArgs(a...)
+	//  }
+	//
+	// Example:
+	//  func args() (int, int) {
+	//  	return 1, 2
+	//  }
+	//
+	//  func printArgs(args ...int) {
+	//  	for _, a := range args {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func g() {
+	//  	printArgs(args()...)
+	//  }
+	InvalidDotDotDotOperand
+
+	// InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in
+	// function.
+	//
+	// Example:
+	//  var s = []int{1, 2, 3}
+	//  var l = len(s...)
+	InvalidDotDotDot
+
+	/* exprs > built-in */
+
+	// UncalledBuiltin occurs when a built-in function is used as a
+	// function-valued expression, instead of being called.
+	//
+	// Per the spec:
+	//  "The built-in functions do not have standard Go types, so they can only
+	//  appear in call expressions; they cannot be used as function values."
+	//
+	// Example:
+	//  var _ = copy
+	UncalledBuiltin
+
+	// InvalidAppend occurs when append is called with a first argument that is
+	// not a slice.
+	//
+	// Example:
+	//  var _ = append(1, 2)
+	InvalidAppend
+
+	// InvalidCap occurs when an argument to the cap built-in function is not of
+	// supported type.
+	//
+	// See https://golang.org/ref/spec#Length_and_capacity for information on
+	// which underlying types are supported as arguments to cap and len.
+	//
+	// Example:
+	//  var s = 2
+	//  var x = cap(s)
+	InvalidCap
+
+	// InvalidClose occurs when close(...) is called with an argument that is
+	// not of channel type, or that is a receive-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x int
+	//  	close(x)
+	//  }
+	InvalidClose
+
+	// InvalidCopy occurs when the arguments are not of slice type or do not
+	// have compatible type.
+	//
+	// See https://golang.org/ref/spec#Appending_and_copying_slices for more
+	// information on the type requirements for the copy built-in.
+	//
+	// Example:
+	//  func f() {
+	//  	var x []int
+	//  	y := []int64{1,2,3}
+	//  	copy(x, y)
+	//  }
+	InvalidCopy
+
+	// InvalidComplex occurs when the complex built-in function is called with
+	// arguments with incompatible types.
+	//
+	// Example:
+	//  var _ = complex(float32(1), float64(2))
+	InvalidComplex
+
+	// InvalidDelete occurs when the delete built-in function is called with a
+	// first argument that is not a map.
+	//
+	// Example:
+	//  func f() {
+	//  	m := "hello"
+	//  	delete(m, "e")
+	//  }
+	InvalidDelete
+
+	// InvalidImag occurs when the imag built-in function is called with an
+	// argument that does not have complex type.
+	//
+	// Example:
+	//  var _ = imag(int(1))
+	InvalidImag
+
+	// InvalidLen occurs when an argument to the len built-in function is not of
+	// supported type.
+	//
+	// See https://golang.org/ref/spec#Length_and_capacity for information on
+	// which underlying types are supported as arguments to cap and len.
+	//
+	// Example:
+	//  var s = 2
+	//  var x = len(s)
+	InvalidLen
+
+	// SwappedMakeArgs occurs when make is called with three arguments, and its
+	// length argument is larger than its capacity argument.
+	//
+	// Example:
+	//  var x = make([]int, 3, 2)
+	SwappedMakeArgs
+
+	// InvalidMake occurs when make is called with an unsupported type argument.
+	//
+	// See https://golang.org/ref/spec#Making_slices_maps_and_channels for
+	// information on the types that may be created using make.
+	//
+	// Example:
+	//  var x = make(int)
+	InvalidMake
+
+	// InvalidReal occurs when the real built-in function is called with an
+	// argument that does not have complex type.
+	//
+	// Example:
+	//  var _ = real(int(1))
+	InvalidReal
+
+	/* exprs > assertion */
+
+	// InvalidAssert occurs when a type assertion is applied to a
+	// value that is not of interface type.
+	//
+	// Example:
+	//  var x = 1
+	//  var _ = x.(float64)
+	InvalidAssert
+
+	// ImpossibleAssert occurs for a type assertion x.(T) when the value x of
+	// interface cannot have dynamic type T, due to a missing or mismatching
+	// method on T.
+	//
+	// Example:
+	//  type T int
+	//
+	//  func (t *T) m() int { return int(*t) }
+	//
+	//  type I interface { m() int }
+	//
+	//  var x I
+	//  var _ = x.(T)
+	ImpossibleAssert
+
+	/* exprs > conversion */
+
+	// InvalidConversion occurs when the argument type cannot be converted to the
+	// target.
+	//
+	// See https://golang.org/ref/spec#Conversions for the rules of
+	// convertibility.
+	//
+	// Example:
+	//  var x float64
+	//  var _ = string(x)
+	InvalidConversion
+
+	// InvalidUntypedConversion occurs when there is no valid implicit
+	// conversion from an untyped value satisfying the type constraints of the
+	// context in which it is used.
+	//
+	// Example:
+	//  var _ = 1 + ""
+	InvalidUntypedConversion
+
+	/* offsetof */
+
+	// BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument
+	// that is not a selector expression.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Offsetof(x)
+	BadOffsetofSyntax
+
+	// InvalidOffsetof occurs when unsafe.Offsetof is called with a method
+	// selector, rather than a field selector, or when the field is embedded via
+	// a pointer.
+	//
+	// Per the spec:
+	//
+	//  "If f is an embedded field, it must be reachable without pointer
+	//  indirections through fields of the struct. "
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type T struct { f int }
+	//  type S struct { *T }
+	//  var s S
+	//  var _ = unsafe.Offsetof(s.f)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type S struct{}
+	//
+	//  func (S) m() {}
+	//
+	//  var s S
+	//  var _ = unsafe.Offsetof(s.m)
+	InvalidOffsetof
+
+	/* control flow > scope */
+
+	// UnusedExpr occurs when a side-effect free expression is used as a
+	// statement. Such a statement has no effect.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	i*i
+	//  }
+	UnusedExpr
+
+	// UnusedVar occurs when a variable is declared but unused.
+	//
+	// Example:
+	//  func f() {
+	//  	x := 1
+	//  }
+	UnusedVar
+
+	// MissingReturn occurs when a function with results is missing a return
+	// statement.
+	//
+	// Example:
+	//  func f() int {}
+	MissingReturn
+
+	// WrongResultCount occurs when a return statement returns an incorrect
+	// number of values.
+	//
+	// Example:
+	//  func ReturnOne() int {
+	//  	return 1, 2
+	//  }
+	WrongResultCount
+
+	// OutOfScopeResult occurs when the name of a value implicitly returned by
+	// an empty return statement is shadowed in a nested scope.
+	//
+	// Example:
+	//  func factor(n int) (i int) {
+	//  	for i := 2; i < n; i++ {
+	//  		if n%i == 0 {
+	//  			return
+	//  		}
+	//  	}
+	//  	return 0
+	//  }
+	OutOfScopeResult
+
+	/* control flow > if */
+
+	// InvalidCond occurs when an if condition is not a boolean expression.
+	//
+	// Example:
+	//  func checkReturn(i int) {
+	//  	if i {
+	//  		panic("non-zero return")
+	//  	}
+	//  }
+	InvalidCond
+
+	/* control flow > for */
+
+	// InvalidPostDecl occurs when there is a declaration in a for-loop post
+	// statement.
+	//
+	// Example:
+	//  func f() {
+	//  	for i := 0; i < 10; j := 0 {}
+	//  }
+	InvalidPostDecl
+
+	// InvalidChanRange occurs when a send-only channel used in a range
+	// expression.
+	//
+	// Example:
+	//  func sum(c chan<- int) {
+	//  	s := 0
+	//  	for i := range c {
+	//  		s += i
+	//  	}
+	//  }
+	InvalidChanRange
+
+	// InvalidIterVar occurs when two iteration variables are used while ranging
+	// over a channel.
+	//
+	// Example:
+	//  func f(c chan int) {
+	//  	for k, v := range c {
+	//  		println(k, v)
+	//  	}
+	//  }
+	InvalidIterVar
+
+	// InvalidRangeExpr occurs when the type of a range expression is not array,
+	// slice, string, map, or channel.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	for j := range i {
+	//  		println(j)
+	//  	}
+	//  }
+	InvalidRangeExpr
+
+	/* control flow > switch */
+
+	// MisplacedBreak occurs when a break statement is not within a for, switch,
+	// or select statement of the innermost function definition.
+	//
+	// Example:
+	//  func f() {
+	//  	break
+	//  }
+	MisplacedBreak
+
+	// MisplacedContinue occurs when a continue statement is not within a for
+	// loop of the innermost function definition.
+	//
+	// Example:
+	//  func sumeven(n int) int {
+	//  	proceed := func() {
+	//  		continue
+	//  	}
+	//  	sum := 0
+	//  	for i := 1; i <= n; i++ {
+	//  		if i % 2 != 0 {
+	//  			proceed()
+	//  		}
+	//  		sum += i
+	//  	}
+	//  	return sum
+	//  }
+	MisplacedContinue
+
+	// MisplacedFallthrough occurs when a fallthrough statement is not within an
+	// expression switch.
+	//
+	// Example:
+	//  func typename(i interface{}) string {
+	//  	switch i.(type) {
+	//  	case int64:
+	//  		fallthrough
+	//  	case int:
+	//  		return "int"
+	//  	}
+	//  	return "unsupported"
+	//  }
+	MisplacedFallthrough
+
+	// DuplicateCase occurs when a type or expression switch has duplicate
+	// cases.
+	//
+	// Example:
+	//  func printInt(i int) {
+	//  	switch i {
+	//  	case 1:
+	//  		println("one")
+	//  	case 1:
+	//  		println("One")
+	//  	}
+	//  }
+	DuplicateCase
+
+	// DuplicateDefault occurs when a type or expression switch has multiple
+	// default clauses.
+	//
+	// Example:
+	//  func printInt(i int) {
+	//  	switch i {
+	//  	case 1:
+	//  		println("one")
+	//  	default:
+	//  		println("One")
+	//  	default:
+	//  		println("1")
+	//  	}
+	//  }
+	DuplicateDefault
+
+	// BadTypeKeyword occurs when a .(type) expression is used anywhere other
+	// than a type switch.
+	//
+	// Example:
+	//  type I interface {
+	//  	m()
+	//  }
+	//  var t I
+	//  var _ = t.(type)
+	BadTypeKeyword
+
+	// InvalidTypeSwitch occurs when .(type) is used on an expression that is
+	// not of interface type.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	switch x := i.(type) {}
+	//  }
+	InvalidTypeSwitch
+
+	// InvalidExprSwitch occurs when a switch expression is not comparable.
+	//
+	// Example:
+	//  func _() {
+	//  	var a struct{ _ func() }
+	//  	switch a /* ERROR cannot switch on a */ {
+	//  	}
+	//  }
+	InvalidExprSwitch
+
+	/* control flow > select */
+
+	// InvalidSelectCase occurs when a select case is not a channel send or
+	// receive.
+	//
+	// Example:
+	//  func checkChan(c <-chan int) bool {
+	//  	select {
+	//  	case c:
+	//  		return true
+	//  	default:
+	//  		return false
+	//  	}
+	//  }
+	InvalidSelectCase
+
+	/* control flow > labels and jumps */
+
+	// UndeclaredLabel occurs when an undeclared label is jumped to.
+	//
+	// Example:
+	//  func f() {
+	//  	goto L
+	//  }
+	UndeclaredLabel
+
+	// DuplicateLabel occurs when a label is declared more than once.
+	//
+	// Example:
+	//  func f() int {
+	//  L:
+	//  L:
+	//  	return 1
+	//  }
+	DuplicateLabel
+
+	// MisplacedLabel occurs when a break or continue label is not on a for,
+	// switch, or select statement.
+	//
+	// Example:
+	//  func f() {
+	//  L:
+	//  	a := []int{1,2,3}
+	//  	for _, e := range a {
+	//  		if e > 10 {
+	//  			break L
+	//  		}
+	//  		println(a)
+	//  	}
+	//  }
+	MisplacedLabel
+
+	// UnusedLabel occurs when a label is declared but not used.
+	//
+	// Example:
+	//  func f() {
+	//  L:
+	//  }
+	UnusedLabel
+
+	// JumpOverDecl occurs when a label jumps over a variable declaration.
+	//
+	// Example:
+	//  func f() int {
+	//  	goto L
+	//  	x := 2
+	//  L:
+	//  	x++
+	//  	return x
+	//  }
+	JumpOverDecl
+
+	// JumpIntoBlock occurs when a forward jump goes to a label inside a nested
+	// block.
+	//
+	// Example:
+	//  func f(x int) {
+	//  	goto L
+	//  	if x > 0 {
+	//  	L:
+	//  		print("inside block")
+	//  	}
+	// }
+	JumpIntoBlock
+
+	/* control flow > calls */
+
+	// InvalidMethodExpr occurs when a pointer method is called but the argument
+	// is not addressable.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func (*T) m() int { return 1 }
+	//
+	//  var _ = T.m(T{})
+	InvalidMethodExpr
+
+	// WrongArgCount occurs when too few or too many arguments are passed by a
+	// function call.
+	//
+	// Example:
+	//  func f(i int) {}
+	//  var x = f()
+	WrongArgCount
+
+	// InvalidCall occurs when an expression is called that is not of function
+	// type.
+	//
+	// Example:
+	//  var x = "x"
+	//  var y = x()
+	InvalidCall
+
+	/* control flow > suspended */
+
+	// UnusedResults occurs when a restricted expression-only built-in function
+	// is suspended via go or defer. Such a suspension discards the results of
+	// these side-effect free built-in functions, and therefore is ineffectual.
+	//
+	// Example:
+	//  func f(a []int) int {
+	//  	defer len(a)
+	//  	return i
+	//  }
+	UnusedResults
+
+	// InvalidDefer occurs when a deferred expression is not a function call,
+	// for example if the expression is a type conversion.
+	//
+	// Example:
+	//  func f(i int) int {
+	//  	defer int32(i)
+	//  	return i
+	//  }
+	InvalidDefer
+
+	// InvalidGo occurs when a go expression is not a function call, for example
+	// if the expression is a type conversion.
+	//
+	// Example:
+	//  func f(i int) int {
+	//  	go int32(i)
+	//  	return i
+	//  }
+	InvalidGo
+
+	// All codes below were added in Go 1.17.
+
+	/* decl */
+
+	// BadDecl occurs when a declaration has invalid syntax.
+	BadDecl
+
+	// RepeatedDecl occurs when an identifier occurs more than once on the left
+	// hand side of a short variable declaration.
+	//
+	// Example:
+	//  func _() {
+	//  	x, y, y := 1, 2, 3
+	//  }
+	RepeatedDecl
+
+	/* unsafe */
+
+	// InvalidUnsafeAdd occurs when unsafe.Add is called with a
+	// length argument that is not of integer type.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var p unsafe.Pointer
+	//  var _ = unsafe.Add(p, float64(1))
+	InvalidUnsafeAdd
+
+	// InvalidUnsafeSlice occurs when unsafe.Slice is called with a
+	// pointer argument that is not of pointer type or a length argument
+	// that is not of integer type, negative, or out of bounds.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(x, 1)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, float64(1))
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, -1)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, uint64(1) << 63)
+	InvalidUnsafeSlice
+
+	// All codes below were added in Go 1.18.
+
+	/* features */
+
+	// UnsupportedFeature occurs when a language feature is used that is not
+	// supported at this Go version.
+	UnsupportedFeature
+
+	/* type params */
+
+	// NotAGenericType occurs when a non-generic type is used where a generic
+	// type is expected: in type or function instantiation.
+	//
+	// Example:
+	//  type T int
+	//
+	//  var _ T[int]
+	NotAGenericType
+
+	// WrongTypeArgCount occurs when a type or function is instantiated with an
+	// incorrect number of type arguments, including when a generic type or
+	// function is used without instantiation.
+	//
+	// Errors involving failed type inference are assigned other error codes.
+	//
+	// Example:
+	//  type T[p any] int
+	//
+	//  var _ T[int, string]
+	//
+	// Example:
+	//  func f[T any]() {}
+	//
+	//  var x = f
+	WrongTypeArgCount
+
+	// CannotInferTypeArgs occurs when type or function type argument inference
+	// fails to infer all type arguments.
+	//
+	// Example:
+	//  func f[T any]() {}
+	//
+	//  func _() {
+	//  	f()
+	//  }
+	//
+	// Example:
+	//   type N[P, Q any] struct{}
+	//
+	//   var _ N[int]
+	CannotInferTypeArgs
+
+	// InvalidTypeArg occurs when a type argument does not satisfy its
+	// corresponding type parameter constraints.
+	//
+	// Example:
+	//  type T[P ~int] struct{}
+	//
+	//  var _ T[string]
+	InvalidTypeArg // arguments? InferenceFailed
+
+	// InvalidInstanceCycle occurs when an invalid cycle is detected
+	// within the instantiation graph.
+	//
+	// Example:
+	//  func f[T any]() { f[*T]() }
+	InvalidInstanceCycle
+
+	// InvalidUnion occurs when an embedded union or approximation element is
+	// not valid.
+	//
+	// Example:
+	//  type _ interface {
+	//   	~int | interface{ m() }
+	//  }
+	InvalidUnion
+
+	// MisplacedConstraintIface occurs when a constraint-type interface is used
+	// outside of constraint position.
+	//
+	// Example:
+	//   type I interface { ~int }
+	//
+	//   var _ I
+	MisplacedConstraintIface
+
+	// InvalidMethodTypeParams occurs when methods have type parameters.
+	//
+	// It cannot be encountered with an AST parsed using go/parser.
+	InvalidMethodTypeParams
+
+	// MisplacedTypeParam occurs when a type parameter is used in a place where
+	// it is not permitted.
+	//
+	// Example:
+	//  type T[P any] P
+	//
+	// Example:
+	//  type T[P any] struct{ *P }
+	MisplacedTypeParam
+
+	// InvalidUnsafeSliceData occurs when unsafe.SliceData is called with
+	// an argument that is not of slice type. It also occurs if it is used
+	// in a package compiled for a language version before go1.20.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.SliceData(x)
+	InvalidUnsafeSliceData
+
+	// InvalidUnsafeString occurs when unsafe.String is called with
+	// a length argument that is not of integer type, negative, or
+	// out of bounds. It also occurs if it is used in a package
+	// compiled for a language version before go1.20.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var b [10]byte
+	//  var _ = unsafe.String(&b[0], -1)
+	InvalidUnsafeString
+
+	// InvalidUnsafeStringData occurs if it is used in a package
+	// compiled for a language version before go1.20.
+	_ // not used anymore
+
+)
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go
new file mode 100644
index 0000000..15ecf7c
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go
@@ -0,0 +1,179 @@
+// Code generated by "stringer -type=ErrorCode"; DO NOT EDIT.
+
+package typesinternal
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[InvalidSyntaxTree - -1]
+	_ = x[Test-1]
+	_ = x[BlankPkgName-2]
+	_ = x[MismatchedPkgName-3]
+	_ = x[InvalidPkgUse-4]
+	_ = x[BadImportPath-5]
+	_ = x[BrokenImport-6]
+	_ = x[ImportCRenamed-7]
+	_ = x[UnusedImport-8]
+	_ = x[InvalidInitCycle-9]
+	_ = x[DuplicateDecl-10]
+	_ = x[InvalidDeclCycle-11]
+	_ = x[InvalidTypeCycle-12]
+	_ = x[InvalidConstInit-13]
+	_ = x[InvalidConstVal-14]
+	_ = x[InvalidConstType-15]
+	_ = x[UntypedNilUse-16]
+	_ = x[WrongAssignCount-17]
+	_ = x[UnassignableOperand-18]
+	_ = x[NoNewVar-19]
+	_ = x[MultiValAssignOp-20]
+	_ = x[InvalidIfaceAssign-21]
+	_ = x[InvalidChanAssign-22]
+	_ = x[IncompatibleAssign-23]
+	_ = x[UnaddressableFieldAssign-24]
+	_ = x[NotAType-25]
+	_ = x[InvalidArrayLen-26]
+	_ = x[BlankIfaceMethod-27]
+	_ = x[IncomparableMapKey-28]
+	_ = x[InvalidIfaceEmbed-29]
+	_ = x[InvalidPtrEmbed-30]
+	_ = x[BadRecv-31]
+	_ = x[InvalidRecv-32]
+	_ = x[DuplicateFieldAndMethod-33]
+	_ = x[DuplicateMethod-34]
+	_ = x[InvalidBlank-35]
+	_ = x[InvalidIota-36]
+	_ = x[MissingInitBody-37]
+	_ = x[InvalidInitSig-38]
+	_ = x[InvalidInitDecl-39]
+	_ = x[InvalidMainDecl-40]
+	_ = x[TooManyValues-41]
+	_ = x[NotAnExpr-42]
+	_ = x[TruncatedFloat-43]
+	_ = x[NumericOverflow-44]
+	_ = x[UndefinedOp-45]
+	_ = x[MismatchedTypes-46]
+	_ = x[DivByZero-47]
+	_ = x[NonNumericIncDec-48]
+	_ = x[UnaddressableOperand-49]
+	_ = x[InvalidIndirection-50]
+	_ = x[NonIndexableOperand-51]
+	_ = x[InvalidIndex-52]
+	_ = x[SwappedSliceIndices-53]
+	_ = x[NonSliceableOperand-54]
+	_ = x[InvalidSliceExpr-55]
+	_ = x[InvalidShiftCount-56]
+	_ = x[InvalidShiftOperand-57]
+	_ = x[InvalidReceive-58]
+	_ = x[InvalidSend-59]
+	_ = x[DuplicateLitKey-60]
+	_ = x[MissingLitKey-61]
+	_ = x[InvalidLitIndex-62]
+	_ = x[OversizeArrayLit-63]
+	_ = x[MixedStructLit-64]
+	_ = x[InvalidStructLit-65]
+	_ = x[MissingLitField-66]
+	_ = x[DuplicateLitField-67]
+	_ = x[UnexportedLitField-68]
+	_ = x[InvalidLitField-69]
+	_ = x[UntypedLit-70]
+	_ = x[InvalidLit-71]
+	_ = x[AmbiguousSelector-72]
+	_ = x[UndeclaredImportedName-73]
+	_ = x[UnexportedName-74]
+	_ = x[UndeclaredName-75]
+	_ = x[MissingFieldOrMethod-76]
+	_ = x[BadDotDotDotSyntax-77]
+	_ = x[NonVariadicDotDotDot-78]
+	_ = x[MisplacedDotDotDot-79]
+	_ = x[InvalidDotDotDotOperand-80]
+	_ = x[InvalidDotDotDot-81]
+	_ = x[UncalledBuiltin-82]
+	_ = x[InvalidAppend-83]
+	_ = x[InvalidCap-84]
+	_ = x[InvalidClose-85]
+	_ = x[InvalidCopy-86]
+	_ = x[InvalidComplex-87]
+	_ = x[InvalidDelete-88]
+	_ = x[InvalidImag-89]
+	_ = x[InvalidLen-90]
+	_ = x[SwappedMakeArgs-91]
+	_ = x[InvalidMake-92]
+	_ = x[InvalidReal-93]
+	_ = x[InvalidAssert-94]
+	_ = x[ImpossibleAssert-95]
+	_ = x[InvalidConversion-96]
+	_ = x[InvalidUntypedConversion-97]
+	_ = x[BadOffsetofSyntax-98]
+	_ = x[InvalidOffsetof-99]
+	_ = x[UnusedExpr-100]
+	_ = x[UnusedVar-101]
+	_ = x[MissingReturn-102]
+	_ = x[WrongResultCount-103]
+	_ = x[OutOfScopeResult-104]
+	_ = x[InvalidCond-105]
+	_ = x[InvalidPostDecl-106]
+	_ = x[InvalidChanRange-107]
+	_ = x[InvalidIterVar-108]
+	_ = x[InvalidRangeExpr-109]
+	_ = x[MisplacedBreak-110]
+	_ = x[MisplacedContinue-111]
+	_ = x[MisplacedFallthrough-112]
+	_ = x[DuplicateCase-113]
+	_ = x[DuplicateDefault-114]
+	_ = x[BadTypeKeyword-115]
+	_ = x[InvalidTypeSwitch-116]
+	_ = x[InvalidExprSwitch-117]
+	_ = x[InvalidSelectCase-118]
+	_ = x[UndeclaredLabel-119]
+	_ = x[DuplicateLabel-120]
+	_ = x[MisplacedLabel-121]
+	_ = x[UnusedLabel-122]
+	_ = x[JumpOverDecl-123]
+	_ = x[JumpIntoBlock-124]
+	_ = x[InvalidMethodExpr-125]
+	_ = x[WrongArgCount-126]
+	_ = x[InvalidCall-127]
+	_ = x[UnusedResults-128]
+	_ = x[InvalidDefer-129]
+	_ = x[InvalidGo-130]
+	_ = x[BadDecl-131]
+	_ = x[RepeatedDecl-132]
+	_ = x[InvalidUnsafeAdd-133]
+	_ = x[InvalidUnsafeSlice-134]
+	_ = x[UnsupportedFeature-135]
+	_ = x[NotAGenericType-136]
+	_ = x[WrongTypeArgCount-137]
+	_ = x[CannotInferTypeArgs-138]
+	_ = x[InvalidTypeArg-139]
+	_ = x[InvalidInstanceCycle-140]
+	_ = x[InvalidUnion-141]
+	_ = x[MisplacedConstraintIface-142]
+	_ = x[InvalidMethodTypeParams-143]
+	_ = x[MisplacedTypeParam-144]
+	_ = x[InvalidUnsafeSliceData-145]
+	_ = x[InvalidUnsafeString-146]
+}
+
+const (
+	_ErrorCode_name_0 = "InvalidSyntaxTree"
+	_ErrorCode_name_1 = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilUseWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParamInvalidUnsafeSliceDataInvalidUnsafeString"
+)
+
+var (
+	_ErrorCode_index_1 = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 218, 234, 253, 261, 277, 295, 312, 330, 354, 362, 377, 393, 411, 428, 443, 450, 461, 484, 499, 511, 522, 537, 551, 566, 581, 594, 603, 617, 632, 643, 658, 667, 683, 703, 721, 740, 752, 771, 790, 806, 823, 842, 856, 867, 882, 895, 910, 926, 940, 956, 971, 988, 1006, 1021, 1031, 1041, 1058, 1080, 1094, 1108, 1128, 1146, 1166, 1184, 1207, 1223, 1238, 1251, 1261, 1273, 1284, 1298, 1311, 1322, 1332, 1347, 1358, 1369, 1382, 1398, 1415, 1439, 1456, 1471, 1481, 1490, 1503, 1519, 1535, 1546, 1561, 1577, 1591, 1607, 1621, 1638, 1658, 1671, 1687, 1701, 1718, 1735, 1752, 1767, 1781, 1795, 1806, 1818, 1831, 1848, 1861, 1872, 1885, 1897, 1906, 1913, 1925, 1941, 1959, 1977, 1992, 2009, 2028, 2042, 2062, 2074, 2098, 2121, 2139, 2161, 2180}
+)
+
+func (i ErrorCode) String() string {
+	switch {
+	case i == -1:
+		return _ErrorCode_name_0
+	case 1 <= i && i <= 146:
+		i -= 1
+		return _ErrorCode_name_1[_ErrorCode_index_1[i]:_ErrorCode_index_1[i+1]]
+	default:
+		return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")"
+	}
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/fx.go b/vendor/golang.org/x/tools/internal/typesinternal/fx.go
new file mode 100644
index 0000000..c846a53
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/fx.go
@@ -0,0 +1,88 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+)
+
+// NoEffects reports whether the expression has no side effects, i.e., it
+// does not modify the memory state. This function is conservative: it may
+// return false even when the expression has no effect.
+func NoEffects(info *types.Info, expr ast.Expr) bool {
+	noEffects := true
+	ast.Inspect(expr, func(n ast.Node) bool {
+		switch v := n.(type) {
+		case nil, *ast.Ident, *ast.BasicLit, *ast.BinaryExpr, *ast.ParenExpr,
+			*ast.SelectorExpr, *ast.IndexExpr, *ast.SliceExpr, *ast.TypeAssertExpr,
+			*ast.StarExpr, *ast.CompositeLit,
+			// non-expressions that may appear within expressions
+			*ast.KeyValueExpr,
+			*ast.FieldList,
+			*ast.Field,
+			*ast.Ellipsis,
+			*ast.IndexListExpr:
+			// No effect.
+
+		case *ast.ArrayType,
+			*ast.StructType,
+			*ast.ChanType,
+			*ast.FuncType,
+			*ast.MapType,
+			*ast.InterfaceType:
+			// Type syntax: no effects, recursively.
+			// Prune descent.
+			return false
+
+		case *ast.UnaryExpr:
+			// Channel send <-ch has effects.
+			if v.Op == token.ARROW {
+				noEffects = false
+			}
+
+		case *ast.CallExpr:
+			// Type conversion has no effects.
+			if !info.Types[v.Fun].IsType() {
+				if CallsPureBuiltin(info, v) {
+					// A call such as len(e) has no effects of its
+					// own, though the subexpression e might.
+				} else {
+					noEffects = false
+				}
+			}
+
+		case *ast.FuncLit:
+			// A FuncLit has no effects, but do not descend into it.
+			return false
+
+		default:
+			// All other expressions have effects
+			noEffects = false
+		}
+
+		return noEffects
+	})
+	return noEffects
+}
+
+// CallsPureBuiltin reports whether call is a call of a built-in
+// function that is a pure computation over its operands (analogous to
+// a + operator). Because it does not depend on program state, it may
+// be evaluated at any point--though not necessarily at multiple
+// points (consider new, make).
+func CallsPureBuiltin(info *types.Info, call *ast.CallExpr) bool {
+	if id, ok := ast.Unparen(call.Fun).(*ast.Ident); ok {
+		if b, ok := info.ObjectOf(id).(*types.Builtin); ok {
+			switch b.Name() {
+			case "len", "cap", "complex", "imag", "real", "make", "new", "max", "min":
+				return true
+			}
+			// Not: append clear close copy delete panic print println recover
+		}
+	}
+	return false
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go b/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go
new file mode 100644
index 0000000..9af27f8
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go
@@ -0,0 +1,69 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/types"
+	"slices"
+)
+
+// IsTypeNamed reports whether t is (or is an alias for) a
+// package-level defined type with the given package path and one of
+// the given names. It returns false if t is nil.
+//
+// This function avoids allocating the concatenation of "pkg.Name",
+// which is important for the performance of syntax matching.
+func IsTypeNamed(t types.Type, pkgPath string, names ...string) bool {
+	if named, ok := types.Unalias(t).(*types.Named); ok {
+		tname := named.Obj()
+		return tname != nil &&
+			IsPackageLevel(tname) &&
+			tname.Pkg().Path() == pkgPath &&
+			slices.Contains(names, tname.Name())
+	}
+	return false
+}
+
+// IsPointerToNamed reports whether t is (or is an alias for) a pointer to a
+// package-level defined type with the given package path and one of the given
+// names. It returns false if t is not a pointer type.
+func IsPointerToNamed(t types.Type, pkgPath string, names ...string) bool {
+	r := Unpointer(t)
+	if r == t {
+		return false
+	}
+	return IsTypeNamed(r, pkgPath, names...)
+}
+
+// IsFunctionNamed reports whether obj is a package-level function
+// defined in the given package and has one of the given names.
+// It returns false if obj is nil.
+//
+// This function avoids allocating the concatenation of "pkg.Name",
+// which is important for the performance of syntax matching.
+func IsFunctionNamed(obj types.Object, pkgPath string, names ...string) bool {
+	f, ok := obj.(*types.Func)
+	return ok &&
+		IsPackageLevel(obj) &&
+		f.Pkg().Path() == pkgPath &&
+		f.Signature().Recv() == nil &&
+		slices.Contains(names, f.Name())
+}
+
+// IsMethodNamed reports whether obj is a method defined on a
+// package-level type with the given package and type name, and has
+// one of the given names. It returns false if obj is nil.
+//
+// This function avoids allocating the concatenation of "pkg.TypeName.Name",
+// which is important for the performance of syntax matching.
+func IsMethodNamed(obj types.Object, pkgPath string, typeName string, names ...string) bool {
+	if fn, ok := obj.(*types.Func); ok {
+		_, T := RecvBase(fn)
+		return T != nil &&
+			IsTypeNamed(T, pkgPath, typeName) &&
+			slices.Contains(names, fn.Name())
+	}
+	return false
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go b/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go
new file mode 100644
index 0000000..4e2756f
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go
@@ -0,0 +1,54 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/ast"
+	"go/types"
+	"strconv"
+)
+
+// FileQualifier returns a [types.Qualifier] function that qualifies
+// imported symbols appropriately based on the import environment of a given
+// file.
+// If the same package is imported multiple times, the last appearance is
+// recorded.
+//
+// TODO(adonovan): this function ignores the effect of shadowing. It
+// should accept a [token.Pos] and a [types.Info] and compute only the
+// set of imports that are not shadowed at that point, analogous to
+// [analysis.AddImport]. It could also compute (as a side
+// effect) the set of additional imports required to ensure that there
+// is an accessible import for each necessary package, making it
+// converge even more closely with AddImport.
+func FileQualifier(f *ast.File, pkg *types.Package) types.Qualifier {
+	// Construct mapping of import paths to their defined names.
+	// It is only necessary to look at renaming imports.
+	imports := make(map[string]string)
+	for _, imp := range f.Imports {
+		if imp.Name != nil && imp.Name.Name != "_" {
+			path, _ := strconv.Unquote(imp.Path.Value)
+			imports[path] = imp.Name.Name
+		}
+	}
+
+	// Define qualifier to replace full package paths with names of the imports.
+	return func(p *types.Package) string {
+		if p == nil || p == pkg {
+			return ""
+		}
+
+		if name, ok := imports[p.Path()]; ok {
+			if name == "." {
+				return ""
+			} else {
+				return name
+			}
+		}
+
+		// If there is no local renaming, fall back to the package name.
+		return p.Name()
+	}
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/recv.go b/vendor/golang.org/x/tools/internal/typesinternal/recv.go
new file mode 100644
index 0000000..564e93b
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/recv.go
@@ -0,0 +1,57 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/types"
+)
+
+// RecvBase returns the receiver base type (if any) of the method fn,
+// and reports whether the receiver is a pointer to it.
+//
+// The spec says of a method declaration: the receiver's "type must be
+// a defined type T or a pointer to a defined type T, possibly followed
+// by a list of type parameter names [P1, P2, …] enclosed in square
+// brackets. T is called the receiver base type."
+//
+// The named result is nil if fn is not a method, or if its receiver
+// is an anonymous interface or struct type, as in interface{ f() }.
+//
+// TODO(adonovan): go.dev/issue/81715 proposes this as a method of *types.Func.
+func RecvBase(fn *types.Func) (isPtr bool, named *types.Named) {
+	// The boolean result appears first to
+	// avoid misinterpretation as an 'ok'
+	// bool, and because that's the natural
+	// reading order in "*Named".
+
+	if recv := fn.Signature().Recv(); recv != nil {
+		t := recv.Type()
+		if ptr, ok := types.Unalias(t).(*types.Pointer); ok {
+			isPtr = true
+			t = ptr.Elem()
+		}
+		named, _ = types.Unalias(t).(*types.Named)
+	}
+	return
+}
+
+// Unpointer returns T given *T or an alias thereof.
+// For all other types it is the identity function.
+// It does not look at underlying types.
+// The result may be an alias.
+//
+// Use this function to strip off the optional pointer on a receiver
+// in a field or method selection, without losing the named type
+// (which is needed to compute the method set).
+//
+// See also [typeparams.MustDeref], which removes one level of
+// indirection from the type, regardless of named types (analogous to
+// a LOAD instruction).
+func Unpointer(t types.Type) types.Type {
+	if ptr, ok := types.Unalias(t).(*types.Pointer); ok {
+		return ptr.Elem()
+	}
+	return t
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go
new file mode 100644
index 0000000..386c59c
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go
@@ -0,0 +1,107 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/types"
+
+	"golang.org/x/tools/internal/stdlib"
+	"golang.org/x/tools/internal/versions"
+)
+
+// TooNewStdSymbols computes the set of package-level symbols
+// exported by pkg that are not available at the specified version.
+//
+// The pkg is allowed to contain type errors.
+func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]stdlib.Symbol {
+	disallowed := make(map[types.Object]stdlib.Symbol)
+
+	// Some symbols are accessible before their release but
+	// only with specific build tags unknown to us here.
+	// Avoid false positives in such cases.
+	if pkg.Path() == "testing/synctest" && versions.AtLeast(version, "go1.24") {
+		// requires go1.24 && goexperiment.synctest || go1.25
+		return disallowed
+	}
+	if (pkg.Path() == "encoding/json/v2" || pkg.Path() == "encoding/json/jsontext") && versions.AtLeast(version, "go1.25") {
+		// requires go1.25 && goexperiment.jsonv2 || go1.27
+		return disallowed
+	}
+
+	// Pass 1: package-level symbols.
+	symbols := stdlib.PackageSymbols[pkg.Path()]
+	for _, sym := range symbols {
+		if versions.Before(version, sym.Version.String()) {
+			switch sym.Kind {
+			case stdlib.Func, stdlib.Var, stdlib.Const, stdlib.Type:
+				disallowed[pkg.Scope().Lookup(sym.Name)] = sym
+			}
+		}
+	}
+
+	// Pass 2: fields and methods.
+	//
+	// We allow fields and methods if their associated type is
+	// disallowed, as otherwise we would report false positives
+	// for compatibility shims. Consider:
+	//
+	//   //go:build go1.22
+	//   type T struct { F std.Real } // correct new API
+	//
+	//   //go:build !go1.22
+	//   type T struct { F fake } // shim
+	//   type fake struct { ... }
+	//   func (fake) M () {}
+	//
+	// These alternative declarations of T use either the std.Real
+	// type, introduced in go1.22, or a fake type, for the field
+	// F. (The fakery could be arbitrarily deep, involving more
+	// nested fields and methods than are shown here.) Clients
+	// that use the compatibility shim T will compile with any
+	// version of go, whether older or newer than go1.22, but only
+	// the newer version will use the std.Real implementation.
+	//
+	// Now consider a reference to method M in new(T).F.M() in a
+	// module that requires a minimum of go1.21. The analysis may
+	// occur using a version of Go higher than 1.21, selecting the
+	// first version of T, so the method M is Real.M. This would
+	// spuriously cause the analyzer to report a reference to a
+	// too-new symbol even though this expression compiles just
+	// fine (with the fake implementation) using go1.21.
+	var noSym stdlib.Symbol
+	depth := make(map[types.Object]int)
+	for _, sym := range symbols {
+		if !versions.Before(version, sym.Version.String()) {
+			continue // allowed
+		}
+
+		var obj types.Object
+		var indices []int
+		switch sym.Kind {
+		case stdlib.Field:
+			typename, name := sym.SplitField()
+			if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == noSym {
+				obj, indices, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name)
+			}
+
+		case stdlib.Method:
+			ptr, recvname, name := sym.SplitMethod()
+			if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == noSym {
+				obj, indices, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name)
+			}
+		}
+		if obj != nil {
+			// In the presence of embedding, two or more "pkg.T.name"
+			// strings may map to the same types.Object.
+			// Prefer the Object with the shorter index path.
+			if min, ok := depth[obj]; !ok || len(indices) < min {
+				depth[obj] = len(indices)
+				disallowed[obj] = sym
+			}
+		}
+	}
+
+	return disallowed
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go
new file mode 100644
index 0000000..3d9dc04
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go
@@ -0,0 +1,282 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package typesinternal provides helpful operators for dealing with
+// go/types:
+//
+//   - operators for querying typed syntax trees (e.g. [Imports], [IsFunctionNamed]);
+//   - functions for converting types to strings or syntax (e.g. [TypeExpr], FileQualifier]);
+//   - helpers for working with the [go/types] API (e.g. [NewTypesInfo]);
+//   - access to internal go/types APIs that are not yet
+//     exported (e.g. [SetUsesCgo], [ErrorCodeStartEnd]); and
+//   - common algorithms related to types (e.g. [TooNewStdSymbols]).
+//
+// See also:
+//   - [golang.org/x/tools/internal/astutil], for operations on untyped syntax;
+//   - [golang.org/x/tools/internal/analysisinernal], for helpers for analyzers;
+//   - [golang.org/x/tools/internal/refactor], for operators to compute text edits.
+package typesinternal
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+	"iter"
+	"reflect"
+
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+func SetUsesCgo(conf *types.Config) bool {
+	v := reflect.ValueOf(conf).Elem()
+
+	f := v.FieldByName("go115UsesCgo")
+	if !f.IsValid() {
+		f = v.FieldByName("UsesCgo")
+		if !f.IsValid() {
+			return false
+		}
+	}
+
+	*(*bool)(f.Addr().UnsafePointer()) = true
+
+	return true
+}
+
+// ErrorCodeStartEnd extracts additional information from types.Error values
+// generated by Go version 1.16 and later: the error code, start position, and
+// end position. If all positions are valid, start <= err.Pos <= end.
+//
+// If the data could not be read, the final result parameter will be false.
+//
+// TODO(adonovan): eliminate start/end when proposal #71803 is accepted.
+func ErrorCodeStartEnd(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) {
+	var data [3]int
+	// By coincidence all of these fields are ints, which simplifies things.
+	v := reflect.ValueOf(err)
+	for i, name := range []string{"go116code", "go116start", "go116end"} {
+		f := v.FieldByName(name)
+		if !f.IsValid() {
+			return 0, 0, 0, false
+		}
+		data[i] = int(f.Int())
+	}
+	return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true
+}
+
+// NameRelativeTo returns a types.Qualifier that qualifies members of
+// all packages other than pkg, using only the package name.
+// (By contrast, [types.RelativeTo] uses the complete package path,
+// which is often excessive.)
+//
+// If pkg is nil, it is equivalent to [*types.Package.Name].
+//
+// TODO(adonovan): all uses of this with TypeString should be
+// eliminated when https://go.dev/issues/75604 is resolved.
+func NameRelativeTo(pkg *types.Package) types.Qualifier {
+	return func(other *types.Package) string {
+		if pkg != nil && pkg == other {
+			return "" // same package; unqualified
+		}
+		return other.Name()
+	}
+}
+
+// TypeNameFor returns the type name symbol for the specified type, if
+// it is a [*types.Alias], [*types.Named], [*types.TypeParam], or a
+// [*types.Basic] representing a type.
+//
+// For all other types, and for Basic types representing a builtin,
+// constant, or nil, it returns nil. Be careful not to convert the
+// resulting nil pointer to a [types.Object]!
+//
+// If t is the type of a constant, it may be an "untyped" type, which
+// has no TypeName. To access the name of such types (e.g. "untyped
+// int"), use [types.Basic.Name].
+func TypeNameFor(t types.Type) *types.TypeName {
+	switch t := t.(type) {
+	case *types.Alias:
+		return t.Obj()
+	case *types.Named:
+		return t.Obj()
+	case *types.TypeParam:
+		return t.Obj()
+	case *types.Basic:
+		// See issues #71886 and #66890 for some history.
+		if tname, ok := types.Universe.Lookup(t.Name()).(*types.TypeName); ok {
+			return tname
+		}
+	}
+	return nil
+}
+
+// A NamedOrAlias is a [types.Type] that is named (as
+// defined by the spec) and capable of bearing type parameters: it
+// abstracts aliases ([types.Alias]) and defined types
+// ([types.Named]).
+//
+// Every type declared by an explicit "type" declaration is a
+// NamedOrAlias. (Built-in type symbols may additionally
+// have type [types.Basic], which is not a NamedOrAlias,
+// though the spec regards them as "named"; see [TypeNameFor].)
+//
+// NamedOrAlias cannot expose the Origin method, because
+// [types.Alias.Origin] and [types.Named.Origin] have different
+// (covariant) result types; use [Origin] instead.
+type NamedOrAlias interface {
+	types.Type
+	Obj() *types.TypeName
+	TypeArgs() *types.TypeList
+	TypeParams() *types.TypeParamList
+	SetTypeParams(tparams []*types.TypeParam)
+}
+
+var (
+	_ NamedOrAlias = (*types.Alias)(nil)
+	_ NamedOrAlias = (*types.Named)(nil)
+)
+
+// Origin returns the generic type of the Named or Alias type t if it
+// is instantiated, otherwise it returns t.
+func Origin(t NamedOrAlias) NamedOrAlias {
+	switch t := t.(type) {
+	case *types.Alias:
+		return t.Origin()
+	case *types.Named:
+		return t.Origin()
+	}
+	return t
+}
+
+// IsPackageLevel reports whether obj is a package-level symbol.
+func IsPackageLevel(obj types.Object) bool {
+	return obj.Pkg() != nil && obj.Parent() == obj.Pkg().Scope()
+}
+
+// NewTypesInfo returns a *types.Info with all maps populated.
+func NewTypesInfo() *types.Info {
+	return &types.Info{
+		Types:        map[ast.Expr]types.TypeAndValue{},
+		Instances:    map[*ast.Ident]types.Instance{},
+		Defs:         map[*ast.Ident]types.Object{},
+		Uses:         map[*ast.Ident]types.Object{},
+		Implicits:    map[ast.Node]types.Object{},
+		Selections:   map[*ast.SelectorExpr]*types.Selection{},
+		Scopes:       map[ast.Node]*types.Scope{},
+		FileVersions: map[*ast.File]string{},
+	}
+}
+
+// EnclosingScope returns the innermost block logically enclosing the cursor.
+func EnclosingScope(info *types.Info, cur inspector.Cursor) *types.Scope {
+	for cur := range cur.Enclosing() {
+		n := cur.Node()
+		// A function's Scope is associated with its FuncType.
+		switch f := n.(type) {
+		case *ast.FuncDecl:
+			n = f.Type
+		case *ast.FuncLit:
+			n = f.Type
+		}
+		if b := info.Scopes[n]; b != nil {
+			return b
+		}
+	}
+	panic("no Scope for *ast.File")
+}
+
+// Imports reports whether path is imported by pkg.
+func Imports(pkg *types.Package, path string) bool {
+	for _, imp := range pkg.Imports() {
+		if imp.Path() == path {
+			return true
+		}
+	}
+	return false
+}
+
+// ObjectKind returns a description of the object's kind.
+//
+// from objectKind in go/types
+func ObjectKind(obj types.Object) string {
+	switch obj := obj.(type) {
+	case *types.PkgName:
+		return "package name"
+	case *types.Const:
+		return "constant"
+	case *types.TypeName:
+		if obj.IsAlias() {
+			return "type alias"
+		} else if _, ok := obj.Type().(*types.TypeParam); ok {
+			return "type parameter"
+		} else {
+			return "defined type"
+		}
+	case *types.Var:
+		switch obj.Kind() {
+		case types.PackageVar:
+			return "package-level variable"
+		case types.LocalVar:
+			return "local variable"
+		case types.RecvVar:
+			return "receiver"
+		case types.ParamVar:
+			return "parameter"
+		case types.ResultVar:
+			return "result variable"
+		case types.FieldVar:
+			return "struct field"
+		}
+	case *types.Func:
+		if obj.Signature().Recv() != nil {
+			return "method"
+		} else {
+			return "function"
+		}
+	case *types.Label:
+		return "label"
+	case *types.Builtin:
+		return "built-in function"
+	case *types.Nil:
+		return "untyped nil"
+	}
+	return "unknown symbol"
+}
+
+// ImplicitFieldSelections returns the sequence of implicit embedded fields
+// traversed by the given selection. It skips the final leaf field or method.
+// The boolean component indicates whether the traversal traversed a pointer.
+func ImplicitFieldSelections(seln *types.Selection) iter.Seq2[*types.Var, bool] {
+	return func(yield func(*types.Var, bool) bool) {
+		var (
+			t       = seln.Recv()
+			indices = seln.Index()
+		)
+		for _, idx := range indices[:len(indices)-1] {
+			ptr, isPtr := t.Underlying().(*types.Pointer)
+			if isPtr {
+				t = ptr.Elem()
+			}
+			structType, ok := t.Underlying().(*types.Struct)
+			if !ok {
+				break
+			}
+			field := structType.Field(idx)
+			if !yield(field, isPtr) {
+				break
+			}
+			t = field.Type()
+		}
+	}
+}
+
+// TupleOf returns a tuple type with the specified list of (unnamed)
+// var types. Neither the zero nor one cases are special.
+func TupleOf(elems ...types.Type) *types.Tuple {
+	params := make([]*types.Var, len(elems))
+	for i, elem := range elems {
+		params[i] = types.NewParam(token.NoPos, nil, "", elem)
+	}
+	return types.NewTuple(params...)
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go b/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go
new file mode 100644
index 0000000..706ad33
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go
@@ -0,0 +1,381 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"strings"
+)
+
+// ZeroString returns the string representation of the zero value for any type t.
+// The boolean result indicates whether the type is or contains an invalid type
+// or a non-basic (constraint) interface type.
+//
+// Even for invalid input types, ZeroString may return a partially correct
+// string representation. The caller should use the returned isValid boolean
+// to determine the validity of the expression.
+//
+// When assigning to a wider type (such as 'any'), it's the caller's
+// responsibility to handle any necessary type conversions.
+//
+// This string can be used on the right-hand side of an assignment where the
+// left-hand side has that explicit type.
+// References to named types are qualified by an appropriate (optional)
+// qualifier function.
+// Exception: This does not apply to tuples. Their string representation is
+// informational only and cannot be used in an assignment.
+//
+// See [ZeroExpr] for a variant that returns an [ast.Expr].
+func ZeroString(t types.Type, qual types.Qualifier) (_ string, isValid bool) {
+	switch t := t.(type) {
+	case *types.Basic:
+		switch {
+		case t.Info()&types.IsBoolean != 0:
+			return "false", true
+		case t.Info()&types.IsNumeric != 0:
+			return "0", true
+		case t.Info()&types.IsString != 0:
+			return `""`, true
+		case t.Kind() == types.UnsafePointer:
+			fallthrough
+		case t.Kind() == types.UntypedNil:
+			return "nil", true
+		case t.Kind() == types.Invalid:
+			return "invalid", false
+		default:
+			panic(fmt.Sprintf("ZeroString for unexpected type %v", t))
+		}
+
+	case *types.Pointer, *types.Slice, *types.Chan, *types.Map, *types.Signature:
+		return "nil", true
+
+	case *types.Interface:
+		if !t.IsMethodSet() {
+			return "invalid", false
+		}
+		return "nil", true
+
+	case *types.Named:
+		switch under := t.Underlying().(type) {
+		case *types.Struct, *types.Array:
+			return types.TypeString(t, qual) + "{}", true
+		default:
+			return ZeroString(under, qual)
+		}
+
+	case *types.Alias:
+		switch t.Underlying().(type) {
+		case *types.Struct, *types.Array:
+			return types.TypeString(t, qual) + "{}", true
+		default:
+			// A type parameter can have alias but alias type's underlying type
+			// can never be a type parameter.
+			// Use types.Unalias to preserve the info of type parameter instead
+			// of call Underlying() going right through and get the underlying
+			// type of the type parameter which is always an interface.
+			return ZeroString(types.Unalias(t), qual)
+		}
+
+	case *types.Array, *types.Struct:
+		return types.TypeString(t, qual) + "{}", true
+
+	case *types.TypeParam:
+		// Assumes func new is not shadowed.
+		return "*new(" + types.TypeString(t, qual) + ")", true
+
+	case *types.Tuple:
+		// Tuples are not normal values.
+		// We are currently format as "(t[0], ..., t[n])". Could be something else.
+		isValid := true
+		components := make([]string, t.Len())
+		for i := 0; i < t.Len(); i++ {
+			comp, ok := ZeroString(t.At(i).Type(), qual)
+
+			components[i] = comp
+			isValid = isValid && ok
+		}
+		return "(" + strings.Join(components, ", ") + ")", isValid
+
+	case *types.Union:
+		// Variables of these types cannot be created, so it makes
+		// no sense to ask for their zero value.
+		panic(fmt.Sprintf("invalid type for a variable: %v", t))
+
+	default:
+		panic(t) // unreachable.
+	}
+}
+
+// ZeroExpr returns the ast.Expr representation of the zero value for any type t.
+// The boolean result indicates whether the type is or contains an invalid type
+// or a non-basic (constraint) interface type.
+//
+// Even for invalid input types, ZeroExpr may return a partially correct ast.Expr
+// representation. The caller should use the returned isValid boolean to determine
+// the validity of the expression.
+//
+// This function is designed for types suitable for variables and should not be
+// used with Tuple or Union types.References to named types are qualified by an
+// appropriate (optional) qualifier function.
+//
+// See [ZeroString] for a variant that returns a string.
+func ZeroExpr(t types.Type, qual types.Qualifier) (_ ast.Expr, isValid bool) {
+	switch t := t.(type) {
+	case *types.Basic:
+		switch {
+		case t.Info()&types.IsBoolean != 0:
+			return &ast.Ident{Name: "false"}, true
+		case t.Info()&types.IsNumeric != 0:
+			return &ast.BasicLit{Kind: token.INT, Value: "0"}, true
+		case t.Info()&types.IsString != 0:
+			return &ast.BasicLit{Kind: token.STRING, Value: `""`}, true
+		case t.Kind() == types.UnsafePointer:
+			fallthrough
+		case t.Kind() == types.UntypedNil:
+			return ast.NewIdent("nil"), true
+		case t.Kind() == types.Invalid:
+			return &ast.BasicLit{Kind: token.STRING, Value: `"invalid"`}, false
+		default:
+			panic(fmt.Sprintf("ZeroExpr for unexpected type %v", t))
+		}
+
+	case *types.Pointer, *types.Slice, *types.Chan, *types.Map, *types.Signature:
+		return ast.NewIdent("nil"), true
+
+	case *types.Interface:
+		if !t.IsMethodSet() {
+			return &ast.BasicLit{Kind: token.STRING, Value: `"invalid"`}, false
+		}
+		return ast.NewIdent("nil"), true
+
+	case *types.Named:
+		switch under := t.Underlying().(type) {
+		case *types.Struct, *types.Array:
+			return &ast.CompositeLit{
+				Type: TypeExpr(t, qual),
+			}, true
+		default:
+			return ZeroExpr(under, qual)
+		}
+
+	case *types.Alias:
+		switch t.Underlying().(type) {
+		case *types.Struct, *types.Array:
+			return &ast.CompositeLit{
+				Type: TypeExpr(t, qual),
+			}, true
+		default:
+			return ZeroExpr(types.Unalias(t), qual)
+		}
+
+	case *types.Array, *types.Struct:
+		return &ast.CompositeLit{
+			Type: TypeExpr(t, qual),
+		}, true
+
+	case *types.TypeParam:
+		return &ast.StarExpr{ // *new(T)
+			X: &ast.CallExpr{
+				// Assumes func new is not shadowed.
+				Fun: ast.NewIdent("new"),
+				Args: []ast.Expr{
+					ast.NewIdent(t.Obj().Name()),
+				},
+			},
+		}, true
+
+	case *types.Tuple:
+		// Unlike ZeroString, there is no ast.Expr can express tuple by
+		// "(t[0], ..., t[n])".
+		panic(fmt.Sprintf("invalid type for a variable: %v", t))
+
+	case *types.Union:
+		// Variables of these types cannot be created, so it makes
+		// no sense to ask for their zero value.
+		panic(fmt.Sprintf("invalid type for a variable: %v", t))
+
+	default:
+		panic(t) // unreachable.
+	}
+}
+
+// TypeExpr returns syntax for the specified type. References to named types
+// are qualified by an appropriate (optional) qualifier function.
+// It may panic for types such as Tuple or Union.
+//
+// See also https://go.dev/issues/75604, which will provide a robust
+// Type-to-valid-Go-syntax formatter.
+func TypeExpr(t types.Type, qual types.Qualifier) ast.Expr {
+	switch t := t.(type) {
+	case *types.Basic:
+		switch t.Kind() {
+		case types.UnsafePointer:
+			return &ast.SelectorExpr{X: ast.NewIdent(qual(types.NewPackage("unsafe", "unsafe"))), Sel: ast.NewIdent("Pointer")}
+		default:
+			return ast.NewIdent(t.Name())
+		}
+
+	case *types.Pointer:
+		return &ast.UnaryExpr{
+			Op: token.MUL,
+			X:  TypeExpr(t.Elem(), qual),
+		}
+
+	case *types.Array:
+		return &ast.ArrayType{
+			Len: &ast.BasicLit{
+				Kind:  token.INT,
+				Value: fmt.Sprintf("%d", t.Len()),
+			},
+			Elt: TypeExpr(t.Elem(), qual),
+		}
+
+	case *types.Slice:
+		return &ast.ArrayType{
+			Elt: TypeExpr(t.Elem(), qual),
+		}
+
+	case *types.Map:
+		return &ast.MapType{
+			Key:   TypeExpr(t.Key(), qual),
+			Value: TypeExpr(t.Elem(), qual),
+		}
+
+	case *types.Chan:
+		dir := ast.ChanDir(t.Dir())
+		if t.Dir() == types.SendRecv {
+			dir = ast.SEND | ast.RECV
+		}
+		return &ast.ChanType{
+			Dir:   dir,
+			Value: TypeExpr(t.Elem(), qual),
+		}
+
+	case *types.Signature:
+		var params []*ast.Field
+		for v := range t.Params().Variables() {
+			var names []*ast.Ident
+			if v.Name() != "" {
+				names = []*ast.Ident{ast.NewIdent(v.Name())}
+			}
+			params = append(params, &ast.Field{
+				Type:  TypeExpr(v.Type(), qual),
+				Names: names,
+			})
+		}
+		if t.Variadic() {
+			last := params[len(params)-1]
+			last.Type = &ast.Ellipsis{Elt: last.Type.(*ast.ArrayType).Elt}
+		}
+		var returns []*ast.Field
+		for v := range t.Results().Variables() {
+			returns = append(returns, &ast.Field{
+				Type: TypeExpr(v.Type(), qual),
+			})
+		}
+		return &ast.FuncType{
+			Params: &ast.FieldList{
+				List: params,
+			},
+			Results: &ast.FieldList{
+				List: returns,
+			},
+		}
+
+	case *types.TypeParam:
+		pkgName := qual(t.Obj().Pkg())
+		if pkgName == "" || t.Obj().Pkg() == nil {
+			return ast.NewIdent(t.Obj().Name())
+		}
+		return &ast.SelectorExpr{
+			X:   ast.NewIdent(pkgName),
+			Sel: ast.NewIdent(t.Obj().Name()),
+		}
+
+	// types.TypeParam also implements interface NamedOrAlias. To differentiate,
+	// case TypeParam need to be present before case NamedOrAlias.
+	// TODO(hxjiang): remove this comment once TypeArgs() is added to interface
+	// NamedOrAlias.
+	case NamedOrAlias:
+		var expr ast.Expr = ast.NewIdent(t.Obj().Name())
+		if pkgName := qual(t.Obj().Pkg()); pkgName != "." && pkgName != "" {
+			expr = &ast.SelectorExpr{
+				X:   ast.NewIdent(pkgName),
+				Sel: expr.(*ast.Ident),
+			}
+		}
+
+		// TODO(hxjiang): call t.TypeArgs after adding method TypeArgs() to
+		// typesinternal.NamedOrAlias.
+		if hasTypeArgs, ok := t.(interface{ TypeArgs() *types.TypeList }); ok {
+			if typeArgs := hasTypeArgs.TypeArgs(); typeArgs != nil && typeArgs.Len() > 0 {
+				var indices []ast.Expr
+				for t0 := range typeArgs.Types() {
+					indices = append(indices, TypeExpr(t0, qual))
+				}
+				expr = &ast.IndexListExpr{
+					X:       expr,
+					Indices: indices,
+				}
+			}
+		}
+
+		return expr
+
+	case *types.Struct:
+		return ast.NewIdent(types.TypeString(t, qual))
+
+	case *types.Interface:
+		return ast.NewIdent(types.TypeString(t, qual))
+
+	case *types.Union:
+		if t.Len() == 0 {
+			panic("Union type should have at least one term")
+		}
+		// Same as go/ast, the return expression will put last term in the
+		// Y field at topmost level of BinaryExpr.
+		// For union of type "float32 | float64 | int64", the structure looks
+		// similar to:
+		// {
+		// 	X: {
+		// 		X: float32,
+		// 		Op: |
+		// 		Y: float64,
+		// 	}
+		// 	Op: |,
+		// 	Y: int64,
+		// }
+		var union ast.Expr
+		for i := range t.Len() {
+			term := t.Term(i)
+			termExpr := TypeExpr(term.Type(), qual)
+			if term.Tilde() {
+				termExpr = &ast.UnaryExpr{
+					Op: token.TILDE,
+					X:  termExpr,
+				}
+			}
+			if i == 0 {
+				union = termExpr
+			} else {
+				union = &ast.BinaryExpr{
+					X:  union,
+					Op: token.OR,
+					Y:  termExpr,
+				}
+			}
+		}
+		return union
+
+	case *types.Tuple:
+		panic("invalid input type types.Tuple")
+
+	default:
+		panic("unreachable")
+	}
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/features.go b/vendor/golang.org/x/tools/internal/versions/features.go
new file mode 100644
index 0000000..360a5b5
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/features.go
@@ -0,0 +1,49 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package versions
+
+// This file contains predicates for working with file versions to
+// decide when a tool should consider a language feature enabled.
+
+// named constants, to avoid misspelling
+const (
+	Go1_17 = "go1.17"
+	Go1_18 = "go1.18"
+	Go1_19 = "go1.19"
+	Go1_20 = "go1.20"
+	Go1_21 = "go1.21"
+	Go1_22 = "go1.22"
+	Go1_23 = "go1.23"
+	Go1_24 = "go1.24"
+	Go1_25 = "go1.25"
+	Go1_26 = "go1.26"
+	Go1_27 = "go1.27"
+)
+
+// Future is an invalid unknown Go version sometime in the future.
+// Do not use directly with Compare.
+const Future = ""
+
+// AtLeast reports whether the file version v comes after a Go release.
+//
+// Use this predicate to enable a behavior once a certain Go release
+// has happened (and stays enabled in the future).
+func AtLeast(v, release string) bool {
+	if v == Future {
+		return true // an unknown future version is always after y.
+	}
+	return Compare(Lang(v), Lang(release)) >= 0
+}
+
+// Before reports whether the file version v is strictly before a Go release.
+//
+// Use this predicate to disable a behavior once a certain Go release
+// has happened (and stays enabled in the future).
+func Before(v, release string) bool {
+	if v == Future {
+		return false // an unknown future version happens after y.
+	}
+	return Compare(Lang(v), Lang(release)) < 0
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/gover.go b/vendor/golang.org/x/tools/internal/versions/gover.go
new file mode 100644
index 0000000..bbabcd2
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/gover.go
@@ -0,0 +1,172 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This is a fork of internal/gover for use by x/tools until
+// go1.21 and earlier are no longer supported by x/tools.
+
+package versions
+
+import "strings"
+
+// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]]
+// The numbers are the original decimal strings to avoid integer overflows
+// and since there is very little actual math. (Probably overflow doesn't matter in practice,
+// but at the time this code was written, there was an existing test that used
+// go1.99999999999, which does not fit in an int on 32-bit platforms.
+// The "big decimal" representation avoids the problem entirely.)
+type gover struct {
+	major string // decimal
+	minor string // decimal or ""
+	patch string // decimal or ""
+	kind  string // "", "alpha", "beta", "rc"
+	pre   string // decimal or ""
+}
+
+// compare returns -1, 0, or +1 depending on whether
+// x < y, x == y, or x > y, interpreted as toolchain versions.
+// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21".
+// Malformed versions compare less than well-formed versions and equal to each other.
+// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0".
+func compare(x, y string) int {
+	vx := parse(x)
+	vy := parse(y)
+
+	if c := cmpInt(vx.major, vy.major); c != 0 {
+		return c
+	}
+	if c := cmpInt(vx.minor, vy.minor); c != 0 {
+		return c
+	}
+	if c := cmpInt(vx.patch, vy.patch); c != 0 {
+		return c
+	}
+	if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc
+		return c
+	}
+	if c := cmpInt(vx.pre, vy.pre); c != 0 {
+		return c
+	}
+	return 0
+}
+
+// lang returns the Go language version. For example, lang("1.2.3") == "1.2".
+func lang(x string) string {
+	v := parse(x)
+	if v.minor == "" || v.major == "1" && v.minor == "0" {
+		return v.major
+	}
+	return v.major + "." + v.minor
+}
+
+// isValid reports whether the version x is valid.
+func isValid(x string) bool {
+	return parse(x) != gover{}
+}
+
+// parse parses the Go version string x into a version.
+// It returns the zero version if x is malformed.
+func parse(x string) gover {
+	var v gover
+
+	// Parse major version.
+	var ok bool
+	v.major, x, ok = cutInt(x)
+	if !ok {
+		return gover{}
+	}
+	if x == "" {
+		// Interpret "1" as "1.0.0".
+		v.minor = "0"
+		v.patch = "0"
+		return v
+	}
+
+	// Parse . before minor version.
+	if x[0] != '.' {
+		return gover{}
+	}
+
+	// Parse minor version.
+	v.minor, x, ok = cutInt(x[1:])
+	if !ok {
+		return gover{}
+	}
+	if x == "" {
+		// Patch missing is same as "0" for older versions.
+		// Starting in Go 1.21, patch missing is different from explicit .0.
+		if cmpInt(v.minor, "21") < 0 {
+			v.patch = "0"
+		}
+		return v
+	}
+
+	// Parse patch if present.
+	if x[0] == '.' {
+		v.patch, x, ok = cutInt(x[1:])
+		if !ok || x != "" {
+			// Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != "").
+			// Allowing them would be a bit confusing because we already have:
+			//	1.21 < 1.21rc1
+			// But a prerelease of a patch would have the opposite effect:
+			//	1.21.3rc1 < 1.21.3
+			// We've never needed them before, so let's not start now.
+			return gover{}
+		}
+		return v
+	}
+
+	// Parse prerelease.
+	i := 0
+	for i < len(x) && (x[i] < '0' || '9' < x[i]) {
+		if x[i] < 'a' || 'z' < x[i] {
+			return gover{}
+		}
+		i++
+	}
+	if i == 0 {
+		return gover{}
+	}
+	v.kind, x = x[:i], x[i:]
+	if x == "" {
+		return v
+	}
+	v.pre, x, ok = cutInt(x)
+	if !ok || x != "" {
+		return gover{}
+	}
+
+	return v
+}
+
+// cutInt scans the leading decimal number at the start of x to an integer
+// and returns that value and the rest of the string.
+func cutInt(x string) (n, rest string, ok bool) {
+	i := 0
+	for i < len(x) && '0' <= x[i] && x[i] <= '9' {
+		i++
+	}
+	if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero
+		return "", "", false
+	}
+	return x[:i], x[i:], true
+}
+
+// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers.
+// (Copied from golang.org/x/mod/semver's compareInt.)
+func cmpInt(x, y string) int {
+	if x == y {
+		return 0
+	}
+	if len(x) < len(y) {
+		return -1
+	}
+	if len(x) > len(y) {
+		return +1
+	}
+	if x < y {
+		return -1
+	} else {
+		return +1
+	}
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/types.go b/vendor/golang.org/x/tools/internal/versions/types.go
new file mode 100644
index 0000000..0fc10ce
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/types.go
@@ -0,0 +1,33 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package versions
+
+import (
+	"go/ast"
+	"go/types"
+)
+
+// FileVersion returns a file's Go version.
+// The reported version is an unknown Future version if a
+// version cannot be determined.
+func FileVersion(info *types.Info, file *ast.File) string {
+	// In tools built with Go >= 1.22, the Go version of a file
+	// follow a cascades of sources:
+	// 1) types.Info.FileVersion, which follows the cascade:
+	//   1.a) file version (ast.File.GoVersion),
+	//   1.b) the package version (types.Config.GoVersion), or
+	// 2) is some unknown Future version.
+	//
+	// File versions require a valid package version to be provided to types
+	// in Config.GoVersion. Config.GoVersion is either from the package's module
+	// or the toolchain (go run). This value should be provided by go/packages
+	// or unitchecker.Config.GoVersion.
+	if v := info.FileVersions[file]; IsValid(v) {
+		return v
+	}
+	// Note: we could instead return runtime.Version() [if valid].
+	// This would act as a max version on what a tool can support.
+	return Future
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/versions.go b/vendor/golang.org/x/tools/internal/versions/versions.go
new file mode 100644
index 0000000..8d1f745
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/versions.go
@@ -0,0 +1,57 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package versions
+
+import (
+	"strings"
+)
+
+// Note: If we use build tags to use go/versions when go >=1.22,
+// we run into go.dev/issue/53737. Under some operations users would see an
+// import of "go/versions" even if they would not compile the file.
+// For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include
+// For this reason, this library just a clone of go/versions for the moment.
+
+// Lang returns the Go language version for version x.
+// If x is not a valid version, Lang returns the empty string.
+// For example:
+//
+//	Lang("go1.21rc2") = "go1.21"
+//	Lang("go1.21.2") = "go1.21"
+//	Lang("go1.21") = "go1.21"
+//	Lang("go1") = "go1"
+//	Lang("bad") = ""
+//	Lang("1.21") = ""
+func Lang(x string) string {
+	v := lang(stripGo(x))
+	if v == "" {
+		return ""
+	}
+	return x[:2+len(v)] // "go"+v without allocation
+}
+
+// Compare returns -1, 0, or +1 depending on whether
+// x < y, x == y, or x > y, interpreted as Go versions.
+// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21".
+// Invalid versions, including the empty string, compare less than
+// valid versions and equal to each other.
+// The language version "go1.21" compares less than the
+// release candidate and eventual releases "go1.21rc1" and "go1.21.0".
+// Custom toolchain suffixes are ignored during comparison:
+// "go1.21.0" and "go1.21.0-bigcorp" are equal.
+func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) }
+
+// IsValid reports whether the version x is valid.
+func IsValid(x string) bool { return isValid(stripGo(x)) }
+
+// stripGo converts from a "go1.21" version to a "1.21" version.
+// If v does not start with "go", stripGo returns the empty string (a known invalid version).
+func stripGo(v string) string {
+	v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix.
+	if len(v) < 2 || v[:2] != "go" {
+		return ""
+	}
+	return v[2:]
+}
diff --git a/vendor/golang.org/x/vuln/LICENSE b/vendor/golang.org/x/vuln/LICENSE
new file mode 100644
index 0000000..2a7cf70
--- /dev/null
+++ b/vendor/golang.org/x/vuln/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2009 The Go Authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google LLC nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/vuln/PATENTS b/vendor/golang.org/x/vuln/PATENTS
new file mode 100644
index 0000000..7330990
--- /dev/null
+++ b/vendor/golang.org/x/vuln/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go.  This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation.  If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/vuln/cmd/govulncheck/doc.go b/vendor/golang.org/x/vuln/cmd/govulncheck/doc.go
new file mode 100644
index 0000000..8de6904
--- /dev/null
+++ b/vendor/golang.org/x/vuln/cmd/govulncheck/doc.go
@@ -0,0 +1,106 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Govulncheck reports known vulnerabilities that affect Go code. It uses static
+analysis of source code or a binary's symbol table to narrow down reports to
+only those that could affect the application.
+
+By default, govulncheck makes requests to the Go vulnerability database at
+https://vuln.go.dev. Requests to the vulnerability database contain only module
+paths with vulnerabilities already known to the database, not code or other
+properties of your program. See https://vuln.go.dev/privacy.html for more.
+Use the -db flag to specify a different database, which must implement the
+specification at https://go.dev/security/vuln/database.
+
+Govulncheck looks for vulnerabilities in Go programs using a specific build
+configuration. For analyzing source code, that configuration is the Go version
+specified by the “go” command found on the PATH. For binaries, the build
+configuration is the one used to build the binary. Note that different build
+configurations may have different known vulnerabilities.
+
+# Usage
+
+To analyze source code, run govulncheck from the module directory, using the
+same package path syntax that the go command uses:
+
+	$ cd my-module
+	$ govulncheck ./...
+
+If no vulnerabilities are found, govulncheck will display a short message. If
+there are vulnerabilities, each is displayed briefly, with a summary of a call
+stack. The summary shows in brief how the package calls a vulnerable function.
+For example, it might say
+
+	main.go:[line]:[column]: mypackage.main calls golang.org/x/text/language.Parse
+
+To control which files are processed, use the -tags flag to provide a
+comma-separated list of build tags, and the -test flag to indicate that test
+files should be included.
+
+To include more detailed stack traces, pass '-show traces', this will cause it to
+print the full call stack for each entry.
+
+To include progress messages and more details on findings, pass '-show verbose'.
+
+To run govulncheck on a compiled binary, pass it the path to the binary file
+with the '-mode binary' flag:
+
+	$ govulncheck -mode binary $HOME/go/bin/my-go-program
+
+Govulncheck uses the binary's symbol information to find mentions of vulnerable
+functions. These functions can belong to binary's transitive dependencies and
+also the main module of the binary. The latter functions are checked for only
+when the precise version of the binary module is known. Govulncheck output on
+binaries omits call stacks, which require source code analysis.
+
+Govulncheck also supports '-mode extract' on a Go binary for extraction of minimal
+information needed to analyze the binary. This will produce a blob, typically much
+smaller than the binary, that can also be passed to govulncheck as an argument with
+'-mode binary'. The users should not rely on the contents or representation of the blob.
+
+# Integrations
+
+Govulncheck supports streaming JSON. For more details, please see [golang.org/x/vuln/internal/govulncheck].
+
+Govulncheck also supports Static Analysis Results Interchange Format (SARIF) output
+format, following the specification at https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif.
+For more details, please see [golang.org/x/vuln/internal/sarif].
+
+Govulncheck supports the Vulnerability EXchange (VEX) output format, following
+the specification at https://github.com/openvex/spec.
+For more details, please see [golang.org/x/vuln/internal/openvex].
+
+# Exit codes
+
+Govulncheck exits successfully (exit code 0) if there are no vulnerabilities,
+and exits unsuccessfully if there are. It also exits successfully if the
+'format -json' ('-json'), '-format sarif', or '-format openvex' is provided,
+regardless of the number of detected vulnerabilities.
+
+# Limitations
+
+Govulncheck has these limitations:
+
+  - Govulncheck analyzes function pointer and interface calls conservatively,
+    which may result in false positives or inaccurate call stacks in some cases.
+  - Calls to functions made using package reflect are not visible to static
+    analysis. Vulnerable code reachable only through those calls will not be
+    reported in source scan mode. Similarly, use of the unsafe package may
+    result in false negatives.
+  - Because Go binaries do not contain detailed call information, govulncheck
+    cannot show the call graphs for detected vulnerabilities. It may also
+    report false positives for code that is in the binary but unreachable.
+  - There is no support for silencing vulnerability findings. See https://go.dev/issue/61211 for
+    updates.
+  - Govulncheck reports only standard library vulnerabilities for binaries
+    built with Go versions prior to Go 1.18.
+  - For binaries where the symbol information cannot be extracted, govulncheck
+    reports vulnerabilities for all modules on which the binary depends.
+
+# Feedback
+
+To share feedback, see https://go.dev/security/vuln#feedback.
+*/
+package main
diff --git a/vendor/golang.org/x/vuln/cmd/govulncheck/main.go b/vendor/golang.org/x/vuln/cmd/govulncheck/main.go
new file mode 100644
index 0000000..b15397d
--- /dev/null
+++ b/vendor/golang.org/x/vuln/cmd/govulncheck/main.go
@@ -0,0 +1,44 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"os"
+
+	"golang.org/x/telemetry"
+	"golang.org/x/vuln/scan"
+)
+
+func main() {
+	telemetry.Start(telemetry.Config{ReportCrashes: true})
+
+	ctx := context.Background()
+
+	cmd := scan.Command(ctx, os.Args[1:]...)
+	err := cmd.Start()
+	if err == nil {
+		err = cmd.Wait()
+	}
+	if err != nil {
+		var e interface{ ExitCode() int }
+		if errors.As(err, &e) {
+			printErrorToStderr := true
+			if _, ok := err.(interface{ ExitCode() int }); ok {
+				// Avoid printing the error to stderr if the exit code error wasn't
+				// wrapped with another error providing context.
+				printErrorToStderr = false
+			}
+			if printErrorToStderr {
+				fmt.Fprintln(os.Stderr, err)
+			}
+			os.Exit(e.ExitCode())
+		}
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(1)
+	}
+}
diff --git a/vendor/golang.org/x/vuln/cmd/govulncheck/test_utils.go b/vendor/golang.org/x/vuln/cmd/govulncheck/test_utils.go
new file mode 100644
index 0000000..826d6ca
--- /dev/null
+++ b/vendor/golang.org/x/vuln/cmd/govulncheck/test_utils.go
@@ -0,0 +1,128 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"encoding/json"
+	"os"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"testing"
+)
+
+// copyTestCase copies the test case at dir into a
+// temporary directory. The created files have 0644
+// permission and directories 0755. It does not create
+// symlinks.
+func copyTestCase(dir string, t *testing.T) string {
+	newDir, err := filepath.Abs(t.TempDir())
+	if err != nil {
+		t.Fatalf("failed to copy test case %s: cannot create root %v", dir, err)
+	}
+
+	if err := copyDir(dir, newDir); err != nil {
+		t.Fatalf("failed to copy test case %s: copy failure %v", dir, err)
+	}
+	return newDir
+}
+
+func copyDir(srcDir, destDir string) error {
+	entries, err := os.ReadDir(srcDir)
+	if err != nil {
+		return err
+	}
+	for _, entry := range entries {
+		src := filepath.Join(srcDir, entry.Name())
+		dest := filepath.Join(destDir, entry.Name())
+
+		fileInfo, err := os.Stat(src)
+		if err != nil {
+			return err
+		}
+
+		switch fileInfo.Mode() & os.ModeType {
+		case os.ModeDir:
+			if err := os.MkdirAll(dest, 0755); err != nil {
+				return err
+			}
+			if err := copyDir(src, dest); err != nil {
+				return err
+			}
+		default:
+			if err := copyFile(src, dest); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func copyFile(src, dest string) error {
+	b, err := os.ReadFile(src)
+	if err != nil {
+		return err
+	}
+	return os.WriteFile(dest, b, 0644)
+}
+
+type config struct {
+	// SkipGOOS is a list of GOOS to skip
+	SkipGOOS []string `json:"skipGOOS,omitempty"`
+	// Copy the folder to isolate it
+	Copy bool `json:"copy,omitempty"`
+	// SkipBuild the test case
+	SkipBuild bool `json:"skipBuild,omitempty"`
+	// Strip indicates if binaries should be stripped
+	Strip bool `json:"strip,omitempty"`
+	// EnableSBOM indicates if sbom should be
+	// printed in JSON.
+	EnableSBOM bool `json:"sbom,omitempty"`
+
+	Fixups []fixup `json:"fixups,omitempty"`
+}
+
+func (c *config) skip() bool {
+	for _, sg := range c.SkipGOOS {
+		if runtime.GOOS == sg {
+			return true
+		}
+	}
+	return false
+}
+
+type fixup struct {
+	Pattern     string `json:"pattern,omitempty"`
+	Replace     string `json:"replace,omitempty"`
+	compiled    *regexp.Regexp
+	replaceFunc func(b []byte) []byte
+}
+
+func (f *fixup) init() {
+	f.compiled = regexp.MustCompile(f.Pattern)
+}
+
+func (f *fixup) apply(data []byte) []byte {
+	if f.replaceFunc != nil {
+		return f.compiled.ReplaceAllFunc(data, f.replaceFunc)
+	}
+	return f.compiled.ReplaceAll(data, []byte(f.Replace))
+}
+
+// loadConfig loads and initializes the config from path.
+func loadConfig(path string) (*config, error) {
+	b, err := os.ReadFile(path)
+	if err != nil {
+		return nil, err
+	}
+	var cfg config
+	if err := json.Unmarshal(b, &cfg); err != nil {
+		return nil, err
+	}
+	for i := range cfg.Fixups {
+		cfg.Fixups[i].init()
+	}
+	return &cfg, nil
+}
diff --git a/vendor/golang.org/x/vuln/internal/buildinfo/README.md b/vendor/golang.org/x/vuln/internal/buildinfo/README.md
new file mode 100644
index 0000000..f04bedd
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/buildinfo/README.md
@@ -0,0 +1,9 @@
+This code is a copied and slightly modified subset of go/src/debug/buildinfo.
+
+It contains logic for parsing Go binary files for the purpose of extracting
+module dependency and symbol table information.
+
+Logic added by vulncheck is located in files with "additions_" prefix.
+
+Within the originally named files, changed or added logic is annotated with
+a comment starting with "Addition:".
diff --git a/vendor/golang.org/x/vuln/internal/buildinfo/additions_buildinfo.go b/vendor/golang.org/x/vuln/internal/buildinfo/additions_buildinfo.go
new file mode 100644
index 0000000..8cb7d69
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/buildinfo/additions_buildinfo.go
@@ -0,0 +1,256 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.18
+
+package buildinfo
+
+// This file adds to buildinfo the functionality for extracting the PCLN table.
+
+import (
+	"debug/elf"
+	"debug/macho"
+	"debug/pe"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+)
+
+// ErrNoSymbols represents non-existence of symbol
+// table in binaries supported by buildinfo.
+var ErrNoSymbols = errors.New("no symbol section")
+
+// SymbolInfo is derived from cmd/internal/objfile/elf.go:symbols, symbolData.
+func (x *elfExe) SymbolInfo(name string) (uint64, uint64, io.ReaderAt, error) {
+	sym, err := x.lookupSymbol(name)
+	if err != nil || sym == nil {
+		if errors.Is(err, elf.ErrNoSymbols) {
+			return 0, 0, nil, ErrNoSymbols
+		}
+		return 0, 0, nil, fmt.Errorf("no symbol %q", name)
+	}
+	prog := x.progContaining(sym.Value)
+	if prog == nil {
+		return 0, 0, nil, fmt.Errorf("no Prog containing value %d for %q", sym.Value, name)
+	}
+	return sym.Value, prog.Vaddr, prog.ReaderAt, nil
+}
+
+func (x *elfExe) lookupSymbol(name string) (*elf.Symbol, error) {
+	x.symbolsOnce.Do(func() {
+		syms, err := x.f.Symbols()
+		if err != nil {
+			x.symbolsErr = err
+			return
+		}
+		x.symbols = make(map[string]*elf.Symbol, len(syms))
+		for _, s := range syms {
+			s := s // make a copy to prevent aliasing
+			x.symbols[s.Name] = &s
+		}
+	})
+	if x.symbolsErr != nil {
+		return nil, x.symbolsErr
+	}
+	return x.symbols[name], nil
+}
+
+func (x *elfExe) progContaining(addr uint64) *elf.Prog {
+	for _, p := range x.f.Progs {
+		if addr >= p.Vaddr && addr < p.Vaddr+p.Filesz {
+			return p
+		}
+	}
+	return nil
+}
+
+const go12magic = 0xfffffffb
+const go116magic = 0xfffffffa
+
+// PCLNTab is derived from cmd/internal/objfile/elf.go:pcln.
+func (x *elfExe) PCLNTab() ([]byte, uint64) {
+	var offset uint64
+	text := x.f.Section(".text")
+	if text != nil {
+		offset = text.Offset
+	}
+	pclntab := x.f.Section(".gopclntab")
+	if pclntab == nil {
+		// Addition: this code is added to support some form of stripping.
+		pclntab = x.f.Section(".data.rel.ro.gopclntab")
+		if pclntab == nil {
+			pclntab = x.f.Section(".data.rel.ro")
+			if pclntab == nil {
+				return nil, 0
+			}
+			// Possibly the PCLN table has been stuck in the .data.rel.ro section, but without
+			// its own section header. We can search for for the start by looking for the four
+			// byte magic and the go magic.
+			b, err := pclntab.Data()
+			if err != nil {
+				return nil, 0
+			}
+			// TODO(rolandshoemaker): I'm not sure if the 16 byte increment during the search is
+			// actually correct. During testing it worked, but that may be because I got lucky
+			// with the binary I was using, and we need to do four byte jumps to exhaustively
+			// search the section?
+			for i := 0; i < len(b); i += 16 {
+				if len(b)-i > 16 && b[i+4] == 0 && b[i+5] == 0 &&
+					(b[i+6] == 1 || b[i+6] == 2 || b[i+6] == 4) &&
+					(b[i+7] == 4 || b[i+7] == 8) {
+					// Also check for the go magic
+					leMagic := binary.LittleEndian.Uint32(b[i:])
+					beMagic := binary.BigEndian.Uint32(b[i:])
+					switch {
+					case leMagic == go12magic:
+						fallthrough
+					case beMagic == go12magic:
+						fallthrough
+					case leMagic == go116magic:
+						fallthrough
+					case beMagic == go116magic:
+						return b[i:], offset
+					}
+				}
+			}
+		}
+	}
+	b, err := pclntab.Data()
+	if err != nil {
+		return nil, 0
+	}
+	return b, offset
+}
+
+// SymbolInfo is derived from cmd/internal/objfile/pe.go:findPESymbol, loadPETable.
+func (x *peExe) SymbolInfo(name string) (uint64, uint64, io.ReaderAt, error) {
+	sym, err := x.lookupSymbol(name)
+	if err != nil {
+		return 0, 0, nil, err
+	}
+	if sym == nil {
+		return 0, 0, nil, fmt.Errorf("no symbol %q", name)
+	}
+	sect := x.f.Sections[sym.SectionNumber-1]
+	// In PE, the symbol's value is the offset from the section start.
+	return uint64(sym.Value), 0, sect.ReaderAt, nil
+}
+
+func (x *peExe) lookupSymbol(name string) (*pe.Symbol, error) {
+	x.symbolsOnce.Do(func() {
+		x.symbols = make(map[string]*pe.Symbol, len(x.f.Symbols))
+		if len(x.f.Symbols) == 0 {
+			x.symbolsErr = ErrNoSymbols
+			return
+		}
+		for _, s := range x.f.Symbols {
+			x.symbols[s.Name] = s
+		}
+	})
+	if x.symbolsErr != nil {
+		return nil, x.symbolsErr
+	}
+	return x.symbols[name], nil
+}
+
+// PCLNTab is derived from cmd/internal/objfile/pe.go:pcln.
+// Assumes that the underlying symbol table exists, otherwise
+// it might panic.
+func (x *peExe) PCLNTab() ([]byte, uint64) {
+	var textOffset uint64
+	for _, section := range x.f.Sections {
+		if section.Name == ".text" {
+			textOffset = uint64(section.Offset)
+			break
+		}
+	}
+
+	var start, end int64
+	var section int
+	if s, _ := x.lookupSymbol("runtime.pclntab"); s != nil {
+		start = int64(s.Value)
+		section = int(s.SectionNumber - 1)
+	}
+	if s, _ := x.lookupSymbol("runtime.epclntab"); s != nil {
+		end = int64(s.Value)
+	}
+	if start == 0 || end == 0 {
+		return nil, 0
+	}
+	offset := int64(x.f.Sections[section].Offset) + start
+	size := end - start
+
+	pclntab := make([]byte, size)
+	if _, err := x.r.ReadAt(pclntab, offset); err != nil {
+		return nil, 0
+	}
+	return pclntab, textOffset
+}
+
+// SymbolInfo is derived from cmd/internal/objfile/macho.go:symbols.
+func (x *machoExe) SymbolInfo(name string) (uint64, uint64, io.ReaderAt, error) {
+	sym, err := x.lookupSymbol(name)
+	if err != nil {
+		return 0, 0, nil, err
+	}
+	if sym == nil {
+		return 0, 0, nil, fmt.Errorf("no symbol %q", name)
+	}
+	seg := x.segmentContaining(sym.Value)
+	if seg == nil {
+		return 0, 0, nil, fmt.Errorf("no Segment containing value %d for %q", sym.Value, name)
+	}
+	return sym.Value, seg.Addr, seg.ReaderAt, nil
+}
+
+func (x *machoExe) lookupSymbol(name string) (*macho.Symbol, error) {
+	const mustExistSymbol = "runtime.main"
+	x.symbolsOnce.Do(func() {
+		x.symbols = make(map[string]*macho.Symbol, len(x.f.Symtab.Syms))
+		for _, s := range x.f.Symtab.Syms {
+			s := s // make a copy to prevent aliasing
+			x.symbols[s.Name] = &s
+		}
+		// In the presence of stripping, the symbol table for darwin
+		// binaries will not be empty, but the program symbols will
+		// be missing.
+		if _, ok := x.symbols[mustExistSymbol]; !ok {
+			x.symbolsErr = ErrNoSymbols
+		}
+	})
+
+	if x.symbolsErr != nil {
+		return nil, x.symbolsErr
+	}
+	return x.symbols[name], nil
+}
+
+func (x *machoExe) segmentContaining(addr uint64) *macho.Segment {
+	for _, load := range x.f.Loads {
+		seg, ok := load.(*macho.Segment)
+		if ok && seg.Addr <= addr && addr <= seg.Addr+seg.Filesz-1 && seg.Name != "__PAGEZERO" {
+			return seg
+		}
+	}
+	return nil
+}
+
+// SymbolInfo is derived from cmd/internal/objfile/macho.go:pcln.
+func (x *machoExe) PCLNTab() ([]byte, uint64) {
+	var textOffset uint64
+	text := x.f.Section("__text")
+	if text != nil {
+		textOffset = uint64(text.Offset)
+	}
+	pclntab := x.f.Section("__gopclntab")
+	if pclntab == nil {
+		return nil, 0
+	}
+	b, err := pclntab.Data()
+	if err != nil {
+		return nil, 0
+	}
+	return b, textOffset
+}
diff --git a/vendor/golang.org/x/vuln/internal/buildinfo/additions_scan.go b/vendor/golang.org/x/vuln/internal/buildinfo/additions_scan.go
new file mode 100644
index 0000000..b94878f
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/buildinfo/additions_scan.go
@@ -0,0 +1,159 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.18
+
+package buildinfo
+
+// Code in this package is dervied from src/cmd/go/internal/version/version.go
+// and cmd/go/internal/version/exe.go.
+
+import (
+	"debug/buildinfo"
+	"errors"
+	"fmt"
+	"net/url"
+	"os"
+	"runtime/debug"
+	"strings"
+
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/vuln/internal/gosym"
+	"golang.org/x/vuln/internal/goversion"
+)
+
+func debugModulesToPackagesModules(debugModules []*debug.Module) []*packages.Module {
+	packagesModules := make([]*packages.Module, len(debugModules))
+	for i, mod := range debugModules {
+		packagesModules[i] = &packages.Module{
+			Path:    mod.Path,
+			Version: mod.Version,
+		}
+		if mod.Replace != nil {
+			packagesModules[i].Replace = &packages.Module{
+				Path:    mod.Replace.Path,
+				Version: mod.Replace.Version,
+			}
+		}
+	}
+	return packagesModules
+}
+
+type Symbol struct {
+	Pkg  string `json:"pkg,omitempty"`
+	Name string `json:"name,omitempty"`
+}
+
+// ExtractPackagesAndSymbols extracts symbols, packages, modules from
+// Go binary file as well as bin's metadata.
+//
+// If the symbol table is not available, such as in the case of stripped
+// binaries, returns module and binary info but without the symbol info.
+func ExtractPackagesAndSymbols(file string) ([]*packages.Module, []Symbol, *debug.BuildInfo, error) {
+	bin, err := os.Open(file)
+	if err != nil {
+		return nil, nil, nil, err
+	}
+	defer bin.Close()
+
+	bi, err := buildinfo.Read(bin)
+	if err != nil {
+		// It could be that bin is an ancient Go binary.
+		v, err := goversion.ReadExe(file)
+		if err != nil {
+			return nil, nil, nil, err
+		}
+		bi := &debug.BuildInfo{
+			GoVersion: v.Release,
+			Main:      debug.Module{Path: v.ModuleInfo},
+		}
+		// We cannot analyze symbol tables of ancient binaries.
+		return nil, nil, bi, nil
+	}
+
+	funcSymName := gosym.FuncSymName(bi.GoVersion)
+	if funcSymName == "" {
+		return nil, nil, nil, fmt.Errorf("binary built using unsupported Go version: %q", bi.GoVersion)
+	}
+
+	x, err := openExe(bin)
+	if err != nil {
+		return nil, nil, nil, err
+	}
+
+	value, base, r, err := x.SymbolInfo(funcSymName)
+	if err != nil {
+		if errors.Is(err, ErrNoSymbols) {
+			// bin is stripped, so return just module info and metadata.
+			return debugModulesToPackagesModules(bi.Deps), nil, bi, nil
+		}
+		return nil, nil, nil, fmt.Errorf("reading %v: %v", funcSymName, err)
+	}
+
+	pclntab, textOffset := x.PCLNTab()
+	if pclntab == nil {
+		// If we have build information, but not PCLN table, fall
+		// back to much higher granularity vulnerability checking.
+		return debugModulesToPackagesModules(bi.Deps), nil, bi, nil
+	}
+	lineTab := gosym.NewLineTable(pclntab, textOffset)
+	if lineTab == nil {
+		return nil, nil, nil, errors.New("invalid line table")
+	}
+	tab, err := gosym.NewTable(nil, lineTab)
+	if err != nil {
+		return nil, nil, nil, err
+	}
+
+	pkgSyms := make(map[Symbol]bool)
+	for _, f := range tab.Funcs {
+		if f.Func == nil {
+			continue
+		}
+		pkgName, symName, err := parseName(f.Func.Sym)
+		if err != nil {
+			return nil, nil, nil, err
+		}
+		pkgSyms[Symbol{pkgName, symName}] = true
+
+		// Collect symbols that were inlined in f.
+		it, err := lineTab.InlineTree(&f, value, base, r)
+		if err != nil {
+			return nil, nil, nil, fmt.Errorf("InlineTree: %v", err)
+		}
+		for _, ic := range it {
+			pkgName, symName, err := parseName(&gosym.Sym{Name: ic.Name})
+			if err != nil {
+				return nil, nil, nil, err
+			}
+			pkgSyms[Symbol{pkgName, symName}] = true
+		}
+	}
+
+	var syms []Symbol
+	for ps := range pkgSyms {
+		syms = append(syms, ps)
+	}
+
+	return debugModulesToPackagesModules(bi.Deps), syms, bi, nil
+}
+
+func parseName(s *gosym.Sym) (pkg, sym string, err error) {
+	symName := s.BaseName()
+	if r := s.ReceiverName(); r != "" {
+		if strings.HasPrefix(r, "(*") {
+			r = strings.Trim(r, "(*)")
+		}
+		symName = fmt.Sprintf("%s.%s", r, symName)
+	}
+
+	pkgName := s.PackageName()
+	if pkgName != "" {
+		pkgName, err = url.PathUnescape(pkgName)
+		if err != nil {
+			return "", "", err
+		}
+	}
+	return pkgName, symName, nil
+}
diff --git a/vendor/golang.org/x/vuln/internal/buildinfo/buildinfo.go b/vendor/golang.org/x/vuln/internal/buildinfo/buildinfo.go
new file mode 100644
index 0000000..15243ae
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/buildinfo/buildinfo.go
@@ -0,0 +1,220 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.18
+
+package buildinfo
+
+// Addition: this file is a trimmed and slightly modified version of debug/buildinfo/buildinfo.go
+
+import (
+	"bytes"
+	"debug/elf"
+	"debug/macho"
+	"debug/pe"
+	"fmt"
+	"sync"
+
+	// "internal/xcoff"
+	"io"
+)
+
+// Addition: modification of rawBuildInfo in the original file.
+// openExe returns reader r as an exe.
+func openExe(r io.ReaderAt) (exe, error) {
+	data := make([]byte, 16)
+	if _, err := r.ReadAt(data, 0); err != nil {
+		return nil, err
+	}
+	if bytes.HasPrefix(data, []byte("\x7FELF")) {
+		e, err := elf.NewFile(r)
+		if err != nil {
+			return nil, err
+		}
+		return &elfExe{f: e}, nil
+	}
+	if bytes.HasPrefix(data, []byte("MZ")) {
+		e, err := pe.NewFile(r)
+		if err != nil {
+			return nil, err
+		}
+		return &peExe{r: r, f: e}, nil
+	}
+	if bytes.HasPrefix(data, []byte("\xFE\xED\xFA")) || bytes.HasPrefix(data[1:], []byte("\xFA\xED\xFE")) {
+		e, err := macho.NewFile(r)
+		if err != nil {
+			return nil, err
+		}
+		return &machoExe{f: e}, nil
+	}
+	return nil, fmt.Errorf("unrecognized executable format")
+}
+
+type exe interface {
+	// ReadData reads and returns up to size byte starting at virtual address addr.
+	ReadData(addr, size uint64) ([]byte, error)
+
+	// DataStart returns the virtual address of the segment or section that
+	// should contain build information. This is either a specially named section
+	// or the first writable non-zero data segment.
+	DataStart() uint64
+
+	PCLNTab() ([]byte, uint64) // Addition: for constructing symbol table
+
+	SymbolInfo(name string) (uint64, uint64, io.ReaderAt, error) // Addition: for inlining purposes
+}
+
+// elfExe is the ELF implementation of the exe interface.
+type elfExe struct {
+	f *elf.File
+
+	symbols     map[string]*elf.Symbol // Addition: symbols in the binary
+	symbolsOnce sync.Once              // Addition: for computing symbols
+	symbolsErr  error                  // Addition: error for computing symbols
+}
+
+func (x *elfExe) ReadData(addr, size uint64) ([]byte, error) {
+	for _, prog := range x.f.Progs {
+		if prog.Vaddr <= addr && addr <= prog.Vaddr+prog.Filesz-1 {
+			n := prog.Vaddr + prog.Filesz - addr
+			if n > size {
+				n = size
+			}
+			data := make([]byte, n)
+			_, err := prog.ReadAt(data, int64(addr-prog.Vaddr))
+			if err != nil {
+				return nil, err
+			}
+			return data, nil
+		}
+	}
+	return nil, fmt.Errorf("address not mapped") // Addition: custom error
+}
+
+func (x *elfExe) DataStart() uint64 {
+	for _, s := range x.f.Sections {
+		if s.Name == ".go.buildinfo" {
+			return s.Addr
+		}
+	}
+	for _, p := range x.f.Progs {
+		if p.Type == elf.PT_LOAD && p.Flags&(elf.PF_X|elf.PF_W) == elf.PF_W {
+			return p.Vaddr
+		}
+	}
+	return 0
+}
+
+// peExe is the PE (Windows Portable Executable) implementation of the exe interface.
+type peExe struct {
+	r io.ReaderAt
+	f *pe.File
+
+	symbols     map[string]*pe.Symbol // Addition: symbols in the binary
+	symbolsOnce sync.Once             // Addition: for computing symbols
+	symbolsErr  error                 // Addition: error for computing symbols
+}
+
+func (x *peExe) imageBase() uint64 {
+	switch oh := x.f.OptionalHeader.(type) {
+	case *pe.OptionalHeader32:
+		return uint64(oh.ImageBase)
+	case *pe.OptionalHeader64:
+		return oh.ImageBase
+	}
+	return 0
+}
+
+func (x *peExe) ReadData(addr, size uint64) ([]byte, error) {
+	addr -= x.imageBase()
+	for _, sect := range x.f.Sections {
+		if uint64(sect.VirtualAddress) <= addr && addr <= uint64(sect.VirtualAddress+sect.Size-1) {
+			n := uint64(sect.VirtualAddress+sect.Size) - addr
+			if n > size {
+				n = size
+			}
+			data := make([]byte, n)
+			_, err := sect.ReadAt(data, int64(addr-uint64(sect.VirtualAddress)))
+			if err != nil {
+				return nil, err
+			}
+			return data, nil
+		}
+	}
+	return nil, fmt.Errorf("address not mapped") // Addition: custom error
+}
+
+func (x *peExe) DataStart() uint64 {
+	// Assume data is first writable section.
+	const (
+		IMAGE_SCN_CNT_CODE               = 0x00000020
+		IMAGE_SCN_CNT_INITIALIZED_DATA   = 0x00000040
+		IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080
+		IMAGE_SCN_MEM_EXECUTE            = 0x20000000
+		IMAGE_SCN_MEM_READ               = 0x40000000
+		IMAGE_SCN_MEM_WRITE              = 0x80000000
+		IMAGE_SCN_MEM_DISCARDABLE        = 0x2000000
+		IMAGE_SCN_LNK_NRELOC_OVFL        = 0x1000000
+		IMAGE_SCN_ALIGN_32BYTES          = 0x600000
+	)
+	for _, sect := range x.f.Sections {
+		if sect.VirtualAddress != 0 && sect.Size != 0 &&
+			sect.Characteristics&^IMAGE_SCN_ALIGN_32BYTES == IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE {
+			return uint64(sect.VirtualAddress) + x.imageBase()
+		}
+	}
+	return 0
+}
+
+// machoExe is the Mach-O (Apple macOS/iOS) implementation of the exe interface.
+type machoExe struct {
+	f *macho.File
+
+	symbols     map[string]*macho.Symbol // Addition: symbols in the binary
+	symbolsOnce sync.Once                // Addition: for computing symbols
+	symbolsErr  error                    // Addition: error for computing symbols
+}
+
+func (x *machoExe) ReadData(addr, size uint64) ([]byte, error) {
+	for _, load := range x.f.Loads {
+		seg, ok := load.(*macho.Segment)
+		if !ok {
+			continue
+		}
+		if seg.Addr <= addr && addr <= seg.Addr+seg.Filesz-1 {
+			if seg.Name == "__PAGEZERO" {
+				continue
+			}
+			n := seg.Addr + seg.Filesz - addr
+			if n > size {
+				n = size
+			}
+			data := make([]byte, n)
+			_, err := seg.ReadAt(data, int64(addr-seg.Addr))
+			if err != nil {
+				return nil, err
+			}
+			return data, nil
+		}
+	}
+	return nil, fmt.Errorf("address not mapped") // Addition: custom error
+}
+
+func (x *machoExe) DataStart() uint64 {
+	// Look for section named "__go_buildinfo".
+	for _, sec := range x.f.Sections {
+		if sec.Name == "__go_buildinfo" {
+			return sec.Addr
+		}
+	}
+	// Try the first non-empty writable segment.
+	const RW = 3
+	for _, load := range x.f.Loads {
+		seg, ok := load.(*macho.Segment)
+		if ok && seg.Addr != 0 && seg.Filesz != 0 && seg.Prot == RW && seg.Maxprot == RW {
+			return seg.Addr
+		}
+	}
+	return 0
+}
diff --git a/vendor/golang.org/x/vuln/internal/client/client.go b/vendor/golang.org/x/vuln/internal/client/client.go
new file mode 100644
index 0000000..236c9d1
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/client/client.go
@@ -0,0 +1,347 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package client provides an interface for accessing vulnerability
+// databases, via either HTTP or local filesystem access.
+//
+// The protocol is described at https://go.dev/security/vuln/database.
+package client
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"net/http"
+	"net/url"
+	"os"
+	"path/filepath"
+	"sort"
+	"strings"
+	"time"
+
+	"golang.org/x/sync/errgroup"
+	"golang.org/x/vuln/internal/derrors"
+	"golang.org/x/vuln/internal/osv"
+	isem "golang.org/x/vuln/internal/semver"
+	"golang.org/x/vuln/internal/web"
+)
+
+// A Client for reading vulnerability databases.
+type Client struct {
+	source
+}
+
+type Options struct {
+	HTTPClient *http.Client
+}
+
+// NewClient returns a client that reads the vulnerability database
+// in source (an "http" or "file" prefixed URL).
+//
+// It supports databases following the API described
+// in https://go.dev/security/vuln/database#api.
+func NewClient(source string, opts *Options) (_ *Client, err error) {
+	source = strings.TrimRight(source, "/")
+	uri, err := url.Parse(source)
+	if err != nil {
+		return nil, err
+	}
+	switch uri.Scheme {
+	case "http", "https":
+		return newHTTPClient(uri, opts)
+	case "file":
+		return newLocalClient(uri)
+	default:
+		return nil, fmt.Errorf("source %q has unsupported scheme", uri)
+	}
+}
+
+var errUnknownSchema = errors.New("unrecognized vulndb format; see https://go.dev/security/vuln/database#api for accepted schema")
+
+func newHTTPClient(uri *url.URL, opts *Options) (*Client, error) {
+	source := uri.String()
+
+	// v1 returns true if the source likely follows the V1 schema.
+	v1 := func() bool {
+		return source == "https://vuln.go.dev" ||
+			endpointExistsHTTP(source, "index/modules.json.gz")
+	}
+
+	if v1() {
+		return &Client{source: newHTTPSource(uri.String(), opts)}, nil
+	}
+
+	return nil, errUnknownSchema
+}
+
+func endpointExistsHTTP(source, endpoint string) bool {
+	r, err := http.Head(source + "/" + endpoint)
+	return err == nil && r.StatusCode == http.StatusOK
+}
+
+func newLocalClient(uri *url.URL) (*Client, error) {
+	dir, err := toDir(uri)
+	if err != nil {
+		return nil, err
+	}
+
+	// Check if the DB likely follows the v1 schema by
+	// looking for the "index/modules.json" endpoint.
+	if endpointExistsDir(dir, modulesEndpoint+".json") {
+		return &Client{source: newLocalSource(dir)}, nil
+	}
+
+	// If the DB doesn't follow the v1 schema,
+	// attempt to intepret it as a flat list of OSV files.
+	// This is currently a "hidden" feature, so don't output the
+	// specific error if this fails.
+	src, err := newHybridSource(dir)
+	if err != nil {
+		return nil, errUnknownSchema
+	}
+	return &Client{source: src}, nil
+}
+
+func toDir(uri *url.URL) (string, error) {
+	dir, err := web.URLToFilePath(uri)
+	if err != nil {
+		return "", err
+	}
+	fi, err := os.Stat(dir)
+	if err != nil {
+		return "", err
+	}
+	if !fi.IsDir() {
+		return "", fmt.Errorf("%s is not a directory", dir)
+	}
+	return dir, nil
+}
+
+func endpointExistsDir(dir, endpoint string) bool {
+	_, err := os.Stat(filepath.Join(dir, endpoint))
+	return err == nil
+}
+
+func NewInMemoryClient(entries []*osv.Entry) (*Client, error) {
+	s, err := newInMemorySource(entries)
+	if err != nil {
+		return nil, err
+	}
+	return &Client{source: s}, nil
+}
+
+func (c *Client) LastModifiedTime(ctx context.Context) (_ time.Time, err error) {
+	derrors.Wrap(&err, "LastModifiedTime()")
+
+	b, err := c.source.get(ctx, dbEndpoint)
+	if err != nil {
+		return time.Time{}, err
+	}
+
+	var dbMeta dbMeta
+	if err := json.Unmarshal(b, &dbMeta); err != nil {
+		return time.Time{}, err
+	}
+
+	return dbMeta.Modified, nil
+}
+
+type ModuleRequest struct {
+	// The module path to filter on.
+	// This must be set (if empty, ByModule errors).
+	Path string
+	// (Optional) If set, only return vulnerabilities affected
+	// at this version.
+	Version string
+}
+
+type ModuleResponse struct {
+	Path    string
+	Version string
+	Entries []*osv.Entry
+}
+
+// ByModules returns a list of responses
+// containing the OSV entries corresponding to each request.
+//
+// The order of the requests is preserved, and each request has
+// a response even if there are no entries (in which case the Entries
+// field is nil).
+func (c *Client) ByModules(ctx context.Context, reqs []*ModuleRequest) (_ []*ModuleResponse, err error) {
+	derrors.Wrap(&err, "ByModules(%v)", reqs)
+
+	metas, err := c.moduleMetas(ctx, reqs)
+	if err != nil {
+		return nil, err
+	}
+
+	resps := make([]*ModuleResponse, len(reqs))
+	g, gctx := errgroup.WithContext(ctx)
+	g.SetLimit(10)
+	for i, req := range reqs {
+		i, req := i, req
+		g.Go(func() error {
+			entries, err := c.byModule(gctx, req, metas[i])
+			if err != nil {
+				return err
+			}
+			resps[i] = &ModuleResponse{
+				Path:    req.Path,
+				Version: req.Version,
+				Entries: entries,
+			}
+			return nil
+		})
+	}
+	if err := g.Wait(); err != nil {
+		return nil, err
+	}
+
+	return resps, nil
+}
+
+func (c *Client) moduleMetas(ctx context.Context, reqs []*ModuleRequest) (_ []*moduleMeta, err error) {
+	b, err := c.source.get(ctx, modulesEndpoint)
+	if err != nil {
+		return nil, err
+	}
+
+	dec, err := newStreamDecoder(b)
+	if err != nil {
+		return nil, err
+	}
+
+	metas := make([]*moduleMeta, len(reqs))
+	for dec.More() {
+		var m moduleMeta
+		err := dec.Decode(&m)
+		if err != nil {
+			return nil, err
+		}
+		for i, req := range reqs {
+			if m.Path == req.Path {
+				metas[i] = &m
+			}
+		}
+	}
+
+	return metas, nil
+}
+
+// byModule returns the OSV entries matching the ModuleRequest,
+// or (nil, nil) if there are none.
+func (c *Client) byModule(ctx context.Context, req *ModuleRequest, m *moduleMeta) (_ []*osv.Entry, err error) {
+	// This module isn't in the database.
+	if m == nil {
+		return nil, nil
+	}
+
+	if req.Path == "" {
+		return nil, fmt.Errorf("module path must be set")
+	}
+
+	if req.Version != "" && !isem.Valid(req.Version) {
+		return nil, fmt.Errorf("version %s is not valid semver", req.Version)
+	}
+
+	var ids []string
+	for _, v := range m.Vulns {
+		if v.Fixed == "" || isem.Less(req.Version, v.Fixed) {
+			ids = append(ids, v.ID)
+		}
+	}
+
+	if len(ids) == 0 {
+		return nil, nil
+	}
+
+	entries, err := c.byIDs(ctx, ids)
+	if err != nil {
+		return nil, err
+	}
+
+	// Filter by version.
+	if req.Version != "" {
+		affected := func(e *osv.Entry) bool {
+			for _, a := range e.Affected {
+				if a.Module.Path == req.Path && isem.Affects(a.Ranges, req.Version) {
+					return true
+				}
+			}
+			return false
+		}
+
+		var filtered []*osv.Entry
+		for _, entry := range entries {
+			if affected(entry) {
+				filtered = append(filtered, entry)
+			}
+		}
+		if len(filtered) == 0 {
+			return nil, nil
+		}
+	}
+
+	sort.SliceStable(entries, func(i, j int) bool {
+		return entries[i].ID < entries[j].ID
+	})
+
+	return entries, nil
+}
+
+func (c *Client) byIDs(ctx context.Context, ids []string) (_ []*osv.Entry, err error) {
+	entries := make([]*osv.Entry, len(ids))
+	g, gctx := errgroup.WithContext(ctx)
+	g.SetLimit(10)
+	for i, id := range ids {
+		i, id := i, id
+		g.Go(func() error {
+			e, err := c.byID(gctx, id)
+			if err != nil {
+				return err
+			}
+			entries[i] = e
+			return nil
+		})
+	}
+	if err := g.Wait(); err != nil {
+		return nil, err
+	}
+
+	return entries, nil
+}
+
+// byID returns the OSV entry with the given ID,
+// or an error if it does not exist / cannot be unmarshaled.
+func (c *Client) byID(ctx context.Context, id string) (_ *osv.Entry, err error) {
+	derrors.Wrap(&err, "byID(%s)", id)
+
+	b, err := c.source.get(ctx, entryEndpoint(id))
+	if err != nil {
+		return nil, err
+	}
+
+	var entry osv.Entry
+	if err := json.Unmarshal(b, &entry); err != nil {
+		return nil, err
+	}
+
+	return &entry, nil
+}
+
+// newStreamDecoder returns a decoder that can be used
+// to read an array of JSON objects.
+func newStreamDecoder(b []byte) (*json.Decoder, error) {
+	dec := json.NewDecoder(bytes.NewBuffer(b))
+
+	// skip open bracket
+	_, err := dec.Token()
+	if err != nil {
+		return nil, err
+	}
+
+	return dec, nil
+}
diff --git a/vendor/golang.org/x/vuln/internal/client/index.go b/vendor/golang.org/x/vuln/internal/client/index.go
new file mode 100644
index 0000000..435980c
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/client/index.go
@@ -0,0 +1,120 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package client
+
+import (
+	"encoding/json"
+	"fmt"
+	"io/fs"
+	"os"
+	"path/filepath"
+
+	"golang.org/x/vuln/internal/osv"
+	isem "golang.org/x/vuln/internal/semver"
+)
+
+// indexFromDir returns a raw index created from a directory
+// containing OSV entries.
+// It skips any non-JSON files but errors if any of the JSON files
+// cannot be unmarshaled into OSV, or have a filename other than .json.
+func indexFromDir(dir string) (map[string][]byte, error) {
+	idx := newIndex()
+	f := os.DirFS(dir)
+
+	if err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
+		fname := d.Name()
+		ext := filepath.Ext(fname)
+		switch {
+		case err != nil:
+			return err
+		case d.IsDir():
+			return nil
+		case ext != ".json":
+			return nil
+		}
+
+		b, err := fs.ReadFile(f, d.Name())
+		if err != nil {
+			return err
+		}
+		var entry osv.Entry
+		if err := json.Unmarshal(b, &entry); err != nil {
+			return err
+		}
+		if fname != entry.ID+".json" {
+			return fmt.Errorf("OSV entries must have filename of the form .json, got %s", fname)
+		}
+
+		idx.add(&entry)
+		return nil
+	}); err != nil {
+		return nil, err
+	}
+
+	return idx.raw()
+}
+
+func indexFromEntries(entries []*osv.Entry) (map[string][]byte, error) {
+	idx := newIndex()
+
+	for _, entry := range entries {
+		idx.add(entry)
+	}
+
+	return idx.raw()
+}
+
+type index struct {
+	db      *dbMeta
+	modules modulesIndex
+}
+
+func newIndex() *index {
+	return &index{
+		db:      &dbMeta{},
+		modules: make(map[string]*moduleMeta),
+	}
+}
+
+func (i *index) add(entry *osv.Entry) {
+	// Add to db index.
+	if entry.Modified.After(i.db.Modified) {
+		i.db.Modified = entry.Modified
+	}
+	// Add to modules index.
+	for _, affected := range entry.Affected {
+		modulePath := affected.Module.Path
+		if _, ok := i.modules[modulePath]; !ok {
+			i.modules[modulePath] = &moduleMeta{
+				Path:  modulePath,
+				Vulns: []moduleVuln{},
+			}
+		}
+		module := i.modules[modulePath]
+		module.Vulns = append(module.Vulns, moduleVuln{
+			ID:       entry.ID,
+			Modified: entry.Modified,
+			Fixed:    isem.NonSupersededFix(affected.Ranges),
+		})
+	}
+}
+
+func (i *index) raw() (map[string][]byte, error) {
+	data := make(map[string][]byte)
+
+	b, err := json.Marshal(i.db)
+	if err != nil {
+		return nil, err
+	}
+	data[dbEndpoint] = b
+
+	b, err = json.Marshal(i.modules)
+	if err != nil {
+		return nil, err
+	}
+	data[modulesEndpoint] = b
+
+	return data, nil
+}
diff --git a/vendor/golang.org/x/vuln/internal/client/schema.go b/vendor/golang.org/x/vuln/internal/client/schema.go
new file mode 100644
index 0000000..0b84237
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/client/schema.go
@@ -0,0 +1,77 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package client
+
+import (
+	"encoding/json"
+	"path"
+	"sort"
+	"time"
+)
+
+const (
+	idDir    = "ID"
+	indexDir = "index"
+)
+
+var (
+	dbEndpoint      = path.Join(indexDir, "db")
+	modulesEndpoint = path.Join(indexDir, "modules")
+)
+
+func entryEndpoint(id string) string {
+	return path.Join(idDir, id)
+}
+
+// dbMeta contains metadata about the database itself.
+type dbMeta struct {
+	// Modified is the time the database was last modified, calculated
+	// as the most recent time any single OSV entry was modified.
+	Modified time.Time `json:"modified"`
+}
+
+// moduleMeta contains metadata about a Go module that has one
+// or more vulnerabilities in the database.
+//
+// Found in the "index/modules" endpoint of the vulnerability database.
+type moduleMeta struct {
+	// Path is the module path.
+	Path string `json:"path"`
+	// Vulns is a list of vulnerabilities that affect this module.
+	Vulns []moduleVuln `json:"vulns"`
+}
+
+// moduleVuln contains metadata about a vulnerability that affects
+// a certain module.
+type moduleVuln struct {
+	// ID is a unique identifier for the vulnerability.
+	// The Go vulnerability database issues IDs of the form
+	// GO--.
+	ID string `json:"id"`
+	// Modified is the time the vuln was last modified.
+	Modified time.Time `json:"modified"`
+	// Fixed is the latest version that introduces a fix for the
+	// vulnerability, in SemVer 2.0.0 format, with no leading "v" prefix.
+	Fixed string `json:"fixed,omitempty"`
+}
+
+// modulesIndex represents an in-memory modules index.
+type modulesIndex map[string]*moduleMeta
+
+func (m modulesIndex) MarshalJSON() ([]byte, error) {
+	modules := make([]*moduleMeta, 0, len(m))
+	for _, module := range m {
+		modules = append(modules, module)
+	}
+	sort.SliceStable(modules, func(i, j int) bool {
+		return modules[i].Path < modules[j].Path
+	})
+	for _, module := range modules {
+		sort.SliceStable(module.Vulns, func(i, j int) bool {
+			return module.Vulns[i].ID < module.Vulns[j].ID
+		})
+	}
+	return json.Marshal(modules)
+}
diff --git a/vendor/golang.org/x/vuln/internal/client/source.go b/vendor/golang.org/x/vuln/internal/client/source.go
new file mode 100644
index 0000000..2e848c3
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/client/source.go
@@ -0,0 +1,150 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package client
+
+import (
+	"compress/gzip"
+	"context"
+	"encoding/json"
+	"fmt"
+	"io"
+	"io/fs"
+	"net/http"
+	"os"
+	"path/filepath"
+
+	"golang.org/x/vuln/internal/derrors"
+	"golang.org/x/vuln/internal/osv"
+)
+
+type source interface {
+	// get returns the raw, uncompressed bytes at the
+	// requested endpoint, which should be bare with no file extensions
+	// (e.g., "index/modules" instead of "index/modules.json.gz").
+	// It errors if the endpoint cannot be reached or does not exist
+	// in the expected form.
+	get(ctx context.Context, endpoint string) ([]byte, error)
+}
+
+func newHTTPSource(url string, opts *Options) *httpSource {
+	c := http.DefaultClient
+	if opts != nil && opts.HTTPClient != nil {
+		c = opts.HTTPClient
+	}
+	return &httpSource{url: url, c: c}
+}
+
+// httpSource reads a vulnerability database from an http(s) source.
+type httpSource struct {
+	url string
+	c   *http.Client
+}
+
+func (hs *httpSource) get(ctx context.Context, endpoint string) (_ []byte, err error) {
+	derrors.Wrap(&err, "get(%s)", endpoint)
+
+	method := http.MethodGet
+	reqURL := fmt.Sprintf("%s/%s", hs.url, endpoint+".json.gz")
+	req, err := http.NewRequestWithContext(ctx, method, reqURL, nil)
+	if err != nil {
+		return nil, err
+	}
+	resp, err := hs.c.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	if resp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf("HTTP %s %s returned unexpected status: %s", method, reqURL, resp.Status)
+	}
+
+	// Uncompress the result.
+	r, err := gzip.NewReader(resp.Body)
+	if err != nil {
+		return nil, err
+	}
+	defer r.Close()
+
+	return io.ReadAll(r)
+}
+
+func newLocalSource(dir string) *localSource {
+	return &localSource{fs: os.DirFS(dir)}
+}
+
+// localSource reads a vulnerability database from a local file system.
+type localSource struct {
+	fs fs.FS
+}
+
+func (ls *localSource) get(ctx context.Context, endpoint string) (_ []byte, err error) {
+	derrors.Wrap(&err, "get(%s)", endpoint)
+
+	return fs.ReadFile(ls.fs, endpoint+".json")
+}
+
+func newHybridSource(dir string) (*hybridSource, error) {
+	index, err := indexFromDir(dir)
+	if err != nil {
+		return nil, err
+	}
+
+	return &hybridSource{
+		index: &inMemorySource{data: index},
+		osv:   &localSource{fs: os.DirFS(dir)},
+	}, nil
+}
+
+// hybridSource reads OSV entries from a local file system, but reads
+// indexes from an in-memory map.
+type hybridSource struct {
+	index *inMemorySource
+	osv   *localSource
+}
+
+func (hs *hybridSource) get(ctx context.Context, endpoint string) (_ []byte, err error) {
+	derrors.Wrap(&err, "get(%s)", endpoint)
+
+	dir, file := filepath.Split(endpoint)
+
+	if filepath.Dir(dir) == indexDir {
+		return hs.index.get(ctx, endpoint)
+	}
+
+	return hs.osv.get(ctx, file)
+}
+
+// newInMemorySource creates a new in-memory source from OSV entries.
+// Adapted from x/vulndb/internal/database.go.
+func newInMemorySource(entries []*osv.Entry) (*inMemorySource, error) {
+	data, err := indexFromEntries(entries)
+	if err != nil {
+		return nil, err
+	}
+
+	for _, entry := range entries {
+		b, err := json.Marshal(entry)
+		if err != nil {
+			return nil, err
+		}
+		data[entryEndpoint(entry.ID)] = b
+	}
+
+	return &inMemorySource{data: data}, nil
+}
+
+// inMemorySource reads databases from an in-memory map.
+// Currently intended for use only in unit tests.
+type inMemorySource struct {
+	data map[string][]byte
+}
+
+func (db *inMemorySource) get(ctx context.Context, endpoint string) ([]byte, error) {
+	b, ok := db.data[endpoint]
+	if !ok {
+		return nil, fmt.Errorf("no data found at endpoint %q", endpoint)
+	}
+	return b, nil
+}
diff --git a/vendor/golang.org/x/vuln/internal/derrors/derrors.go b/vendor/golang.org/x/vuln/internal/derrors/derrors.go
new file mode 100644
index 0000000..cc1259b
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/derrors/derrors.go
@@ -0,0 +1,23 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package derrors defines internal error values to categorize the different
+// types error semantics supported by x/vuln.
+package derrors
+
+import (
+	"fmt"
+)
+
+// Wrap adds context to the error and allows
+// unwrapping the result to recover the original error.
+//
+// Example:
+//
+//	defer derrors.Wrap(&err, "copy(%s, %s)", dst, src)
+func Wrap(errp *error, format string, args ...interface{}) {
+	if *errp != nil {
+		*errp = fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), *errp)
+	}
+}
diff --git a/vendor/golang.org/x/vuln/internal/gosym/README.md b/vendor/golang.org/x/vuln/internal/gosym/README.md
new file mode 100644
index 0000000..dacb83f
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/gosym/README.md
@@ -0,0 +1,11 @@
+This code is a copied and slightly modified version of go/src/debug/gosym.
+
+The original code contains logic for accessing symbol tables and line numbers
+in Go binaries. The only reason why this is copied is to support inlining.
+
+Code added by vulncheck is located in files with "additions_" prefix and it
+contains logic for accessing inlining information.
+
+Within the originally named files, deleted or added logic is annotated with
+a comment starting with "Addition:". The modified logic allows the inlining
+code in "additions_*" files to access the necessary information.
diff --git a/vendor/golang.org/x/vuln/internal/gosym/additions.go b/vendor/golang.org/x/vuln/internal/gosym/additions.go
new file mode 100644
index 0000000..022cf92
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/gosym/additions.go
@@ -0,0 +1,184 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gosym
+
+import (
+	"encoding/binary"
+	"io"
+	"strings"
+
+	sv "golang.org/x/mod/semver"
+	"golang.org/x/vuln/internal/semver"
+)
+
+const (
+	funcSymNameGo119Lower string = "go.func.*"
+	funcSymNameGo120      string = "go:func.*"
+)
+
+// FuncSymName returns symbol name for Go functions used in binaries
+// based on Go version. Supported Go versions are 1.18 and greater.
+// If the go version is unreadable it assumes that it is a newer version
+// and returns the symbol name for go version 1.20 or greater.
+func FuncSymName(goVersion string) string {
+	// Support devel goX.Y...
+	v := strings.TrimPrefix(goVersion, "devel ")
+	v = semver.GoTagToSemver(v)
+	mm := sv.MajorMinor(v)
+	if sv.Compare(mm, "v1.20") >= 0 || mm == "" {
+		return funcSymNameGo120
+	} else if sv.Compare(mm, "v1.18") >= 0 {
+		return funcSymNameGo119Lower
+	}
+	return ""
+}
+
+// Additions to the original package from cmd/internal/objabi/funcdata.go
+const (
+	pcdata_InlTreeIndex = 2
+	funcdata_InlTree    = 3
+)
+
+// InlineTree returns the inline tree for Func f as a sequence of InlinedCalls.
+// goFuncValue is the value of the gosym.FuncSymName symbol.
+// baseAddr is the address of the memory region (ELF Prog) containing goFuncValue.
+// progReader is a ReaderAt positioned at the start of that region.
+func (t *LineTable) InlineTree(f *Func, goFuncValue, baseAddr uint64, progReader io.ReaderAt) ([]InlinedCall, error) {
+	if f.inlineTreeCount == 0 {
+		return nil, nil
+	}
+	if f.inlineTreeOffset == ^uint32(0) {
+		return nil, nil
+	}
+	var offset int64
+	if t.version >= ver118 {
+		offset = int64(goFuncValue - baseAddr + uint64(f.inlineTreeOffset))
+	} else {
+		offset = int64(uint64(f.inlineTreeOffset) - baseAddr)
+	}
+
+	r := io.NewSectionReader(progReader, offset, 1<<32) // pick a size larger than we need
+	ics := make([]InlinedCall, 0, f.inlineTreeCount)
+	for i := 0; i < f.inlineTreeCount; i++ {
+		if t.version >= ver120 {
+			var ric rawInlinedCall120
+			if err := binary.Read(r, t.binary, &ric); err != nil {
+				return nil, err
+			}
+			ics = append(ics, InlinedCall{
+				FuncID:   ric.FuncID,
+				Name:     t.funcName(uint32(ric.NameOff)),
+				ParentPC: ric.ParentPC,
+			})
+		} else {
+			var ric rawInlinedCall112
+			if err := binary.Read(r, t.binary, &ric); err != nil {
+				return nil, err
+			}
+			ics = append(ics, InlinedCall{
+				FuncID:   ric.FuncID,
+				Name:     t.funcName(uint32(ric.Func_)),
+				ParentPC: ric.ParentPC,
+			})
+		}
+	}
+	return ics, nil
+}
+
+// InlinedCall describes a call to an inlined function.
+type InlinedCall struct {
+	FuncID   uint8  // type of the called function
+	Name     string // name of called function
+	ParentPC int32  // position of an instruction whose source position is the call site (offset from entry)
+}
+
+// rawInlinedCall112 is the encoding of entries in the FUNCDATA_InlTree table
+// from Go 1.12 through 1.19. It is equivalent to runtime.inlinedCall.
+type rawInlinedCall112 struct {
+	Parent   int16 // index of parent in the inltree, or < 0
+	FuncID   uint8 // type of the called function
+	_        byte
+	File     int32 // perCU file index for inlined call. See cmd/link:pcln.go
+	Line     int32 // line number of the call site
+	Func_    int32 // offset into pclntab for name of called function
+	ParentPC int32 // position of an instruction whose source position is the call site (offset from entry)
+}
+
+// rawInlinedCall120 is the encoding of entries in the FUNCDATA_InlTree table
+// from Go 1.20. It is equivalent to runtime.inlinedCall.
+type rawInlinedCall120 struct {
+	FuncID    uint8 // type of the called function
+	_         [3]byte
+	NameOff   int32 // offset into pclntab for name of called function
+	ParentPC  int32 // position of an instruction whose source position is the call site (offset from entry)
+	StartLine int32 // line number of start of function (func keyword/TEXT directive)
+}
+
+func (f funcData) npcdata() uint32 { return f.field(7) }
+func (f funcData) nfuncdata(numFuncFields uint32) uint32 {
+	return uint32(f.data[f.fieldOffset(numFuncFields-1)+3])
+}
+
+func (f funcData) funcdataOffset(i uint8, numFuncFields uint32) uint32 {
+	if uint32(i) >= f.nfuncdata(numFuncFields) {
+		return ^uint32(0)
+	}
+	var off uint32
+	if f.t.version >= ver118 {
+		off = f.fieldOffset(numFuncFields) + // skip fixed part of _func
+			f.npcdata()*4 + // skip pcdata
+			uint32(i)*4 // index of i'th FUNCDATA
+	} else {
+		off = f.fieldOffset(numFuncFields) + // skip fixed part of _func
+			f.npcdata()*4
+		off += uint32(i) * f.t.ptrsize
+	}
+	return f.t.binary.Uint32(f.data[off:])
+}
+
+func (f funcData) fieldOffset(n uint32) uint32 {
+	// In Go 1.18, the first field of _func changed
+	// from a uintptr entry PC to a uint32 entry offset.
+	sz0 := f.t.ptrsize
+	if f.t.version >= ver118 {
+		sz0 = 4
+	}
+	return sz0 + (n-1)*4 // subsequent fields are 4 bytes each
+}
+
+func (f funcData) pcdataOffset(i uint8, numFuncFields uint32) uint32 {
+	if uint32(i) >= f.npcdata() {
+		return ^uint32(0)
+	}
+	off := f.fieldOffset(numFuncFields) + // skip fixed part of _func
+		uint32(i)*4 // index of i'th PCDATA
+	return f.t.binary.Uint32(f.data[off:])
+}
+
+// maxInlineTreeIndexValue returns the maximum value of the inline tree index
+// pc-value table in info. This is the only way to determine how many
+// IndexedCalls are in an inline tree, since the data of the tree itself is not
+// delimited in any way.
+func (t *LineTable) maxInlineTreeIndexValue(info funcData, numFuncFields uint32) int {
+	if info.npcdata() <= pcdata_InlTreeIndex {
+		return -1
+	}
+	off := info.pcdataOffset(pcdata_InlTreeIndex, numFuncFields)
+	p := t.pctab[off:]
+	val := int32(-1)
+	max := int32(-1)
+	var pc uint64
+	for t.step(&p, &pc, &val, pc == 0) {
+		if val > max {
+			max = val
+		}
+	}
+	return int(max)
+}
+
+type inlTree struct {
+	inlineTreeOffset uint32 // offset from go.func.* symbol
+	inlineTreeCount  int    // number of entries in inline tree
+}
diff --git a/vendor/golang.org/x/vuln/internal/gosym/pclntab.go b/vendor/golang.org/x/vuln/internal/gosym/pclntab.go
new file mode 100644
index 0000000..5fa5e97
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/gosym/pclntab.go
@@ -0,0 +1,704 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * Line tables
+ */
+
+package gosym
+
+import (
+	"bytes"
+	"encoding/binary"
+	"sort"
+	"sync"
+)
+
+// version of the pclntab
+type version int
+
+const (
+	verUnknown version = iota
+	ver11
+	ver12
+	ver116
+	ver118
+	ver120
+)
+
+// A LineTable is a data structure mapping program counters to line numbers.
+//
+// In Go 1.1 and earlier, each function (represented by a Func) had its own LineTable,
+// and the line number corresponded to a numbering of all source lines in the
+// program, across all files. That absolute line number would then have to be
+// converted separately to a file name and line number within the file.
+//
+// In Go 1.2, the format of the data changed so that there is a single LineTable
+// for the entire program, shared by all Funcs, and there are no absolute line
+// numbers, just line numbers within specific files.
+//
+// For the most part, LineTable's methods should be treated as an internal
+// detail of the package; callers should use the methods on Table instead.
+type LineTable struct {
+	Data []byte
+	PC   uint64
+	Line int
+
+	// This mutex is used to keep parsing of pclntab synchronous.
+	mu sync.Mutex
+
+	// Contains the version of the pclntab section.
+	version version
+
+	// Go 1.2/1.16/1.18 state
+	binary      binary.ByteOrder
+	quantum     uint32
+	ptrsize     uint32
+	textStart   uint64 // address of runtime.text symbol (1.18+)
+	funcnametab []byte
+	cutab       []byte
+	funcdata    []byte
+	functab     []byte
+	nfunctab    uint32
+	filetab     []byte
+	pctab       []byte // points to the pctables.
+	nfiletab    uint32
+	funcNames   map[uint32]string // cache the function names
+	strings     map[uint32]string // interned substrings of Data, keyed by offset
+	// fileMap varies depending on the version of the object file.
+	// For ver12, it maps the name to the index in the file table.
+	// For ver116, it maps the name to the offset in filetab.
+	fileMap map[string]uint32
+}
+
+// NOTE(rsc): This is wrong for GOARCH=arm, which uses a quantum of 4,
+// but we have no idea whether we're using arm or not. This only
+// matters in the old (pre-Go 1.2) symbol table format, so it's not worth
+// fixing.
+const oldQuantum = 1
+
+func (t *LineTable) parse(targetPC uint64, targetLine int) (b []byte, pc uint64, line int) {
+	// The PC/line table can be thought of as a sequence of
+	//  * 
+	// batches. Each update batch results in a (pc, line) pair,
+	// where line applies to every PC from pc up to but not
+	// including the pc of the next pair.
+	//
+	// Here we process each update individually, which simplifies
+	// the code, but makes the corner cases more confusing.
+	b, pc, line = t.Data, t.PC, t.Line
+	for pc <= targetPC && line != targetLine && len(b) > 0 {
+		code := b[0]
+		b = b[1:]
+		switch {
+		case code == 0:
+			if len(b) < 4 {
+				b = b[0:0]
+				break
+			}
+			val := binary.BigEndian.Uint32(b)
+			b = b[4:]
+			line += int(val)
+		case code <= 64:
+			line += int(code)
+		case code <= 128:
+			line -= int(code - 64)
+		default:
+			pc += oldQuantum * uint64(code-128)
+			continue
+		}
+		pc += oldQuantum
+	}
+	return b, pc, line
+}
+
+func (t *LineTable) slice(pc uint64) *LineTable {
+	data, pc, line := t.parse(pc, -1)
+	return &LineTable{Data: data, PC: pc, Line: line}
+}
+
+// PCToLine returns the line number for the given program counter.
+//
+// Deprecated: Use Table's PCToLine method instead.
+func (t *LineTable) PCToLine(pc uint64) int {
+	if t.isGo12() {
+		return t.go12PCToLine(pc)
+	}
+	_, _, line := t.parse(pc, -1)
+	return line
+}
+
+// LineToPC returns the program counter for the given line number,
+// considering only program counters before maxpc.
+//
+// Deprecated: Use Table's LineToPC method instead.
+func (t *LineTable) LineToPC(line int, maxpc uint64) uint64 {
+	if t.isGo12() {
+		return 0
+	}
+	_, pc, line1 := t.parse(maxpc, line)
+	if line1 != line {
+		return 0
+	}
+	// Subtract quantum from PC to account for post-line increment
+	return pc - oldQuantum
+}
+
+// NewLineTable returns a new PC/line table
+// corresponding to the encoded data.
+// Text must be the start address of the
+// corresponding text segment.
+func NewLineTable(data []byte, text uint64) *LineTable {
+	return &LineTable{Data: data, PC: text, Line: 0, funcNames: make(map[uint32]string), strings: make(map[uint32]string)}
+}
+
+// Go 1.2 symbol table format.
+// See golang.org/s/go12symtab.
+//
+// A general note about the methods here: rather than try to avoid
+// index out of bounds errors, we trust Go to detect them, and then
+// we recover from the panics and treat them as indicative of a malformed
+// or incomplete table.
+//
+// The methods called by symtab.go, which begin with "go12" prefixes,
+// are expected to have that recovery logic.
+
+// isGo12 reports whether this is a Go 1.2 (or later) symbol table.
+func (t *LineTable) isGo12() bool {
+	t.parsePclnTab()
+	return t.version >= ver12
+}
+
+const (
+	go12magic  = 0xfffffffb
+	go116magic = 0xfffffffa
+	go118magic = 0xfffffff0
+	go120magic = 0xfffffff1
+)
+
+// uintptr returns the pointer-sized value encoded at b.
+// The pointer size is dictated by the table being read.
+func (t *LineTable) uintptr(b []byte) uint64 {
+	if t.ptrsize == 4 {
+		return uint64(t.binary.Uint32(b))
+	}
+	return t.binary.Uint64(b)
+}
+
+// parsePclnTab parses the pclntab, setting the version.
+func (t *LineTable) parsePclnTab() {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	if t.version != verUnknown {
+		return
+	}
+
+	// Note that during this function, setting the version is the last thing we do.
+	// If we set the version too early, and parsing failed (likely as a panic on
+	// slice lookups), we'd have a mistaken version.
+	//
+	// Error paths through this code will default the version to 1.1.
+	t.version = ver11
+
+	if !disableRecover {
+		defer func() {
+			// If we panic parsing, assume it's a Go 1.1 pclntab.
+			_ = recover()
+		}()
+	}
+
+	// Check header: 4-byte magic, two zeros, pc quantum, pointer size.
+	if len(t.Data) < 16 || t.Data[4] != 0 || t.Data[5] != 0 ||
+		(t.Data[6] != 1 && t.Data[6] != 2 && t.Data[6] != 4) || // pc quantum
+		(t.Data[7] != 4 && t.Data[7] != 8) { // pointer size
+		return
+	}
+
+	var possibleVersion version
+	leMagic := binary.LittleEndian.Uint32(t.Data)
+	beMagic := binary.BigEndian.Uint32(t.Data)
+	switch {
+	case leMagic == go12magic:
+		t.binary, possibleVersion = binary.LittleEndian, ver12
+	case beMagic == go12magic:
+		t.binary, possibleVersion = binary.BigEndian, ver12
+	case leMagic == go116magic:
+		t.binary, possibleVersion = binary.LittleEndian, ver116
+	case beMagic == go116magic:
+		t.binary, possibleVersion = binary.BigEndian, ver116
+	case leMagic == go118magic:
+		t.binary, possibleVersion = binary.LittleEndian, ver118
+	case beMagic == go118magic:
+		t.binary, possibleVersion = binary.BigEndian, ver118
+	case leMagic == go120magic:
+		t.binary, possibleVersion = binary.LittleEndian, ver120
+	case beMagic == go120magic:
+		t.binary, possibleVersion = binary.BigEndian, ver120
+	default:
+		return
+	}
+	t.version = possibleVersion
+
+	// quantum and ptrSize are the same between 1.2, 1.16, and 1.18
+	t.quantum = uint32(t.Data[6])
+	t.ptrsize = uint32(t.Data[7])
+
+	offset := func(word uint32) uint64 {
+		return t.uintptr(t.Data[8+word*t.ptrsize:])
+	}
+	data := func(word uint32) []byte {
+		return t.Data[offset(word):]
+	}
+
+	switch possibleVersion {
+	case ver118, ver120:
+		t.nfunctab = uint32(offset(0))
+		t.nfiletab = uint32(offset(1))
+		t.textStart = t.PC // use the start PC instead of reading from the table, which may be unrelocated
+		t.funcnametab = data(3)
+		t.cutab = data(4)
+		t.filetab = data(5)
+		t.pctab = data(6)
+		t.funcdata = data(7)
+		t.functab = data(7)
+		functabsize := (int(t.nfunctab)*2 + 1) * t.functabFieldSize()
+		t.functab = t.functab[:functabsize]
+	case ver116:
+		t.nfunctab = uint32(offset(0))
+		t.nfiletab = uint32(offset(1))
+		t.funcnametab = data(2)
+		t.cutab = data(3)
+		t.filetab = data(4)
+		t.pctab = data(5)
+		t.funcdata = data(6)
+		t.functab = data(6)
+		functabsize := (int(t.nfunctab)*2 + 1) * t.functabFieldSize()
+		t.functab = t.functab[:functabsize]
+	case ver12:
+		t.nfunctab = uint32(t.uintptr(t.Data[8:]))
+		t.funcdata = t.Data
+		t.funcnametab = t.Data
+		t.functab = t.Data[8+t.ptrsize:]
+		t.pctab = t.Data
+		functabsize := (int(t.nfunctab)*2 + 1) * t.functabFieldSize()
+		fileoff := t.binary.Uint32(t.functab[functabsize:])
+		t.functab = t.functab[:functabsize]
+		t.filetab = t.Data[fileoff:]
+		t.nfiletab = t.binary.Uint32(t.filetab)
+		t.filetab = t.filetab[:t.nfiletab*4]
+	default:
+		panic("unreachable")
+	}
+}
+
+// go12Funcs returns a slice of Funcs derived from the Go 1.2+ pcln table.
+func (t *LineTable) go12Funcs() []Func {
+	// Assume it is malformed and return nil on error.
+	if !disableRecover {
+		defer func() {
+			_ = recover()
+		}()
+	}
+
+	ft := t.funcTab()
+	funcs := make([]Func, ft.Count())
+	syms := make([]Sym, len(funcs))
+	for i := range funcs {
+		f := &funcs[i]
+		f.Entry = ft.pc(i)
+		f.End = ft.pc(i + 1)
+		info := t.funcData(uint32(i))
+		f.LineTable = t
+		f.FrameSize = int(info.deferreturn())
+
+		// Additions:
+		// numFuncField is the number of (32 bit) fields in _func (src/runtime/runtime2.go)
+		// Note that the last 4 fields are 32 bits combined. This number is 11 for go1.20,
+		// 10 for earlier versions down to go1.16, and 9 before that.
+		var numFuncFields uint32 = 11
+		if t.version < ver116 {
+			numFuncFields = 9
+		} else if t.version < ver120 {
+			numFuncFields = 10
+		}
+		f.inlineTreeOffset = info.funcdataOffset(funcdata_InlTree, numFuncFields)
+		f.inlineTreeCount = 1 + t.maxInlineTreeIndexValue(info, numFuncFields)
+
+		syms[i] = Sym{
+			Value:     f.Entry,
+			Type:      'T',
+			Name:      t.funcName(info.nameOff()),
+			GoType:    0,
+			Func:      f,
+			goVersion: t.version,
+		}
+		f.Sym = &syms[i]
+	}
+	return funcs
+}
+
+// findFunc returns the funcData corresponding to the given program counter.
+func (t *LineTable) findFunc(pc uint64) funcData {
+	ft := t.funcTab()
+	if pc < ft.pc(0) || pc >= ft.pc(ft.Count()) {
+		return funcData{}
+	}
+	idx := sort.Search(int(t.nfunctab), func(i int) bool {
+		return ft.pc(i) > pc
+	})
+	idx--
+	return t.funcData(uint32(idx))
+}
+
+// readvarint reads, removes, and returns a varint from *pp.
+func (t *LineTable) readvarint(pp *[]byte) uint32 {
+	var v, shift uint32
+	p := *pp
+	for shift = 0; ; shift += 7 {
+		b := p[0]
+		p = p[1:]
+		v |= (uint32(b) & 0x7F) << shift
+		if b&0x80 == 0 {
+			break
+		}
+	}
+	*pp = p
+	return v
+}
+
+// funcName returns the name of the function found at off.
+func (t *LineTable) funcName(off uint32) string {
+	if s, ok := t.funcNames[off]; ok {
+		return s
+	}
+	i := bytes.IndexByte(t.funcnametab[off:], 0)
+	s := string(t.funcnametab[off : off+uint32(i)])
+	t.funcNames[off] = s
+	return s
+}
+
+// stringFrom returns a Go string found at off from a position.
+func (t *LineTable) stringFrom(arr []byte, off uint32) string {
+	if s, ok := t.strings[off]; ok {
+		return s
+	}
+	i := bytes.IndexByte(arr[off:], 0)
+	s := string(arr[off : off+uint32(i)])
+	t.strings[off] = s
+	return s
+}
+
+// string returns a Go string found at off.
+func (t *LineTable) string(off uint32) string {
+	return t.stringFrom(t.funcdata, off)
+}
+
+// functabFieldSize returns the size in bytes of a single functab field.
+func (t *LineTable) functabFieldSize() int {
+	if t.version >= ver118 {
+		return 4
+	}
+	return int(t.ptrsize)
+}
+
+// funcTab returns t's funcTab.
+func (t *LineTable) funcTab() funcTab {
+	return funcTab{LineTable: t, sz: t.functabFieldSize()}
+}
+
+// funcTab is memory corresponding to a slice of functab structs, followed by an invalid PC.
+// A functab struct is a PC and a func offset.
+type funcTab struct {
+	*LineTable
+	sz int // cached result of t.functabFieldSize
+}
+
+// Count returns the number of func entries in f.
+func (f funcTab) Count() int {
+	return int(f.nfunctab)
+}
+
+// pc returns the PC of the i'th func in f.
+func (f funcTab) pc(i int) uint64 {
+	u := f.uint(f.functab[2*i*f.sz:])
+	if f.version >= ver118 {
+		u += f.textStart
+	}
+	return u
+}
+
+// funcOff returns the funcdata offset of the i'th func in f.
+func (f funcTab) funcOff(i int) uint64 {
+	return f.uint(f.functab[(2*i+1)*f.sz:])
+}
+
+// uint returns the uint stored at b.
+func (f funcTab) uint(b []byte) uint64 {
+	if f.sz == 4 {
+		return uint64(f.binary.Uint32(b))
+	}
+	return f.binary.Uint64(b)
+}
+
+// funcData is memory corresponding to an _func struct.
+type funcData struct {
+	t    *LineTable // LineTable this data is a part of
+	data []byte     // raw memory for the function
+}
+
+// funcData returns the ith funcData in t.functab.
+func (t *LineTable) funcData(i uint32) funcData {
+	data := t.funcdata[t.funcTab().funcOff(int(i)):]
+	return funcData{t: t, data: data}
+}
+
+// IsZero reports whether f is the zero value.
+func (f funcData) IsZero() bool {
+	return f.t == nil && f.data == nil
+}
+
+// entryPC returns the func's entry PC.
+func (f *funcData) entryPC() uint64 {
+	// In Go 1.18, the first field of _func changed
+	// from a uintptr entry PC to a uint32 entry offset.
+	if f.t.version >= ver118 {
+		// TODO: support multiple text sections.
+		// See runtime/symtab.go:(*moduledata).textAddr.
+		return uint64(f.t.binary.Uint32(f.data)) + f.t.textStart
+	}
+	return f.t.uintptr(f.data)
+}
+
+func (f funcData) nameOff() uint32     { return f.field(1) }
+func (f funcData) deferreturn() uint32 { return f.field(3) }
+func (f funcData) pcfile() uint32      { return f.field(5) }
+func (f funcData) pcln() uint32        { return f.field(6) }
+func (f funcData) cuOffset() uint32    { return f.field(8) }
+
+// field returns the nth field of the _func struct.
+// It panics if n == 0 or n > 9; for n == 0, call f.entryPC.
+// Most callers should use a named field accessor (just above).
+func (f funcData) field(n uint32) uint32 {
+	if n == 0 || n > 9 {
+		panic("bad funcdata field")
+	}
+	// Addition: some code deleted here to support inlining.
+	off := f.fieldOffset(n)
+	data := f.data[off:]
+	return f.t.binary.Uint32(data)
+}
+
+// step advances to the next pc, value pair in the encoded table.
+func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool {
+	uvdelta := t.readvarint(p)
+	if uvdelta == 0 && !first {
+		return false
+	}
+	if uvdelta&1 != 0 {
+		uvdelta = ^(uvdelta >> 1)
+	} else {
+		uvdelta >>= 1
+	}
+	vdelta := int32(uvdelta)
+	pcdelta := t.readvarint(p) * t.quantum
+	*pc += uint64(pcdelta)
+	*val += vdelta
+	return true
+}
+
+// pcvalue reports the value associated with the target pc.
+// off is the offset to the beginning of the pc-value table,
+// and entry is the start PC for the corresponding function.
+func (t *LineTable) pcvalue(off uint32, entry, targetpc uint64) int32 {
+	p := t.pctab[off:]
+
+	val := int32(-1)
+	pc := entry
+	for t.step(&p, &pc, &val, pc == entry) {
+		if targetpc < pc {
+			return val
+		}
+	}
+	return -1
+}
+
+// findFileLine scans one function in the binary looking for a
+// program counter in the given file on the given line.
+// It does so by running the pc-value tables mapping program counter
+// to file number. Since most functions come from a single file, these
+// are usually short and quick to scan. If a file match is found, then the
+// code goes to the expense of looking for a simultaneous line number match.
+func (t *LineTable) findFileLine(entry uint64, filetab, linetab uint32, filenum, line int32, cutab []byte) uint64 {
+	if filetab == 0 || linetab == 0 {
+		return 0
+	}
+
+	fp := t.pctab[filetab:]
+	fl := t.pctab[linetab:]
+	fileVal := int32(-1)
+	filePC := entry
+	lineVal := int32(-1)
+	linePC := entry
+	fileStartPC := filePC
+	for t.step(&fp, &filePC, &fileVal, filePC == entry) {
+		fileIndex := fileVal
+		if t.version == ver116 || t.version == ver118 || t.version == ver120 {
+			fileIndex = int32(t.binary.Uint32(cutab[fileVal*4:]))
+		}
+		if fileIndex == filenum && fileStartPC < filePC {
+			// fileIndex is in effect starting at fileStartPC up to
+			// but not including filePC, and it's the file we want.
+			// Run the PC table looking for a matching line number
+			// or until we reach filePC.
+			lineStartPC := linePC
+			for linePC < filePC && t.step(&fl, &linePC, &lineVal, linePC == entry) {
+				// lineVal is in effect until linePC, and lineStartPC < filePC.
+				if lineVal == line {
+					if fileStartPC <= lineStartPC {
+						return lineStartPC
+					}
+					if fileStartPC < linePC {
+						return fileStartPC
+					}
+				}
+				lineStartPC = linePC
+			}
+		}
+		fileStartPC = filePC
+	}
+	return 0
+}
+
+// go12PCToLine maps program counter to line number for the Go 1.2+ pcln table.
+func (t *LineTable) go12PCToLine(pc uint64) (line int) {
+	defer func() {
+		if !disableRecover && recover() != nil {
+			line = -1
+		}
+	}()
+
+	f := t.findFunc(pc)
+	if f.IsZero() {
+		return -1
+	}
+	entry := f.entryPC()
+	linetab := f.pcln()
+	return int(t.pcvalue(linetab, entry, pc))
+}
+
+// go12PCToFile maps program counter to file name for the Go 1.2+ pcln table.
+func (t *LineTable) go12PCToFile(pc uint64) (file string) {
+	defer func() {
+		if !disableRecover && recover() != nil {
+			file = ""
+		}
+	}()
+
+	f := t.findFunc(pc)
+	if f.IsZero() {
+		return ""
+	}
+	entry := f.entryPC()
+	filetab := f.pcfile()
+	fno := t.pcvalue(filetab, entry, pc)
+	if t.version == ver12 {
+		if fno <= 0 {
+			return ""
+		}
+		return t.string(t.binary.Uint32(t.filetab[4*fno:]))
+	}
+	// Go ≥ 1.16
+	if fno < 0 { // 0 is valid for ≥ 1.16
+		return ""
+	}
+	cuoff := f.cuOffset()
+	if fnoff := t.binary.Uint32(t.cutab[(cuoff+uint32(fno))*4:]); fnoff != ^uint32(0) {
+		return t.stringFrom(t.filetab, fnoff)
+	}
+	return ""
+}
+
+// go12LineToPC maps a (file, line) pair to a program counter for the Go 1.2+ pcln table.
+func (t *LineTable) go12LineToPC(file string, line int) (pc uint64) {
+	defer func() {
+		if !disableRecover && recover() != nil {
+			pc = 0
+		}
+	}()
+
+	t.initFileMap()
+	filenum, ok := t.fileMap[file]
+	if !ok {
+		return 0
+	}
+
+	// Scan all functions.
+	// If this turns out to be a bottleneck, we could build a map[int32][]int32
+	// mapping file number to a list of functions with code from that file.
+	var cutab []byte
+	for i := uint32(0); i < t.nfunctab; i++ {
+		f := t.funcData(i)
+		entry := f.entryPC()
+		filetab := f.pcfile()
+		linetab := f.pcln()
+		if t.version == ver116 || t.version == ver118 || t.version == ver120 {
+			if f.cuOffset() == ^uint32(0) {
+				// skip functions without compilation unit (not real function, or linker generated)
+				continue
+			}
+			cutab = t.cutab[f.cuOffset()*4:]
+		}
+		pc := t.findFileLine(entry, filetab, linetab, int32(filenum), int32(line), cutab)
+		if pc != 0 {
+			return pc
+		}
+	}
+	return 0
+}
+
+// initFileMap initializes the map from file name to file number.
+func (t *LineTable) initFileMap() {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+
+	if t.fileMap != nil {
+		return
+	}
+	m := make(map[string]uint32)
+
+	if t.version == ver12 {
+		for i := uint32(1); i < t.nfiletab; i++ {
+			s := t.string(t.binary.Uint32(t.filetab[4*i:]))
+			m[s] = i
+		}
+	} else {
+		var pos uint32
+		for i := uint32(0); i < t.nfiletab; i++ {
+			s := t.stringFrom(t.filetab, pos)
+			m[s] = pos
+			pos += uint32(len(s) + 1)
+		}
+	}
+	t.fileMap = m
+}
+
+// go12MapFiles adds to m a key for every file in the Go 1.2 LineTable.
+// Every key maps to obj. That's not a very interesting map, but it provides
+// a way for callers to obtain the list of files in the program.
+func (t *LineTable) go12MapFiles(m map[string]*Obj, obj *Obj) {
+	if !disableRecover {
+		defer func() {
+			_ = recover()
+		}()
+	}
+
+	t.initFileMap()
+	for file := range t.fileMap {
+		m[file] = obj
+	}
+}
+
+// disableRecover causes this package not to swallow panics.
+// This is useful when making changes.
+const disableRecover = true
diff --git a/vendor/golang.org/x/vuln/internal/gosym/symtab.go b/vendor/golang.org/x/vuln/internal/gosym/symtab.go
new file mode 100644
index 0000000..7f172ff
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/gosym/symtab.go
@@ -0,0 +1,776 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gosym implements access to the Go symbol
+// and line number tables embedded in Go binaries generated
+// by the gc compilers.
+package gosym
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+/*
+ * Symbols
+ */
+
+// A Sym represents a single symbol table entry.
+type Sym struct {
+	Value  uint64
+	Type   byte
+	Name   string
+	GoType uint64
+	// If this symbol is a function symbol, the corresponding Func
+	Func *Func
+
+	goVersion version
+}
+
+// Static reports whether this symbol is static (not visible outside its file).
+func (s *Sym) Static() bool { return s.Type >= 'a' }
+
+// nameWithoutInst returns s.Name if s.Name has no brackets (does not reference an
+// instantiated type, function, or method). If s.Name contains brackets, then it
+// returns s.Name with all the contents between (and including) the outermost left
+// and right bracket removed. This is useful to ignore any extra slashes or dots
+// inside the brackets from the string searches below, where needed.
+func (s *Sym) nameWithoutInst() string {
+	start := strings.Index(s.Name, "[")
+	if start < 0 {
+		return s.Name
+	}
+	end := strings.LastIndex(s.Name, "]")
+	if end < 0 {
+		// Malformed name, should contain closing bracket too.
+		return s.Name
+	}
+	return s.Name[0:start] + s.Name[end+1:]
+}
+
+// PackageName returns the package part of the symbol name,
+// or the empty string if there is none.
+func (s *Sym) PackageName() string {
+	name := s.nameWithoutInst()
+
+	// Since go1.20, a prefix of "type:" and "go:" is a compiler-generated symbol,
+	// they do not belong to any package.
+	//
+	// See cmd/compile/internal/base/link.go:ReservedImports variable.
+	if s.goVersion >= ver120 && (strings.HasPrefix(name, "go:") || strings.HasPrefix(name, "type:")) {
+		return ""
+	}
+
+	// For go1.18 and below, the prefix are "type." and "go." instead.
+	if s.goVersion <= ver118 && (strings.HasPrefix(name, "go.") || strings.HasPrefix(name, "type.")) {
+		return ""
+	}
+
+	pathend := strings.LastIndex(name, "/")
+	if pathend < 0 {
+		pathend = 0
+	}
+
+	if i := strings.Index(name[pathend:], "."); i != -1 {
+		return name[:pathend+i]
+	}
+	return ""
+}
+
+// ReceiverName returns the receiver type name of this symbol,
+// or the empty string if there is none.  A receiver name is only detected in
+// the case that s.Name is fully-specified with a package name.
+func (s *Sym) ReceiverName() string {
+	name := s.nameWithoutInst()
+	// If we find a slash in name, it should precede any bracketed expression
+	// that was removed, so pathend will apply correctly to name and s.Name.
+	pathend := strings.LastIndex(name, "/")
+	if pathend < 0 {
+		pathend = 0
+	}
+	// Find the first dot after pathend (or from the beginning, if there was
+	// no slash in name).
+	l := strings.Index(name[pathend:], ".")
+	// Find the last dot after pathend (or the beginning).
+	r := strings.LastIndex(name[pathend:], ".")
+	if l == -1 || r == -1 || l == r {
+		// There is no receiver if we didn't find two distinct dots after pathend.
+		return ""
+	}
+	// Given there is a trailing '.' that is in name, find it now in s.Name.
+	// pathend+l should apply to s.Name, because it should be the dot in the
+	// package name.
+	r = strings.LastIndex(s.Name[pathend:], ".")
+	return s.Name[pathend+l+1 : pathend+r]
+}
+
+// BaseName returns the symbol name without the package or receiver name.
+func (s *Sym) BaseName() string {
+	name := s.nameWithoutInst()
+	if i := strings.LastIndex(name, "."); i != -1 {
+		if s.Name != name {
+			brack := strings.Index(s.Name, "[")
+			if i > brack {
+				// BaseName is a method name after the brackets, so
+				// recalculate for s.Name. Otherwise, i applies
+				// correctly to s.Name, since it is before the
+				// brackets.
+				i = strings.LastIndex(s.Name, ".")
+			}
+		}
+		return s.Name[i+1:]
+	}
+	return s.Name
+}
+
+// A Func collects information about a single function.
+type Func struct {
+	Entry uint64
+	*Sym
+	End       uint64
+	Params    []*Sym // nil for Go 1.3 and later binaries
+	Locals    []*Sym // nil for Go 1.3 and later binaries
+	FrameSize int
+	LineTable *LineTable
+	Obj       *Obj
+	// Addition: extra data to support inlining.
+	inlTree
+}
+
+// An Obj represents a collection of functions in a symbol table.
+//
+// The exact method of division of a binary into separate Objs is an internal detail
+// of the symbol table format.
+//
+// In early versions of Go each source file became a different Obj.
+//
+// In Go 1 and Go 1.1, each package produced one Obj for all Go sources
+// and one Obj per C source file.
+//
+// In Go 1.2, there is a single Obj for the entire program.
+type Obj struct {
+	// Funcs is a list of functions in the Obj.
+	Funcs []Func
+
+	// In Go 1.1 and earlier, Paths is a list of symbols corresponding
+	// to the source file names that produced the Obj.
+	// In Go 1.2, Paths is nil.
+	// Use the keys of Table.Files to obtain a list of source files.
+	Paths []Sym // meta
+}
+
+/*
+ * Symbol tables
+ */
+
+// Table represents a Go symbol table. It stores all of the
+// symbols decoded from the program and provides methods to translate
+// between symbols, names, and addresses.
+type Table struct {
+	Syms  []Sym // nil for Go 1.3 and later binaries
+	Funcs []Func
+	Files map[string]*Obj // for Go 1.2 and later all files map to one Obj
+	Objs  []Obj           // for Go 1.2 and later only one Obj in slice
+
+	go12line *LineTable // Go 1.2 line number table
+}
+
+type sym struct {
+	value  uint64
+	gotype uint64
+	typ    byte
+	name   []byte
+}
+
+var (
+	littleEndianSymtab    = []byte{0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00}
+	bigEndianSymtab       = []byte{0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00}
+	oldLittleEndianSymtab = []byte{0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00}
+)
+
+func walksymtab(data []byte, fn func(sym) error) error {
+	if len(data) == 0 { // missing symtab is okay
+		return nil
+	}
+	var order binary.ByteOrder = binary.BigEndian
+	newTable := false
+	switch {
+	case bytes.HasPrefix(data, oldLittleEndianSymtab):
+		// Same as Go 1.0, but little endian.
+		// Format was used during interim development between Go 1.0 and Go 1.1.
+		// Should not be widespread, but easy to support.
+		data = data[6:]
+		order = binary.LittleEndian
+	case bytes.HasPrefix(data, bigEndianSymtab):
+		newTable = true
+	case bytes.HasPrefix(data, littleEndianSymtab):
+		newTable = true
+		order = binary.LittleEndian
+	}
+	var ptrsz int
+	if newTable {
+		if len(data) < 8 {
+			return &DecodingError{len(data), "unexpected EOF", nil}
+		}
+		ptrsz = int(data[7])
+		if ptrsz != 4 && ptrsz != 8 {
+			return &DecodingError{7, "invalid pointer size", ptrsz}
+		}
+		data = data[8:]
+	}
+	var s sym
+	p := data
+	for len(p) >= 4 {
+		var typ byte
+		if newTable {
+			// Symbol type, value, Go type.
+			typ = p[0] & 0x3F
+			wideValue := p[0]&0x40 != 0
+			goType := p[0]&0x80 != 0
+			if typ < 26 {
+				typ += 'A'
+			} else {
+				typ += 'a' - 26
+			}
+			s.typ = typ
+			p = p[1:]
+			if wideValue {
+				if len(p) < ptrsz {
+					return &DecodingError{len(data), "unexpected EOF", nil}
+				}
+				// fixed-width value
+				if ptrsz == 8 {
+					s.value = order.Uint64(p[0:8])
+					p = p[8:]
+				} else {
+					s.value = uint64(order.Uint32(p[0:4]))
+					p = p[4:]
+				}
+			} else {
+				// varint value
+				s.value = 0
+				shift := uint(0)
+				for len(p) > 0 && p[0]&0x80 != 0 {
+					s.value |= uint64(p[0]&0x7F) << shift
+					shift += 7
+					p = p[1:]
+				}
+				if len(p) == 0 {
+					return &DecodingError{len(data), "unexpected EOF", nil}
+				}
+				s.value |= uint64(p[0]) << shift
+				p = p[1:]
+			}
+			if goType {
+				if len(p) < ptrsz {
+					return &DecodingError{len(data), "unexpected EOF", nil}
+				}
+				// fixed-width go type
+				if ptrsz == 8 {
+					s.gotype = order.Uint64(p[0:8])
+					p = p[8:]
+				} else {
+					s.gotype = uint64(order.Uint32(p[0:4]))
+					p = p[4:]
+				}
+			}
+		} else {
+			// Value, symbol type.
+			s.value = uint64(order.Uint32(p[0:4]))
+			if len(p) < 5 {
+				return &DecodingError{len(data), "unexpected EOF", nil}
+			}
+			typ = p[4]
+			if typ&0x80 == 0 {
+				return &DecodingError{len(data) - len(p) + 4, "bad symbol type", typ}
+			}
+			typ &^= 0x80
+			s.typ = typ
+			p = p[5:]
+		}
+
+		// Name.
+		var i int
+		var nnul int
+		for i = 0; i < len(p); i++ {
+			if p[i] == 0 {
+				nnul = 1
+				break
+			}
+		}
+		switch typ {
+		case 'z', 'Z':
+			p = p[i+nnul:]
+			for i = 0; i+2 <= len(p); i += 2 {
+				if p[i] == 0 && p[i+1] == 0 {
+					nnul = 2
+					break
+				}
+			}
+		}
+		if len(p) < i+nnul {
+			return &DecodingError{len(data), "unexpected EOF", nil}
+		}
+		s.name = p[0:i]
+		i += nnul
+		p = p[i:]
+
+		if !newTable {
+			if len(p) < 4 {
+				return &DecodingError{len(data), "unexpected EOF", nil}
+			}
+			// Go type.
+			s.gotype = uint64(order.Uint32(p[:4]))
+			p = p[4:]
+		}
+		_ = fn(s)
+	}
+	return nil
+}
+
+// NewTable decodes the Go symbol table (the ".gosymtab" section in ELF),
+// returning an in-memory representation.
+// Starting with Go 1.3, the Go symbol table no longer includes symbol data.
+func NewTable(symtab []byte, pcln *LineTable) (*Table, error) {
+	var n int
+	err := walksymtab(symtab, func(s sym) error {
+		n++
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	var t Table
+	if pcln.isGo12() {
+		t.go12line = pcln
+	}
+	fname := make(map[uint16]string)
+	t.Syms = make([]Sym, 0, n)
+	nf := 0
+	nz := 0
+	lasttyp := uint8(0)
+	err = walksymtab(symtab, func(s sym) error {
+		n := len(t.Syms)
+		t.Syms = t.Syms[0 : n+1]
+		ts := &t.Syms[n]
+		ts.Type = s.typ
+		ts.Value = s.value
+		ts.GoType = s.gotype
+		ts.goVersion = pcln.version
+		switch s.typ {
+		default:
+			// rewrite name to use . instead of · (c2 b7)
+			w := 0
+			b := s.name
+			for i := 0; i < len(b); i++ {
+				if b[i] == 0xc2 && i+1 < len(b) && b[i+1] == 0xb7 {
+					i++
+					b[i] = '.'
+				}
+				b[w] = b[i]
+				w++
+			}
+			ts.Name = string(s.name[0:w])
+		case 'z', 'Z':
+			if lasttyp != 'z' && lasttyp != 'Z' {
+				nz++
+			}
+			for i := 0; i < len(s.name); i += 2 {
+				eltIdx := binary.BigEndian.Uint16(s.name[i : i+2])
+				elt, ok := fname[eltIdx]
+				if !ok {
+					return &DecodingError{-1, "bad filename code", eltIdx}
+				}
+				if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' {
+					ts.Name += "/"
+				}
+				ts.Name += elt
+			}
+		}
+		switch s.typ {
+		case 'T', 't', 'L', 'l':
+			nf++
+		case 'f':
+			fname[uint16(s.value)] = ts.Name
+		}
+		lasttyp = s.typ
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	t.Funcs = make([]Func, 0, nf)
+	t.Files = make(map[string]*Obj)
+
+	var obj *Obj
+	if t.go12line != nil {
+		// Put all functions into one Obj.
+		t.Objs = make([]Obj, 1)
+		obj = &t.Objs[0]
+		t.go12line.go12MapFiles(t.Files, obj)
+	} else {
+		t.Objs = make([]Obj, 0, nz)
+	}
+
+	// Count text symbols and attach frame sizes, parameters, and
+	// locals to them. Also, find object file boundaries.
+	lastf := 0
+	for i := 0; i < len(t.Syms); i++ {
+		sym := &t.Syms[i]
+		switch sym.Type {
+		case 'Z', 'z': // path symbol
+			if t.go12line != nil {
+				// Go 1.2 binaries have the file information elsewhere. Ignore.
+				break
+			}
+			// Finish the current object
+			if obj != nil {
+				obj.Funcs = t.Funcs[lastf:]
+			}
+			lastf = len(t.Funcs)
+
+			// Start new object
+			n := len(t.Objs)
+			t.Objs = t.Objs[0 : n+1]
+			obj = &t.Objs[n]
+
+			// Count & copy path symbols
+			var end int
+			for end = i + 1; end < len(t.Syms); end++ {
+				if c := t.Syms[end].Type; c != 'Z' && c != 'z' {
+					break
+				}
+			}
+			obj.Paths = t.Syms[i:end]
+			i = end - 1 // loop will i++
+
+			// Record file names
+			depth := 0
+			for j := range obj.Paths {
+				s := &obj.Paths[j]
+				if s.Name == "" {
+					depth--
+				} else {
+					if depth == 0 {
+						t.Files[s.Name] = obj
+					}
+					depth++
+				}
+			}
+
+		case 'T', 't', 'L', 'l': // text symbol
+			if n := len(t.Funcs); n > 0 {
+				t.Funcs[n-1].End = sym.Value
+			}
+			if sym.Name == "runtime.etext" || sym.Name == "etext" {
+				continue
+			}
+
+			// Count parameter and local (auto) syms
+			var np, na int
+			var end int
+		countloop:
+			for end = i + 1; end < len(t.Syms); end++ {
+				switch t.Syms[end].Type {
+				case 'T', 't', 'L', 'l', 'Z', 'z':
+					break countloop
+				case 'p':
+					np++
+				case 'a':
+					na++
+				}
+			}
+
+			// Fill in the function symbol
+			n := len(t.Funcs)
+			t.Funcs = t.Funcs[0 : n+1]
+			fn := &t.Funcs[n]
+			sym.Func = fn
+			fn.Params = make([]*Sym, 0, np)
+			fn.Locals = make([]*Sym, 0, na)
+			fn.Sym = sym
+			fn.Entry = sym.Value
+			fn.Obj = obj
+			if t.go12line != nil {
+				// All functions share the same line table.
+				// It knows how to narrow down to a specific
+				// function quickly.
+				fn.LineTable = t.go12line
+			} else if pcln != nil {
+				fn.LineTable = pcln.slice(fn.Entry)
+				pcln = fn.LineTable
+			}
+			for j := i; j < end; j++ {
+				s := &t.Syms[j]
+				switch s.Type {
+				case 'm':
+					fn.FrameSize = int(s.Value)
+				case 'p':
+					n := len(fn.Params)
+					fn.Params = fn.Params[0 : n+1]
+					fn.Params[n] = s
+				case 'a':
+					n := len(fn.Locals)
+					fn.Locals = fn.Locals[0 : n+1]
+					fn.Locals[n] = s
+				}
+			}
+			i = end - 1 // loop will i++
+		}
+	}
+
+	if t.go12line != nil && nf == 0 {
+		t.Funcs = t.go12line.go12Funcs()
+	}
+	if obj != nil {
+		obj.Funcs = t.Funcs[lastf:]
+	}
+	return &t, nil
+}
+
+// PCToFunc returns the function containing the program counter pc,
+// or nil if there is no such function.
+func (t *Table) PCToFunc(pc uint64) *Func {
+	funcs := t.Funcs
+	for len(funcs) > 0 {
+		m := len(funcs) / 2
+		fn := &funcs[m]
+		switch {
+		case pc < fn.Entry:
+			funcs = funcs[0:m]
+		case fn.Entry <= pc && pc < fn.End:
+			return fn
+		default:
+			funcs = funcs[m+1:]
+		}
+	}
+	return nil
+}
+
+// PCToLine looks up line number information for a program counter.
+// If there is no information, it returns fn == nil.
+func (t *Table) PCToLine(pc uint64) (file string, line int, fn *Func) {
+	if fn = t.PCToFunc(pc); fn == nil {
+		return
+	}
+	if t.go12line != nil {
+		file = t.go12line.go12PCToFile(pc)
+		line = t.go12line.go12PCToLine(pc)
+	} else {
+		file, line = fn.Obj.lineFromAline(fn.LineTable.PCToLine(pc))
+	}
+	return
+}
+
+// LineToPC looks up the first program counter on the given line in
+// the named file. It returns UnknownPathError or UnknownLineError if
+// there is an error looking up this line.
+func (t *Table) LineToPC(file string, line int) (pc uint64, fn *Func, err error) {
+	obj, ok := t.Files[file]
+	if !ok {
+		return 0, nil, UnknownFileError(file)
+	}
+
+	if t.go12line != nil {
+		pc := t.go12line.go12LineToPC(file, line)
+		if pc == 0 {
+			return 0, nil, &UnknownLineError{file, line}
+		}
+		return pc, t.PCToFunc(pc), nil
+	}
+
+	abs, err := obj.alineFromLine(file, line)
+	if err != nil {
+		return
+	}
+	for i := range obj.Funcs {
+		f := &obj.Funcs[i]
+		pc := f.LineTable.LineToPC(abs, f.End)
+		if pc != 0 {
+			return pc, f, nil
+		}
+	}
+	return 0, nil, &UnknownLineError{file, line}
+}
+
+// LookupSym returns the text, data, or bss symbol with the given name,
+// or nil if no such symbol is found.
+func (t *Table) LookupSym(name string) *Sym {
+	// TODO(austin) Maybe make a map
+	for i := range t.Syms {
+		s := &t.Syms[i]
+		switch s.Type {
+		case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b':
+			if s.Name == name {
+				return s
+			}
+		}
+	}
+	return nil
+}
+
+// LookupFunc returns the text, data, or bss symbol with the given name,
+// or nil if no such symbol is found.
+func (t *Table) LookupFunc(name string) *Func {
+	for i := range t.Funcs {
+		f := &t.Funcs[i]
+		if f.Sym.Name == name {
+			return f
+		}
+	}
+	return nil
+}
+
+// SymByAddr returns the text, data, or bss symbol starting at the given address.
+func (t *Table) SymByAddr(addr uint64) *Sym {
+	for i := range t.Syms {
+		s := &t.Syms[i]
+		switch s.Type {
+		case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b':
+			if s.Value == addr {
+				return s
+			}
+		}
+	}
+	return nil
+}
+
+/*
+ * Object files
+ */
+
+// This is legacy code for Go 1.1 and earlier, which used the
+// Plan 9 format for pc-line tables. This code was never quite
+// correct. It's probably very close, and it's usually correct, but
+// we never quite found all the corner cases.
+//
+// Go 1.2 and later use a simpler format, documented at golang.org/s/go12symtab.
+
+func (o *Obj) lineFromAline(aline int) (string, int) {
+	type stackEnt struct {
+		path   string
+		start  int
+		offset int
+		prev   *stackEnt
+	}
+
+	noPath := &stackEnt{"", 0, 0, nil}
+	tos := noPath
+
+pathloop:
+	for _, s := range o.Paths {
+		val := int(s.Value)
+		switch {
+		case val > aline:
+			break pathloop
+
+		case val == 1:
+			// Start a new stack
+			tos = &stackEnt{s.Name, val, 0, noPath}
+
+		case s.Name == "":
+			// Pop
+			if tos == noPath {
+				return "", 0
+			}
+			tos.prev.offset += val - tos.start
+			tos = tos.prev
+
+		default:
+			// Push
+			tos = &stackEnt{s.Name, val, 0, tos}
+		}
+	}
+
+	if tos == noPath {
+		return "", 0
+	}
+	return tos.path, aline - tos.start - tos.offset + 1
+}
+
+func (o *Obj) alineFromLine(path string, line int) (int, error) {
+	if line < 1 {
+		return 0, &UnknownLineError{path, line}
+	}
+
+	for i, s := range o.Paths {
+		// Find this path
+		if s.Name != path {
+			continue
+		}
+
+		// Find this line at this stack level
+		depth := 0
+		var incstart int
+		line += int(s.Value)
+	pathloop:
+		for _, s := range o.Paths[i:] {
+			val := int(s.Value)
+			switch {
+			case depth == 1 && val >= line:
+				return line - 1, nil
+
+			case s.Name == "":
+				depth--
+				if depth == 0 {
+					break pathloop
+				} else if depth == 1 {
+					line += val - incstart
+				}
+
+			default:
+				if depth == 1 {
+					incstart = val
+				}
+				depth++
+			}
+		}
+		return 0, &UnknownLineError{path, line}
+	}
+	return 0, UnknownFileError(path)
+}
+
+/*
+ * Errors
+ */
+
+// UnknownFileError represents a failure to find the specific file in
+// the symbol table.
+type UnknownFileError string
+
+func (e UnknownFileError) Error() string { return "unknown file: " + string(e) }
+
+// UnknownLineError represents a failure to map a line to a program
+// counter, either because the line is beyond the bounds of the file
+// or because there is no code on the given line.
+type UnknownLineError struct {
+	File string
+	Line int
+}
+
+func (e *UnknownLineError) Error() string {
+	return "no code at " + e.File + ":" + strconv.Itoa(e.Line)
+}
+
+// DecodingError represents an error during the decoding of
+// the symbol table.
+type DecodingError struct {
+	off int
+	msg string
+	val any
+}
+
+func (e *DecodingError) Error() string {
+	msg := e.msg
+	if e.val != nil {
+		msg += fmt.Sprintf(" '%v'", e.val)
+	}
+	msg += fmt.Sprintf(" at byte %#x", e.off)
+	return msg
+}
diff --git a/vendor/golang.org/x/vuln/internal/goversion/asm.go b/vendor/golang.org/x/vuln/internal/goversion/asm.go
new file mode 100644
index 0000000..1c165e6
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/goversion/asm.go
@@ -0,0 +1,349 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package goversion
+
+import (
+	"encoding/binary"
+	"fmt"
+	"os"
+)
+
+type matcher [][]uint32
+
+const (
+	pWild    uint32 = 0xff00
+	pAddr    uint32 = 0x10000
+	pEnd     uint32 = 0x20000
+	pRelAddr uint32 = 0x30000
+
+	opMaybe = 1 + iota
+	opMust
+	opDone
+	opAnchor = 0x100
+	opSub8   = 0x200
+	opFlags  = opAnchor | opSub8
+)
+
+var amd64Matcher = matcher{
+	{opMaybe | opAnchor,
+		// __rt0_amd64_darwin:
+		//	JMP __rt0_amd64
+		0xe9, pWild | pAddr, pWild, pWild, pWild | pEnd, 0xcc, 0xcc, 0xcc,
+	},
+	{opMaybe,
+		// _rt0_amd64_linux:
+		//	lea 0x8(%rsp), %rsi
+		//	mov (%rsp), %rdi
+		//	lea ADDR(%rip), %rax # main
+		//	jmpq *%rax
+		0x48, 0x8d, 0x74, 0x24, 0x08,
+		0x48, 0x8b, 0x3c, 0x24, 0x48,
+		0x8d, 0x05, pWild | pAddr, pWild, pWild, pWild | pEnd,
+		0xff, 0xe0,
+	},
+	{opMaybe,
+		// _rt0_amd64_linux:
+		//	lea 0x8(%rsp), %rsi
+		//	mov (%rsp), %rdi
+		//	mov $ADDR, %eax # main
+		//	jmpq *%rax
+		0x48, 0x8d, 0x74, 0x24, 0x08,
+		0x48, 0x8b, 0x3c, 0x24,
+		0xb8, pWild | pAddr, pWild, pWild, pWild,
+		0xff, 0xe0,
+	},
+	{opMaybe,
+		// __rt0_amd64:
+		//	mov (%rsp), %rdi
+		//	lea 8(%rsp), %rsi
+		//	jmp runtime.rt0_g0
+		0x48, 0x8b, 0x3c, 0x24,
+		0x48, 0x8d, 0x74, 0x24, 0x08,
+		0xe9, pWild | pAddr, pWild, pWild, pWild | pEnd,
+		0xcc, 0xcc,
+	},
+	{opMaybe,
+		// _start (toward end)
+		//	lea __libc_csu_fini(%rip), %r8
+		//	lea __libc_csu_init(%rip), %rcx
+		//	lea ADDR(%rip), %rdi # main
+		//	callq *xxx(%rip)
+		0x4c, 0x8d, 0x05, pWild, pWild, pWild, pWild,
+		0x48, 0x8d, 0x0d, pWild, pWild, pWild, pWild,
+		0x48, 0x8d, 0x3d, pWild | pAddr, pWild, pWild, pWild | pEnd,
+		0xff, 0x15,
+	},
+	{opMaybe,
+		// _start (toward end)
+		//	push %rsp (1)
+		//	mov $__libc_csu_fini, %r8 (7)
+		//	mov $__libc_csu_init, %rcx (7)
+		//	mov $ADDR, %rdi # main (7)
+		//	callq *xxx(%rip)
+		0x54,
+		0x49, 0xc7, 0xc0, pWild, pWild, pWild, pWild,
+		0x48, 0xc7, 0xc1, pWild, pWild, pWild, pWild,
+		0x48, 0xc7, 0xc7, pAddr | pWild, pWild, pWild, pWild,
+	},
+	{opMaybe | opAnchor,
+		// main:
+		//	lea ADDR(%rip), %rax # rt0_go
+		//	jmpq *%rax
+		0x48, 0x8d, 0x05, pWild | pAddr, pWild, pWild, pWild | pEnd,
+		0xff, 0xe0,
+	},
+	{opMaybe | opAnchor,
+		// main:
+		//	mov $ADDR, %eax
+		//	jmpq *%rax
+		0xb8, pWild | pAddr, pWild, pWild, pWild,
+		0xff, 0xe0,
+	},
+	{opMaybe | opAnchor,
+		// main:
+		//	JMP runtime.rt0_go(SB)
+		0xe9, pWild | pAddr, pWild, pWild, pWild | pEnd, 0xcc, 0xcc, 0xcc,
+	},
+	{opMust | opAnchor,
+		// rt0_go:
+		//	mov %rdi, %rax
+		//	mov %rsi, %rbx
+		//	sub %0x27, %rsp
+		//	and $0xfffffffffffffff0,%rsp
+		//	mov %rax,0x10(%rsp)
+		//	mov %rbx,0x18(%rsp)
+		0x48, 0x89, 0xf8,
+		0x48, 0x89, 0xf3,
+		0x48, 0x83, 0xec, 0x27,
+		0x48, 0x83, 0xe4, 0xf0,
+		0x48, 0x89, 0x44, 0x24, 0x10,
+		0x48, 0x89, 0x5c, 0x24, 0x18,
+	},
+	{opMust,
+		// later in rt0_go:
+		//	mov %eax, (%rsp)
+		//	mov 0x18(%rsp), %rax
+		//	mov %rax, 0x8(%rsp)
+		//	callq runtime.args
+		//	callq runtime.osinit
+		//	callq runtime.schedinit (ADDR)
+		0x89, 0x04, 0x24,
+		0x48, 0x8b, 0x44, 0x24, 0x18,
+		0x48, 0x89, 0x44, 0x24, 0x08,
+		0xe8, pWild, pWild, pWild, pWild,
+		0xe8, pWild, pWild, pWild, pWild,
+		0xe8, pWild, pWild, pWild, pWild,
+	},
+	{opMaybe,
+		// later in rt0_go:
+		//	mov %eax, (%rsp)
+		//	mov 0x18(%rsp), %rax
+		//	mov %rax, 0x8(%rsp)
+		//	callq runtime.args
+		//	callq runtime.osinit
+		//	callq runtime.schedinit (ADDR)
+		//	lea other(%rip), %rdi
+		0x89, 0x04, 0x24,
+		0x48, 0x8b, 0x44, 0x24, 0x18,
+		0x48, 0x89, 0x44, 0x24, 0x08,
+		0xe8, pWild, pWild, pWild, pWild,
+		0xe8, pWild, pWild, pWild, pWild,
+		0xe8, pWild | pAddr, pWild, pWild, pWild | pEnd,
+		0x48, 0x8d, 0x05,
+	},
+	{opMaybe,
+		// later in rt0_go:
+		//	mov %eax, (%rsp)
+		//	mov 0x18(%rsp), %rax
+		//	mov %rax, 0x8(%rsp)
+		//	callq runtime.args
+		//	callq runtime.osinit
+		//	callq runtime.hashinit
+		//	callq runtime.schedinit (ADDR)
+		//	pushq $main.main
+		0x89, 0x04, 0x24,
+		0x48, 0x8b, 0x44, 0x24, 0x18,
+		0x48, 0x89, 0x44, 0x24, 0x08,
+		0xe8, pWild, pWild, pWild, pWild,
+		0xe8, pWild, pWild, pWild, pWild,
+		0xe8, pWild, pWild, pWild, pWild,
+		0xe8, pWild | pAddr, pWild, pWild, pWild | pEnd,
+		0x68,
+	},
+	{opDone | opSub8,
+		// schedinit (toward end)
+		//	mov ADDR(%rip), %rax
+		//	test %rax, %rax
+		//	jne 
+		//	movq $0x7, ADDR(%rip)
+		//
+		0x48, 0x8b, 0x05, pWild, pWild, pWild, pWild,
+		0x48, 0x85, 0xc0,
+		0x75, pWild,
+		0x48, 0xc7, 0x05, pWild | pAddr, pWild, pWild, pWild, 0x07, 0x00, 0x00, 0x00 | pEnd,
+	},
+	{opDone | opSub8,
+		// schedinit (toward end)
+		//	mov ADDR(%rip), %rbx
+		//	cmp $0x0, %rbx
+		//	jne 
+		//	lea "unknown"(%rip), %rbx
+		//	mov %rbx, ADDR(%rip)
+		//	movq $7, (ADDR+8)(%rip)
+		0x48, 0x8b, 0x1d, pWild, pWild, pWild, pWild,
+		0x48, 0x83, 0xfb, 0x00,
+		0x75, pWild,
+		0x48, 0x8d, 0x1d, pWild, pWild, pWild, pWild,
+		0x48, 0x89, 0x1d, pWild, pWild, pWild, pWild,
+		0x48, 0xc7, 0x05, pWild | pAddr, pWild, pWild, pWild, 0x07, 0x00, 0x00, 0x00 | pEnd,
+	},
+	{opDone,
+		// schedinit (toward end)
+		//	cmpq $0x0, ADDR(%rip)
+		//	jne 
+		//	lea "unknown"(%rip), %rax
+		//	mov %rax, ADDR(%rip)
+		//	lea ADDR(%rip), %rax
+		//	movq $7, 8(%rax)
+		0x48, 0x83, 0x3d, pWild | pAddr, pWild, pWild, pWild, 0x00,
+		0x75, pWild,
+		0x48, 0x8d, 0x05, pWild, pWild, pWild, pWild,
+		0x48, 0x89, 0x05, pWild, pWild, pWild, pWild,
+		0x48, 0x8d, 0x05, pWild | pAddr, pWild, pWild, pWild | pEnd,
+		0x48, 0xc7, 0x40, 0x08, 0x07, 0x00, 0x00, 0x00,
+	},
+	{opDone,
+		// schedinit (toward end)
+		//	cmpq $0x0, ADDR(%rip)
+		//	jne 
+		//	movq $0x7, ADDR(%rip)
+		0x48, 0x83, 0x3d, pWild | pAddr, pWild, pWild, pWild, 0x00,
+		0x75, pWild,
+		0x48, 0xc7, 0x05 | pEnd, pWild | pAddr, pWild, pWild, pWild, 0x07, 0x00, 0x00, 0x00,
+	},
+	{opDone,
+		//	test %eax, %eax
+		//	jne 
+		//	lea "unknown"(RIP), %rax
+		//	mov %rax, ADDR(%rip)
+		0x48, 0x85, 0xc0, 0x75, pWild, 0x48, 0x8d, 0x05, pWild, pWild, pWild, pWild, 0x48, 0x89, 0x05, pWild | pAddr, pWild, pWild, pWild | pEnd,
+	},
+	{opDone,
+		// schedinit (toward end)
+		//	mov ADDR(%rip), %rcx
+		//	test %rcx, %rcx
+		//	jne 
+		//	movq $0x7, ADDR(%rip)
+		//
+		0x48, 0x8b, 0x0d, pWild, pWild, pWild, pWild,
+		0x48, 0x85, 0xc9,
+		0x75, pWild,
+		0x48, 0xc7, 0x05 | pEnd, pWild | pAddr, pWild, pWild, pWild, 0x07, 0x00, 0x00, 0x00,
+	},
+}
+
+var DebugMatch bool
+
+func (m matcher) match(f exe, addr uint64) (uint64, bool) {
+	data, err := f.ReadData(addr, 512)
+	if DebugMatch {
+		fmt.Fprintf(os.Stderr, "data @%#x: %x\n", addr, data[:16])
+	}
+	if err != nil {
+		if DebugMatch {
+			fmt.Fprintf(os.Stderr, "match: %v\n", err)
+		}
+		return 0, false
+	}
+	if DebugMatch {
+		fmt.Fprintf(os.Stderr, "data: %x\n", data[:32])
+	}
+Matchers:
+	for pc, p := range m {
+		op := p[0]
+		p = p[1:]
+	Search:
+		for i := 0; i <= len(data)-len(p); i++ {
+			a := -1
+			e := -1
+			if i > 0 && op&opAnchor != 0 {
+				break
+			}
+			for j := 0; j < len(p); j++ {
+				b := byte(p[j])
+				m := byte(p[j] >> 8)
+				if data[i+j]&^m != b {
+					continue Search
+				}
+				if p[j]&pAddr != 0 {
+					a = j
+				}
+				if p[j]&pEnd != 0 {
+					e = j + 1
+				}
+			}
+			// matched
+			if DebugMatch {
+				fmt.Fprintf(os.Stderr, "match (%d) %#x+%d %x %x\n", pc, addr, i, p, data[i:i+len(p)])
+			}
+			if a != -1 {
+				val := uint64(int32(binary.LittleEndian.Uint32(data[i+a:])))
+				if e == -1 {
+					addr = val
+				} else {
+					addr += uint64(i+e) + val
+				}
+				if op&opSub8 != 0 {
+					addr -= 8
+				}
+			}
+			if op&^opFlags == opDone {
+				if DebugMatch {
+					fmt.Fprintf(os.Stderr, "done %x\n", addr)
+				}
+				return addr, true
+			}
+			if a != -1 {
+				// changed addr, so reload
+				data, err = f.ReadData(addr, 512)
+				if err != nil {
+					return 0, false
+				}
+				if DebugMatch {
+					fmt.Fprintf(os.Stderr, "reload @%#x: %x\n", addr, data[:32])
+				}
+			}
+			continue Matchers
+		}
+		// not matched
+		if DebugMatch {
+			fmt.Fprintf(os.Stderr, "no match (%d) %#x %x %x\n", pc, addr, p, data[:32])
+		}
+		if op&^opFlags == opMust {
+			return 0, false
+		}
+	}
+	// ran off end of matcher
+	return 0, false
+}
+
+func readBuildVersionX86Asm(f exe) (isGo bool, buildVersion string) {
+	entry := f.Entry()
+	if entry == 0 {
+		if DebugMatch {
+			fmt.Fprintf(os.Stderr, "missing entry!\n")
+		}
+		return
+	}
+	addr, ok := amd64Matcher.match(f, entry)
+	if !ok {
+		return
+	}
+	v, err := readBuildVersion(f, addr, 16)
+	if err != nil {
+		return
+	}
+	return true, v
+}
diff --git a/vendor/golang.org/x/vuln/internal/goversion/exe.go b/vendor/golang.org/x/vuln/internal/goversion/exe.go
new file mode 100644
index 0000000..d833bfe
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/goversion/exe.go
@@ -0,0 +1,324 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package goversion
+
+import (
+	"bytes"
+	"debug/elf"
+	"debug/macho"
+	"debug/pe"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"os"
+)
+
+type sym struct {
+	Name string
+	Addr uint64
+	Size uint64
+}
+
+type exe interface {
+	AddrSize() int // bytes
+	ReadData(addr, size uint64) ([]byte, error)
+	Symbols() ([]sym, error)
+	SectionNames() []string
+	Close() error
+	ByteOrder() binary.ByteOrder
+	Entry() uint64
+	TextRange() (uint64, uint64)
+	RODataRange() (uint64, uint64)
+}
+
+func openExe(file string) (exe, error) {
+	f, err := os.Open(file)
+	if err != nil {
+		return nil, err
+	}
+	data := make([]byte, 16)
+	if _, err := io.ReadFull(f, data); err != nil {
+		return nil, err
+	}
+	f.Seek(0, 0)
+	if bytes.HasPrefix(data, []byte("\x7FELF")) {
+		e, err := elf.NewFile(f)
+		if err != nil {
+			f.Close()
+			return nil, err
+		}
+		return &elfExe{f, e}, nil
+	}
+	if bytes.HasPrefix(data, []byte("MZ")) {
+		e, err := pe.NewFile(f)
+		if err != nil {
+			f.Close()
+			return nil, err
+		}
+		return &peExe{f, e}, nil
+	}
+	if bytes.HasPrefix(data, []byte("\xFE\xED\xFA")) || bytes.HasPrefix(data[1:], []byte("\xFA\xED\xFE")) {
+		e, err := macho.NewFile(f)
+		if err != nil {
+			f.Close()
+			return nil, err
+		}
+		return &machoExe{f, e}, nil
+	}
+	return nil, fmt.Errorf("unrecognized executable format")
+}
+
+type elfExe struct {
+	os *os.File
+	f  *elf.File
+}
+
+func (x *elfExe) AddrSize() int { return 0 }
+
+func (x *elfExe) ByteOrder() binary.ByteOrder { return x.f.ByteOrder }
+
+func (x *elfExe) Close() error {
+	return x.os.Close()
+}
+
+func (x *elfExe) Entry() uint64 { return x.f.Entry }
+
+func (x *elfExe) ReadData(addr, size uint64) ([]byte, error) {
+	for _, prog := range x.f.Progs {
+		// The following line was commented from the original code.
+		//fmt.Printf("%#x %#x %#x\n", addr, prog.Vaddr, prog.Vaddr+prog.Filesz)
+		if prog.Vaddr <= addr && addr <= prog.Vaddr+prog.Filesz-1 {
+			n := prog.Vaddr + prog.Filesz - addr
+			if n > size {
+				n = size
+			}
+			data := make([]byte, n)
+			_, err := prog.ReadAt(data, int64(addr-prog.Vaddr))
+			if err != nil {
+				return nil, err
+			}
+			return data, nil
+		}
+	}
+	return nil, fmt.Errorf("address not mapped")
+}
+
+func (x *elfExe) Symbols() ([]sym, error) {
+	syms, err := x.f.Symbols()
+	if err != nil {
+		return nil, err
+	}
+	var out []sym
+	for _, s := range syms {
+		out = append(out, sym{s.Name, s.Value, s.Size})
+	}
+	return out, nil
+}
+
+func (x *elfExe) SectionNames() []string {
+	var names []string
+	for _, sect := range x.f.Sections {
+		names = append(names, sect.Name)
+	}
+	return names
+}
+
+func (x *elfExe) TextRange() (uint64, uint64) {
+	for _, p := range x.f.Progs {
+		if p.Type == elf.PT_LOAD && p.Flags&elf.PF_X != 0 {
+			return p.Vaddr, p.Vaddr + p.Filesz
+		}
+	}
+	return 0, 0
+}
+
+func (x *elfExe) RODataRange() (uint64, uint64) {
+	for _, p := range x.f.Progs {
+		if p.Type == elf.PT_LOAD && p.Flags&(elf.PF_R|elf.PF_W|elf.PF_X) == elf.PF_R {
+			return p.Vaddr, p.Vaddr + p.Filesz
+		}
+	}
+	for _, p := range x.f.Progs {
+		if p.Type == elf.PT_LOAD && p.Flags&(elf.PF_R|elf.PF_W|elf.PF_X) == (elf.PF_R|elf.PF_X) {
+			return p.Vaddr, p.Vaddr + p.Filesz
+		}
+	}
+	return 0, 0
+}
+
+type peExe struct {
+	os *os.File
+	f  *pe.File
+}
+
+func (x *peExe) imageBase() uint64 {
+	switch oh := x.f.OptionalHeader.(type) {
+	case *pe.OptionalHeader32:
+		return uint64(oh.ImageBase)
+	case *pe.OptionalHeader64:
+		return oh.ImageBase
+	}
+	return 0
+}
+
+func (x *peExe) AddrSize() int {
+	if x.f.Machine == pe.IMAGE_FILE_MACHINE_AMD64 {
+		return 8
+	}
+	return 4
+}
+
+func (x *peExe) ByteOrder() binary.ByteOrder { return binary.LittleEndian }
+
+func (x *peExe) Close() error {
+	return x.os.Close()
+}
+
+func (x *peExe) Entry() uint64 {
+	switch oh := x.f.OptionalHeader.(type) {
+	case *pe.OptionalHeader32:
+		return uint64(oh.ImageBase + oh.AddressOfEntryPoint)
+	case *pe.OptionalHeader64:
+		return oh.ImageBase + uint64(oh.AddressOfEntryPoint)
+	}
+	return 0
+}
+
+func (x *peExe) ReadData(addr, size uint64) ([]byte, error) {
+	addr -= x.imageBase()
+	data := make([]byte, size)
+	for _, sect := range x.f.Sections {
+		if uint64(sect.VirtualAddress) <= addr && addr+size-1 <= uint64(sect.VirtualAddress+sect.Size-1) {
+			_, err := sect.ReadAt(data, int64(addr-uint64(sect.VirtualAddress)))
+			if err != nil {
+				return nil, err
+			}
+			return data, nil
+		}
+	}
+	return nil, fmt.Errorf("address not mapped")
+}
+
+func (x *peExe) Symbols() ([]sym, error) {
+	base := x.imageBase()
+	var out []sym
+	for _, s := range x.f.Symbols {
+		if s.SectionNumber <= 0 || int(s.SectionNumber) > len(x.f.Sections) {
+			continue
+		}
+		sect := x.f.Sections[s.SectionNumber-1]
+		out = append(out, sym{s.Name, uint64(s.Value) + base + uint64(sect.VirtualAddress), 0})
+	}
+	return out, nil
+}
+
+func (x *peExe) SectionNames() []string {
+	var names []string
+	for _, sect := range x.f.Sections {
+		names = append(names, sect.Name)
+	}
+	return names
+}
+
+func (x *peExe) TextRange() (uint64, uint64) {
+	// Assume text is first non-empty section.
+	for _, sect := range x.f.Sections {
+		if sect.VirtualAddress != 0 && sect.Size != 0 {
+			return uint64(sect.VirtualAddress) + x.imageBase(), uint64(sect.VirtualAddress+sect.Size) + x.imageBase()
+		}
+	}
+	return 0, 0
+}
+
+func (x *peExe) RODataRange() (uint64, uint64) {
+	return x.TextRange()
+}
+
+type machoExe struct {
+	os *os.File
+	f  *macho.File
+}
+
+func (x *machoExe) AddrSize() int {
+	if x.f.Cpu&0x01000000 != 0 {
+		return 8
+	}
+	return 4
+}
+
+func (x *machoExe) ByteOrder() binary.ByteOrder { return x.f.ByteOrder }
+
+func (x *machoExe) Close() error {
+	return x.os.Close()
+}
+
+func (x *machoExe) Entry() uint64 {
+	for _, load := range x.f.Loads {
+		b, ok := load.(macho.LoadBytes)
+		if !ok {
+			continue
+		}
+		// TODO: Other thread states.
+		bo := x.f.ByteOrder
+		const x86_THREAD_STATE64 = 4
+		cmd, siz := macho.LoadCmd(bo.Uint32(b[0:4])), bo.Uint32(b[4:8])
+		if cmd == macho.LoadCmdUnixThread && siz == 184 && bo.Uint32(b[8:12]) == x86_THREAD_STATE64 {
+			return bo.Uint64(b[144:])
+		}
+	}
+	return 0
+}
+
+func (x *machoExe) ReadData(addr, size uint64) ([]byte, error) {
+	data := make([]byte, size)
+	for _, load := range x.f.Loads {
+		seg, ok := load.(*macho.Segment)
+		if !ok {
+			continue
+		}
+		if seg.Addr <= addr && addr+size-1 <= seg.Addr+seg.Filesz-1 {
+			if seg.Name == "__PAGEZERO" {
+				continue
+			}
+			_, err := seg.ReadAt(data, int64(addr-seg.Addr))
+			if err != nil {
+				return nil, err
+			}
+			return data, nil
+		}
+	}
+	return nil, fmt.Errorf("address not mapped")
+}
+
+func (x *machoExe) Symbols() ([]sym, error) {
+	var out []sym
+	for _, s := range x.f.Symtab.Syms {
+		out = append(out, sym{s.Name, s.Value, 0})
+	}
+	return out, nil
+}
+
+func (x *machoExe) SectionNames() []string {
+	var names []string
+	for _, sect := range x.f.Sections {
+		names = append(names, sect.Name)
+	}
+	return names
+}
+
+func (x *machoExe) TextRange() (uint64, uint64) {
+	// Assume text is first non-empty segment.
+	for _, load := range x.f.Loads {
+		seg, ok := load.(*macho.Segment)
+		if ok && seg.Name != "__PAGEZERO" && seg.Addr != 0 && seg.Filesz != 0 {
+			return seg.Addr, seg.Addr + seg.Filesz
+		}
+	}
+	return 0, 0
+}
+
+func (x *machoExe) RODataRange() (uint64, uint64) {
+	return x.TextRange()
+}
diff --git a/vendor/golang.org/x/vuln/internal/goversion/read.go b/vendor/golang.org/x/vuln/internal/goversion/read.go
new file mode 100644
index 0000000..f298ef0
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/goversion/read.go
@@ -0,0 +1,246 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package goversion reports the Go version used to build program executables.
+//
+// This is a copy of rsc.io/goversion/version. We renamed the package to goversion
+// to differentiate between version package in standard library that we also use.
+package goversion
+
+import (
+	"bytes"
+	"encoding/hex"
+	"errors"
+	"fmt"
+	"regexp"
+	"strings"
+)
+
+// Version is the information reported by ReadExe.
+type Version struct {
+	Release        string // Go version (runtime.Version in the program)
+	ModuleInfo     string // program's module information
+	BoringCrypto   bool   // program uses BoringCrypto
+	StandardCrypto bool   // program uses standard crypto (replaced by BoringCrypto)
+	FIPSOnly       bool   // program imports "crypto/tls/fipsonly"
+}
+
+// ReadExe reports information about the Go version used to build
+// the program executable named by file.
+func ReadExe(file string) (Version, error) {
+	var v Version
+	f, err := openExe(file)
+	if err != nil {
+		return v, err
+	}
+	defer f.Close()
+	isGo := false
+	for _, name := range f.SectionNames() {
+		if name == ".note.go.buildid" {
+			isGo = true
+		}
+	}
+	syms, symsErr := f.Symbols()
+	isGccgo := false
+	for _, sym := range syms {
+		name := sym.Name
+		if name == "runtime.main" || name == "main.main" {
+			isGo = true
+		}
+		if strings.HasPrefix(name, "runtime.") && strings.HasSuffix(name, "$descriptor") {
+			isGccgo = true
+		}
+		if name == "runtime.buildVersion" {
+			isGo = true
+			release, err := readBuildVersion(f, sym.Addr, sym.Size)
+			if err != nil {
+				return v, err
+			}
+			v.Release = release
+		}
+		// Note: Using strings.HasPrefix because Go 1.17+ adds ".abi0" to many of these symbols.
+		if strings.Contains(name, "_Cfunc__goboringcrypto_") || strings.HasPrefix(name, "crypto/internal/boring/sig.BoringCrypto") {
+			v.BoringCrypto = true
+		}
+		if strings.HasPrefix(name, "crypto/internal/boring/sig.FIPSOnly") {
+			v.FIPSOnly = true
+		}
+		for _, re := range standardCryptoNames {
+			if re.MatchString(name) {
+				v.StandardCrypto = true
+			}
+		}
+		if strings.HasPrefix(name, "crypto/internal/boring/sig.StandardCrypto") {
+			v.StandardCrypto = true
+		}
+	}
+
+	if DebugMatch {
+		v.Release = ""
+	}
+	if err := findModuleInfo(&v, f); err != nil {
+		return v, err
+	}
+	if v.Release == "" {
+		g, release := readBuildVersionX86Asm(f)
+		if g {
+			isGo = true
+			v.Release = release
+			if err := findCryptoSigs(&v, f); err != nil {
+				return v, err
+			}
+		}
+	}
+	if isGccgo && v.Release == "" {
+		isGo = true
+		v.Release = "gccgo (version unknown)"
+	}
+	if !isGo && symsErr != nil {
+		return v, symsErr
+	}
+
+	if !isGo {
+		return v, errors.New("not a Go executable")
+	}
+	if v.Release == "" {
+		v.Release = "unknown Go version"
+	}
+	return v, nil
+}
+
+var re = regexp.MustCompile
+
+var standardCryptoNames = []*regexp.Regexp{
+	re(`^crypto/sha1\.\(\*digest\)`),
+	re(`^crypto/sha256\.\(\*digest\)`),
+	re(`^crypto/rand\.\(\*devReader\)`),
+	re(`^crypto/rsa\.encrypt(\.abi.)?$`),
+	re(`^crypto/rsa\.decrypt(\.abi.)?$`),
+}
+
+func readBuildVersion(f exe, addr, size uint64) (string, error) {
+	if size == 0 {
+		size = uint64(f.AddrSize() * 2)
+	}
+	if size != 8 && size != 16 {
+		return "", fmt.Errorf("invalid size for runtime.buildVersion")
+	}
+	data, err := f.ReadData(addr, size)
+	if err != nil {
+		return "", fmt.Errorf("reading runtime.buildVersion: %v", err)
+	}
+
+	if size == 8 {
+		addr = uint64(f.ByteOrder().Uint32(data))
+		size = uint64(f.ByteOrder().Uint32(data[4:]))
+	} else {
+		addr = f.ByteOrder().Uint64(data)
+		size = f.ByteOrder().Uint64(data[8:])
+	}
+	if size > 1000 {
+		return "", fmt.Errorf("implausible string size %d for runtime.buildVersion", size)
+	}
+
+	data, err = f.ReadData(addr, size)
+	if err != nil {
+		return "", fmt.Errorf("reading runtime.buildVersion string data: %v", err)
+	}
+	return string(data), nil
+}
+
+// Code signatures that indicate BoringCrypto or crypto/internal/fipsonly.
+// These are not byte literals in order to avoid the actual
+// byte signatures appearing in the goversion binary,
+// because on some systems you can't tell rodata from text.
+var (
+	sigBoringCrypto, _   = hex.DecodeString("EB1DF448F44BF4B332F52813A3B450D441CC2485F001454E92101B1D2F1950C3")
+	sigStandardCrypto, _ = hex.DecodeString("EB1DF448F44BF4BAEE4DFA9851CA56A91145E83E99C59CF911CB8E80DAF12FC3")
+	sigFIPSOnly, _       = hex.DecodeString("EB1DF448F44BF4363CB9CE9D68047D31F28D325D5CA5873F5D80CAF6D6151BC3")
+)
+
+func findCryptoSigs(v *Version, f exe) error {
+	const maxSigLen = 1 << 10
+	start, end := f.TextRange()
+	for addr := start; addr < end; {
+		size := uint64(1 << 20)
+		if end-addr < size {
+			size = end - addr
+		}
+		data, err := f.ReadData(addr, size)
+		if err != nil {
+			return fmt.Errorf("reading text: %v", err)
+		}
+		if haveSig(data, sigBoringCrypto) {
+			v.BoringCrypto = true
+		}
+		if haveSig(data, sigFIPSOnly) {
+			v.FIPSOnly = true
+		}
+		if haveSig(data, sigStandardCrypto) {
+			v.StandardCrypto = true
+		}
+		if addr+size < end {
+			size -= maxSigLen
+		}
+		addr += size
+	}
+	return nil
+}
+
+func haveSig(data, sig []byte) bool {
+	const align = 16
+	for {
+		i := bytes.Index(data, sig)
+		if i < 0 {
+			return false
+		}
+		if i&(align-1) == 0 {
+			return true
+		}
+		// Found unaligned match; unexpected but
+		// skip to next aligned boundary and keep searching.
+		data = data[(i+align-1)&^(align-1):]
+	}
+}
+
+func findModuleInfo(v *Version, f exe) error {
+	const maxModInfo = 128 << 10
+	start, end := f.RODataRange()
+	for addr := start; addr < end; {
+		size := uint64(4 << 20)
+		if end-addr < size {
+			size = end - addr
+		}
+		data, err := f.ReadData(addr, size)
+		if err != nil {
+			return fmt.Errorf("reading text: %v", err)
+		}
+		if haveModuleInfo(data, v) {
+			return nil
+		}
+		if addr+size < end {
+			size -= maxModInfo
+		}
+		addr += size
+	}
+	return nil
+}
+
+var (
+	infoStart, _ = hex.DecodeString("3077af0c9274080241e1c107e6d618e6")
+	infoEnd, _   = hex.DecodeString("f932433186182072008242104116d8f2")
+)
+
+func haveModuleInfo(data []byte, v *Version) bool {
+	i := bytes.Index(data, infoStart)
+	if i < 0 {
+		return false
+	}
+	j := bytes.Index(data[i:], infoEnd)
+	if j < 0 {
+		return false
+	}
+	v.ModuleInfo = string(data[i+len(infoStart) : i+j])
+	return true
+}
diff --git a/vendor/golang.org/x/vuln/internal/govulncheck/govulncheck.go b/vendor/golang.org/x/vuln/internal/govulncheck/govulncheck.go
new file mode 100644
index 0000000..377a378
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/govulncheck/govulncheck.go
@@ -0,0 +1,241 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package govulncheck contains the JSON output structs for govulncheck.
+//
+// govulncheck supports streaming JSON by emitting a series of Message
+// objects as it analyzes user code and discovers vulnerabilities.
+// Streaming JSON is useful for displaying progress in real-time for
+// large projects where govulncheck execution might take some time.
+//
+// govulncheck JSON emits configuration used to perform the analysis,
+// a user-friendly message about what is being analyzed, and the
+// vulnerability findings. Findings for the same vulnerability can
+// can be emitted several times. For instance, govulncheck JSON will
+// emit a finding when it sees that a vulnerable module is required
+// before proceeding to check if the vulnerability is imported or called.
+// Please see documentation on Message and related types for precise
+// details on the stream encoding.
+//
+// There are no guarantees on the order of messages. The pattern of emitted
+// messages can change in the future. Clients can follow code in handler.go
+// for consuming the streaming JSON programmatically.
+package govulncheck
+
+import (
+	"time"
+
+	"golang.org/x/vuln/internal/osv"
+)
+
+const (
+	// ProtocolVersion is the current protocol version this file implements
+	ProtocolVersion = "v1.0.0"
+)
+
+// Message is an entry in the output stream. It will always have exactly one
+// field filled in.
+type Message struct {
+	Config   *Config   `json:"config,omitempty"`
+	Progress *Progress `json:"progress,omitempty"`
+	SBOM     *SBOM     `json:"SBOM,omitempty"`
+	// OSV is emitted for every vulnerability in the current database
+	// that applies to user modules regardless of their version. If a
+	// module is being used at a vulnerable version, the corresponding
+	// OSV will be referenced in Findings depending on the type of usage
+	// and the desired scan level.
+	OSV     *osv.Entry `json:"osv,omitempty"`
+	Finding *Finding   `json:"finding,omitempty"`
+}
+
+// Config must occur as the first message of a stream and informs the client
+// about the information used to generate the findings.
+// The only required field is the protocol version.
+type Config struct {
+	// ProtocolVersion specifies the version of the JSON protocol.
+	ProtocolVersion string `json:"protocol_version"`
+
+	// ScannerName is the name of the tool, for example, govulncheck.
+	//
+	// We expect this JSON format to be used by other tools that wrap
+	// govulncheck, which will have a different name.
+	ScannerName string `json:"scanner_name,omitempty"`
+
+	// ScannerVersion is the version of the tool.
+	ScannerVersion string `json:"scanner_version,omitempty"`
+
+	// DB is the database used by the tool, for example,
+	// vuln.go.dev.
+	DB string `json:"db,omitempty"`
+
+	// LastModified is the last modified time of the data source.
+	DBLastModified *time.Time `json:"db_last_modified,omitempty"`
+
+	// GoVersion is the version of Go used for analyzing standard library
+	// vulnerabilities.
+	GoVersion string `json:"go_version,omitempty"`
+
+	// ScanLevel instructs govulncheck to analyze at a specific level of detail.
+	// Valid values include module, package and symbol.
+	ScanLevel ScanLevel `json:"scan_level,omitempty"`
+
+	// ScanMode instructs govulncheck how to interpret the input and
+	// what to do with it. Valid values are source, binary, query,
+	// and extract.
+	ScanMode ScanMode `json:"scan_mode,omitempty"`
+}
+
+// SBOM contains minimal information about the artifacts govulncheck is scanning.
+type SBOM struct {
+	// The go version used by govulncheck when scanning, which also defines
+	// the version of the standard library used for detecting vulns.
+	GoVersion string `json:"go_version,omitempty"`
+
+	// The set of modules included in the scan.
+	Modules []*Module `json:"modules,omitempty"`
+
+	// The roots of the scan, as package paths.
+	// For binaries, this will be the main package.
+	// For source code, this will be the packages matching the provided package patterns.
+	Roots []string `json:"roots,omitempty"`
+}
+
+type Module struct {
+	// The full module path.
+	Path string `json:"path,omitempty"`
+
+	// The version of the module.
+	Version string `json:"version,omitempty"`
+}
+
+// Progress messages are informational only, intended to allow users to monitor
+// the progress of a long running scan.
+// A stream must remain fully valid and able to be interpreted with all progress
+// messages removed.
+type Progress struct {
+	// A time stamp for the message.
+	Timestamp *time.Time `json:"time,omitempty"`
+
+	// Message is the progress message.
+	Message string `json:"message,omitempty"`
+}
+
+// Finding contains information on a discovered vulnerability. Each vulnerability
+// will likely have multiple findings in JSON mode. This is because govulncheck
+// emits findings as it does work, and therefore could emit one module level,
+// one package level, and potentially multiple symbol level findings depending
+// on scan level.
+// Multiple symbol level findings can be emitted when multiple symbols of the
+// same vuln are called or govulncheck decides to show multiple traces for the
+// same symbol.
+type Finding struct {
+	// OSV is the id of the detected vulnerability.
+	OSV string `json:"osv,omitempty"`
+
+	// FixedVersion is the module version where the vulnerability was
+	// fixed. This is empty if a fix is not available.
+	//
+	// If there are multiple fixed versions in the OSV report, this will
+	// be the fixed version in the latest range event for the OSV report.
+	//
+	// For example, if the range events are
+	// {introduced: 0, fixed: 1.0.0} and {introduced: 1.1.0}, the fixed version
+	// will be empty.
+	//
+	// For the stdlib, we will show the fixed version closest to the
+	// Go version that is used. For example, if a fix is available in 1.17.5 and
+	// 1.18.5, and the GOVERSION is 1.17.3, 1.17.5 will be returned as the
+	// fixed version.
+	FixedVersion string `json:"fixed_version,omitempty"`
+
+	// Trace contains an entry for each frame in the trace.
+	//
+	// Frames are sorted starting from the imported vulnerable symbol
+	// until the entry point. The first frame in Frames should match
+	// Symbol.
+	//
+	// In binary mode, trace will contain a single-frame with no position
+	// information.
+	//
+	// For module level source findings, the trace will contain a single-frame
+	// with no symbol, position, or package information. For package level source
+	// findings, the trace will contain a single-frame with no symbol or position
+	// information.
+	Trace []*Frame `json:"trace,omitempty"`
+}
+
+// Frame represents an entry in a finding trace.
+type Frame struct {
+	// Module is the module path of the module containing this symbol.
+	//
+	// Importable packages in the standard library will have the path "stdlib".
+	Module string `json:"module"`
+
+	// Version is the module version from the build graph.
+	Version string `json:"version,omitempty"`
+
+	// Package is the import path.
+	Package string `json:"package,omitempty"`
+
+	// Function is the function name.
+	Function string `json:"function,omitempty"`
+
+	// Receiver is the receiver type if the called symbol is a method.
+	//
+	// The client can create the final symbol name by
+	// prepending Receiver to FuncName.
+	Receiver string `json:"receiver,omitempty"`
+
+	// Position describes an arbitrary source position
+	// including the file, line, and column location.
+	// A Position is valid if the line number is > 0.
+	//
+	// The filenames are relative to the directory of
+	// the enclosing module and always use "/" for
+	// portability.
+	Position *Position `json:"position,omitempty"`
+}
+
+// Position represents arbitrary source position.
+type Position struct {
+	Filename string `json:"filename,omitempty"` // filename, if any
+	Offset   int    `json:"offset"`             // byte offset, starting at 0
+	Line     int    `json:"line"`               // line number, starting at 1
+	Column   int    `json:"column"`             // column number, starting at 1 (byte count)
+}
+
+// ScanLevel represents the detail level at which a scan occurred.
+// This can be necessary to correctly interpret the findings, for instance if
+// a scan is at symbol level and a finding does not have a symbol it means the
+// vulnerability was imported but not called. If the scan however was at
+// "package" level, that determination cannot be made.
+type ScanLevel string
+
+const (
+	ScanLevelModule  = "module"
+	ScanLevelPackage = "package"
+	ScanLevelSymbol  = "symbol"
+)
+
+// WantSymbols can be used to check whether the scan level is one that is able
+// to generate symbol-level findings.
+func (l ScanLevel) WantSymbols() bool { return l == ScanLevelSymbol }
+
+// WantPackages can be used to check whether the scan level is one that is able
+// to generate package-level findings.
+func (l ScanLevel) WantPackages() bool { return l == ScanLevelPackage || l == ScanLevelSymbol }
+
+// ScanMode represents the mode in which a scan occurred. This can
+// be necessary to correctly to interpret findings. For instance,
+// a binary can be checked for vulnerabilities or the user just wants
+// to extract minimal data necessary for the vulnerability check.
+type ScanMode string
+
+const (
+	ScanModeSource  = "source"
+	ScanModeBinary  = "binary"
+	ScanModeConvert = "convert"
+	ScanModeQuery   = "query"
+	ScanModeExtract = "extract" // currently, only binary extraction is supported
+)
diff --git a/vendor/golang.org/x/vuln/internal/govulncheck/handler.go b/vendor/golang.org/x/vuln/internal/govulncheck/handler.go
new file mode 100644
index 0000000..5ce7d53
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/govulncheck/handler.go
@@ -0,0 +1,65 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package govulncheck
+
+import (
+	"encoding/json"
+	"io"
+
+	"golang.org/x/vuln/internal/osv"
+)
+
+// Handler handles messages to be presented in a vulnerability scan output
+// stream.
+type Handler interface {
+	// Config communicates introductory message to the user.
+	Config(config *Config) error
+
+	// SBOM shows information about what govulncheck is scanning.
+	SBOM(sbom *SBOM) error
+
+	// Progress is called to display a progress message.
+	Progress(progress *Progress) error
+
+	// OSV is invoked for each osv Entry in the stream.
+	OSV(entry *osv.Entry) error
+
+	// Finding is called for each vulnerability finding in the stream.
+	Finding(finding *Finding) error
+}
+
+// HandleJSON reads the json from the supplied stream and hands the decoded
+// output to the handler.
+func HandleJSON(from io.Reader, to Handler) error {
+	dec := json.NewDecoder(from)
+	for dec.More() {
+		msg := Message{}
+		// decode the next message in the stream
+		if err := dec.Decode(&msg); err != nil {
+			return err
+		}
+		// dispatch the message
+		var err error
+		if msg.Config != nil {
+			err = to.Config(msg.Config)
+		}
+		if msg.Progress != nil {
+			err = to.Progress(msg.Progress)
+		}
+		if msg.SBOM != nil {
+			err = to.SBOM(msg.SBOM)
+		}
+		if msg.OSV != nil {
+			err = to.OSV(msg.OSV)
+		}
+		if msg.Finding != nil {
+			err = to.Finding(msg.Finding)
+		}
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/vendor/golang.org/x/vuln/internal/govulncheck/jsonhandler.go b/vendor/golang.org/x/vuln/internal/govulncheck/jsonhandler.go
new file mode 100644
index 0000000..b1586e0
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/govulncheck/jsonhandler.go
@@ -0,0 +1,49 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package govulncheck
+
+import (
+	"encoding/json"
+
+	"io"
+
+	"golang.org/x/vuln/internal/osv"
+)
+
+type jsonHandler struct {
+	enc *json.Encoder
+}
+
+// NewJSONHandler returns a handler that writes govulncheck output as json.
+func NewJSONHandler(w io.Writer) Handler {
+	enc := json.NewEncoder(w)
+	enc.SetIndent("", "  ")
+	return &jsonHandler{enc: enc}
+}
+
+// Config writes config block in JSON to the underlying writer.
+func (h *jsonHandler) Config(config *Config) error {
+	return h.enc.Encode(Message{Config: config})
+}
+
+// Progress writes a progress message in JSON to the underlying writer.
+func (h *jsonHandler) Progress(progress *Progress) error {
+	return h.enc.Encode(Message{Progress: progress})
+}
+
+// SBOM writes the SBOM block in JSON to the underlying writer.
+func (h *jsonHandler) SBOM(sbom *SBOM) error {
+	return h.enc.Encode(Message{SBOM: sbom})
+}
+
+// OSV writes an osv entry in JSON to the underlying writer.
+func (h *jsonHandler) OSV(entry *osv.Entry) error {
+	return h.enc.Encode(Message{OSV: entry})
+}
+
+// Finding writes a finding in JSON to the underlying writer.
+func (h *jsonHandler) Finding(finding *Finding) error {
+	return h.enc.Encode(Message{Finding: finding})
+}
diff --git a/vendor/golang.org/x/vuln/internal/internal.go b/vendor/golang.org/x/vuln/internal/internal.go
new file mode 100644
index 0000000..8e6b7f5
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/internal.go
@@ -0,0 +1,32 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package internal contains functionality for x/vuln.
+package internal
+
+// IDDirectory is the name of the directory that contains entries
+// listed by their IDs.
+const IDDirectory = "ID"
+
+// Pseudo-module paths used for parts of the Go system.
+// These are technically not valid module paths, so we
+// mustn't pass them to module.EscapePath.
+// Keep in sync with vulndb/internal/database/generate.go.
+const (
+	// GoStdModulePath is the internal Go module path string used
+	// when listing vulnerabilities in standard library.
+	GoStdModulePath = "stdlib"
+
+	// GoCmdModulePath is the internal Go module path string used
+	// when listing vulnerabilities in the go command.
+	GoCmdModulePath = "toolchain"
+
+	// UnknownModulePath is a special module path for when we cannot work out
+	// the module for a package.
+	UnknownModulePath = "unknown-module"
+
+	// UnknownPackagePath is a special package path for when we cannot work out
+	// the packagUnknownModulePath = "unknown"
+	UnknownPackagePath = "unknown-package"
+)
diff --git a/vendor/golang.org/x/vuln/internal/openvex/handler.go b/vendor/golang.org/x/vuln/internal/openvex/handler.go
new file mode 100644
index 0000000..a2d3282
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/openvex/handler.go
@@ -0,0 +1,261 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openvex
+
+import (
+	"crypto/sha256"
+	"encoding/json"
+	"fmt"
+	"io"
+	"slices"
+	"time"
+
+	"golang.org/x/vuln/internal/govulncheck"
+	"golang.org/x/vuln/internal/osv"
+)
+
+type findingLevel int
+
+const (
+	invalid findingLevel = iota
+	required
+	imported
+	called
+)
+
+type handler struct {
+	w    io.Writer
+	cfg  *govulncheck.Config
+	sbom *govulncheck.SBOM
+	osvs map[string]*osv.Entry
+	// findings contains same-level findings for an
+	// OSV at the most precise level of granularity
+	// available. This means, for instance, that if
+	// an osv is indeed called, then all findings for
+	// the osv will have call stack info.
+	findings map[string][]*govulncheck.Finding
+}
+
+func NewHandler(w io.Writer) *handler {
+	return &handler{
+		w:        w,
+		osvs:     make(map[string]*osv.Entry),
+		findings: make(map[string][]*govulncheck.Finding),
+	}
+}
+
+func (h *handler) Config(cfg *govulncheck.Config) error {
+	h.cfg = cfg
+	return nil
+}
+
+func (h *handler) Progress(progress *govulncheck.Progress) error {
+	return nil
+}
+
+func (h *handler) SBOM(s *govulncheck.SBOM) error {
+	h.sbom = s
+	return nil
+}
+
+func (h *handler) OSV(e *osv.Entry) error {
+	h.osvs[e.ID] = e
+	return nil
+}
+
+// foundAtLevel returns the level at which a specific finding is present in the
+// scanned product.
+func foundAtLevel(f *govulncheck.Finding) findingLevel {
+	frame := f.Trace[0]
+	if frame.Function != "" {
+		return called
+	}
+	if frame.Package != "" {
+		return imported
+	}
+	return required
+}
+
+// moreSpecific favors a call finding over a non-call
+// finding and a package finding over a module finding.
+func moreSpecific(f1, f2 *govulncheck.Finding) int {
+	if len(f1.Trace) > 1 && len(f2.Trace) > 1 {
+		// Both are call stack findings.
+		return 0
+	}
+	if len(f1.Trace) > 1 {
+		return -1
+	}
+	if len(f2.Trace) > 1 {
+		return 1
+	}
+
+	fr1, fr2 := f1.Trace[0], f2.Trace[0]
+	if fr1.Function != "" && fr2.Function == "" {
+		return -1
+	}
+	if fr1.Function == "" && fr2.Function != "" {
+		return 1
+	}
+	if fr1.Package != "" && fr2.Package == "" {
+		return -1
+	}
+	if fr1.Package == "" && fr2.Package != "" {
+		return -1
+	}
+	return 0 // findings always have module info
+}
+
+func (h *handler) Finding(f *govulncheck.Finding) error {
+	fs := h.findings[f.OSV]
+	if len(fs) == 0 {
+		fs = []*govulncheck.Finding{f}
+	} else {
+		if ms := moreSpecific(f, fs[0]); ms == -1 {
+			// The new finding is more specific, so we need
+			// to erase existing findings and add the new one.
+			fs = []*govulncheck.Finding{f}
+		} else if ms == 0 {
+			// The new finding is at the same level of precision.
+			fs = append(fs, f)
+		}
+		// Otherwise, the new finding is at a less precise level.
+	}
+	h.findings[f.OSV] = fs
+	return nil
+}
+
+// Flush is used to print the vex json to w.
+// This is needed as vex is not streamed.
+func (h *handler) Flush() error {
+	doc := toVex(h)
+	out, err := json.MarshalIndent(doc, "", "  ")
+	if err != nil {
+		return err
+	}
+	_, err = h.w.Write(out)
+	return err
+}
+
+func toVex(h *handler) Document {
+	doc := Document{
+		Context:    ContextURI,
+		Author:     DefaultAuthor,
+		Timestamp:  time.Now().UTC(),
+		Version:    1,
+		Tooling:    Tooling,
+		Statements: statements(h),
+	}
+
+	id := hashVex(doc)
+	doc.ID = "govulncheck/vex:" + id
+	return doc
+}
+
+// Given a slice of findings, returns those findings as a set of subcomponents
+// that are unique per the vulnerable artifact's PURL.
+func subcomponentSet(findings []*govulncheck.Finding) []Component {
+	var scs []Component
+	seen := make(map[string]bool)
+	for _, f := range findings {
+		purl := purlFromFinding(f)
+		if !seen[purl] {
+			scs = append(scs, Component{
+				ID: purlFromFinding(f),
+			})
+			seen[purl] = true
+		}
+	}
+	return scs
+}
+
+// statements combines all OSVs found by govulncheck and generates the list of
+// vex statements with the proper affected level and justification to match the
+// openVex specification.
+func statements(h *handler) []Statement {
+	var scanLevel findingLevel
+	switch h.cfg.ScanLevel {
+	case govulncheck.ScanLevelModule:
+		scanLevel = required
+	case govulncheck.ScanLevelPackage:
+		scanLevel = imported
+	case govulncheck.ScanLevelSymbol:
+		scanLevel = called
+	}
+
+	var statements []Statement
+	for id, osv := range h.osvs {
+		// if there are no findings emitted for a given OSV that means that
+		// the vulnerable module is not required at a vulnerable version.
+		if len(h.findings[id]) == 0 {
+			continue
+		}
+		description := osv.Summary
+		if description == "" {
+			description = osv.Details
+		}
+
+		s := Statement{
+			Vulnerability: Vulnerability{
+				ID:          fmt.Sprintf("https://pkg.go.dev/vuln/%s", id),
+				Name:        id,
+				Description: description,
+				Aliases:     osv.Aliases,
+			},
+			Products: []Product{
+				{
+					Component:     Component{ID: DefaultPID},
+					Subcomponents: subcomponentSet(h.findings[id]),
+				},
+			},
+		}
+
+		// Findings are guaranteed to be at the same level, so we can just check the first element
+		fLevel := foundAtLevel(h.findings[id][0])
+		if fLevel >= scanLevel {
+			s.Status = StatusAffected
+		} else {
+			s.Status = StatusNotAffected
+			s.ImpactStatement = Impact
+			s.Justification = JustificationNotPresent
+			// We only reach this case if running in symbol mode
+			if fLevel == imported {
+				s.Justification = JustificationNotExecuted
+			}
+		}
+		statements = append(statements, s)
+	}
+
+	slices.SortFunc(statements, func(a, b Statement) int {
+		if a.Vulnerability.ID > b.Vulnerability.ID {
+			return 1
+		}
+		if a.Vulnerability.ID < b.Vulnerability.ID {
+			return -1
+		}
+		// this should never happen in practice, since statements are being
+		// populated from a map with the vulnerability IDs as keys
+		return 0
+	})
+	return statements
+}
+
+func hashVex(doc Document) string {
+	// json.Marshal should never error here (because of the structure of Document).
+	// If an error does occur, it won't be a jsonerror, but instead a panic
+	d := Document{
+		Context:    doc.Context,
+		ID:         doc.ID,
+		Author:     doc.Author,
+		Version:    doc.Version,
+		Tooling:    doc.Tooling,
+		Statements: doc.Statements,
+	}
+	out, err := json.Marshal(d)
+	if err != nil {
+		panic(err)
+	}
+	return fmt.Sprintf("%x", sha256.Sum256(out))
+}
diff --git a/vendor/golang.org/x/vuln/internal/openvex/purl.go b/vendor/golang.org/x/vuln/internal/openvex/purl.go
new file mode 100644
index 0000000..fc1cea9
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/openvex/purl.go
@@ -0,0 +1,46 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openvex
+
+import (
+	"net/url"
+	"strings"
+
+	"golang.org/x/vuln/internal/govulncheck"
+)
+
+// The PURL is printed as: pkg:golang/MODULE_PATH@VERSION
+// Conceptually there is no namespace and the name is entirely defined by
+// the module path. See https://github.com/package-url/purl-spec/issues/63
+// for further disucssion.
+
+const suffix = "pkg:golang/"
+
+type purl struct {
+	name    string
+	version string
+}
+
+func (p *purl) String() string {
+	var b strings.Builder
+	b.WriteString(suffix)
+	b.WriteString(url.PathEscape(p.name))
+	if p.version != "" {
+		b.WriteString("@")
+		b.WriteString(p.version)
+	}
+	return b.String()
+}
+
+// purlFromFinding takes a govulncheck finding and generates a purl to the
+// vulnerable dependency.
+func purlFromFinding(f *govulncheck.Finding) string {
+	purl := purl{
+		name:    f.Trace[0].Module,
+		version: f.Trace[0].Version,
+	}
+
+	return purl.String()
+}
diff --git a/vendor/golang.org/x/vuln/internal/openvex/vex.go b/vendor/golang.org/x/vuln/internal/openvex/vex.go
new file mode 100644
index 0000000..18779f7
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/openvex/vex.go
@@ -0,0 +1,113 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package vex defines the Vulnerability EXchange Format (VEX) types
+// supported by govulncheck.
+//
+// These types match the OpenVEX standard. See https://github.com/openvex for
+// more information on VEX and OpenVEX.
+//
+// This is intended to be the minimimal amount of information required to output
+// a complete VEX document according to the specification.
+package openvex
+
+import "time"
+
+const (
+	ContextURI = "https://openvex.dev/ns/v0.2.0"
+	Tooling    = "https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck"
+	Impact     = "Govulncheck determined that the vulnerable code isn't called"
+
+	DefaultAuthor = "Unknown Author"
+	DefaultPID    = "Unknown Product"
+
+	// The following are defined by the VEX standard.
+	StatusAffected    = "affected"
+	StatusNotAffected = "not_affected"
+
+	// The following are defined by the VEX standard.
+	JustificationNotExecuted = "vulnerable_code_not_in_execute_path"
+	JustificationNotPresent  = "vulnerable_code_not_present"
+)
+
+// Document is the top-level struct for a VEX document.
+type Document struct {
+	// Context is an IRI pointing to the version of openVEX being used by the doc
+	// For govulncheck, it will always be https://openvex.dev/ns/v0.2.0
+	Context string `json:"@context,omitempty"`
+
+	// ID is the identifying string for the VEX document.
+	// govulncheck/vex-[content-based-hash]
+	ID string `json:"@id,omitempty"`
+
+	// Author is the identifier for the author of the VEX statement.
+	// Govulncheck will leave this field default (Unknown author) to be filled in by the user.
+	Author string `json:"author,omitempty"`
+
+	// Timestamp defines the time at which the document was issued.
+	Timestamp time.Time `json:"timestamp,omitempty"`
+
+	// Version is the document version. For govulncheck's output, this will always be 1.
+	Version int `json:"version,omitempty"`
+
+	// Tooling expresses how the VEX document and contained VEX statements were
+	// generated. In this case, it will always be:
+	// "https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck"
+	Tooling string `json:"tooling,omitempty"`
+
+	// Statements are all statements for a given govulncheck output.
+	// Each OSV emitted by govulncheck will have a corresponding statement.
+	Statements []Statement `json:"statements,omitempty"`
+}
+
+// Statement conveys a single status for a single vulnerability for one or more products.
+type Statement struct {
+	// Vulnerability is the vuln being referenced by the statement.
+	Vulnerability Vulnerability `json:"vulnerability,omitempty"`
+
+	// Products are the products associated with the given vulnerability in the statement.
+	Products []Product `json:"products,omitempty"`
+
+	// The status of the vulnerability. Will be either not_affected or affected for govulncheck.
+	Status string `json:"status,omitempty"`
+
+	// If the status is not_affected, this must be filled. The official VEX justification that
+	// best matches govulncheck's vuln filtering is "vulnerable_code_not_in_execute_path"
+	Justification string `json:"justification,omitempty"`
+
+	// If the status is not_affected, this must be filled. For govulncheck, this will always be:
+	// "Govulncheck determined that the vulnerable code isn't called"
+	ImpactStatement string `json:"impact_statement,omitempty"`
+}
+
+// Vulnerability captures a vulnerability and its identifiers/aliases.
+type Vulnerability struct {
+	// ID is a URI that in govulncheck's case points to the govulndb link for the vulnerability.
+	// I.E. https://pkg.go.dev/vuln/GO-2024-2497
+	ID string `json:"@id,omitempty"`
+
+	// Name is the main identifier for the vulnerability (GO-YYYY-XXXX)
+	Name string `json:"name,omitempty"`
+
+	// Description is a short text description of the vulnerability.
+	// It will be populated from the 'summary' field of the vuln's OSV if it exists,
+	// and the 'description' field of the osv if a summary isn't present.
+	Description string `json:"description,omitempty"`
+
+	// Aliases a list of identifiers that other systems are using to track the vulnerability.
+	// I.E. GHSA or CVE ids.
+	Aliases []string `json:"aliases,omitempty"`
+}
+
+// Product identifies the products associated with the given vuln.
+type Product struct {
+	// The main product ID will remian default for now.
+	Component
+	// The subcomponent ID will be a PURL to the vulnerable dependency.
+	Subcomponents []Component `json:"subcomponents,omitempty"`
+}
+
+type Component struct {
+	ID string `json:"@id,omitempty"`
+}
diff --git a/vendor/golang.org/x/vuln/internal/osv/osv.go b/vendor/golang.org/x/vuln/internal/osv/osv.go
new file mode 100644
index 0000000..0bb44b2
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/osv/osv.go
@@ -0,0 +1,240 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package osv implements the Go OSV vulnerability format
+// (https://go.dev/security/vuln/database#schema), which is a subset of
+// the OSV shared vulnerability format
+// (https://ossf.github.io/osv-schema), with database and
+// ecosystem-specific meanings and fields.
+//
+// As this package is intended for use with the Go vulnerability
+// database, only the subset of features which are used by that
+// database are implemented (for instance, only the SEMVER affected
+// range type is implemented).
+package osv
+
+import "time"
+
+// RangeType specifies the type of version range being recorded and
+// defines the interpretation of the RangeEvent object's Introduced
+// and Fixed fields.
+//
+// In this implementation, only the "SEMVER" type is supported.
+//
+// See https://ossf.github.io/osv-schema/#affectedrangestype-field.
+type RangeType string
+
+// RangeTypeSemver indicates a semantic version as defined by
+// SemVer 2.0.0, with no leading "v" prefix.
+const RangeTypeSemver RangeType = "SEMVER"
+
+// Ecosystem identifies the overall library ecosystem.
+// In this implementation, only the "Go" ecosystem is supported.
+type Ecosystem string
+
+// GoEcosystem indicates the Go ecosystem.
+const GoEcosystem Ecosystem = "Go"
+
+// Pseudo-module paths used to describe vulnerabilities
+// in the Go standard library and toolchain.
+const (
+	// GoStdModulePath is the pseudo-module path string used
+	// to describe vulnerabilities in the Go standard library.
+	GoStdModulePath = "stdlib"
+	// GoCmdModulePath is the pseudo-module path string used
+	// to describe vulnerabilities in the go command.
+	GoCmdModulePath = "toolchain"
+)
+
+// Module identifies the Go module containing the vulnerability.
+// Note that this field is called "package" in the OSV specification.
+//
+// See https://ossf.github.io/osv-schema/#affectedpackage-field.
+type Module struct {
+	// The Go module path. Required.
+	// For the Go standard library, this is "stdlib".
+	// For the Go toolchain, this is "toolchain."
+	Path string `json:"name"`
+	// The ecosystem containing the module. Required.
+	// This should always be "Go".
+	Ecosystem Ecosystem `json:"ecosystem"`
+}
+
+// RangeEvent describes a single module version that either
+// introduces or fixes a vulnerability.
+//
+// Exactly one of Introduced and Fixed must be present. Other range
+// event types (e.g, "last_affected" and "limit") are not supported in
+// this implementation.
+//
+// See https://ossf.github.io/osv-schema/#affectedrangesevents-fields.
+type RangeEvent struct {
+	// Introduced is a version that introduces the vulnerability.
+	// A special value, "0", represents a version that sorts before
+	// any other version, and should be used to indicate that the
+	// vulnerability exists from the "beginning of time".
+	Introduced string `json:"introduced,omitempty"`
+	// Fixed is a version that fixes the vulnerability.
+	Fixed string `json:"fixed,omitempty"`
+}
+
+// Range describes the affected versions of the vulnerable module.
+//
+// See https://ossf.github.io/osv-schema/#affectedranges-field.
+type Range struct {
+	// Type is the version type that should be used to interpret the
+	// versions in Events. Required.
+	// In this implementation, only the "SEMVER" type is supported.
+	Type RangeType `json:"type"`
+	// Events is a list of versions representing the ranges in which
+	// the module is vulnerable. Required.
+	// The events should be sorted, and MUST represent non-overlapping
+	// ranges.
+	// There must be at least one RangeEvent containing a value for
+	// Introduced.
+	// See https://ossf.github.io/osv-schema/#examples for examples.
+	Events []RangeEvent `json:"events"`
+}
+
+// ReferenceType is a reference (link) type.
+type ReferenceType string
+
+const (
+	// ReferenceTypeAdvisory is a published security advisory for
+	// the vulnerability.
+	ReferenceTypeAdvisory = ReferenceType("ADVISORY")
+	// ReferenceTypeArticle is an article or blog post describing the vulnerability.
+	ReferenceTypeArticle = ReferenceType("ARTICLE")
+	// ReferenceTypeReport is a report, typically on a bug or issue tracker, of
+	// the vulnerability.
+	ReferenceTypeReport = ReferenceType("REPORT")
+	// ReferenceTypeFix is a source code browser link to the fix (e.g., a GitHub commit).
+	ReferenceTypeFix = ReferenceType("FIX")
+	// ReferenceTypePackage is a home web page for the package.
+	ReferenceTypePackage = ReferenceType("PACKAGE")
+	// ReferenceTypeEvidence is a demonstration of the validity of a vulnerability claim.
+	ReferenceTypeEvidence = ReferenceType("EVIDENCE")
+	// ReferenceTypeWeb is a web page of some unspecified kind.
+	ReferenceTypeWeb = ReferenceType("WEB")
+)
+
+// Reference is a reference URL containing additional information,
+// advisories, issue tracker entries, etc., about the vulnerability.
+//
+// See https://ossf.github.io/osv-schema/#references-field.
+type Reference struct {
+	// The type of reference. Required.
+	Type ReferenceType `json:"type"`
+	// The fully-qualified URL of the reference. Required.
+	URL string `json:"url"`
+}
+
+// Affected gives details about a module affected by the vulnerability.
+//
+// See https://ossf.github.io/osv-schema/#affected-fields.
+type Affected struct {
+	// The affected Go module. Required.
+	// Note that this field is called "package" in the OSV specification.
+	Module Module `json:"package"`
+	// The module version ranges affected by the vulnerability.
+	Ranges []Range `json:"ranges,omitempty"`
+	// Details on the affected packages and symbols within the module.
+	EcosystemSpecific EcosystemSpecific `json:"ecosystem_specific"`
+}
+
+// Package contains additional information about an affected package.
+// This is an ecosystem-specific field for the Go ecosystem.
+type Package struct {
+	// Path is the package import path. Required.
+	Path string `json:"path,omitempty"`
+	// GOOS is the execution operating system where the symbols appear, if
+	// known.
+	GOOS []string `json:"goos,omitempty"`
+	// GOARCH specifies the execution architecture where the symbols appear, if
+	// known.
+	GOARCH []string `json:"goarch,omitempty"`
+	// Symbols is a list of function and method names affected by
+	// this vulnerability. Methods are listed as ..
+	//
+	// If included, only programs which use these symbols will be marked as
+	// vulnerable by `govulncheck`. If omitted, any program which imports this
+	// package will be marked vulnerable.
+	Symbols []string `json:"symbols,omitempty"`
+}
+
+// EcosystemSpecific contains additional information about the vulnerable
+// module for the Go ecosystem.
+//
+// See https://go.dev/security/vuln/database#schema.
+type EcosystemSpecific struct {
+	// Packages is the list of affected packages within the module.
+	Packages []Package `json:"imports,omitempty"`
+}
+
+// Entry represents a vulnerability in the Go OSV format, documented
+// in https://go.dev/security/vuln/database#schema.
+// It is a subset of the OSV schema (https://ossf.github.io/osv-schema).
+// Only fields that are published in the Go Vulnerability Database
+// are supported.
+type Entry struct {
+	// SchemaVersion is the OSV schema version used to encode this
+	// vulnerability.
+	SchemaVersion string `json:"schema_version,omitempty"`
+	// ID is a unique identifier for the vulnerability. Required.
+	// The Go vulnerability database issues IDs of the form
+	// GO--.
+	ID string `json:"id"`
+	// Modified is the time the entry was last modified. Required.
+	Modified time.Time `json:"modified,omitempty"`
+	// Published is the time the entry should be considered to have
+	// been published.
+	Published time.Time `json:"published,omitempty"`
+	// Withdrawn is the time the entry should be considered to have
+	// been withdrawn. If the field is missing, then the entry has
+	// not been withdrawn.
+	Withdrawn *time.Time `json:"withdrawn,omitempty"`
+	// Aliases is a list of IDs for the same vulnerability in other
+	// databases.
+	Aliases []string `json:"aliases,omitempty"`
+	// Summary gives a one-line, English textual summary of the vulnerability.
+	// It is recommended that this field be kept short, on the order of no more
+	// than 120 characters.
+	Summary string `json:"summary,omitempty"`
+	// Details contains additional English textual details about the vulnerability.
+	Details string `json:"details"`
+	// Affected contains information on the modules and versions
+	// affected by the vulnerability.
+	Affected []Affected `json:"affected"`
+	// References contains links to more information about the
+	// vulnerability.
+	References []Reference `json:"references,omitempty"`
+	// Credits contains credits to entities that helped find or fix the
+	// vulnerability.
+	Credits []Credit `json:"credits,omitempty"`
+	// DatabaseSpecific contains additional information about the
+	// vulnerability, specific to the Go vulnerability database.
+	DatabaseSpecific *DatabaseSpecific `json:"database_specific,omitempty"`
+}
+
+// Credit represents a credit for the discovery, confirmation, patch, or
+// other event in the life cycle of a vulnerability.
+//
+// See https://ossf.github.io/osv-schema/#credits-fields.
+type Credit struct {
+	// Name is the name, label, or other identifier of the individual or
+	// entity being credited. Required.
+	Name string `json:"name"`
+}
+
+// DatabaseSpecific contains additional information about the
+// vulnerability, specific to the Go vulnerability database.
+//
+// See https://go.dev/security/vuln/database#schema.
+type DatabaseSpecific struct {
+	// The URL of the Go advisory for this vulnerability, of the form
+	// "https://pkg.go.dev/GO-YYYY-XXXX".
+	URL string `json:"url,omitempty"`
+	// The review status of this report (UNREVIEWED or REVIEWED).
+	ReviewStatus ReviewStatus `json:"review_status,omitempty"`
+}
diff --git a/vendor/golang.org/x/vuln/internal/osv/review_status.go b/vendor/golang.org/x/vuln/internal/osv/review_status.go
new file mode 100644
index 0000000..7185e18
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/osv/review_status.go
@@ -0,0 +1,67 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package osv
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+type ReviewStatus int
+
+const (
+	ReviewStatusUnknown ReviewStatus = iota
+	ReviewStatusUnreviewed
+	ReviewStatusReviewed
+)
+
+var statusStrs = []string{
+	ReviewStatusUnknown:    "",
+	ReviewStatusUnreviewed: "UNREVIEWED",
+	ReviewStatusReviewed:   "REVIEWED",
+}
+
+func (r ReviewStatus) String() string {
+	if !r.IsValid() {
+		return fmt.Sprintf("INVALID(%d)", r)
+	}
+	return statusStrs[r]
+}
+
+func ReviewStatusValues() []string {
+	return statusStrs[1:]
+}
+
+func (r ReviewStatus) IsValid() bool {
+	return int(r) >= 0 && int(r) < len(statusStrs)
+}
+
+func ToReviewStatus(s string) (ReviewStatus, bool) {
+	for stat, str := range statusStrs {
+		if s == str {
+			return ReviewStatus(stat), true
+		}
+	}
+	return 0, false
+}
+
+func (r ReviewStatus) MarshalJSON() ([]byte, error) {
+	if !r.IsValid() {
+		return nil, fmt.Errorf("MarshalJSON: unrecognized review status: %d", r)
+	}
+	return json.Marshal(r.String())
+}
+
+func (r *ReviewStatus) UnmarshalJSON(b []byte) error {
+	var s string
+	if err := json.Unmarshal(b, &s); err != nil {
+		return err
+	}
+	if rs, ok := ToReviewStatus(s); ok {
+		*r = rs
+		return nil
+	}
+	return fmt.Errorf("UnmarshalJSON: unrecognized review status: %s", s)
+}
diff --git a/vendor/golang.org/x/vuln/internal/sarif/handler.go b/vendor/golang.org/x/vuln/internal/sarif/handler.go
new file mode 100644
index 0000000..d9e585b
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/sarif/handler.go
@@ -0,0 +1,409 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sarif
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+	"path/filepath"
+	"sort"
+
+	"golang.org/x/vuln/internal"
+	"golang.org/x/vuln/internal/govulncheck"
+	"golang.org/x/vuln/internal/osv"
+	"golang.org/x/vuln/internal/traces"
+)
+
+// handler for sarif output.
+type handler struct {
+	w    io.Writer
+	cfg  *govulncheck.Config
+	osvs map[string]*osv.Entry
+	// findings contains same-level findings for an
+	// OSV at the most precise level of granularity
+	// available. This means, for instance, that if
+	// an osv is indeed called, then all findings for
+	// the osv will have call stack info.
+	findings map[string][]*govulncheck.Finding
+}
+
+func NewHandler(w io.Writer) *handler {
+	return &handler{
+		w:        w,
+		osvs:     make(map[string]*osv.Entry),
+		findings: make(map[string][]*govulncheck.Finding),
+	}
+}
+
+func (h *handler) Config(c *govulncheck.Config) error {
+	h.cfg = c
+	return nil
+}
+
+func (h *handler) Progress(p *govulncheck.Progress) error {
+	return nil // not needed by sarif
+}
+
+func (h *handler) SBOM(s *govulncheck.SBOM) error {
+	return nil // not needed by sarif
+}
+
+func (h *handler) OSV(e *osv.Entry) error {
+	h.osvs[e.ID] = e
+	return nil
+}
+
+// moreSpecific favors a call finding over a non-call
+// finding and a package finding over a module finding.
+func moreSpecific(f1, f2 *govulncheck.Finding) int {
+	if len(f1.Trace) > 1 && len(f2.Trace) > 1 {
+		// Both are call stack findings.
+		return 0
+	}
+	if len(f1.Trace) > 1 {
+		return -1
+	}
+	if len(f2.Trace) > 1 {
+		return 1
+	}
+
+	fr1, fr2 := f1.Trace[0], f2.Trace[0]
+	if fr1.Function != "" && fr2.Function == "" {
+		return -1
+	}
+	if fr1.Function == "" && fr2.Function != "" {
+		return 1
+	}
+	if fr1.Package != "" && fr2.Package == "" {
+		return -1
+	}
+	if fr1.Package == "" && fr2.Package != "" {
+		return -1
+	}
+	return 0 // findings always have module info
+}
+
+func (h *handler) Finding(f *govulncheck.Finding) error {
+	fs := h.findings[f.OSV]
+	if len(fs) == 0 {
+		fs = []*govulncheck.Finding{f}
+	} else {
+		if ms := moreSpecific(f, fs[0]); ms == -1 {
+			// The new finding is more specific, so we need
+			// to erase existing findings and add the new one.
+			fs = []*govulncheck.Finding{f}
+		} else if ms == 0 {
+			// The new finding is equal to an existing one and
+			// because of the invariant on h.findings, it is
+			// also equal to all existing ones.
+			fs = append(fs, f)
+		}
+		// Otherwise, the new finding is at a less precise level.
+	}
+	h.findings[f.OSV] = fs
+	return nil
+}
+
+// Flush is used to print out to w the sarif json output.
+// This is needed as sarif is not streamed.
+func (h *handler) Flush() error {
+	sLog := toSarif(h)
+	s, err := json.MarshalIndent(sLog, "", "  ")
+	if err != nil {
+		return err
+	}
+	h.w.Write(s)
+	return nil
+}
+
+func toSarif(h *handler) Log {
+	cfg := h.cfg
+	r := Run{
+		Tool: Tool{
+			Driver: Driver{
+				Name:           cfg.ScannerName,
+				Version:        cfg.ScannerVersion,
+				InformationURI: "https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck",
+				Properties:     *cfg,
+				Rules:          rules(h),
+			},
+		},
+		Results: results(h),
+	}
+
+	return Log{
+		Version: "2.1.0",
+		Schema:  "https://json.schemastore.org/sarif-2.1.0.json",
+		Runs:    []Run{r},
+	}
+}
+
+func rules(h *handler) []Rule {
+	rs := make([]Rule, 0, len(h.findings)) // must not be nil
+	for id := range h.findings {
+		osv := h.osvs[id]
+		// s is either summary if it exists, or details
+		// otherwise. Govulncheck text does the same.
+		s := osv.Summary
+		if s == "" {
+			s = osv.Details
+		}
+		rs = append(rs, Rule{
+			ID:               osv.ID,
+			ShortDescription: Description{Text: fmt.Sprintf("[%s] %s", osv.ID, s)},
+			FullDescription:  Description{Text: s},
+			HelpURI:          fmt.Sprintf("https://pkg.go.dev/vuln/%s", osv.ID),
+			Help:             Description{Text: osv.Details},
+			Properties:       RuleTags{Tags: tags(osv)},
+		})
+	}
+	sort.SliceStable(rs, func(i, j int) bool { return rs[i].ID < rs[j].ID })
+	return rs
+}
+
+// tags returns an slice of zero or
+// more aliases of o.
+func tags(o *osv.Entry) []string {
+	if len(o.Aliases) > 0 {
+		return o.Aliases
+	}
+	return []string{} // must not be nil
+}
+
+func results(h *handler) []Result {
+	results := make([]Result, 0, len(h.findings)) // must not be nil
+	for osv, fs := range h.findings {
+		var locs []Location
+		if h.cfg.ScanMode != govulncheck.ScanModeBinary {
+			// Attach result to the go.mod file for source analysis.
+			// But there is no such place for binaries.
+			locs = []Location{{PhysicalLocation: PhysicalLocation{
+				ArtifactLocation: ArtifactLocation{
+					URI:       "go.mod",
+					URIBaseID: SrcRootID,
+				},
+				Region: Region{StartLine: 1}, // for now, point to the first line
+			},
+				Message: Description{Text: fmt.Sprintf("Findings for vulnerability %s", osv)}, // not having a message here results in an invalid sarif
+			}}
+		}
+
+		res := Result{
+			RuleID:    osv,
+			Level:     level(fs[0], h.cfg),
+			Message:   Description{Text: resultMessage(fs, h.cfg)},
+			Stacks:    stacks(h, fs),
+			CodeFlows: codeFlows(h, fs),
+			Locations: locs,
+		}
+		results = append(results, res)
+	}
+	sort.SliceStable(results, func(i, j int) bool { return results[i].RuleID < results[j].RuleID }) // for deterministic output
+	return results
+}
+
+func resultMessage(findings []*govulncheck.Finding, cfg *govulncheck.Config) string {
+	// We can infer the findings' level by just looking at the
+	// top trace frame of any finding.
+	frame := findings[0].Trace[0]
+	uniqueElems := make(map[string]bool)
+	if frame.Function == "" && frame.Package == "" { // module level findings
+		for _, f := range findings {
+			uniqueElems[f.Trace[0].Module] = true
+		}
+	} else { // symbol and package level findings
+		for _, f := range findings {
+			uniqueElems[f.Trace[0].Package] = true
+		}
+	}
+	var elems []string
+	for e := range uniqueElems {
+		elems = append(elems, e)
+	}
+	sort.Strings(elems)
+
+	l := len(elems)
+	elemList := list(elems)
+	main, addition := "", ""
+	const runCallAnalysis = "Run the call-level analysis to understand whether your code actually calls the vulnerabilities."
+	switch {
+	case frame.Function != "":
+		main = fmt.Sprintf("calls vulnerable functions in %d package%s (%s).", l, choose("", "s", l == 1), elemList)
+	case frame.Package != "":
+		main = fmt.Sprintf("imports %d vulnerable package%s (%s)", l, choose("", "s", l == 1), elemList)
+		addition = choose(", but doesn’t appear to call any of the vulnerable symbols.", ". "+runCallAnalysis, cfg.ScanLevel.WantSymbols())
+	default:
+		main = fmt.Sprintf("depends on %d vulnerable module%s (%s)", l, choose("", "s", l == 1), elemList)
+		informational := ", but doesn't appear to " + choose("call", "import", cfg.ScanLevel.WantSymbols()) + " any of the vulnerable symbols."
+		addition = choose(informational, ". "+runCallAnalysis, cfg.ScanLevel.WantPackages())
+	}
+
+	return fmt.Sprintf("Your code %s%s", main, addition)
+}
+
+const (
+	errorLevel         = "error"
+	warningLevel       = "warning"
+	informationalLevel = "note"
+)
+
+func level(f *govulncheck.Finding, cfg *govulncheck.Config) string {
+	fr := f.Trace[0]
+	switch {
+	case cfg.ScanLevel.WantSymbols():
+		if fr.Function != "" {
+			return errorLevel
+		}
+		if fr.Package != "" {
+			return warningLevel
+		}
+		return informationalLevel
+	case cfg.ScanLevel.WantPackages():
+		if fr.Package != "" {
+			return errorLevel
+		}
+		return warningLevel
+	default:
+		return errorLevel
+	}
+}
+
+func stacks(h *handler, fs []*govulncheck.Finding) []Stack {
+	if fs[0].Trace[0].Function == "" { // not call level findings
+		return nil
+	}
+
+	var stacks []Stack
+	for _, f := range fs {
+		stacks = append(stacks, stack(h, f))
+	}
+	// Sort stacks for deterministic output. We sort by message
+	// which is effectively sorting by full symbol name. The
+	// performance should not be an issue here.
+	sort.SliceStable(stacks, func(i, j int) bool { return stacks[i].Message.Text < stacks[j].Message.Text })
+	return stacks
+}
+
+// stack transforms call stack in f to a sarif stack.
+func stack(h *handler, f *govulncheck.Finding) Stack {
+	trace := f.Trace
+	top := trace[len(trace)-1] // belongs to top level module
+
+	frames := make([]Frame, 0, len(trace)) // must not be nil
+	for i := len(trace) - 1; i >= 0; i-- { // vulnerable symbol is at the top frame
+		frame := trace[i]
+		pos := govulncheck.Position{Line: 1, Column: 1}
+		if frame.Position != nil {
+			pos = *frame.Position
+		}
+
+		sf := Frame{
+			Module:   frame.Module + "@" + frame.Version,
+			Location: Location{Message: Description{Text: symbol(frame)}}, // show the (full) symbol name
+		}
+		file, base := fileURIInfo(pos.Filename, top.Module, frame.Module, frame.Version)
+		if h.cfg.ScanMode != govulncheck.ScanModeBinary {
+			sf.Location.PhysicalLocation = PhysicalLocation{
+				ArtifactLocation: ArtifactLocation{
+					URI:       file,
+					URIBaseID: base,
+				},
+				Region: Region{
+					StartLine:   pos.Line,
+					StartColumn: pos.Column,
+				},
+			}
+		}
+		frames = append(frames, sf)
+	}
+
+	return Stack{
+		Frames:  frames,
+		Message: Description{Text: fmt.Sprintf("A call stack for vulnerable function %s", symbol(trace[0]))},
+	}
+}
+
+func codeFlows(h *handler, fs []*govulncheck.Finding) []CodeFlow {
+	if fs[0].Trace[0].Function == "" { // not call level findings
+		return nil
+	}
+
+	// group call stacks per symbol. There should
+	// be one call stack currently per symbol, but
+	// this might change in the future.
+	m := make(map[govulncheck.Frame][]*govulncheck.Finding)
+	for _, f := range fs {
+		// fr.Position is currently the position
+		// of the definition of the vuln symbol
+		fr := *f.Trace[0]
+		m[fr] = append(m[fr], f)
+	}
+
+	var codeFlows []CodeFlow
+	for fr, fs := range m {
+		tfs := threadFlows(h, fs)
+		codeFlows = append(codeFlows, CodeFlow{
+			ThreadFlows: tfs,
+			// TODO: should we instead show the message from govulncheck text output?
+			Message: Description{Text: fmt.Sprintf("A summarized code flow for vulnerable function %s", symbol(&fr))},
+		})
+	}
+	// Sort flows for deterministic output. We sort by message
+	// which is effectively sorting by full symbol name. The
+	// performance should not be an issue here.
+	sort.SliceStable(codeFlows, func(i, j int) bool { return codeFlows[i].Message.Text < codeFlows[j].Message.Text })
+	return codeFlows
+}
+
+func threadFlows(h *handler, fs []*govulncheck.Finding) []ThreadFlow {
+	tfs := make([]ThreadFlow, 0, len(fs)) // must not be nil
+	for _, f := range fs {
+		trace := traces.Compact(f)
+		top := trace[len(trace)-1] // belongs to top level module
+
+		var tf []ThreadFlowLocation
+		for i := len(trace) - 1; i >= 0; i-- { // vulnerable symbol is at the top frame
+			// TODO: should we, similar to govulncheck text output, only
+			// mention three elements of the compact trace?
+			frame := trace[i]
+			pos := govulncheck.Position{Line: 1, Column: 1}
+			if frame.Position != nil {
+				pos = *frame.Position
+			}
+
+			tfl := ThreadFlowLocation{
+				Module:   frame.Module + "@" + frame.Version,
+				Location: Location{Message: Description{Text: symbol(frame)}}, // show the (full) symbol name
+			}
+			file, base := fileURIInfo(pos.Filename, top.Module, frame.Module, frame.Version)
+			if h.cfg.ScanMode != govulncheck.ScanModeBinary {
+				tfl.Location.PhysicalLocation = PhysicalLocation{
+					ArtifactLocation: ArtifactLocation{
+						URI:       file,
+						URIBaseID: base,
+					},
+					Region: Region{
+						StartLine:   pos.Line,
+						StartColumn: pos.Column,
+					},
+				}
+			}
+			tf = append(tf, tfl)
+		}
+		tfs = append(tfs, ThreadFlow{Locations: tf})
+	}
+	return tfs
+}
+
+func fileURIInfo(filename, top, module, version string) (string, string) {
+	if top == module {
+		return filename, SrcRootID
+	}
+	if module == internal.GoStdModulePath {
+		return filename, GoRootID
+	}
+	return filepath.ToSlash(filepath.Join(module+"@"+version, filename)), GoModCacheID
+}
diff --git a/vendor/golang.org/x/vuln/internal/sarif/sarif.go b/vendor/golang.org/x/vuln/internal/sarif/sarif.go
new file mode 100644
index 0000000..934ade8
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/sarif/sarif.go
@@ -0,0 +1,213 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package sarif defines Static Analysis Results Interchange Format
+// (SARIF) types supported by govulncheck.
+//
+// The implementation covers the subset of the specification available
+// at https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif.
+//
+// The sarif encoding models govulncheck findings as Results. Each
+// Result encodes findings for a unique OSV entry at the most precise
+// detected level only. CodeFlows summarize call stacks, similar to govulncheck
+// textual output, while Stacks contain call stack information verbatim.
+//
+// The result Levels are defined by the govulncheck.ScanLevel and the most
+// precise level at which the finding was detected. Result error is produced
+// when the finding level matches the user desired level of scan precision;
+// all other finding levels are then classified as progressively weaker.
+// For instance, if the user specified symbol scan level and govulncheck
+// detected a use of a vulnerable symbol, then the Result will have error
+// Level. If the symbol was not used but its package was imported, then the
+// Result Level is warning, and so on.
+//
+// Each Result is attached to the first line of the go.mod file. Other
+// ArtifactLocations are paths relative to their enclosing modules.
+// Similar to JSON output format, this makes govulncheck sarif locations
+// portable.
+//
+// The relative paths in PhysicalLocations also come with a URIBaseID offset.
+// Paths for the source module analyzed, the Go standard library, and third-party
+// dependencies are relative to %SRCROOT%, %GOROOT%, and %GOMODCACHE% offsets,
+// resp. We note that the URIBaseID offsets are not explicitly defined in
+// the sarif output. It is the clients responsibility to set them to resolve
+// paths at their local machines.
+//
+// All paths use "/" delimiter for portability.
+//
+// Properties field of a Tool.Driver is a govulncheck.Config used for the
+// invocation of govulncheck producing the Results. Properties field of
+// a Rule contains information on CVE and GHSA aliases for the corresponding
+// rule OSV. Clients can use this information to, say, suppress and filter
+// vulnerabilities.
+//
+// Please see the definition of types below for more information.
+package sarif
+
+import "golang.org/x/vuln/internal/govulncheck"
+
+// Log is the top-level SARIF object encoded in UTF-8.
+type Log struct {
+	// Version should always be "2.1.0"
+	Version string `json:"version,omitempty"`
+
+	// Schema should always be "https://json.schemastore.org/sarif-2.1.0.json"
+	Schema string `json:"$schema,omitempty"`
+
+	// Runs describes executions of static analysis tools. For govulncheck,
+	// there will be only one run object.
+	Runs []Run `json:"runs,omitempty"`
+}
+
+// Run summarizes results of a single invocation of a static analysis tool,
+// in this case govulncheck.
+type Run struct {
+	Tool Tool `json:"tool,omitempty"`
+	// Results contain govulncheck findings. There should be exactly one
+	// Result per a detected use of an OSV.
+	Results []Result `json:"results"`
+}
+
+// Tool captures information about govulncheck analysis that was run.
+type Tool struct {
+	Driver Driver `json:"driver,omitempty"`
+}
+
+// Driver provides details about the govulncheck binary being executed.
+type Driver struct {
+	// Name is "govulncheck"
+	Name string `json:"name,omitempty"`
+	// Version is the govulncheck version
+	Version string `json:"semanticVersion,omitempty"`
+	// InformationURI points to the description of govulncheck tool
+	InformationURI string `json:"informationUri,omitempty"`
+	// Properties are govulncheck run metadata, such as vuln db, Go version, etc.
+	Properties govulncheck.Config `json:"properties,omitempty"`
+
+	Rules []Rule `json:"rules"`
+}
+
+// Rule corresponds to the static analysis rule/analyzer that
+// produces findings. For govulncheck, rules are OSVs.
+type Rule struct {
+	// ID is OSV.ID
+	ID               string      `json:"id,omitempty"`
+	ShortDescription Description `json:"shortDescription,omitempty"`
+	FullDescription  Description `json:"fullDescription,omitempty"`
+	Help             Description `json:"help,omitempty"`
+	HelpURI          string      `json:"helpUri,omitempty"`
+	// Properties contain OSV.Aliases (CVEs and GHSAs) as tags.
+	// Consumers of govulncheck SARIF can use these tags to filter
+	// results.
+	Properties RuleTags `json:"properties,omitempty"`
+}
+
+// RuleTags defines properties.tags.
+type RuleTags struct {
+	Tags []string `json:"tags"`
+}
+
+// Description is a text in its raw or markdown form.
+type Description struct {
+	Text     string `json:"text,omitempty"`
+	Markdown string `json:"markdown,omitempty"`
+}
+
+// Result is a set of govulncheck findings for an OSV. For call stack
+// mode, it will contain call stacks for the OSV. There is exactly
+// one Result per detected OSV. Only findings at the most precise
+// detected level appear in the Result. For instance, if there are
+// symbol findings for an OSV, those findings will be in the Result,
+// but not the package and module level findings for the same OSV.
+type Result struct {
+	// RuleID is the Rule.ID/OSV producing the finding.
+	RuleID string `json:"ruleId,omitempty"`
+	// Level is one of "error", "warning", and "note".
+	Level string `json:"level,omitempty"`
+	// Message explains the overall findings.
+	Message Description `json:"message,omitempty"`
+	// Locations to which the findings are associated. Always
+	// a single location pointing to the first line of the go.mod
+	// file. The path to the file is "go.mod".
+	Locations []Location `json:"locations,omitempty"`
+	// CodeFlows summarize call stacks produced by govulncheck.
+	CodeFlows []CodeFlow `json:"codeFlows,omitempty"`
+	// Stacks encode call stacks produced by govulncheck.
+	Stacks []Stack `json:"stacks,omitempty"`
+}
+
+// CodeFlow summarizes a detected offending flow of information in terms of
+// code locations. More precisely, it can contain several related information
+// flows, keeping them together. In govulncheck, those can be all call stacks
+// for, say, a particular symbol or package.
+type CodeFlow struct {
+	// ThreadFlows is effectively a set of related information flows.
+	ThreadFlows []ThreadFlow `json:"threadFlows"`
+	Message     Description  `json:"message,omitempty"`
+}
+
+// ThreadFlow encodes an information flow as a sequence of locations.
+// For govulncheck, it can encode a call stack.
+type ThreadFlow struct {
+	Locations []ThreadFlowLocation `json:"locations,omitempty"`
+}
+
+type ThreadFlowLocation struct {
+	// Module is module information in the form @.
+	//  can be empty when the module version is not known as
+	// with, say, the source module analyzed.
+	Module string `json:"module,omitempty"`
+	// Location also contains a Message field.
+	Location Location `json:"location,omitempty"`
+}
+
+// Stack is a sequence of frames and can encode a govulncheck call stack.
+type Stack struct {
+	Message Description `json:"message,omitempty"`
+	Frames  []Frame     `json:"frames"`
+}
+
+// Frame is effectively a module location. It can also contain thread and
+// parameter info, but those are not needed for govulncheck.
+type Frame struct {
+	// Module is module information in the form @.
+	//  can be empty when the module version is not known as
+	// with, say, the source module analyzed.
+	Module   string   `json:"module,omitempty"`
+	Location Location `json:"location,omitempty"`
+}
+
+// Location is currently a physical location annotated with a message.
+type Location struct {
+	PhysicalLocation PhysicalLocation `json:"physicalLocation,omitempty"`
+	Message          Description      `json:"message,omitempty"`
+}
+
+type PhysicalLocation struct {
+	ArtifactLocation ArtifactLocation `json:"artifactLocation,omitempty"`
+	Region           Region           `json:"region,omitempty"`
+}
+
+const (
+	SrcRootID    = "%SRCROOT%"
+	GoRootID     = "%GOROOT%"
+	GoModCacheID = "%GOMODCACHE%"
+)
+
+// ArtifactLocation is a path to an offending file.
+type ArtifactLocation struct {
+	// URI is a path relative to URIBaseID.
+	URI string `json:"uri,omitempty"`
+	// URIBaseID is offset for URI, one of %SRCROOT%, %GOROOT%,
+	// and %GOMODCACHE%.
+	URIBaseID string `json:"uriBaseId,omitempty"`
+}
+
+// Region is a target region within a file.
+type Region struct {
+	StartLine   int `json:"startLine,omitempty"`
+	StartColumn int `json:"startColumn,omitempty"`
+	EndLine     int `json:"endLine,omitempty"`
+	EndColumn   int `json:"endColumn,omitempty"`
+}
diff --git a/vendor/golang.org/x/vuln/internal/sarif/utils.go b/vendor/golang.org/x/vuln/internal/sarif/utils.go
new file mode 100644
index 0000000..045cac7
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/sarif/utils.go
@@ -0,0 +1,46 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sarif
+
+import (
+	"strings"
+
+	"golang.org/x/vuln/internal/govulncheck"
+)
+
+func choose(s1, s2 string, cond bool) string {
+	if cond {
+		return s1
+	}
+	return s2
+}
+
+func list(elems []string) string {
+	l := len(elems)
+	if l == 0 {
+		return ""
+	}
+	if l == 1 {
+		return elems[0]
+	}
+
+	cList := strings.Join(elems[:l-1], ", ")
+	return cList + choose("", ",", l == 2) + " and " + elems[l-1]
+}
+
+// symbol is simplified adaptation of internal/scan/symbol.
+func symbol(fr *govulncheck.Frame) string {
+	if fr.Function == "" {
+		return ""
+	}
+	sym := strings.Split(fr.Function, "$")[0]
+	if fr.Receiver != "" {
+		sym = fr.Receiver + "." + sym
+	}
+	if fr.Package != "" {
+		sym = fr.Package + "." + sym
+	}
+	return sym
+}
diff --git a/vendor/golang.org/x/vuln/internal/scan/binary.go b/vendor/golang.org/x/vuln/internal/scan/binary.go
new file mode 100644
index 0000000..5cc8f6b
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/binary.go
@@ -0,0 +1,110 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"os"
+	"runtime/debug"
+
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/vuln/internal/buildinfo"
+	"golang.org/x/vuln/internal/client"
+	"golang.org/x/vuln/internal/derrors"
+	"golang.org/x/vuln/internal/govulncheck"
+	"golang.org/x/vuln/internal/vulncheck"
+)
+
+// runBinary detects presence of vulnerable symbols in an executable or its minimal blob representation.
+func runBinary(ctx context.Context, handler govulncheck.Handler, cfg *config, client *client.Client) (err error) {
+	defer derrors.Wrap(&err, "govulncheck")
+
+	bin, err := createBin(cfg.patterns[0])
+	if err != nil {
+		return err
+	}
+
+	p := &govulncheck.Progress{Message: binaryProgressMessage}
+	if err := handler.Progress(p); err != nil {
+		return err
+	}
+	return vulncheck.Binary(ctx, handler, bin, &cfg.Config, client)
+}
+
+func createBin(path string) (*vulncheck.Bin, error) {
+	// First check if the path points to a Go binary. Otherwise, blob
+	// parsing might json decode a Go binary which takes time.
+	//
+	// TODO(#64716): use fingerprinting to make this precise, clean, and fast.
+	mods, packageSymbols, bi, err := buildinfo.ExtractPackagesAndSymbols(path)
+	if err == nil {
+		var main *packages.Module
+		if bi.Main.Path != "" {
+			main = &packages.Module{
+				Path:    bi.Main.Path,
+				Version: bi.Main.Version,
+			}
+		}
+
+		return &vulncheck.Bin{
+			Path:       bi.Path,
+			Main:       main,
+			Modules:    mods,
+			PkgSymbols: packageSymbols,
+			GoVersion:  bi.GoVersion,
+			GOOS:       findSetting("GOOS", bi),
+			GOARCH:     findSetting("GOARCH", bi),
+		}, nil
+	}
+
+	// Otherwise, see if the path points to a valid blob.
+	bin := parseBlob(path)
+	if bin != nil {
+		return bin, nil
+	}
+
+	return nil, errors.New("unrecognized binary format")
+}
+
+// parseBlob extracts vulncheck.Bin from a valid blob at path.
+// If it cannot recognize a valid blob, returns nil.
+func parseBlob(path string) *vulncheck.Bin {
+	from, err := os.Open(path)
+	if err != nil {
+		return nil
+	}
+	defer from.Close()
+
+	dec := json.NewDecoder(from)
+
+	var h header
+	if err := dec.Decode(&h); err != nil {
+		return nil // no header
+	} else if h.Name != extractModeID || h.Version != extractModeVersion {
+		return nil // invalid header
+	}
+
+	var b vulncheck.Bin
+	if err := dec.Decode(&b); err != nil {
+		return nil // no body
+	}
+	if dec.More() {
+		return nil // we want just header and body, nothing else
+	}
+	return &b
+}
+
+// findSetting returns value of setting from bi if present.
+// Otherwise, returns "".
+func findSetting(setting string, bi *debug.BuildInfo) string {
+	for _, s := range bi.Settings {
+		if s.Key == setting {
+			return s.Value
+		}
+	}
+	return ""
+}
diff --git a/vendor/golang.org/x/vuln/internal/scan/color.go b/vendor/golang.org/x/vuln/internal/scan/color.go
new file mode 100644
index 0000000..7ef0fca
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/color.go
@@ -0,0 +1,97 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+package scan
+
+const (
+	// These are all the constants for the terminal escape strings
+
+	colorEscape = "\033["
+	colorEnd    = "m"
+
+	colorReset     = colorEscape + "0" + colorEnd
+	colorBold      = colorEscape + "1" + colorEnd
+	colorFaint     = colorEscape + "2" + colorEnd
+	colorUnderline = colorEscape + "4" + colorEnd
+	colorBlink     = colorEscape + "5" + colorEnd
+
+	fgBlack   = colorEscape + "30" + colorEnd
+	fgRed     = colorEscape + "31" + colorEnd
+	fgGreen   = colorEscape + "32" + colorEnd
+	fgYellow  = colorEscape + "33" + colorEnd
+	fgBlue    = colorEscape + "34" + colorEnd
+	fgMagenta = colorEscape + "35" + colorEnd
+	fgCyan    = colorEscape + "36" + colorEnd
+	fgWhite   = colorEscape + "37" + colorEnd
+
+	bgBlack   = colorEscape + "40" + colorEnd
+	bgRed     = colorEscape + "41" + colorEnd
+	bgGreen   = colorEscape + "42" + colorEnd
+	bgYellow  = colorEscape + "43" + colorEnd
+	bgBlue    = colorEscape + "44" + colorEnd
+	bgMagenta = colorEscape + "45" + colorEnd
+	bgCyan    = colorEscape + "46" + colorEnd
+	bgWhite   = colorEscape + "47" + colorEnd
+
+	fgBlackHi   = colorEscape + "90" + colorEnd
+	fgRedHi     = colorEscape + "91" + colorEnd
+	fgGreenHi   = colorEscape + "92" + colorEnd
+	fgYellowHi  = colorEscape + "93" + colorEnd
+	fgBlueHi    = colorEscape + "94" + colorEnd
+	fgMagentaHi = colorEscape + "95" + colorEnd
+	fgCyanHi    = colorEscape + "96" + colorEnd
+	fgWhiteHi   = colorEscape + "97" + colorEnd
+
+	bgBlackHi   = colorEscape + "100" + colorEnd
+	bgRedHi     = colorEscape + "101" + colorEnd
+	bgGreenHi   = colorEscape + "102" + colorEnd
+	bgYellowHi  = colorEscape + "103" + colorEnd
+	bgBlueHi    = colorEscape + "104" + colorEnd
+	bgMagentaHi = colorEscape + "105" + colorEnd
+	bgCyanHi    = colorEscape + "106" + colorEnd
+	bgWhiteHi   = colorEscape + "107" + colorEnd
+)
+
+const (
+	_ = colorReset
+	_ = colorBold
+	_ = colorFaint
+	_ = colorUnderline
+	_ = colorBlink
+
+	_ = fgBlack
+	_ = fgRed
+	_ = fgGreen
+	_ = fgYellow
+	_ = fgBlue
+	_ = fgMagenta
+	_ = fgCyan
+	_ = fgWhite
+
+	_ = fgBlackHi
+	_ = fgRedHi
+	_ = fgGreenHi
+	_ = fgYellowHi
+	_ = fgBlueHi
+	_ = fgMagentaHi
+	_ = fgCyanHi
+	_ = fgWhiteHi
+
+	_ = bgBlack
+	_ = bgRed
+	_ = bgGreen
+	_ = bgYellow
+	_ = bgBlue
+	_ = bgMagenta
+	_ = bgCyan
+	_ = bgWhite
+
+	_ = bgBlackHi
+	_ = bgRedHi
+	_ = bgGreenHi
+	_ = bgYellowHi
+	_ = bgBlueHi
+	_ = bgMagentaHi
+	_ = bgCyanHi
+	_ = bgWhiteHi
+)
diff --git a/vendor/golang.org/x/vuln/internal/scan/errors.go b/vendor/golang.org/x/vuln/internal/scan/errors.go
new file mode 100644
index 0000000..905e1e6
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/errors.go
@@ -0,0 +1,79 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"errors"
+	"strings"
+)
+
+//lint:file-ignore ST1005 Ignore staticcheck message about error formatting
+var (
+	// errVulnerabilitiesFound indicates that vulnerabilities were detected
+	// when running govulncheck. This returns exit status 3 when running
+	// without the -json flag.
+	errVulnerabilitiesFound = &exitCodeError{message: "vulnerabilities found", code: 3}
+
+	// errHelp indicates that usage help was requested.
+	errHelp = &exitCodeError{message: "help requested", code: 0}
+
+	// errUsage indicates that there was a usage error on the command line.
+	//
+	// In this case, we assume that the user does not know how to run
+	// govulncheck and exit with status 2.
+	errUsage = &exitCodeError{message: "invalid usage", code: 2}
+
+	// errNoPatterns indicates that no package patterns were provided if the scan level is WantPackages.
+	errNoPatterns = &exitCodeError{
+		message: "no package patterns provided\n\nTo scan the current module, run: govulncheck ./...",
+		code:    2,
+	}
+
+	// errNoPackagesMatched indicates that the provided patterns matched no packages if scan level is WantPackages.
+	errNoPackagesMatched = &exitCodeError{
+		message: "no packages matched the provided patterns",
+		code:    2,
+	}
+
+	// errGoVersionMismatch is used to indicate that there is a mismatch between
+	// the Go version used to build govulncheck and the one currently on PATH.
+	errGoVersionMismatch = errors.New(`Loading packages failed, possibly due to a mismatch between the Go version
+used to build govulncheck and the Go version on PATH. Consider rebuilding
+govulncheck with the current Go version.`)
+
+	// errNoGoMod indicates that a go.mod file was not found in this module.
+	errNoGoMod = errors.New(`no go.mod file
+
+govulncheck only works with Go modules. Try navigating to your module directory.
+Otherwise, run go mod init to make your project a module.
+
+See https://go.dev/doc/modules/managing-dependencies for more information.`)
+
+	// errNoBinaryFlag indicates that govulncheck was run on a file, without
+	// the -mode=binary flag.
+	errNoBinaryFlag = errors.New(`By default, govulncheck runs source analysis on Go modules.
+
+Did you mean to run govulncheck with -mode=binary?
+
+For details, run govulncheck -h.`)
+)
+
+type exitCodeError struct {
+	message string
+	code    int
+}
+
+func (e *exitCodeError) Error() string { return e.message }
+func (e *exitCodeError) ExitCode() int { return e.code }
+
+// isGoVersionMismatchError checks if err is due to mismatch between
+// the Go version used to build govulncheck and the one currently
+// on PATH.
+func isGoVersionMismatchError(err error) bool {
+	msg := err.Error()
+	// See golang.org/x/tools/go/packages/packages.go.
+	return strings.Contains(msg, "This application uses version go") &&
+		strings.Contains(msg, "It may fail to process source files")
+}
diff --git a/vendor/golang.org/x/vuln/internal/scan/extract.go b/vendor/golang.org/x/vuln/internal/scan/extract.go
new file mode 100644
index 0000000..58a3f67
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/extract.go
@@ -0,0 +1,60 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+	"sort"
+
+	"golang.org/x/vuln/internal/derrors"
+	"golang.org/x/vuln/internal/vulncheck"
+)
+
+const (
+	// extractModeID is the unique name of the extract mode protocol
+	extractModeID      = "govulncheck-extract"
+	extractModeVersion = "0.1.0"
+)
+
+// header information for the blob output.
+type header struct {
+	Name    string `json:"name"`
+	Version string `json:"version"`
+}
+
+// runExtract dumps the extracted abstraction of binary at cfg.patterns to out.
+// It prints out exactly two blob messages, one with the header and one with
+// the vulncheck.Bin as the body.
+func runExtract(cfg *config, out io.Writer) (err error) {
+	defer derrors.Wrap(&err, "govulncheck")
+
+	bin, err := createBin(cfg.patterns[0])
+	if err != nil {
+		return err
+	}
+	sortBin(bin) // sort for easier testing and validation
+	header := header{
+		Name:    extractModeID,
+		Version: extractModeVersion,
+	}
+
+	enc := json.NewEncoder(out)
+
+	if err := enc.Encode(header); err != nil {
+		return fmt.Errorf("marshaling blob header: %v", err)
+	}
+	if err := enc.Encode(bin); err != nil {
+		return fmt.Errorf("marshaling blob body: %v", err)
+	}
+	return nil
+}
+
+func sortBin(bin *vulncheck.Bin) {
+	sort.SliceStable(bin.PkgSymbols, func(i, j int) bool {
+		return bin.PkgSymbols[i].Pkg+"."+bin.PkgSymbols[i].Name < bin.PkgSymbols[j].Pkg+"."+bin.PkgSymbols[j].Name
+	})
+}
diff --git a/vendor/golang.org/x/vuln/internal/scan/filepath.go b/vendor/golang.org/x/vuln/internal/scan/filepath.go
new file mode 100644
index 0000000..afd1bb4
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/filepath.go
@@ -0,0 +1,35 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"path/filepath"
+	"strings"
+)
+
+// AbsRelShorter takes path and returns its path relative
+// to the current directory, if shorter. Returns path
+// when path is an empty string or upon any error.
+func AbsRelShorter(path string) string {
+	if path == "" {
+		return ""
+	}
+
+	c, err := filepath.Abs(".")
+	if err != nil {
+		return path
+	}
+	r, err := filepath.Rel(c, path)
+	if err != nil {
+		return path
+	}
+
+	rSegments := strings.Split(r, string(filepath.Separator))
+	pathSegments := strings.Split(path, string(filepath.Separator))
+	if len(rSegments) < len(pathSegments) {
+		return r
+	}
+	return path
+}
diff --git a/vendor/golang.org/x/vuln/internal/scan/flags.go b/vendor/golang.org/x/vuln/internal/scan/flags.go
new file mode 100644
index 0000000..e67c0a1
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/flags.go
@@ -0,0 +1,305 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"errors"
+	"flag"
+	"fmt"
+	"io"
+	"os"
+	"strings"
+
+	"golang.org/x/tools/go/buildutil"
+	"golang.org/x/vuln/internal/govulncheck"
+)
+
+type config struct {
+	govulncheck.Config
+	patterns []string
+	db       string
+	dir      string
+	tags     buildutil.TagsFlag
+	test     bool
+	show     ShowFlag
+	format   FormatFlag
+	version  bool
+	env      []string
+}
+
+func parseFlags(cfg *config, stderr io.Writer, args []string) error {
+	var version bool
+	var json bool
+	var scanFlag ScanFlag
+	var modeFlag ModeFlag
+	flags := flag.NewFlagSet("", flag.ContinueOnError)
+	flags.SetOutput(stderr)
+	flags.BoolVar(&json, "json", false, "output JSON (Go compatible legacy flag, see format flag)")
+	flags.BoolVar(&cfg.test, "test", false, "analyze test files (only valid for source mode, default false)")
+	flags.StringVar(&cfg.dir, "C", "", "change to `dir` before running govulncheck")
+	flags.StringVar(&cfg.db, "db", "https://vuln.go.dev", "vulnerability database `url`")
+	flags.Var(&modeFlag, "mode", "supports 'source', 'binary', and 'extract' (default 'source')")
+	flags.Var(&cfg.tags, "tags", "comma-separated `list` of build tags")
+	flags.Var(&cfg.show, "show", "enable display of additional information specified by the comma separated `list`\nThe supported values are 'traces','color', 'version', and 'verbose'")
+	flags.Var(&cfg.format, "format", "specify format output\nThe supported values are 'text', 'json', 'sarif', and 'openvex' (default 'text')")
+	flags.BoolVar(&version, "version", false, "print the version information")
+	flags.Var(&scanFlag, "scan", "set the scanning level desired, one of 'module', 'package', or 'symbol' (default 'symbol')")
+
+	// We don't want to print the whole usage message on each flags
+	// error, so we set to a no-op and do the printing ourselves.
+	flags.Usage = func() {}
+	usage := func() {
+		fmt.Fprint(flags.Output(), `Govulncheck reports known vulnerabilities in dependencies.
+
+Usage:
+
+	govulncheck [flags] [patterns]
+	govulncheck -mode=binary [flags] [binary]
+
+`)
+		flags.PrintDefaults()
+		fmt.Fprintf(flags.Output(), "\n%s\n", detailsMessage)
+	}
+
+	if err := flags.Parse(args); err != nil {
+		if err == flag.ErrHelp {
+			usage() // print usage only on help
+			return errHelp
+		}
+		return errUsage
+	}
+	cfg.patterns = flags.Args()
+	if version {
+		cfg.show = append(cfg.show, "version")
+		cfg.version = true
+	}
+	cfg.ScanLevel = govulncheck.ScanLevel(scanFlag)
+	cfg.ScanMode = govulncheck.ScanMode(modeFlag)
+	if err := validateConfig(cfg, json); err != nil {
+		fmt.Fprintln(flags.Output(), err)
+		return errUsage
+	}
+	return nil
+}
+
+func validateConfig(cfg *config, json bool) error {
+	// take care of default values
+	if cfg.ScanMode == "" {
+		cfg.ScanMode = govulncheck.ScanModeSource
+	}
+	if cfg.ScanLevel == "" {
+		cfg.ScanLevel = govulncheck.ScanLevelSymbol
+	}
+	if json {
+		if cfg.format != formatUnset {
+			return fmt.Errorf("the -json flag cannot be used with -format flag")
+		}
+		cfg.format = formatJSON
+	} else {
+		if cfg.format == formatUnset {
+			cfg.format = formatText
+		}
+	}
+
+	// show flag is only supported with text output
+	if cfg.format != formatText && len(cfg.show) > 0 {
+		return fmt.Errorf("the -show flag is not supported for %s output", cfg.format)
+	}
+
+	switch cfg.ScanMode {
+	case govulncheck.ScanModeSource:
+		if len(cfg.patterns) == 1 && isFile(cfg.patterns[0]) {
+			return fmt.Errorf("%q is a file.\n\n%v", cfg.patterns[0], errNoBinaryFlag)
+		}
+		if cfg.ScanLevel == govulncheck.ScanLevelModule && len(cfg.patterns) != 0 {
+			return fmt.Errorf("patterns are not accepted for module only scanning")
+		}
+	case govulncheck.ScanModeBinary:
+		if cfg.test {
+			return fmt.Errorf("the -test flag is not supported in binary mode")
+		}
+		if len(cfg.tags) > 0 {
+			return fmt.Errorf("the -tags flag is not supported in binary mode")
+		}
+		if len(cfg.patterns) != 1 {
+			return fmt.Errorf("only 1 binary can be analyzed at a time")
+		}
+		if !isFile(cfg.patterns[0]) {
+			return fmt.Errorf("%q is not a file", cfg.patterns[0])
+		}
+	case govulncheck.ScanModeExtract:
+		if cfg.test {
+			return fmt.Errorf("the -test flag is not supported in extract mode")
+		}
+		if len(cfg.tags) > 0 {
+			return fmt.Errorf("the -tags flag is not supported in extract mode")
+		}
+		if len(cfg.patterns) != 1 {
+			return fmt.Errorf("only 1 binary can be extracted at a time")
+		}
+		if cfg.format == formatJSON {
+			return fmt.Errorf("the json format must be off in extract mode")
+		}
+		if !isFile(cfg.patterns[0]) {
+			return fmt.Errorf("%q is not a file (source extraction is not supported)", cfg.patterns[0])
+		}
+	case govulncheck.ScanModeConvert:
+		if len(cfg.patterns) != 0 {
+			return fmt.Errorf("patterns are not accepted in convert mode")
+		}
+		if cfg.dir != "" {
+			return fmt.Errorf("the -C flag is not supported in convert mode")
+		}
+		if cfg.test {
+			return fmt.Errorf("the -test flag is not supported in convert mode")
+		}
+		if len(cfg.tags) > 0 {
+			return fmt.Errorf("the -tags flag is not supported in convert mode")
+		}
+	case govulncheck.ScanModeQuery:
+		if cfg.test {
+			return fmt.Errorf("the -test flag is not supported in query mode")
+		}
+		if len(cfg.tags) > 0 {
+			return fmt.Errorf("the -tags flag is not supported in query mode")
+		}
+		if cfg.format != formatJSON {
+			return fmt.Errorf("the json format must be set in query mode")
+		}
+		for _, pattern := range cfg.patterns {
+			// Parse the input here so that we can catch errors before
+			// outputting the Config.
+			if _, _, err := parseModuleQuery(pattern); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func isFile(path string) bool {
+	s, err := os.Stat(path)
+	if err != nil {
+		return false
+	}
+	return !s.IsDir()
+}
+
+var errFlagParse = errors.New("see -help for details")
+
+// ShowFlag is used for parsing and validation of
+// govulncheck -show flag.
+type ShowFlag []string
+
+var supportedShows = map[string]bool{
+	"traces":  true,
+	"color":   true,
+	"verbose": true,
+	"version": true,
+}
+
+func (v *ShowFlag) Set(s string) error {
+	if s == "" {
+		return nil
+	}
+	for _, show := range strings.Split(s, ",") {
+		sh := strings.TrimSpace(show)
+		if _, ok := supportedShows[sh]; !ok {
+			return errFlagParse
+		}
+		*v = append(*v, sh)
+	}
+	return nil
+}
+
+func (v *ShowFlag) Get() interface{} { return *v }
+func (v *ShowFlag) String() string   { return "" }
+
+// Update the text handler h with values of the flag.
+func (v ShowFlag) Update(h *TextHandler) {
+	for _, show := range v {
+		switch show {
+		case "traces":
+			h.showTraces = true
+		case "color":
+			h.showColor = true
+		case "version":
+			h.showVersion = true
+		case "verbose":
+			h.showVerbose = true
+		}
+	}
+}
+
+// FormatFlag is used for parsing and validation of
+// govulncheck -format flag.
+type FormatFlag string
+
+const (
+	formatUnset   = ""
+	formatJSON    = "json"
+	formatText    = "text"
+	formatSarif   = "sarif"
+	formatOpenVEX = "openvex"
+)
+
+var supportedFormats = map[string]bool{
+	formatJSON:    true,
+	formatText:    true,
+	formatSarif:   true,
+	formatOpenVEX: true,
+}
+
+func (f *FormatFlag) Get() interface{} { return *f }
+func (f *FormatFlag) Set(s string) error {
+	if _, ok := supportedFormats[s]; !ok {
+		return errFlagParse
+	}
+	*f = FormatFlag(s)
+	return nil
+}
+func (f *FormatFlag) String() string { return "" }
+
+// ModeFlag is used for parsing and validation of
+// govulncheck -mode flag.
+type ModeFlag string
+
+var supportedModes = map[string]bool{
+	govulncheck.ScanModeSource:  true,
+	govulncheck.ScanModeBinary:  true,
+	govulncheck.ScanModeConvert: true,
+	govulncheck.ScanModeQuery:   true,
+	govulncheck.ScanModeExtract: true,
+}
+
+func (f *ModeFlag) Get() interface{} { return *f }
+func (f *ModeFlag) Set(s string) error {
+	if _, ok := supportedModes[s]; !ok {
+		return errFlagParse
+	}
+	*f = ModeFlag(s)
+	return nil
+}
+func (f *ModeFlag) String() string { return "" }
+
+// ScanFlag is used for parsing and validation of
+// govulncheck -scan flag.
+type ScanFlag string
+
+var supportedLevels = map[string]bool{
+	govulncheck.ScanLevelModule:  true,
+	govulncheck.ScanLevelPackage: true,
+	govulncheck.ScanLevelSymbol:  true,
+}
+
+func (f *ScanFlag) Get() interface{} { return *f }
+func (f *ScanFlag) Set(s string) error {
+	if _, ok := supportedLevels[s]; !ok {
+		return errFlagParse
+	}
+	*f = ScanFlag(s)
+	return nil
+}
+func (f *ScanFlag) String() string { return "" }
diff --git a/vendor/golang.org/x/vuln/internal/scan/query.go b/vendor/golang.org/x/vuln/internal/scan/query.go
new file mode 100644
index 0000000..7b47218
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/query.go
@@ -0,0 +1,74 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"context"
+	"fmt"
+	"regexp"
+
+	"golang.org/x/vuln/internal/client"
+	"golang.org/x/vuln/internal/govulncheck"
+	isem "golang.org/x/vuln/internal/semver"
+)
+
+// runQuery reports vulnerabilities that apply to the queries in the config.
+func runQuery(ctx context.Context, handler govulncheck.Handler, cfg *config, c *client.Client) error {
+	reqs := make([]*client.ModuleRequest, len(cfg.patterns))
+	for i, query := range cfg.patterns {
+		mod, ver, err := parseModuleQuery(query)
+		if err != nil {
+			return err
+		}
+		if err := handler.Progress(queryProgressMessage(mod, ver)); err != nil {
+			return err
+		}
+		reqs[i] = &client.ModuleRequest{
+			Path: mod, Version: ver,
+		}
+	}
+
+	resps, err := c.ByModules(ctx, reqs)
+	if err != nil {
+		return err
+	}
+
+	ids := make(map[string]bool)
+	for _, resp := range resps {
+		for _, entry := range resp.Entries {
+			if _, ok := ids[entry.ID]; !ok {
+				err := handler.OSV(entry)
+				if err != nil {
+					return err
+				}
+				ids[entry.ID] = true
+			}
+		}
+	}
+
+	return nil
+}
+
+func queryProgressMessage(module, version string) *govulncheck.Progress {
+	return &govulncheck.Progress{
+		Message: fmt.Sprintf("Looking up vulnerabilities in %s at %s...", module, version),
+	}
+}
+
+var modQueryRegex = regexp.MustCompile(`(.+)@(.+)`)
+
+func parseModuleQuery(pattern string) (_ string, _ string, err error) {
+	matches := modQueryRegex.FindStringSubmatch(pattern)
+	// matches should be [module@version, module, version]
+	if len(matches) != 3 {
+		return "", "", fmt.Errorf("invalid query %s: must be of the form module@version", pattern)
+	}
+	mod, ver := matches[1], matches[2]
+	if !isem.Valid(ver) {
+		return "", "", fmt.Errorf("version %s is not valid semver", ver)
+	}
+
+	return mod, ver, nil
+}
diff --git a/vendor/golang.org/x/vuln/internal/scan/run.go b/vendor/golang.org/x/vuln/internal/scan/run.go
new file mode 100644
index 0000000..560a3ad
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/run.go
@@ -0,0 +1,165 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"context"
+	"fmt"
+	"io"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"runtime/debug"
+	"strings"
+	"time"
+
+	"golang.org/x/telemetry/counter"
+	"golang.org/x/vuln/internal/client"
+	"golang.org/x/vuln/internal/govulncheck"
+	"golang.org/x/vuln/internal/openvex"
+	"golang.org/x/vuln/internal/sarif"
+)
+
+// RunGovulncheck performs main govulncheck functionality.
+// On failure, the returned error wraps an exit code error (see scan.Cmd.Wait).
+func RunGovulncheck(ctx context.Context, env []string, r io.Reader, stdout io.Writer, stderr io.Writer, args []string) error {
+	cfg := &config{env: env}
+	if err := parseFlags(cfg, stderr, args); err != nil {
+		return err
+	}
+
+	client, err := client.NewClient(cfg.db, nil)
+	if err != nil {
+		return fmt.Errorf("creating client: %w", err)
+	}
+
+	prepareConfig(ctx, cfg, client)
+	var handler govulncheck.Handler
+	switch cfg.format {
+	case formatJSON:
+		handler = govulncheck.NewJSONHandler(stdout)
+	case formatSarif:
+		handler = sarif.NewHandler(stdout)
+	case formatOpenVEX:
+		handler = openvex.NewHandler(stdout)
+	default:
+		th := NewTextHandler(stdout)
+		cfg.show.Update(th)
+		handler = th
+	}
+
+	if err := handler.Config(&cfg.Config); err != nil {
+		return err
+	}
+
+	if cfg.version {
+		// If the -version flag is passed, exit before doing anything else. This is different than
+		// passing -show which includes "version".
+		return nil
+	}
+
+	incTelemetryFlagCounters(cfg)
+
+	switch cfg.ScanMode {
+	case govulncheck.ScanModeSource:
+		dir := filepath.FromSlash(cfg.dir)
+		err = runSource(ctx, handler, cfg, client, dir)
+	case govulncheck.ScanModeBinary:
+		err = runBinary(ctx, handler, cfg, client)
+	case govulncheck.ScanModeExtract:
+		return runExtract(cfg, stdout)
+	case govulncheck.ScanModeQuery:
+		err = runQuery(ctx, handler, cfg, client)
+	case govulncheck.ScanModeConvert:
+		err = govulncheck.HandleJSON(r, handler)
+	}
+	if err != nil {
+		return err
+	}
+	return Flush(handler)
+}
+
+func prepareConfig(ctx context.Context, cfg *config, client *client.Client) {
+	cfg.ProtocolVersion = govulncheck.ProtocolVersion
+	cfg.DB = cfg.db
+	if cfg.ScanMode == govulncheck.ScanModeSource && cfg.GoVersion == "" {
+		const goverPrefix = "GOVERSION="
+		for _, env := range cfg.env {
+			if val := strings.TrimPrefix(env, goverPrefix); val != env {
+				cfg.GoVersion = val
+			}
+		}
+		if cfg.GoVersion == "" {
+			if out, err := exec.Command("go", "env", "GOVERSION").Output(); err == nil {
+				cfg.GoVersion = strings.TrimSpace(string(out))
+			}
+		}
+	}
+	if bi, ok := debug.ReadBuildInfo(); ok {
+		scannerVersion(cfg, bi)
+	}
+	if mod, err := client.LastModifiedTime(ctx); err == nil {
+		cfg.DBLastModified = &mod
+	}
+}
+
+// scannerVersion reconstructs the current version of
+// this binary used from the build info.
+func scannerVersion(cfg *config, bi *debug.BuildInfo) {
+	if bi.Path != "" {
+		cfg.ScannerName = strings.TrimSuffix(path.Base(bi.Path), ".test")
+	}
+	if bi.Main.Version != "" && bi.Main.Version != "(devel)" {
+		cfg.ScannerVersion = bi.Main.Version
+		return
+	}
+
+	// TODO(https://go.dev/issue/29228): we need to manually construct the
+	// version string when it is "(devel)" until #29228 is resolved.
+	var revision, at string
+	for _, s := range bi.Settings {
+		if s.Key == "vcs.revision" {
+			revision = s.Value
+		}
+		if s.Key == "vcs.time" {
+			at = s.Value
+		}
+	}
+	buf := strings.Builder{}
+	buf.WriteString("v0.0.0")
+	if revision != "" {
+		buf.WriteString("-")
+		buf.WriteString(revision[:12])
+	}
+	if at != "" {
+		// commit time is of the form 2023-01-25T19:57:54Z
+		p, err := time.Parse(time.RFC3339, at)
+		if err == nil {
+			buf.WriteString("-")
+			buf.WriteString(p.Format("20060102150405"))
+		}
+	}
+	cfg.ScannerVersion = buf.String()
+}
+
+func incTelemetryFlagCounters(cfg *config) {
+	counter.Inc(fmt.Sprintf("govulncheck/mode:%s", cfg.ScanMode))
+	counter.Inc(fmt.Sprintf("govulncheck/scan:%s", cfg.ScanLevel))
+	counter.Inc(fmt.Sprintf("govulncheck/format:%s", cfg.format))
+
+	if len(cfg.show) == 0 {
+		counter.Inc("govulncheck/show:none")
+	}
+	for _, s := range cfg.show {
+		counter.Inc(fmt.Sprintf("govulncheck/show:%s", s))
+	}
+}
+
+func Flush(h govulncheck.Handler) error {
+	if th, ok := h.(interface{ Flush() error }); ok {
+		return th.Flush()
+	}
+	return nil
+}
diff --git a/vendor/golang.org/x/vuln/internal/scan/source.go b/vendor/golang.org/x/vuln/internal/scan/source.go
new file mode 100644
index 0000000..b34e443
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/source.go
@@ -0,0 +1,49 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"context"
+	"fmt"
+
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/vuln/internal/client"
+	"golang.org/x/vuln/internal/derrors"
+	"golang.org/x/vuln/internal/govulncheck"
+	"golang.org/x/vuln/internal/vulncheck"
+)
+
+// runSource reports vulnerabilities that affect the analyzed packages.
+//
+// Vulnerabilities can be called (affecting the package, because a vulnerable
+// symbol is actually exercised) or just imported by the package
+// (likely having a non-affecting outcome).
+func runSource(ctx context.Context, handler govulncheck.Handler, cfg *config, client *client.Client, dir string) (err error) {
+	defer derrors.Wrap(&err, "govulncheck")
+
+	if cfg.ScanLevel.WantPackages() && len(cfg.patterns) == 0 {
+		return errNoPatterns
+	}
+	if !gomodExists(dir) {
+		return errNoGoMod
+	}
+	graph := vulncheck.NewPackageGraph(cfg.GoVersion)
+	pkgConfig := &packages.Config{
+		Dir:   dir,
+		Tests: cfg.test,
+		Env:   cfg.env,
+	}
+	if err := graph.LoadPackagesAndMods(pkgConfig, cfg.tags, cfg.patterns, cfg.ScanLevel == govulncheck.ScanLevelSymbol); err != nil {
+		if isGoVersionMismatchError(err) {
+			return fmt.Errorf("%v\n\n%v", errGoVersionMismatch, err)
+		}
+		return fmt.Errorf("loading packages: %w", err)
+	}
+
+	if cfg.ScanLevel.WantPackages() && len(graph.TopPkgs()) == 0 {
+		return errNoPackagesMatched
+	}
+	return vulncheck.Source(ctx, handler, &cfg.Config, client, graph)
+}
diff --git a/vendor/golang.org/x/vuln/internal/scan/stdlib.go b/vendor/golang.org/x/vuln/internal/scan/stdlib.go
new file mode 100644
index 0000000..19b9fb4
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/stdlib.go
@@ -0,0 +1,71 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"fmt"
+	"strings"
+
+	"golang.org/x/mod/semver"
+)
+
+// Support functions for standard library packages.
+// These are copied from the internal/stdlib package in the pkgsite repo.
+
+// semverToGoTag returns the Go standard library repository tag corresponding
+// to semver, a version string without the initial "v".
+// Go tags differ from standard semantic versions in a few ways,
+// such as beginning with "go" instead of "v".
+func semverToGoTag(v string) string {
+	if strings.HasPrefix(v, "v0.0.0") {
+		return "master"
+	}
+	// Special case: v1.0.0 => go1.
+	if v == "v1.0.0" {
+		return "go1"
+	}
+	if !semver.IsValid(v) {
+		return fmt.Sprintf("", v)
+	}
+	goVersion := semver.Canonical(v)
+	prerelease := semver.Prerelease(goVersion)
+	versionWithoutPrerelease := strings.TrimSuffix(goVersion, prerelease)
+	patch := strings.TrimPrefix(versionWithoutPrerelease, semver.MajorMinor(goVersion)+".")
+	if patch == "0" {
+		versionWithoutPrerelease = strings.TrimSuffix(versionWithoutPrerelease, ".0")
+	}
+	goVersion = fmt.Sprintf("go%s", strings.TrimPrefix(versionWithoutPrerelease, "v"))
+	if prerelease != "" {
+		// Go prereleases look like  "beta1" instead of "beta.1".
+		// "beta1" is bad for sorting (since beta10 comes before beta9), so
+		// require the dot form.
+		i := finalDigitsIndex(prerelease)
+		if i >= 1 {
+			if prerelease[i-1] != '.' {
+				return fmt.Sprintf("", v)
+			}
+			// Remove the dot.
+			prerelease = prerelease[:i-1] + prerelease[i:]
+		}
+		goVersion += strings.TrimPrefix(prerelease, "-")
+	}
+	return goVersion
+}
+
+// finalDigitsIndex returns the index of the first digit in the sequence of digits ending s.
+// If s doesn't end in digits, it returns -1.
+func finalDigitsIndex(s string) int {
+	// Assume ASCII (since the semver package does anyway).
+	var i int
+	for i = len(s) - 1; i >= 0; i-- {
+		if s[i] < '0' || s[i] > '9' {
+			break
+		}
+	}
+	if i == len(s)-1 {
+		return -1
+	}
+	return i + 1
+}
diff --git a/vendor/golang.org/x/vuln/internal/scan/template.go b/vendor/golang.org/x/vuln/internal/scan/template.go
new file mode 100644
index 0000000..5c1a4a7
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/template.go
@@ -0,0 +1,290 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"go/token"
+	"io"
+	"path"
+	"sort"
+	"strconv"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"golang.org/x/vuln/internal/govulncheck"
+	"golang.org/x/vuln/internal/osv"
+	"golang.org/x/vuln/internal/traces"
+)
+
+type findingSummary struct {
+	*govulncheck.Finding
+	Compact string
+	OSV     *osv.Entry
+}
+
+type summaryCounters struct {
+	VulnerabilitiesCalled   int
+	ModulesCalled           int
+	VulnerabilitiesImported int
+	VulnerabilitiesRequired int
+	StdlibCalled            bool
+}
+
+func fixupFindings(osvs []*osv.Entry, findings []*findingSummary) {
+	for _, f := range findings {
+		f.OSV = getOSV(osvs, f.Finding.OSV)
+	}
+}
+
+func groupByVuln(findings []*findingSummary) [][]*findingSummary {
+	return groupBy(findings, func(left, right *findingSummary) int {
+		return -strings.Compare(left.OSV.ID, right.OSV.ID)
+	})
+}
+
+func groupByModule(findings []*findingSummary) [][]*findingSummary {
+	return groupBy(findings, func(left, right *findingSummary) int {
+		return strings.Compare(left.Trace[0].Module, right.Trace[0].Module)
+	})
+}
+
+func groupBy(findings []*findingSummary, compare func(left, right *findingSummary) int) [][]*findingSummary {
+	switch len(findings) {
+	case 0:
+		return nil
+	case 1:
+		return [][]*findingSummary{findings}
+	}
+	sort.SliceStable(findings, func(i, j int) bool {
+		return compare(findings[i], findings[j]) < 0
+	})
+	result := [][]*findingSummary{}
+	first := 0
+	for i, next := range findings {
+		if i == first {
+			continue
+		}
+		if compare(findings[first], next) != 0 {
+			result = append(result, findings[first:i])
+			first = i
+		}
+	}
+	result = append(result, findings[first:])
+	return result
+}
+
+func isRequired(findings []*findingSummary) bool {
+	for _, f := range findings {
+		if f.Trace[0].Module != "" {
+			return true
+		}
+	}
+	return false
+}
+
+func isImported(findings []*findingSummary) bool {
+	for _, f := range findings {
+		if f.Trace[0].Package != "" {
+			return true
+		}
+	}
+	return false
+}
+
+func isCalled(findings []*findingSummary) bool {
+	for _, f := range findings {
+		if f.Trace[0].Function != "" {
+			return true
+		}
+	}
+	return false
+}
+
+func getOSV(osvs []*osv.Entry, id string) *osv.Entry {
+	for _, entry := range osvs {
+		if entry.ID == id {
+			return entry
+		}
+	}
+	return &osv.Entry{
+		ID:               id,
+		DatabaseSpecific: &osv.DatabaseSpecific{},
+	}
+}
+
+func newFindingSummary(f *govulncheck.Finding) *findingSummary {
+	return &findingSummary{
+		Finding: f,
+		Compact: compactTrace(f),
+	}
+}
+
+// platforms returns a string describing the GOOS, GOARCH,
+// or GOOS/GOARCH pairs that the vuln affects for a particular
+// module mod. If it affects all of them, it returns the empty
+// string.
+//
+// When mod is an empty string, returns platform information for
+// all modules of e.
+func platforms(mod string, e *osv.Entry) []string {
+	if e == nil {
+		return nil
+	}
+	platforms := map[string]bool{}
+	for _, a := range e.Affected {
+		if mod != "" && a.Module.Path != mod {
+			continue
+		}
+		for _, p := range a.EcosystemSpecific.Packages {
+			for _, os := range p.GOOS {
+				// In case there are no specific architectures,
+				// just list the os entries.
+				if len(p.GOARCH) == 0 {
+					platforms[os] = true
+					continue
+				}
+				// Otherwise, list all the os+arch combinations.
+				for _, arch := range p.GOARCH {
+					platforms[os+"/"+arch] = true
+				}
+			}
+			// Cover the case where there are no specific
+			// operating systems listed.
+			if len(p.GOOS) == 0 {
+				for _, arch := range p.GOARCH {
+					platforms[arch] = true
+				}
+			}
+		}
+	}
+	var keys []string
+	for k := range platforms {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	return keys
+}
+
+func posToString(p *govulncheck.Position) string {
+	if p == nil || p.Line <= 0 {
+		return ""
+	}
+	return token.Position{
+		Filename: AbsRelShorter(p.Filename),
+		Offset:   p.Offset,
+		Line:     p.Line,
+		Column:   p.Column,
+	}.String()
+}
+
+func symbol(frame *govulncheck.Frame, short bool) string {
+	buf := &strings.Builder{}
+	addSymbol(buf, frame, short)
+	return buf.String()
+}
+
+func symbolName(frame *govulncheck.Frame) string {
+	buf := &strings.Builder{}
+	addSymbolName(buf, frame)
+	return buf.String()
+}
+
+// compactTrace returns a short description of the call stack.
+// It prefers to show you the edge from the top module to other code, along with
+// the vulnerable symbol.
+// Where the vulnerable symbol directly called by the users code, it will only
+// show those two points.
+// If the vulnerable symbol is in the users code, it will show the entry point
+// and the vulnerable symbol.
+func compactTrace(finding *govulncheck.Finding) string {
+	compact := traces.Compact(finding)
+	if len(compact) == 0 {
+		return ""
+	}
+
+	l := len(compact)
+	iTop := l - 1
+	buf := &strings.Builder{}
+	topPos := posToString(compact[iTop].Position)
+	if topPos != "" {
+		buf.WriteString(topPos)
+		buf.WriteString(": ")
+	}
+
+	if l > 1 {
+		// print the root of the compact trace
+		addSymbol(buf, compact[iTop], true)
+		buf.WriteString(" calls ")
+	}
+	if l > 2 {
+		// print next element of the trace, if any
+		addSymbol(buf, compact[iTop-1], true)
+		buf.WriteString(", which")
+		if l > 3 {
+			// don't print the third element, just acknowledge it
+			buf.WriteString(" eventually")
+		}
+		buf.WriteString(" calls ")
+	}
+	addSymbol(buf, compact[0], true) // print the vulnerable symbol
+	return buf.String()
+}
+
+// notIdentifier reports whether ch is an invalid identifier character.
+func notIdentifier(ch rune) bool {
+	return !('a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' ||
+		'0' <= ch && ch <= '9' ||
+		ch == '_' ||
+		ch >= utf8.RuneSelf && (unicode.IsLetter(ch) || unicode.IsDigit(ch)))
+}
+
+// importPathToAssumedName is taken from goimports, it works out the natural imported name
+// for a package.
+// This is used to get a shorter identifier in the compact stack trace
+func importPathToAssumedName(importPath string) string {
+	base := path.Base(importPath)
+	if strings.HasPrefix(base, "v") {
+		if _, err := strconv.Atoi(base[1:]); err == nil {
+			dir := path.Dir(importPath)
+			if dir != "." {
+				base = path.Base(dir)
+			}
+		}
+	}
+	base = strings.TrimPrefix(base, "go-")
+	if i := strings.IndexFunc(base, notIdentifier); i >= 0 {
+		base = base[:i]
+	}
+	return base
+}
+
+func addSymbol(w io.Writer, frame *govulncheck.Frame, short bool) {
+	if frame.Function == "" {
+		return
+	}
+	if frame.Package != "" {
+		pkg := frame.Package
+		if short {
+			pkg = importPathToAssumedName(frame.Package)
+		}
+		io.WriteString(w, pkg)
+		io.WriteString(w, ".")
+	}
+	addSymbolName(w, frame)
+}
+
+func addSymbolName(w io.Writer, frame *govulncheck.Frame) {
+	if frame.Receiver != "" {
+		if frame.Receiver[0] == '*' {
+			io.WriteString(w, frame.Receiver[1:])
+		} else {
+			io.WriteString(w, frame.Receiver)
+		}
+		io.WriteString(w, ".")
+	}
+	funcname := strings.Split(frame.Function, "$")[0]
+	io.WriteString(w, funcname)
+}
diff --git a/vendor/golang.org/x/vuln/internal/scan/text.go b/vendor/golang.org/x/vuln/internal/scan/text.go
new file mode 100644
index 0000000..ab49bdd
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/text.go
@@ -0,0 +1,575 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"fmt"
+	"io"
+	"sort"
+	"strings"
+
+	"golang.org/x/vuln/internal"
+	"golang.org/x/vuln/internal/govulncheck"
+	"golang.org/x/vuln/internal/osv"
+	"golang.org/x/vuln/internal/vulncheck"
+)
+
+type style int
+
+const (
+	defaultStyle = style(iota)
+	osvCalledStyle
+	osvImportedStyle
+	detailsStyle
+	sectionStyle
+	keyStyle
+	valueStyle
+)
+
+// NewtextHandler returns a handler that writes govulncheck output as text.
+func NewTextHandler(w io.Writer) *TextHandler {
+	return &TextHandler{w: w}
+}
+
+type TextHandler struct {
+	w         io.Writer
+	sbom      *govulncheck.SBOM
+	osvs      []*osv.Entry
+	findings  []*findingSummary
+	scanLevel govulncheck.ScanLevel
+	scanMode  govulncheck.ScanMode
+
+	err error
+
+	showColor   bool
+	showTraces  bool
+	showVersion bool
+	showVerbose bool
+}
+
+const (
+	detailsMessage = `For details, see https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck.`
+
+	binaryProgressMessage = `Scanning your binary for known vulnerabilities...`
+
+	noVulnsMessage = `No vulnerabilities found.`
+
+	noOtherVulnsMessage = `No other vulnerabilities found.`
+
+	verboseMessage = `'-show verbose' for more details`
+
+	symbolMessage = `'-scan symbol' for more fine grained vulnerability detection`
+)
+
+func (h *TextHandler) Flush() error {
+	if h.showVerbose {
+		h.printSBOM()
+	}
+	if len(h.findings) == 0 {
+		h.print(noVulnsMessage + "\n")
+	} else {
+		fixupFindings(h.osvs, h.findings)
+		counters := h.allVulns(h.findings)
+		h.summary(counters)
+	}
+	if h.err != nil {
+		return h.err
+	}
+	// We found vulnerabilities when the findings' level matches the scan level.
+	if (isCalled(h.findings) && h.scanLevel == govulncheck.ScanLevelSymbol) ||
+		(isImported(h.findings) && h.scanLevel == govulncheck.ScanLevelPackage) ||
+		(isRequired(h.findings) && h.scanLevel == govulncheck.ScanLevelModule) {
+		return errVulnerabilitiesFound
+	}
+
+	return nil
+}
+
+// Config writes version information only if --version was set.
+func (h *TextHandler) Config(config *govulncheck.Config) error {
+	h.scanLevel = config.ScanLevel
+	h.scanMode = config.ScanMode
+
+	if !h.showVersion {
+		return nil
+	}
+	if config.GoVersion != "" {
+		h.style(keyStyle, "Go: ")
+		h.print(config.GoVersion, "\n")
+	}
+	if config.ScannerName != "" {
+		h.style(keyStyle, "Scanner: ")
+		h.print(config.ScannerName)
+		if config.ScannerVersion != "" {
+			h.print(`@`, config.ScannerVersion)
+		}
+		h.print("\n")
+	}
+	if config.DB != "" {
+		h.style(keyStyle, "DB: ")
+		h.print(config.DB, "\n")
+		if config.DBLastModified != nil {
+			h.style(keyStyle, "DB updated: ")
+			h.print(*config.DBLastModified, "\n")
+		}
+	}
+	h.print("\n")
+	return h.err
+}
+
+func (h *TextHandler) SBOM(sbom *govulncheck.SBOM) error {
+	h.sbom = sbom
+	return nil
+}
+
+func (h *TextHandler) printSBOM() error {
+	if h.sbom == nil {
+		h.print("No packages matched the provided pattern.\n")
+		return nil
+	}
+
+	printed := false
+
+	for i, root := range h.sbom.Roots {
+		if i == 0 {
+			if len(h.sbom.Roots) > 1 {
+				h.print("The package pattern matched the following ", len(h.sbom.Roots), " root packages:\n")
+			} else {
+				h.print("The package pattern matched the following root package:\n")
+			}
+		}
+
+		h.print("  ", root, "\n")
+		printed = true
+	}
+	for i, mod := range h.sbom.Modules {
+		if i == 0 && mod.Path != "stdlib" {
+			h.print("Govulncheck scanned the following ", len(h.sbom.Modules)-1, " modules and the ", h.sbom.GoVersion, " standard library:\n")
+		}
+
+		if mod.Path == "stdlib" {
+			continue
+		}
+
+		h.print("  ", mod.Path)
+		if mod.Version != "" {
+			h.print("@", mod.Version)
+		}
+		h.print("\n")
+		printed = true
+	}
+	if printed {
+		h.print("\n")
+	}
+	return nil
+}
+
+// Progress writes progress updates during govulncheck execution.
+func (h *TextHandler) Progress(progress *govulncheck.Progress) error {
+	if h.showVerbose {
+		h.print(progress.Message, "\n\n")
+	}
+	return h.err
+}
+
+// OSV gathers osv entries to be written.
+func (h *TextHandler) OSV(entry *osv.Entry) error {
+	h.osvs = append(h.osvs, entry)
+	return nil
+}
+
+// Finding gathers vulnerability findings to be written.
+func (h *TextHandler) Finding(finding *govulncheck.Finding) error {
+	if err := validateFindings(finding); err != nil {
+		return err
+	}
+	h.findings = append(h.findings, newFindingSummary(finding))
+	return nil
+}
+
+func (h *TextHandler) allVulns(findings []*findingSummary) summaryCounters {
+	byVuln := groupByVuln(findings)
+	var called, imported, required [][]*findingSummary
+	mods := map[string]struct{}{}
+	stdlibCalled := false
+	for _, findings := range byVuln {
+		switch {
+		case isCalled(findings):
+			called = append(called, findings)
+			if isStdFindings(findings) {
+				stdlibCalled = true
+			} else {
+				mods[findings[0].Trace[0].Module] = struct{}{}
+			}
+		case isImported(findings):
+			imported = append(imported, findings)
+		default:
+			required = append(required, findings)
+		}
+	}
+
+	if h.scanLevel.WantSymbols() {
+		h.style(sectionStyle, "=== Symbol Results ===\n\n")
+		if len(called) == 0 {
+			h.print(noVulnsMessage, "\n\n")
+		}
+		for index, findings := range called {
+			h.vulnerability(index, findings)
+		}
+	}
+
+	if h.scanLevel == govulncheck.ScanLevelPackage || (h.scanLevel.WantPackages() && h.showVerbose) {
+		h.style(sectionStyle, "=== Package Results ===\n\n")
+		if len(imported) == 0 {
+			h.print(choose(!h.scanLevel.WantSymbols(), noVulnsMessage, noOtherVulnsMessage), "\n\n")
+		}
+		for index, findings := range imported {
+			h.vulnerability(index, findings)
+		}
+	}
+
+	if h.showVerbose || h.scanLevel == govulncheck.ScanLevelModule {
+		h.style(sectionStyle, "=== Module Results ===\n\n")
+		if len(required) == 0 {
+			h.print(choose(!h.scanLevel.WantPackages(), noVulnsMessage, noOtherVulnsMessage), "\n\n")
+		}
+		for index, findings := range required {
+			h.vulnerability(index, findings)
+		}
+	}
+
+	return summaryCounters{
+		VulnerabilitiesCalled:   len(called),
+		VulnerabilitiesImported: len(imported),
+		VulnerabilitiesRequired: len(required),
+		ModulesCalled:           len(mods),
+		StdlibCalled:            stdlibCalled,
+	}
+}
+
+func (h *TextHandler) vulnerability(index int, findings []*findingSummary) {
+	h.style(keyStyle, "Vulnerability")
+	h.print(" #", index+1, ": ")
+	if isCalled(findings) {
+		h.style(osvCalledStyle, findings[0].OSV.ID)
+	} else {
+		h.style(osvImportedStyle, findings[0].OSV.ID)
+	}
+	h.print("\n")
+	h.style(detailsStyle)
+	description := findings[0].OSV.Summary
+	if description == "" {
+		description = findings[0].OSV.Details
+	}
+	h.wrap("    ", description, 80)
+	h.style(defaultStyle)
+	h.print("\n")
+	h.style(keyStyle, "  More info:")
+	h.print(" ", findings[0].OSV.DatabaseSpecific.URL, "\n")
+
+	byModule := groupByModule(findings)
+	first := true
+	for _, module := range byModule {
+		// Note: there can be several findingSummaries for the same vulnerability
+		// emitted during streaming for different scan levels.
+
+		// The module is same for all finding summaries.
+		lastFrame := module[0].Trace[0]
+		mod := lastFrame.Module
+		// For stdlib, try to show package path as module name where
+		// the scan level allows it.
+		// TODO: should this be done in byModule as well?
+		path := lastFrame.Module
+		if stdPkg := h.pkg(module); path == internal.GoStdModulePath && stdPkg != "" {
+			path = stdPkg
+		}
+		// All findings on a module are found and fixed at the same version
+		foundVersion := moduleVersionString(lastFrame.Module, lastFrame.Version)
+		fixedVersion := moduleVersionString(lastFrame.Module, module[0].FixedVersion)
+		if !first {
+			h.print("\n")
+		}
+		first = false
+		h.print("  ")
+		if mod == internal.GoStdModulePath {
+			h.print("Standard library")
+		} else {
+			h.style(keyStyle, "Module: ")
+			h.print(mod)
+		}
+		h.print("\n    ")
+		h.style(keyStyle, "Found in: ")
+		h.print(path, "@", foundVersion, "\n    ")
+		h.style(keyStyle, "Fixed in: ")
+		if fixedVersion != "" {
+			h.print(path, "@", fixedVersion)
+		} else {
+			h.print("N/A")
+		}
+		h.print("\n")
+		platforms := platforms(mod, module[0].OSV)
+		if len(platforms) > 0 {
+			h.style(keyStyle, "    Platforms: ")
+			for ip, p := range platforms {
+				if ip > 0 {
+					h.print(", ")
+				}
+				h.print(p)
+			}
+			h.print("\n")
+		}
+		h.traces(module)
+	}
+	h.print("\n")
+}
+
+// pkg gives the package information for findings summaries
+// if one exists. This is only used to print package path
+// instead of a module for stdlib vulnerabilities at symbol
+// and package scan level.
+func (h *TextHandler) pkg(summaries []*findingSummary) string {
+	for _, f := range summaries {
+		if pkg := f.Trace[0].Package; pkg != "" {
+			return pkg
+		}
+	}
+	return ""
+}
+
+// traces prints out the most precise trace information
+// found in the given summaries.
+func (h *TextHandler) traces(traces []*findingSummary) {
+	// Sort the traces by the vulnerable symbol. This
+	// guarantees determinism since we are currently
+	// showing only one trace per symbol.
+	sort.SliceStable(traces, func(i, j int) bool {
+		return symbol(traces[i].Trace[0], true) < symbol(traces[j].Trace[0], true)
+	})
+
+	// compacts are finding summaries with compact traces
+	// suitable for non-verbose textual output. Currently,
+	// only traces produced by symbol analysis.
+	var compacts []*findingSummary
+	for _, t := range traces {
+		if t.Compact != "" {
+			compacts = append(compacts, t)
+		}
+	}
+
+	// binLimit is a limit on the number of binary traces
+	// to show. Traces for binaries are less interesting
+	// as users cannot act on them and they can hence
+	// spam users.
+	const binLimit = 5
+	binary := h.scanMode == govulncheck.ScanModeBinary
+	for i, entry := range compacts {
+		if i == 0 {
+			if binary {
+				h.style(keyStyle, "    Vulnerable symbols found:\n")
+			} else {
+				h.style(keyStyle, "    Example traces found:\n")
+			}
+		}
+
+		// skip showing all symbols in binary mode unless '-show traces' is on.
+		if binary && (i+1) > binLimit && !h.showTraces {
+			h.print("      Use '-show traces' to see the other ", len(compacts)-binLimit, " found symbols\n")
+			break
+		}
+
+		h.print("      #", i+1, ": ")
+
+		if !h.showTraces { // show summarized traces
+			h.print(entry.Compact, "\n")
+			continue
+		}
+
+		if binary {
+			// There are no call stacks in binary mode
+			// so just show the full symbol name.
+			h.print(symbol(entry.Trace[0], false), "\n")
+		} else {
+			h.print("for function ", symbol(entry.Trace[0], false), "\n")
+			for i := len(entry.Trace) - 1; i >= 0; i-- {
+				t := entry.Trace[i]
+				h.print("        ")
+				h.print(symbolName(t))
+				if t.Position != nil {
+					h.print(" @ ", symbolPath(t))
+				}
+				h.print("\n")
+			}
+		}
+	}
+}
+
+// symbolPath returns a user-friendly path to a symbol.
+func symbolPath(t *govulncheck.Frame) string {
+	// Add module path prefix to symbol paths to be more
+	// explicit to which module the symbols belong to.
+	return t.Module + "/" + posToString(t.Position)
+}
+
+func (h *TextHandler) summary(c summaryCounters) {
+	// print short summary of findings identified at the desired level of scan precision
+	var vulnCount int
+	h.print("Your code ", choose(h.scanLevel.WantSymbols(), "is", "may be"), " affected by ")
+	switch h.scanLevel {
+	case govulncheck.ScanLevelSymbol:
+		vulnCount = c.VulnerabilitiesCalled
+	case govulncheck.ScanLevelPackage:
+		vulnCount = c.VulnerabilitiesImported
+	case govulncheck.ScanLevelModule:
+		vulnCount = c.VulnerabilitiesRequired
+	}
+	h.style(valueStyle, vulnCount)
+	h.print(choose(vulnCount == 1, ` vulnerability`, ` vulnerabilities`))
+	if h.scanLevel.WantSymbols() {
+		h.print(choose(c.ModulesCalled > 0 || c.StdlibCalled, ` from `, ``))
+		if c.ModulesCalled > 0 {
+			h.style(valueStyle, c.ModulesCalled)
+			h.print(choose(c.ModulesCalled == 1, ` module`, ` modules`))
+		}
+		if c.StdlibCalled {
+			if c.ModulesCalled != 0 {
+				h.print(` and `)
+			}
+			h.print(`the Go standard library`)
+		}
+	}
+	h.print(".\n")
+
+	// print summary for vulnerabilities found at other levels of scan precision
+	if other := h.summaryOtherVulns(c); other != "" {
+		h.wrap("", other, 80)
+		h.print("\n")
+	}
+
+	// print suggested flags for more/better info depending on scan level and if in verbose mode
+	if sugg := h.summarySuggestion(); sugg != "" {
+		h.wrap("", sugg, 80)
+		h.print("\n")
+	}
+}
+
+func (h *TextHandler) summaryOtherVulns(c summaryCounters) string {
+	var summary strings.Builder
+	if c.VulnerabilitiesRequired+c.VulnerabilitiesImported == 0 {
+		summary.WriteString("This scan found no other vulnerabilities in ")
+		if h.scanLevel.WantSymbols() {
+			summary.WriteString("packages you import or ")
+		}
+		summary.WriteString("modules you require.")
+	} else {
+		summary.WriteString(choose(h.scanLevel.WantPackages(), "This scan also found ", ""))
+		if h.scanLevel.WantSymbols() {
+			summary.WriteString(fmt.Sprint(c.VulnerabilitiesImported))
+			summary.WriteString(choose(c.VulnerabilitiesImported == 1, ` vulnerability `, ` vulnerabilities `))
+			summary.WriteString("in packages you import and ")
+		}
+		if h.scanLevel.WantPackages() {
+			summary.WriteString(fmt.Sprint(c.VulnerabilitiesRequired))
+			summary.WriteString(choose(c.VulnerabilitiesRequired == 1, ` vulnerability `, ` vulnerabilities `))
+			summary.WriteString("in modules you require")
+			summary.WriteString(choose(h.scanLevel.WantSymbols(), ", but your code doesn't appear to call these vulnerabilities.", "."))
+		}
+	}
+	return summary.String()
+}
+
+func (h *TextHandler) summarySuggestion() string {
+	var sugg strings.Builder
+	switch h.scanLevel {
+	case govulncheck.ScanLevelSymbol:
+		if !h.showVerbose {
+			sugg.WriteString("Use " + verboseMessage + ".")
+		}
+	case govulncheck.ScanLevelPackage:
+		sugg.WriteString("Use " + symbolMessage)
+		if !h.showVerbose {
+			sugg.WriteString(" and " + verboseMessage)
+		}
+		sugg.WriteString(".")
+	case govulncheck.ScanLevelModule:
+		sugg.WriteString("Use " + symbolMessage + ".")
+	}
+	return sugg.String()
+}
+
+func (h *TextHandler) style(style style, values ...any) {
+	if h.showColor {
+		switch style {
+		default:
+			h.print(colorReset)
+		case osvCalledStyle:
+			h.print(colorBold, fgRed)
+		case osvImportedStyle:
+			h.print(colorBold, fgGreen)
+		case detailsStyle:
+			h.print(colorFaint)
+		case sectionStyle:
+			h.print(fgBlue)
+		case keyStyle:
+			h.print(colorFaint, fgYellow)
+		case valueStyle:
+			h.print(colorBold, fgCyan)
+		}
+	}
+	h.print(values...)
+	if h.showColor && len(values) > 0 {
+		h.print(colorReset)
+	}
+}
+
+func (h *TextHandler) print(values ...any) int {
+	total, w := 0, 0
+	for _, v := range values {
+		if h.err != nil {
+			return total
+		}
+		// do we need to specialize for some types, like time?
+		w, h.err = fmt.Fprint(h.w, v)
+		total += w
+	}
+	return total
+}
+
+// wrap wraps s to fit in maxWidth by breaking it into lines at whitespace. If a
+// single word is longer than maxWidth, it is retained as its own line.
+func (h *TextHandler) wrap(indent string, s string, maxWidth int) {
+	w := 0
+	for _, f := range strings.Fields(s) {
+		if w > 0 && w+len(f)+1 > maxWidth {
+			// line would be too long with this word
+			h.print("\n")
+			w = 0
+		}
+		if w == 0 {
+			// first field on line, indent
+			w = h.print(indent)
+		} else {
+			// not first word, space separate
+			w += h.print(" ")
+		}
+		// now write the word
+		w += h.print(f)
+	}
+}
+
+func choose[t any](b bool, yes, no t) t {
+	if b {
+		return yes
+	}
+	return no
+}
+
+func isStdFindings(findings []*findingSummary) bool {
+	for _, f := range findings {
+		if vulncheck.IsStdPackage(f.Trace[0].Package) || f.Trace[0].Module == internal.GoStdModulePath {
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/golang.org/x/vuln/internal/scan/util.go b/vendor/golang.org/x/vuln/internal/scan/util.go
new file mode 100644
index 0000000..0d82ca8
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/scan/util.go
@@ -0,0 +1,60 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scan
+
+import (
+	"fmt"
+	"os"
+	"os/exec"
+	"strings"
+
+	"golang.org/x/vuln/internal"
+	"golang.org/x/vuln/internal/govulncheck"
+)
+
+// validateFindings checks that the supplied findings all obey the protocol
+// rules.
+func validateFindings(findings ...*govulncheck.Finding) error {
+	for _, f := range findings {
+		if f.OSV == "" {
+			return fmt.Errorf("invalid finding: all findings must have an associated OSV")
+		}
+		if len(f.Trace) < 1 {
+			return fmt.Errorf("invalid finding: all callstacks must have at least one frame")
+		}
+		for _, frame := range f.Trace {
+			if frame.Version != "" && frame.Module == "" {
+				return fmt.Errorf("invalid finding: if Frame.Version (%s) is set, Frame.Module must also be", frame.Version)
+			}
+			if frame.Package != "" && frame.Module == "" {
+				return fmt.Errorf("invalid finding: if Frame.Package (%s) is set, Frame.Module must also be", frame.Package)
+			}
+			if frame.Function != "" && frame.Package == "" {
+				return fmt.Errorf("invalid finding: if Frame.Function (%s) is set, Frame.Package must also be", frame.Function)
+			}
+		}
+	}
+	return nil
+}
+
+func moduleVersionString(modulePath, version string) string {
+	if version == "" {
+		return ""
+	}
+	if modulePath == internal.GoStdModulePath || modulePath == internal.GoCmdModulePath {
+		version = semverToGoTag(version)
+	}
+	return version
+}
+
+func gomodExists(dir string) bool {
+	cmd := exec.Command("go", "env", "GOMOD")
+	cmd.Dir = dir
+	out, err := cmd.Output()
+	output := strings.TrimSpace(string(out))
+	// If module-aware mode is enabled, but there is no go.mod, GOMOD will be os.DevNull
+	// If module-aware mode is disabled, GOMOD will be the empty string.
+	return err == nil && !(output == os.DevNull || output == "")
+}
diff --git a/vendor/golang.org/x/vuln/internal/semver/affects.go b/vendor/golang.org/x/vuln/internal/semver/affects.go
new file mode 100644
index 0000000..03ea6fd
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/semver/affects.go
@@ -0,0 +1,94 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package semver
+
+import (
+	"sort"
+
+	"golang.org/x/vuln/internal/osv"
+)
+
+func Affects(a []osv.Range, v string) bool {
+	if len(a) == 0 {
+		// No ranges implies all versions are affected
+		return true
+	}
+	var semverRangePresent bool
+	for _, r := range a {
+		if r.Type != osv.RangeTypeSemver {
+			continue
+		}
+		semverRangePresent = true
+		if ContainsSemver(r, v) {
+			return true
+		}
+	}
+	// If there were no semver ranges present we
+	// assume that all semvers are affected, similarly
+	// to how to we assume all semvers are affected
+	// if there are no ranges at all.
+	return !semverRangePresent
+}
+
+// ContainsSemver checks if semver version v is in the
+// range encoded by ar. If ar is not a semver range,
+// returns false. A range is interpreted as a left-closed
+// and right-open interval.
+//
+// Assumes that
+//   - exactly one of Introduced or Fixed fields is set
+//   - ranges in ar are not overlapping
+//   - beginning of time is encoded with .Introduced="0"
+//   - no-fix is not an event, as opposed to being an
+//     event where Introduced="" and Fixed=""
+func ContainsSemver(ar osv.Range, v string) bool {
+	if ar.Type != osv.RangeTypeSemver {
+		return false
+	}
+	if len(ar.Events) == 0 {
+		return true
+	}
+
+	// Strip and then add the semver prefix so we can support bare versions,
+	// versions prefixed with 'v', and versions prefixed with 'go'.
+	v = canonicalizeSemverPrefix(v)
+
+	// Sort events by semver versions. Event for beginning
+	// of time, if present, always comes first.
+	sort.SliceStable(ar.Events, func(i, j int) bool {
+		e1 := ar.Events[i]
+		v1 := e1.Introduced
+		if v1 == "0" {
+			// -inf case.
+			return true
+		}
+		if e1.Fixed != "" {
+			v1 = e1.Fixed
+		}
+
+		e2 := ar.Events[j]
+		v2 := e2.Introduced
+		if v2 == "0" {
+			// -inf case.
+			return false
+		}
+		if e2.Fixed != "" {
+			v2 = e2.Fixed
+		}
+
+		return Less(v1, v2)
+	})
+
+	var affected bool
+	for _, e := range ar.Events {
+		if !affected && e.Introduced != "" {
+			affected = e.Introduced == "0" || !Less(v, e.Introduced)
+		} else if affected && e.Fixed != "" {
+			affected = Less(v, e.Fixed)
+		}
+	}
+
+	return affected
+}
diff --git a/vendor/golang.org/x/vuln/internal/semver/fixed.go b/vendor/golang.org/x/vuln/internal/semver/fixed.go
new file mode 100644
index 0000000..bd29c40
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/semver/fixed.go
@@ -0,0 +1,36 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package semver
+
+import "golang.org/x/vuln/internal/osv"
+
+// NonSupersededFix returns a fixed version from ranges
+// that is not superseded by any other fix or any other
+// introduction of a vulnerability. Returns "" in case
+// there is no such fixed version.
+func NonSupersededFix(ranges []osv.Range) string {
+	var latestFixed string
+	for _, r := range ranges {
+		if r.Type == "SEMVER" {
+			for _, e := range r.Events {
+				fixed := e.Fixed
+				if fixed != "" && Less(latestFixed, fixed) {
+					latestFixed = fixed
+				}
+			}
+
+			// If the vulnerability was re-introduced after the latest fix
+			// we found, there is no latest fix for this range.
+			for _, e := range r.Events {
+				introduced := e.Introduced
+				if introduced != "" && introduced != "0" && Less(latestFixed, introduced) {
+					latestFixed = ""
+					break
+				}
+			}
+		}
+	}
+	return latestFixed
+}
diff --git a/vendor/golang.org/x/vuln/internal/semver/semver.go b/vendor/golang.org/x/vuln/internal/semver/semver.go
new file mode 100644
index 0000000..efe1e00
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/semver/semver.go
@@ -0,0 +1,140 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package semver provides shared utilities for manipulating
+// Go semantic versions.
+package semver
+
+import (
+	"fmt"
+	"regexp"
+	"strings"
+
+	"golang.org/x/mod/semver"
+)
+
+// addSemverPrefix adds a 'v' prefix to s if it isn't already prefixed
+// with 'v' or 'go'. This allows us to easily test go-style SEMVER
+// strings against normal SEMVER strings.
+func addSemverPrefix(s string) string {
+	if !strings.HasPrefix(s, "v") && !strings.HasPrefix(s, "go") {
+		return "v" + s
+	}
+	return s
+}
+
+// removeSemverPrefix removes the 'v' or 'go' prefixes from go-style
+// SEMVER strings, for usage in the public vulnerability format.
+func removeSemverPrefix(s string) string {
+	s = strings.TrimPrefix(s, "v")
+	s = strings.TrimPrefix(s, "go")
+	return s
+}
+
+// canonicalizeSemverPrefix turns a SEMVER string into the canonical
+// representation using the 'v' prefix, as used by the OSV format.
+// Input may be a bare SEMVER ("1.2.3"), Go prefixed SEMVER ("go1.2.3"),
+// or already canonical SEMVER ("v1.2.3").
+func canonicalizeSemverPrefix(s string) string {
+	return addSemverPrefix(removeSemverPrefix(s))
+}
+
+// Less returns whether v1 < v2, where v1 and v2 are
+// semver versions with either a "v", "go" or no prefix.
+func Less(v1, v2 string) bool {
+	return semver.Compare(canonicalizeSemverPrefix(v1), canonicalizeSemverPrefix(v2)) < 0
+}
+
+// Valid returns whether v is valid semver, allowing
+// either a "v", "go" or no prefix.
+func Valid(v string) bool {
+	return semver.IsValid(canonicalizeSemverPrefix(v))
+}
+
+var (
+	// Regexp for matching go tags. The groups are:
+	// 1  the major.minor version
+	// 2  the patch version, or empty if none
+	// 3  the entire prerelease, if present
+	// 4  the prerelease type ("beta" or "rc")
+	// 5  the prerelease number
+	tagRegexp = regexp.MustCompile(`^go(\d+\.\d+)(\.\d+|)((beta|rc|-pre)(\d+))?$`)
+)
+
+// This is a modified copy of pkgsite/internal/stdlib:VersionForTag.
+func GoTagToSemver(tag string) string {
+	if tag == "" {
+		return ""
+	}
+
+	tag = strings.Fields(tag)[0]
+	// Special cases for go1.
+	if tag == "go1" {
+		return "v1.0.0"
+	}
+	if tag == "go1.0" {
+		return ""
+	}
+	m := tagRegexp.FindStringSubmatch(tag)
+	if m == nil {
+		return ""
+	}
+	version := "v" + m[1]
+	if m[2] != "" {
+		version += m[2]
+	} else {
+		version += ".0"
+	}
+	if m[3] != "" {
+		if !strings.HasPrefix(m[4], "-") {
+			version += "-"
+		}
+		version += m[4] + "." + m[5]
+	}
+	return version
+}
+
+// This is a modified copy of pkgsite/internal/stlib:TagForVersion
+func SemverToGoTag(v string) string {
+	// Special case: v1.0.0 => go1.
+	if v == "v1.0.0" {
+		return "go1"
+	}
+
+	goVersion := semver.Canonical(v)
+	prerelease := semver.Prerelease(goVersion)
+	versionWithoutPrerelease := strings.TrimSuffix(goVersion, prerelease)
+	patch := strings.TrimPrefix(versionWithoutPrerelease, semver.MajorMinor(goVersion)+".")
+	if patch == "0" && (semver.Compare(v, "v1.21.0") < 0 || prerelease != "") {
+		// Starting with go1.21.0, the first patch version includes .0.
+		// Prereleases do not include .0 (we don't do prereleases for other patch releases).
+		versionWithoutPrerelease = strings.TrimSuffix(versionWithoutPrerelease, ".0")
+	}
+	goVersion = fmt.Sprintf("go%s", strings.TrimPrefix(versionWithoutPrerelease, "v"))
+	if prerelease != "" {
+		i := finalDigitsIndex(prerelease)
+		if i >= 1 {
+			// Remove the dot.
+			prerelease = prerelease[:i-1] + prerelease[i:]
+		}
+		goVersion += prerelease
+	}
+	return goVersion
+}
+
+// finalDigitsIndex returns the index of the first digit in the sequence of digits ending s.
+// If s doesn't end in digits, it returns -1.
+func finalDigitsIndex(s string) int {
+	// Assume ASCII (since the semver package does anyway).
+	var i int
+	for i = len(s) - 1; i >= 0; i-- {
+		if s[i] < '0' || s[i] > '9' {
+			break
+		}
+	}
+	if i == len(s)-1 {
+		return -1
+	}
+	return i + 1
+}
diff --git a/vendor/golang.org/x/vuln/internal/traces/traces.go b/vendor/golang.org/x/vuln/internal/traces/traces.go
new file mode 100644
index 0000000..e413ae7
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/traces/traces.go
@@ -0,0 +1,46 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package traces
+
+import (
+	"golang.org/x/vuln/internal/govulncheck"
+)
+
+// Compact returns a summarization of finding.Trace. The first
+// returned element is the vulnerable symbol and the last element
+// is the exit point of the user module. There can also be two
+// elements in between, if applicable, which are the two elements
+// preceding the user module exit point.
+func Compact(finding *govulncheck.Finding) []*govulncheck.Frame {
+	if len(finding.Trace) < 1 {
+		return nil
+	}
+	iTop := len(finding.Trace) - 1
+	topModule := finding.Trace[iTop].Module
+	// search for the exit point of the top module
+	for i, frame := range finding.Trace {
+		if frame.Module == topModule {
+			iTop = i
+			break
+		}
+	}
+
+	if iTop == 0 {
+		// all in one module, reset to the end
+		iTop = len(finding.Trace) - 1
+	}
+
+	compact := []*govulncheck.Frame{finding.Trace[0]}
+	if iTop > 1 {
+		if iTop > 2 {
+			compact = append(compact, finding.Trace[iTop-2])
+		}
+		compact = append(compact, finding.Trace[iTop-1])
+	}
+	if iTop > 0 {
+		compact = append(compact, finding.Trace[iTop])
+	}
+	return compact
+}
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/binary.go b/vendor/golang.org/x/vuln/internal/vulncheck/binary.go
new file mode 100644
index 0000000..d78af3f
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/binary.go
@@ -0,0 +1,237 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vulncheck
+
+import (
+	"context"
+	"fmt"
+
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/vuln/internal"
+	"golang.org/x/vuln/internal/buildinfo"
+	"golang.org/x/vuln/internal/client"
+	"golang.org/x/vuln/internal/govulncheck"
+	"golang.org/x/vuln/internal/semver"
+)
+
+// Bin is an abstraction of Go binary containing
+// minimal information needed by govulncheck.
+type Bin struct {
+	// Path of the main package.
+	Path string `json:"path,omitempty"`
+	// Main module. When present, it never has empty information.
+	Main       *packages.Module   `json:"main,omitempty"`
+	Modules    []*packages.Module `json:"modules,omitempty"`
+	PkgSymbols []buildinfo.Symbol `json:"pkgSymbols,omitempty"`
+	GoVersion  string             `json:"goVersion,omitempty"`
+	GOOS       string             `json:"goos,omitempty"`
+	GOARCH     string             `json:"goarch,omitempty"`
+}
+
+// Binary detects presence of vulnerable symbols in bin and
+// emits findings to handler.
+func Binary(ctx context.Context, handler govulncheck.Handler, bin *Bin, cfg *govulncheck.Config, client *client.Client) error {
+	vr, err := binary(ctx, handler, bin, cfg, client)
+	if err != nil {
+		return err
+	}
+	if cfg.ScanLevel.WantSymbols() {
+		return emitCallFindings(handler, binaryCallstacks(vr))
+	}
+	return nil
+}
+
+// binary detects presence of vulnerable symbols in bin.
+// It does not compute call graphs so the corresponding
+// info in Result will be empty.
+func binary(ctx context.Context, handler govulncheck.Handler, bin *Bin, cfg *govulncheck.Config, client *client.Client) (*Result, error) {
+	graph := NewPackageGraph(bin.GoVersion)
+	mods := append(bin.Modules, graph.GetModule(internal.GoStdModulePath))
+
+	if bin.Main != nil {
+		mods = append(mods, bin.Main)
+	}
+
+	graph.AddModules(mods...)
+
+	if err := handler.SBOM(bin.SBOM()); err != nil {
+		return nil, err
+	}
+
+	if err := handler.Progress(&govulncheck.Progress{Message: fetchingVulnsMessage}); err != nil {
+		return nil, err
+	}
+
+	mv, err := FetchVulnerabilities(ctx, client, mods)
+	if err != nil {
+		return nil, err
+	}
+
+	// Emit OSV entries immediately in their raw unfiltered form.
+	if err := emitOSVs(handler, mv); err != nil {
+		return nil, err
+	}
+
+	if err := handler.Progress(&govulncheck.Progress{Message: checkingBinVulnsMessage}); err != nil {
+		return nil, err
+	}
+
+	// Emit warning message for ancient Go binaries, defined as binaries
+	// built with Go version without support for debug.BuildInfo (< go1.18).
+	if semver.Valid(bin.GoVersion) && semver.Less(bin.GoVersion, "go1.18") {
+		p := &govulncheck.Progress{Message: fmt.Sprintf("warning: binary built with Go version %s, only standard library vulnerabilities will be checked", bin.GoVersion)}
+		if err := handler.Progress(p); err != nil {
+			return nil, err
+		}
+	}
+
+	if bin.GOOS == "" || bin.GOARCH == "" {
+		p := &govulncheck.Progress{Message: fmt.Sprintf("warning: failed to extract build system specification GOOS: %s GOARCH: %s\n", bin.GOOS, bin.GOARCH)}
+		if err := handler.Progress(p); err != nil {
+			return nil, err
+		}
+	}
+	affVulns := affectingVulnerabilities(mv, bin.GOOS, bin.GOARCH)
+	if err := emitModuleFindings(handler, affVulns); err != nil {
+		return nil, err
+	}
+
+	if !cfg.ScanLevel.WantPackages() || len(affVulns) == 0 {
+		return &Result{}, nil
+	}
+
+	// Group symbols per package to avoid querying affVulns all over again.
+	var pkgSymbols map[string][]string
+	if len(bin.PkgSymbols) == 0 {
+		// The binary exe is stripped. We currently cannot detect inlined
+		// symbols for stripped binaries (see #57764), so we report
+		// vulnerabilities at the go.mod-level precision.
+		pkgSymbols = allKnownVulnerableSymbols(affVulns)
+	} else {
+		pkgSymbols = packagesAndSymbols(bin)
+	}
+
+	impVulns := binImportedVulnPackages(graph, pkgSymbols, affVulns)
+	// Emit information on imported vulnerable packages now to
+	// mimic behavior of source.
+	if err := emitPackageFindings(handler, impVulns); err != nil {
+		return nil, err
+	}
+
+	// Return result immediately if not in symbol mode to mimic the
+	// behavior of source.
+	if !cfg.ScanLevel.WantSymbols() || len(impVulns) == 0 {
+		return &Result{Vulns: impVulns}, nil
+	}
+
+	symVulns := binVulnSymbols(graph, pkgSymbols, affVulns)
+	return &Result{Vulns: symVulns}, nil
+}
+
+func packagesAndSymbols(bin *Bin) map[string][]string {
+	pkgSymbols := make(map[string][]string)
+	for _, sym := range bin.PkgSymbols {
+		// If the name of the package is main, we need to expand
+		// it to its full path as that is what vuln db uses.
+		if sym.Pkg == "main" && bin.Path != "" {
+			pkgSymbols[bin.Path] = append(pkgSymbols[bin.Path], sym.Name)
+		} else {
+			pkgSymbols[sym.Pkg] = append(pkgSymbols[sym.Pkg], sym.Name)
+		}
+	}
+	return pkgSymbols
+}
+
+func binImportedVulnPackages(graph *PackageGraph, pkgSymbols map[string][]string, affVulns affectingVulns) []*Vuln {
+	var vulns []*Vuln
+	for pkg := range pkgSymbols {
+		for _, osv := range affVulns.ForPackage(internal.UnknownModulePath, pkg) {
+			vuln := &Vuln{
+				OSV:     osv,
+				Package: graph.GetPackage(pkg),
+			}
+			vulns = append(vulns, vuln)
+		}
+	}
+	return vulns
+}
+
+func binVulnSymbols(graph *PackageGraph, pkgSymbols map[string][]string, affVulns affectingVulns) []*Vuln {
+	var vulns []*Vuln
+	for pkg, symbols := range pkgSymbols {
+		for _, symbol := range symbols {
+			for _, osv := range affVulns.ForSymbol(internal.UnknownModulePath, pkg, symbol) {
+				vuln := &Vuln{
+					OSV:     osv,
+					Symbol:  symbol,
+					Package: graph.GetPackage(pkg),
+				}
+				vulns = append(vulns, vuln)
+			}
+		}
+	}
+	return vulns
+}
+
+// allKnownVulnerableSymbols returns all known vulnerable symbols for packages in graph.
+// If all symbols of a package are vulnerable, that is modeled as a wild car symbol "/*".
+func allKnownVulnerableSymbols(affVulns affectingVulns) map[string][]string {
+	pkgSymbols := make(map[string][]string)
+	for _, mv := range affVulns {
+		for _, osv := range mv.Vulns {
+			for _, affected := range osv.Affected {
+				for _, p := range affected.EcosystemSpecific.Packages {
+					syms := p.Symbols
+					if len(syms) == 0 {
+						// If every symbol of pkg is vulnerable, we would ideally
+						// compute every symbol mentioned in the pkg and then add
+						// Vuln entry for it, just as we do in Source. However,
+						// we don't have code of pkg here and we don't even have
+						// pkg symbols used in stripped binary, so we add a placeholder
+						// symbol.
+						//
+						// Note: this should not affect output of govulncheck since
+						// in binary mode no symbol/call stack information is
+						// communicated back to the user.
+						syms = []string{fmt.Sprintf("%s/*", p.Path)}
+					}
+
+					pkgSymbols[p.Path] = append(pkgSymbols[p.Path], syms...)
+				}
+			}
+		}
+	}
+	return pkgSymbols
+}
+
+func (bin *Bin) SBOM() (sbom *govulncheck.SBOM) {
+	sbom = &govulncheck.SBOM{}
+	if bin.Main != nil {
+		sbom.Roots = []string{bin.Main.Path}
+		sbom.Modules = append(sbom.Modules, &govulncheck.Module{
+			Path:    bin.Main.Path,
+			Version: bin.Main.Version,
+		})
+	}
+
+	sbom.GoVersion = bin.GoVersion
+	for _, mod := range bin.Modules {
+		if mod.Replace != nil {
+			mod = mod.Replace
+		}
+		sbom.Modules = append(sbom.Modules, &govulncheck.Module{
+			Path:    mod.Path,
+			Version: mod.Version,
+		})
+	}
+
+	// add stdlib to mirror source mode output
+	sbom.Modules = append(sbom.Modules, &govulncheck.Module{
+		Path:    internal.GoStdModulePath,
+		Version: bin.GoVersion,
+	})
+
+	return sbom
+}
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/doc.go b/vendor/golang.org/x/vuln/internal/vulncheck/doc.go
new file mode 100644
index 0000000..e56cdfb
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/doc.go
@@ -0,0 +1,54 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package vulncheck detects uses of known vulnerabilities
+in Go programs.
+
+Vulncheck identifies vulnerability uses in Go programs
+at the level of call graph, package import graph, and module
+requires graph. For instance, vulncheck identifies which
+vulnerable functions and methods are transitively called
+from the program entry points. vulncheck also detects
+transitively imported packages and required modules that
+contain known vulnerable functions and methods.
+
+We recommend using the command line tool [govulncheck] to
+detect vulnerabilities in your code.
+
+# Usage
+
+The two main APIs of vulncheck, [Source] and [Binary], allow vulnerability
+detection in Go source code and binaries, respectively.
+
+[Source] accepts a list of [Package] objects, which
+are a trimmed version of [golang.org/x/tools/go/packages.Package] objects to
+reduce memory consumption. [Binary] accepts a path to a Go binary file.
+
+Both [Source] and [Binary] require information about known
+vulnerabilities in the form of a vulnerability database,
+specifically a [golang.org/x/vuln/internal/client.Client].
+The vulnerabilities
+are modeled using the [golang.org/x/vuln/internal/osv] format.
+
+# Results
+
+The results of vulncheck are slices of the call graph, package imports graph,
+and module requires graph leading to the use of an identified vulnerability.
+The parts of these graphs not related to any vulnerabilities are omitted.
+
+The [CallStacks] and [ImportChains] functions search the returned slices for
+user-friendly representative call stacks and import chains. These call stacks
+and import chains are provided as examples of vulnerability uses in the client
+code.
+
+# Limitations
+
+There are some limitations with vulncheck. Please see the
+[documented limitations] for more information.
+
+[govulncheck]: https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck
+[documented limitations]: https://go.dev/security/vulncheck#limitations.
+*/
+package vulncheck
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/emit.go b/vendor/golang.org/x/vuln/internal/vulncheck/emit.go
new file mode 100644
index 0000000..fc9b2d7
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/emit.go
@@ -0,0 +1,198 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vulncheck
+
+import (
+	"go/token"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/vuln/internal/govulncheck"
+)
+
+// emitOSVs emits all OSV vuln entries in modVulns to handler.
+func emitOSVs(handler govulncheck.Handler, modVulns []*ModVulns) error {
+	for _, mv := range modVulns {
+		for _, v := range mv.Vulns {
+			if err := handler.OSV(v); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+// emitModuleFindings emits module-level findings for vulnerabilities in modVulns.
+func emitModuleFindings(handler govulncheck.Handler, affVulns affectingVulns) error {
+	for _, vuln := range affVulns {
+		for _, osv := range vuln.Vulns {
+			if err := handler.Finding(&govulncheck.Finding{
+				OSV:          osv.ID,
+				FixedVersion: FixedVersion(modPath(vuln.Module), modVersion(vuln.Module), osv.Affected),
+				Trace:        []*govulncheck.Frame{frameFromModule(vuln.Module)},
+			}); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+// emitPackageFinding emits package-level findings fod vulnerabilities in vulns.
+func emitPackageFindings(handler govulncheck.Handler, vulns []*Vuln) error {
+	for _, v := range vulns {
+		if err := handler.Finding(&govulncheck.Finding{
+			OSV:          v.OSV.ID,
+			FixedVersion: FixedVersion(modPath(v.Package.Module), modVersion(v.Package.Module), v.OSV.Affected),
+			Trace:        []*govulncheck.Frame{frameFromPackage(v.Package)},
+		}); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// emitCallFindings emits call-level findings for vulnerabilities
+// that have a call stack in callstacks.
+func emitCallFindings(handler govulncheck.Handler, callstacks map[*Vuln]CallStack) error {
+	var vulns []*Vuln
+	for v := range callstacks {
+		vulns = append(vulns, v)
+	}
+
+	for _, vuln := range vulns {
+		stack := callstacks[vuln]
+		if stack == nil {
+			continue
+		}
+		fixed := FixedVersion(modPath(vuln.Package.Module), modVersion(vuln.Package.Module), vuln.OSV.Affected)
+		if err := handler.Finding(&govulncheck.Finding{
+			OSV:          vuln.OSV.ID,
+			FixedVersion: fixed,
+			Trace:        traceFromEntries(stack),
+		}); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// traceFromEntries creates a sequence of
+// frames from vcs. Position of a Frame is the
+// call position of the corresponding stack entry.
+func traceFromEntries(vcs CallStack) []*govulncheck.Frame {
+	var frames []*govulncheck.Frame
+	for i := len(vcs) - 1; i >= 0; i-- {
+		e := vcs[i]
+		fr := frameFromPackage(e.Function.Package)
+		fr.Function = e.Function.Name
+		fr.Receiver = e.Function.Receiver()
+		isSink := i == (len(vcs) - 1)
+		fr.Position = posFromStackEntry(e, isSink)
+		frames = append(frames, fr)
+	}
+	return frames
+}
+
+func posFromStackEntry(e StackEntry, sink bool) *govulncheck.Position {
+	var p *token.Position
+	var f *FuncNode
+	if sink && e.Function != nil && e.Function.Pos != nil {
+		// For sinks, i.e., vulns we take the position
+		// of the symbol.
+		p = e.Function.Pos
+		f = e.Function
+	} else if e.Call != nil && e.Call.Pos != nil {
+		// Otherwise, we take the position of
+		// the call statement.
+		p = e.Call.Pos
+		f = e.Call.Parent
+	}
+
+	if p == nil {
+		return nil
+	}
+	return &govulncheck.Position{
+		Filename: pathRelativeToMod(p.Filename, f),
+		Offset:   p.Offset,
+		Line:     p.Line,
+		Column:   p.Column,
+	}
+}
+
+// pathRelativeToMod computes a version of path
+// relative to the module of f. If it does not
+// have all the necessary information, returns
+// an empty string.
+//
+// The returned paths always use slash as separator
+// so they can work across different platforms.
+func pathRelativeToMod(path string, f *FuncNode) string {
+	if path == "" || f == nil || f.Package == nil { // sanity
+		return ""
+	}
+
+	mod := f.Package.Module
+	if mod.Replace != nil {
+		mod = mod.Replace // for replace directive
+	}
+
+	modDir := modDirWithVendor(mod.Dir, path, mod.Path)
+	p, err := filepath.Rel(modDir, path)
+	if err != nil {
+		return ""
+	}
+	// make sure paths are portable.
+	return filepath.ToSlash(p)
+}
+
+// modDirWithVendor returns modDir if modDir is not empty.
+// Otherwise, the module might be located in the vendor
+// directory. This function attempts to reconstruct the
+// vendored module directory from path and module. It
+// returns an empty string if reconstruction fails.
+func modDirWithVendor(modDir, path, module string) string {
+	if modDir != "" {
+		return modDir
+	}
+
+	sep := string(os.PathSeparator)
+	vendor := sep + "vendor" + sep
+	vendorIndex := strings.Index(path, vendor)
+	if vendorIndex == -1 {
+		return ""
+	}
+	return filepath.Join(path[:vendorIndex], "vendor", filepath.FromSlash(module))
+}
+
+func frameFromPackage(pkg *packages.Package) *govulncheck.Frame {
+	fr := &govulncheck.Frame{}
+	if pkg != nil {
+		fr.Module = pkg.Module.Path
+		fr.Version = pkg.Module.Version
+		fr.Package = pkg.PkgPath
+	}
+	if pkg.Module.Replace != nil {
+		fr.Module = pkg.Module.Replace.Path
+		fr.Version = pkg.Module.Replace.Version
+	}
+	return fr
+}
+
+func frameFromModule(mod *packages.Module) *govulncheck.Frame {
+	fr := &govulncheck.Frame{
+		Module:  mod.Path,
+		Version: mod.Version,
+	}
+
+	if mod.Replace != nil {
+		fr.Module = mod.Replace.Path
+		fr.Version = mod.Replace.Version
+	}
+
+	return fr
+}
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/entries.go b/vendor/golang.org/x/vuln/internal/vulncheck/entries.go
new file mode 100644
index 0000000..3d46f6c
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/entries.go
@@ -0,0 +1,56 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vulncheck
+
+import (
+	"strings"
+
+	"golang.org/x/tools/go/ssa"
+)
+
+// entryPoints returns functions of topPackages considered entry
+// points of govulncheck analysis: main, inits, and exported methods
+// and functions.
+//
+// TODO(https://go.dev/issue/57221): currently, entry functions
+// that are generics are not considered an entry point.
+func entryPoints(topPackages []*ssa.Package) []*ssa.Function {
+	var entries []*ssa.Function
+	for _, pkg := range topPackages {
+		if pkg.Pkg.Name() == "main" {
+			// for "main" packages the only valid entry points are the "main"
+			// function and any "init#" functions, even if there are other
+			// exported functions or types. similarly to isEntry it should be
+			// safe to ignore the validity of the main or init# signatures,
+			// since the compiler will reject malformed definitions,
+			// and the init function is synthetic
+			entries = append(entries, memberFuncs(pkg.Members["main"], pkg.Prog)...)
+			for name, member := range pkg.Members {
+				if strings.HasPrefix(name, "init#") || name == "init" {
+					entries = append(entries, memberFuncs(member, pkg.Prog)...)
+				}
+			}
+			continue
+		}
+		for _, member := range pkg.Members {
+			for _, f := range memberFuncs(member, pkg.Prog) {
+				if isEntry(f) {
+					entries = append(entries, f)
+				}
+			}
+		}
+	}
+	return entries
+}
+
+func isEntry(f *ssa.Function) bool {
+	// it should be safe to ignore checking that the signature of the "init" function
+	// is valid, since it is synthetic
+	if f.Name() == "init" && f.Synthetic == "package initializer" {
+		return true
+	}
+
+	return f.Synthetic == "" && f.Object() != nil && f.Object().Exported()
+}
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/fetch.go b/vendor/golang.org/x/vuln/internal/vulncheck/fetch.go
new file mode 100644
index 0000000..700a7f9
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/fetch.go
@@ -0,0 +1,42 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vulncheck
+
+import (
+	"context"
+	"fmt"
+
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/vuln/internal/client"
+)
+
+// FetchVulnerabilities fetches vulnerabilities that affect the supplied modules.
+func FetchVulnerabilities(ctx context.Context, c *client.Client, modules []*packages.Module) ([]*ModVulns, error) {
+	mreqs := make([]*client.ModuleRequest, len(modules))
+	for i, mod := range modules {
+		modPath := mod.Path
+		if mod.Replace != nil {
+			modPath = mod.Replace.Path
+		}
+		mreqs[i] = &client.ModuleRequest{
+			Path: modPath,
+		}
+	}
+	resps, err := c.ByModules(ctx, mreqs)
+	if err != nil {
+		return nil, fmt.Errorf("fetching vulnerabilities: %v", err)
+	}
+	var mv []*ModVulns
+	for i, resp := range resps {
+		if len(resp.Entries) == 0 {
+			continue
+		}
+		mv = append(mv, &ModVulns{
+			Module: modules[i],
+			Vulns:  resp.Entries,
+		})
+	}
+	return mv, nil
+}
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/packages.go b/vendor/golang.org/x/vuln/internal/vulncheck/packages.go
new file mode 100644
index 0000000..484e549
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/packages.go
@@ -0,0 +1,318 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vulncheck
+
+import (
+	"fmt"
+	"os/exec"
+	"slices"
+	"strings"
+
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/vuln/internal"
+	"golang.org/x/vuln/internal/govulncheck"
+	"golang.org/x/vuln/internal/semver"
+)
+
+// PackageGraph holds a complete module and package graph.
+// Its primary purpose is to allow fast access to the nodes
+// by path and make sure all(stdlib)  packages have a module.
+type PackageGraph struct {
+	// topPkgs are top-level packages specified by the user.
+	// Empty in binary mode.
+	topPkgs  []*packages.Package
+	modules  map[string]*packages.Module  // all modules (even replacing ones)
+	packages map[string]*packages.Package // all packages (even dependencies)
+}
+
+func NewPackageGraph(goVersion string) *PackageGraph {
+	graph := &PackageGraph{
+		modules:  map[string]*packages.Module{},
+		packages: map[string]*packages.Package{},
+	}
+
+	goRoot := ""
+	if out, err := exec.Command("go", "env", "GOROOT").Output(); err == nil {
+		goRoot = strings.TrimSpace(string(out))
+	}
+	stdlibModule := &packages.Module{
+		Path:    internal.GoStdModulePath,
+		Version: semver.GoTagToSemver(goVersion),
+		Dir:     goRoot,
+	}
+	graph.AddModules(stdlibModule)
+	return graph
+}
+
+func (g *PackageGraph) TopPkgs() []*packages.Package {
+	return g.topPkgs
+}
+
+// DepPkgs returns the number of packages that graph.TopPkgs()
+// strictly depend on. This does not include topPkgs even if
+// they are dependency of each other.
+func (g *PackageGraph) DepPkgs() []*packages.Package {
+	topPkgs := g.TopPkgs()
+	tops := make(map[string]bool)
+	depPkgs := make(map[string]*packages.Package)
+
+	for _, t := range topPkgs {
+		tops[t.PkgPath] = true
+	}
+
+	var visit func(*packages.Package, bool)
+	visit = func(p *packages.Package, top bool) {
+		path := p.PkgPath
+		if _, ok := depPkgs[path]; ok {
+			return
+		}
+		if tops[path] && !top {
+			// A top package that is a dependency
+			// will not be in depPkgs, so we skip
+			// reiterating on it here.
+			return
+		}
+
+		// We don't count a top-level package as
+		// a dependency even when they are used
+		// as a dependent package.
+		if !tops[path] {
+			depPkgs[path] = p
+		}
+
+		for _, d := range p.Imports {
+			visit(d, false)
+		}
+	}
+
+	for _, t := range topPkgs {
+		visit(t, true)
+	}
+
+	var deps []*packages.Package
+	for _, d := range depPkgs {
+		deps = append(deps, g.GetPackage(d.PkgPath))
+	}
+	return deps
+}
+
+func (g *PackageGraph) Modules() []*packages.Module {
+	var mods []*packages.Module
+	for _, m := range g.modules {
+		mods = append(mods, m)
+	}
+	return mods
+}
+
+// AddModules adds the modules and any replace modules provided.
+// It will ignore modules that have duplicate paths to ones the
+// graph already holds.
+func (g *PackageGraph) AddModules(mods ...*packages.Module) {
+	for _, mod := range mods {
+		if _, found := g.modules[mod.Path]; found {
+			//TODO: check duplicates are okay?
+			continue
+		}
+		g.modules[mod.Path] = mod
+		if mod.Replace != nil {
+			g.AddModules(mod.Replace)
+		}
+	}
+}
+
+// GetModule gets module at path if one exists. Otherwise,
+// it creates a module and returns it.
+func (g *PackageGraph) GetModule(path string) *packages.Module {
+	if mod, ok := g.modules[path]; ok {
+		return mod
+	}
+	mod := &packages.Module{
+		Path:    path,
+		Version: "",
+	}
+	g.AddModules(mod)
+	return mod
+}
+
+// AddPackages adds the packages and their full graph of imported packages.
+// It also adds the modules of the added packages. It will ignore packages
+// that have duplicate paths to ones the graph already holds.
+func (g *PackageGraph) AddPackages(pkgs ...*packages.Package) {
+	for _, pkg := range pkgs {
+		if _, found := g.packages[pkg.PkgPath]; found {
+			//TODO: check duplicates are okay?
+			continue
+		}
+		g.packages[pkg.PkgPath] = pkg
+		g.fixupPackage(pkg)
+		for _, child := range pkg.Imports {
+			g.AddPackages(child)
+		}
+	}
+}
+
+// fixupPackage adds the module of pkg, if any, to the set
+// of all modules in g. If packages is not assigned a module
+// (likely stdlib package), a module set for pkg.
+func (g *PackageGraph) fixupPackage(pkg *packages.Package) {
+	if pkg.Module != nil {
+		g.AddModules(pkg.Module)
+		return
+	}
+	pkg.Module = g.findModule(pkg.PkgPath)
+}
+
+// findModule finds a module for package.
+// It does a longest prefix search amongst the existing modules, if that does
+// not find anything, it returns the "unknown" module.
+func (g *PackageGraph) findModule(pkgPath string) *packages.Module {
+	//TODO: better stdlib test
+	if IsStdPackage(pkgPath) {
+		return g.GetModule(internal.GoStdModulePath)
+	}
+	for _, m := range g.modules {
+		//TODO: not first match, best match...
+		if pkgPath == m.Path || strings.HasPrefix(pkgPath, m.Path+"/") {
+			return m
+		}
+	}
+	return g.GetModule(internal.UnknownModulePath)
+}
+
+// GetPackage returns the package matching the path.
+// If the graph does not already know about the package, a new one is added.
+func (g *PackageGraph) GetPackage(path string) *packages.Package {
+	if pkg, ok := g.packages[path]; ok {
+		return pkg
+	}
+	pkg := &packages.Package{
+		PkgPath: path,
+	}
+	g.AddPackages(pkg)
+	return pkg
+}
+
+// LoadPackages loads the packages specified by the patterns into the graph.
+// See golang.org/x/tools/go/packages.Load for details of how it works.
+func (g *PackageGraph) LoadPackagesAndMods(cfg *packages.Config, tags []string, patterns []string, wantSymbols bool) error {
+	if len(tags) > 0 {
+		cfg.BuildFlags = []string{fmt.Sprintf("-tags=%s", strings.Join(tags, ","))}
+	}
+
+	addLoadMode(cfg, wantSymbols)
+
+	pkgs, err := packages.Load(cfg, patterns...)
+	if err != nil {
+		return err
+	}
+	var perrs []packages.Error
+	packages.Visit(pkgs, nil, func(p *packages.Package) {
+		perrs = append(perrs, p.Errors...)
+	})
+	if len(perrs) > 0 {
+		err = &packageError{perrs}
+	}
+
+	// Add all packages, top-level ones and their imports.
+	// This will also add their respective modules.
+	g.AddPackages(pkgs...)
+
+	// save top-level packages
+	for _, p := range pkgs {
+		g.topPkgs = append(g.topPkgs, g.GetPackage(p.PkgPath))
+	}
+	return err
+}
+
+func addLoadMode(cfg *packages.Config, wantSymbols bool) {
+	cfg.Mode |=
+		packages.NeedModule |
+			packages.NeedName |
+			packages.NeedDeps |
+			packages.NeedImports
+	if wantSymbols {
+		cfg.Mode |= packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo
+	}
+}
+
+// packageError contains errors from loading a set of packages.
+type packageError struct {
+	Errors []packages.Error
+}
+
+func (e *packageError) Error() string {
+	var b strings.Builder
+	fmt.Fprintln(&b, "\nThere are errors with the provided package patterns:")
+	fmt.Fprintln(&b, "")
+	for _, e := range e.Errors {
+		fmt.Fprintln(&b, e)
+	}
+	fmt.Fprintln(&b, "\nFor details on package patterns, see https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns.")
+	return b.String()
+}
+
+func (g *PackageGraph) SBOM() *govulncheck.SBOM {
+	getMod := func(mod *packages.Module) *govulncheck.Module {
+		if mod.Replace != nil {
+			return &govulncheck.Module{
+				Path:    mod.Replace.Path,
+				Version: mod.Replace.Version,
+			}
+		}
+
+		return &govulncheck.Module{
+			Path:    mod.Path,
+			Version: mod.Version,
+		}
+	}
+
+	var roots []string
+	rootMods := make(map[string]*govulncheck.Module)
+	for _, pkg := range g.TopPkgs() {
+		roots = append(roots, pkg.PkgPath)
+		mod := getMod(pkg.Module)
+		rootMods[mod.Path] = mod
+	}
+
+	// Govulncheck attempts to put the modules that correspond to the matched package patterns (i.e. the root modules)
+	// at the beginning of the SBOM.Modules message.
+	// Note: This does not guarantee that the first element is the root module.
+	var topMods, depMods []*govulncheck.Module
+	var goVersion string
+	for _, mod := range g.Modules() {
+		mod := getMod(mod)
+
+		if mod.Path == internal.GoStdModulePath {
+			goVersion = semver.SemverToGoTag(mod.Version)
+		}
+
+		// if the mod is not associated with a root package, add it to depMods
+		if rootMods[mod.Path] == nil {
+			depMods = append(depMods, mod)
+		}
+	}
+
+	for _, mod := range rootMods {
+		topMods = append(topMods, mod)
+	}
+	// Sort for deterministic output
+	sortMods(topMods)
+	sortMods(depMods)
+
+	mods := append(topMods, depMods...)
+
+	return &govulncheck.SBOM{
+		GoVersion: goVersion,
+		Modules:   mods,
+		Roots:     roots,
+	}
+}
+
+// Sorts modules alphabetically by path.
+func sortMods(mods []*govulncheck.Module) {
+	slices.SortFunc(mods, func(a, b *govulncheck.Module) int {
+		return strings.Compare(a.Path, b.Path)
+	})
+}
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/slicing.go b/vendor/golang.org/x/vuln/internal/vulncheck/slicing.go
new file mode 100644
index 0000000..0bfa160
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/slicing.go
@@ -0,0 +1,46 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vulncheck
+
+import (
+	"golang.org/x/tools/go/callgraph"
+	"golang.org/x/tools/go/ssa"
+)
+
+// forwardSlice computes the transitive closure of functions forward reachable
+// via calls in cg or referred to in an instruction starting from `sources`.
+func forwardSlice(sources map[*ssa.Function]bool, cg *callgraph.Graph) map[*ssa.Function]bool {
+	seen := make(map[*ssa.Function]bool)
+	var visit func(f *ssa.Function)
+	visit = func(f *ssa.Function) {
+		if seen[f] {
+			return
+		}
+		seen[f] = true
+
+		if n := cg.Nodes[f]; n != nil {
+			for _, e := range n.Out {
+				if e.Site != nil {
+					visit(e.Callee.Func)
+				}
+			}
+		}
+
+		var buf [10]*ssa.Value // avoid alloc in common case
+		for _, b := range f.Blocks {
+			for _, instr := range b.Instrs {
+				for _, op := range instr.Operands(buf[:0]) {
+					if fn, ok := (*op).(*ssa.Function); ok {
+						visit(fn)
+					}
+				}
+			}
+		}
+	}
+	for source := range sources {
+		visit(source)
+	}
+	return seen
+}
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/source.go b/vendor/golang.org/x/vuln/internal/vulncheck/source.go
new file mode 100644
index 0000000..348c3b9
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/source.go
@@ -0,0 +1,312 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vulncheck
+
+import (
+	"context"
+	"sync"
+
+	"golang.org/x/tools/go/callgraph"
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/tools/go/ssa"
+	"golang.org/x/vuln/internal/client"
+	"golang.org/x/vuln/internal/govulncheck"
+	"golang.org/x/vuln/internal/osv"
+)
+
+// Source detects vulnerabilities in pkgs and emits the findings to handler.
+func Source(ctx context.Context, handler govulncheck.Handler, cfg *govulncheck.Config, client *client.Client, graph *PackageGraph) error {
+	vr, err := source(ctx, handler, cfg, client, graph)
+	if err != nil {
+		return err
+	}
+
+	if cfg.ScanLevel.WantSymbols() {
+		return emitCallFindings(handler, sourceCallstacks(vr))
+	}
+	return nil
+}
+
+// source detects vulnerabilities in packages. It emits findings to handler
+// and produces a Result that contains info on detected vulnerabilities.
+//
+// Assumes that pkgs are non-empty and belong to the same program.
+func source(ctx context.Context, handler govulncheck.Handler, cfg *govulncheck.Config, client *client.Client, graph *PackageGraph) (*Result, error) {
+	ctx, cancel := context.WithCancel(ctx)
+	defer cancel()
+
+	// If we are building the callgraph, build ssa and the callgraph in parallel
+	// with fetching vulnerabilities. If the vulns set is empty, return without
+	// waiting for SSA construction or callgraph to finish.
+	var (
+		wg       sync.WaitGroup // guards entries, cg, and buildErr
+		entries  []*ssa.Function
+		cg       *callgraph.Graph
+		buildErr error
+	)
+	if cfg.ScanLevel.WantSymbols() {
+		fset := graph.TopPkgs()[0].Fset
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			prog, ssaPkgs := buildSSA(graph.TopPkgs(), fset)
+			entries = entryPoints(ssaPkgs)
+			cg, buildErr = callGraph(ctx, prog, entries)
+		}()
+	}
+
+	if err := handler.SBOM(graph.SBOM()); err != nil {
+		return nil, err
+	}
+
+	if err := handler.Progress(&govulncheck.Progress{Message: fetchingVulnsMessage}); err != nil {
+		return nil, err
+	}
+
+	mv, err := FetchVulnerabilities(ctx, client, graph.Modules())
+	if err != nil {
+		return nil, err
+	}
+
+	// Emit OSV entries immediately in their raw unfiltered form.
+	if err := emitOSVs(handler, mv); err != nil {
+		return nil, err
+	}
+
+	if err := handler.Progress(&govulncheck.Progress{Message: checkingSrcVulnsMessage}); err != nil {
+		return nil, err
+	}
+
+	affVulns := affectingVulnerabilities(mv, "", "")
+	if err := emitModuleFindings(handler, affVulns); err != nil {
+		return nil, err
+	}
+
+	if !cfg.ScanLevel.WantPackages() || len(affVulns) == 0 {
+		return &Result{}, nil
+	}
+
+	impVulns := importedVulnPackages(affVulns, graph)
+	// Emit information on imported vulnerable packages now as
+	// call graph computation might take a while.
+	if err := emitPackageFindings(handler, impVulns); err != nil {
+		return nil, err
+	}
+
+	// Return result immediately if not in symbol mode or
+	// if there are no vulnerabilities imported.
+	if !cfg.ScanLevel.WantSymbols() || len(impVulns) == 0 {
+		return &Result{Vulns: impVulns}, nil
+	}
+
+	wg.Wait() // wait for build to finish
+	if buildErr != nil {
+		return nil, err
+	}
+
+	entryFuncs, callVulns := calledVulnSymbols(entries, affVulns, cg, graph)
+	return &Result{EntryFunctions: entryFuncs, Vulns: callVulns}, nil
+}
+
+// importedVulnPackages detects imported vulnerable packages.
+func importedVulnPackages(affVulns affectingVulns, graph *PackageGraph) []*Vuln {
+	var vulns []*Vuln
+	analyzed := make(map[*packages.Package]bool) // skip analyzing the same package multiple times
+	var vulnImports func(pkg *packages.Package)
+	vulnImports = func(pkg *packages.Package) {
+		if analyzed[pkg] {
+			return
+		}
+
+		osvs := affVulns.ForPackage(pkgModPath(pkg), pkg.PkgPath)
+		// Create Vuln entry for each OSV entry for pkg.
+		for _, osv := range osvs {
+			vuln := &Vuln{
+				OSV:     osv,
+				Package: graph.GetPackage(pkg.PkgPath),
+			}
+			vulns = append(vulns, vuln)
+		}
+
+		analyzed[pkg] = true
+		for _, imp := range pkg.Imports {
+			vulnImports(imp)
+		}
+	}
+
+	for _, pkg := range graph.TopPkgs() {
+		vulnImports(pkg)
+	}
+	return vulns
+}
+
+// calledVulnSymbols detects vuln symbols transitively reachable from sources
+// via call graph cg.
+//
+// A slice of call graph is computed related to the reachable vulnerabilities. Each
+// reachable Vuln has attached FuncNode that can be upward traversed to the entry points.
+// Entry points that reach the vulnerable symbols are also returned.
+func calledVulnSymbols(sources []*ssa.Function, affVulns affectingVulns, cg *callgraph.Graph, graph *PackageGraph) ([]*FuncNode, []*Vuln) {
+	sinksWithVulns := vulnFuncs(cg, affVulns, graph)
+
+	// Compute call graph backwards reachable
+	// from vulnerable functions and methods.
+	var sinks []*callgraph.Node
+	for n := range sinksWithVulns {
+		sinks = append(sinks, n)
+	}
+	bcg := callGraphSlice(sinks, false)
+
+	// Interesect backwards call graph with forward
+	// reachable graph to remove redundant edges.
+	var filteredSources []*callgraph.Node
+	for _, e := range sources {
+		if n, ok := bcg.Nodes[e]; ok {
+			filteredSources = append(filteredSources, n)
+		}
+	}
+	fcg := callGraphSlice(filteredSources, true)
+
+	// Get the sinks that are in fact reachable from entry points.
+	filteredSinks := make(map[*callgraph.Node][]*osv.Entry)
+	for n, vs := range sinksWithVulns {
+		if fn, ok := fcg.Nodes[n.Func]; ok {
+			filteredSinks[fn] = vs
+		}
+	}
+
+	// Transform the resulting call graph slice into
+	// vulncheck representation.
+	return vulnCallGraph(filteredSources, filteredSinks, graph)
+}
+
+// callGraphSlice computes a slice of callgraph beginning at starts
+// in the direction (forward/backward) controlled by forward flag.
+func callGraphSlice(starts []*callgraph.Node, forward bool) *callgraph.Graph {
+	g := &callgraph.Graph{Nodes: make(map[*ssa.Function]*callgraph.Node)}
+
+	visited := make(map[*callgraph.Node]bool)
+	var visit func(*callgraph.Node)
+	visit = func(n *callgraph.Node) {
+		if visited[n] {
+			return
+		}
+		visited[n] = true
+
+		var edges []*callgraph.Edge
+		if forward {
+			edges = n.Out
+		} else {
+			edges = n.In
+		}
+
+		for _, edge := range edges {
+			nCallee := g.CreateNode(edge.Callee.Func)
+			nCaller := g.CreateNode(edge.Caller.Func)
+			callgraph.AddEdge(nCaller, edge.Site, nCallee)
+
+			if forward {
+				visit(edge.Callee)
+			} else {
+				visit(edge.Caller)
+			}
+		}
+	}
+
+	for _, s := range starts {
+		visit(s)
+	}
+	return g
+}
+
+// vulnCallGraph creates vulnerability call graph in terms of sources and sinks.
+func vulnCallGraph(sources []*callgraph.Node, sinks map[*callgraph.Node][]*osv.Entry, graph *PackageGraph) ([]*FuncNode, []*Vuln) {
+	var entries []*FuncNode
+	var vulns []*Vuln
+	nodes := make(map[*ssa.Function]*FuncNode)
+
+	// First create entries and sinks and store relevant information.
+	for _, s := range sources {
+		fn := createNode(nodes, s.Func, graph)
+		entries = append(entries, fn)
+	}
+
+	for s, osvs := range sinks {
+		f := s.Func
+		funNode := createNode(nodes, s.Func, graph)
+
+		// Populate CallSink field for each detected vuln symbol.
+		for _, osv := range osvs {
+			vulns = append(vulns, calledVuln(funNode, osv, dbFuncName(f), funNode.Package))
+		}
+	}
+
+	visited := make(map[*callgraph.Node]bool)
+	var visit func(*callgraph.Node)
+	visit = func(n *callgraph.Node) {
+		if visited[n] {
+			return
+		}
+		visited[n] = true
+
+		for _, edge := range n.In {
+			nCallee := createNode(nodes, edge.Callee.Func, graph)
+			nCaller := createNode(nodes, edge.Caller.Func, graph)
+
+			call := edge.Site
+			cs := &CallSite{
+				Parent:   nCaller,
+				Name:     call.Common().Value.Name(),
+				RecvType: callRecvType(call),
+				Resolved: resolved(call),
+				Pos:      instrPosition(call),
+			}
+			nCallee.CallSites = append(nCallee.CallSites, cs)
+
+			visit(edge.Caller)
+		}
+	}
+
+	for s := range sinks {
+		visit(s)
+	}
+	return entries, vulns
+}
+
+// vulnFuncs returns vulnerability information for vulnerable functions in cg.
+func vulnFuncs(cg *callgraph.Graph, affVulns affectingVulns, graph *PackageGraph) map[*callgraph.Node][]*osv.Entry {
+	m := make(map[*callgraph.Node][]*osv.Entry)
+	for f, n := range cg.Nodes {
+		p := pkgPath(f)
+		vulns := affVulns.ForSymbol(pkgModPath(graph.GetPackage(p)), p, dbFuncName(f))
+		if len(vulns) > 0 {
+			m[n] = vulns
+		}
+	}
+	return m
+}
+
+func createNode(nodes map[*ssa.Function]*FuncNode, f *ssa.Function, graph *PackageGraph) *FuncNode {
+	if fn, ok := nodes[f]; ok {
+		return fn
+	}
+	fn := &FuncNode{
+		Name:     f.Name(),
+		Package:  graph.GetPackage(pkgPath(f)),
+		RecvType: funcRecvType(f),
+		Pos:      funcPosition(f),
+	}
+	nodes[f] = fn
+	return fn
+}
+
+func calledVuln(call *FuncNode, osv *osv.Entry, symbol string, pkg *packages.Package) *Vuln {
+	return &Vuln{
+		Symbol:   symbol,
+		Package:  pkg,
+		OSV:      osv,
+		CallSink: call,
+	}
+}
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/utils.go b/vendor/golang.org/x/vuln/internal/vulncheck/utils.go
new file mode 100644
index 0000000..fb32a2c
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/utils.go
@@ -0,0 +1,346 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vulncheck
+
+import (
+	"bytes"
+	"context"
+	"go/token"
+	"go/types"
+	"sort"
+	"strings"
+
+	"golang.org/x/tools/go/callgraph"
+	"golang.org/x/tools/go/callgraph/cha"
+	"golang.org/x/tools/go/callgraph/vta"
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/tools/go/types/typeutil"
+	"golang.org/x/vuln/internal"
+	"golang.org/x/vuln/internal/osv"
+	"golang.org/x/vuln/internal/semver"
+
+	"golang.org/x/tools/go/ssa"
+)
+
+// buildSSA creates an ssa representation for pkgs. Returns
+// the ssa program encapsulating the packages and top level
+// ssa packages corresponding to pkgs.
+func buildSSA(pkgs []*packages.Package, fset *token.FileSet) (*ssa.Program, []*ssa.Package) {
+	prog := ssa.NewProgram(fset, ssa.InstantiateGenerics)
+
+	imports := make(map[*packages.Package]*ssa.Package)
+	var createImports func(map[string]*packages.Package)
+	createImports = func(pkgs map[string]*packages.Package) {
+		for _, p := range pkgs {
+			if _, ok := imports[p]; !ok {
+				i := prog.CreatePackage(p.Types, p.Syntax, p.TypesInfo, true)
+				imports[p] = i
+				createImports(p.Imports)
+			}
+		}
+	}
+
+	for _, tp := range pkgs {
+		createImports(tp.Imports)
+	}
+
+	var ssaPkgs []*ssa.Package
+	for _, tp := range pkgs {
+		if sp, ok := imports[tp]; ok {
+			ssaPkgs = append(ssaPkgs, sp)
+		} else {
+			sp := prog.CreatePackage(tp.Types, tp.Syntax, tp.TypesInfo, false)
+			ssaPkgs = append(ssaPkgs, sp)
+		}
+	}
+	prog.Build()
+	return prog, ssaPkgs
+}
+
+// callGraph builds a call graph of prog based on VTA analysis.
+func callGraph(ctx context.Context, prog *ssa.Program, entries []*ssa.Function) (*callgraph.Graph, error) {
+	entrySlice := make(map[*ssa.Function]bool)
+	for _, e := range entries {
+		entrySlice[e] = true
+	}
+
+	if err := ctx.Err(); err != nil { // cancelled?
+		return nil, err
+	}
+	initial := cha.CallGraph(prog)
+
+	fslice := forwardSlice(entrySlice, initial)
+	if err := ctx.Err(); err != nil { // cancelled?
+		return nil, err
+	}
+	vtaCg := vta.CallGraph(fslice, initial)
+
+	// Repeat the process once more, this time using
+	// the produced VTA call graph as the base graph.
+	fslice = forwardSlice(entrySlice, vtaCg)
+	if err := ctx.Err(); err != nil { // cancelled?
+		return nil, err
+	}
+	cg := vta.CallGraph(fslice, vtaCg)
+	cg.DeleteSyntheticNodes()
+	return cg, nil
+}
+
+// dbTypeFormat formats the name of t according how types
+// are encoded in vulnerability database:
+//   - pointer designation * is skipped
+//   - full path prefix is skipped as well
+func dbTypeFormat(t types.Type) string {
+	switch tt := types.Unalias(t).(type) {
+	case *types.Pointer:
+		return dbTypeFormat(tt.Elem())
+	case *types.Named:
+		return tt.Obj().Name()
+	default:
+		return types.TypeString(t, func(p *types.Package) string { return "" })
+	}
+}
+
+// dbFuncName computes a function name consistent with the namings used in vulnerability
+// databases. Effectively, a qualified name of a function local to its enclosing package.
+// If a receiver is a pointer, this information is not encoded in the resulting name. If
+// a function has type argument/parameter, this information is omitted. The name of
+// anonymous functions is simply "". The function names are unique subject to the enclosing
+// package, but not globally.
+//
+// Examples:
+//
+//	func (a A) foo (...) {...}  -> A.foo
+//	func foo(...) {...}         -> foo
+//	func (b *B) bar (...) {...} -> B.bar
+//	func (c C[T]) do(...) {...} -> C.do
+func dbFuncName(f *ssa.Function) string {
+	selectBound := func(f *ssa.Function) types.Type {
+		// If f is a "bound" function introduced by ssa for a given type, return the type.
+		// When "f" is a "bound" function, it will have 1 free variable of that type within
+		// the function. This is subject to change when ssa changes.
+		if len(f.FreeVars) == 1 && strings.HasPrefix(f.Synthetic, "bound ") {
+			return f.FreeVars[0].Type()
+		}
+		return nil
+	}
+	selectThunk := func(f *ssa.Function) types.Type {
+		// If f is a "thunk" function introduced by ssa for a given type, return the type.
+		// When "f" is a "thunk" function, the first parameter will have that type within
+		// the function. This is subject to change when ssa changes.
+		params := f.Signature.Params() // params.Len() == 1 then params != nil.
+		if strings.HasPrefix(f.Synthetic, "thunk ") && params.Len() >= 1 {
+			if first := params.At(0); first != nil {
+				return first.Type()
+			}
+		}
+		return nil
+	}
+	var qprefix string
+	if recv := f.Signature.Recv(); recv != nil {
+		qprefix = dbTypeFormat(recv.Type())
+	} else if btype := selectBound(f); btype != nil {
+		qprefix = dbTypeFormat(btype)
+	} else if ttype := selectThunk(f); ttype != nil {
+		qprefix = dbTypeFormat(ttype)
+	}
+
+	if qprefix == "" {
+		return funcName(f)
+	}
+	return qprefix + "." + funcName(f)
+}
+
+// funcName returns the name of the ssa function f.
+// It is f.Name() without additional type argument
+// information in case of generics.
+func funcName(f *ssa.Function) string {
+	n, _, _ := strings.Cut(f.Name(), "[")
+	return n
+}
+
+// memberFuncs returns functions associated with the `member`:
+// 1) `member` itself if `member` is a function
+// 2) `member` methods if `member` is a type
+// 3) empty list otherwise
+func memberFuncs(member ssa.Member, prog *ssa.Program) []*ssa.Function {
+	switch t := member.(type) {
+	case *ssa.Type:
+		methods := typeutil.IntuitiveMethodSet(t.Type(), &prog.MethodSets)
+		var funcs []*ssa.Function
+		for _, m := range methods {
+			if f := prog.MethodValue(m); f != nil {
+				funcs = append(funcs, f)
+			}
+		}
+		return funcs
+	case *ssa.Function:
+		return []*ssa.Function{t}
+	default:
+		return nil
+	}
+}
+
+// funcPosition gives the position of `f`. Returns empty token.Position
+// if no file information on `f` is available.
+func funcPosition(f *ssa.Function) *token.Position {
+	pos := f.Prog.Fset.Position(f.Pos())
+	return &pos
+}
+
+// instrPosition gives the position of `instr`. Returns empty token.Position
+// if no file information on `instr` is available.
+func instrPosition(instr ssa.Instruction) *token.Position {
+	pos := instr.Parent().Prog.Fset.Position(instr.Pos())
+	return &pos
+}
+
+func resolved(call ssa.CallInstruction) bool {
+	if call == nil {
+		return true
+	}
+	return call.Common().StaticCallee() != nil
+}
+
+func callRecvType(call ssa.CallInstruction) string {
+	if !call.Common().IsInvoke() {
+		return ""
+	}
+	buf := new(bytes.Buffer)
+	types.WriteType(buf, call.Common().Value.Type(), nil)
+	return buf.String()
+}
+
+func funcRecvType(f *ssa.Function) string {
+	v := f.Signature.Recv()
+	if v == nil {
+		return ""
+	}
+	buf := new(bytes.Buffer)
+	types.WriteType(buf, v.Type(), nil)
+	return buf.String()
+}
+
+func FixedVersion(modulePath, version string, affected []osv.Affected) string {
+	fixed := earliestValidFix(modulePath, version, affected)
+	// Add "v" prefix if one does not exist. moduleVersionString
+	// will later on replace it with "go" if needed.
+	if fixed != "" && !strings.HasPrefix(fixed, "v") {
+		fixed = "v" + fixed
+	}
+	return fixed
+}
+
+// earliestValidFix returns the earliest fix for version of modulePath that
+// itself is not vulnerable in affected.
+//
+// Suppose we have a version "v1.0.0" and we use {...} to denote different
+// affected regions. Assume for simplicity that all affected apply to the
+// same input modulePath.
+//
+//	{[v0.1.0, v0.1.9), [v1.0.0, v2.0.0)} -> v2.0.0
+//	{[v1.0.0, v1.5.0), [v2.0.0, v2.1.0}, {[v1.4.0, v1.6.0)} -> v2.1.0
+func earliestValidFix(modulePath, version string, affected []osv.Affected) string {
+	var moduleAffected []osv.Affected
+	for _, a := range affected {
+		if a.Module.Path == modulePath {
+			moduleAffected = append(moduleAffected, a)
+		}
+	}
+
+	vFixes := validFixes(version, moduleAffected)
+	for _, fix := range vFixes {
+		if !fixNegated(fix, moduleAffected) {
+			return fix
+		}
+	}
+	return ""
+
+}
+
+// validFixes computes all fixes for version in affected and
+// returns them sorted increasingly. Assumes that all affected
+// apply to the same module.
+func validFixes(version string, affected []osv.Affected) []string {
+	var fixes []string
+	for _, a := range affected {
+		for _, r := range a.Ranges {
+			if r.Type != osv.RangeTypeSemver {
+				continue
+			}
+			for _, e := range r.Events {
+				fix := e.Fixed
+				if fix != "" && semver.Less(version, fix) {
+					fixes = append(fixes, fix)
+				}
+			}
+		}
+	}
+	sort.SliceStable(fixes, func(i, j int) bool { return semver.Less(fixes[i], fixes[j]) })
+	return fixes
+}
+
+// fixNegated checks if fix is negated to by a re-introduction
+// of a vulnerability in affected. Assumes that all affected apply
+// to the same module.
+func fixNegated(fix string, affected []osv.Affected) bool {
+	for _, a := range affected {
+		for _, r := range a.Ranges {
+			if semver.ContainsSemver(r, fix) {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+func modPath(mod *packages.Module) string {
+	if mod.Replace != nil {
+		return mod.Replace.Path
+	}
+	return mod.Path
+}
+
+func modVersion(mod *packages.Module) string {
+	if mod.Replace != nil {
+		return mod.Replace.Version
+	}
+	return mod.Version
+}
+
+// pkgPath returns the path of the f's enclosing package, if any.
+// Otherwise, returns internal.UnknownPackagePath.
+func pkgPath(f *ssa.Function) string {
+	g := f
+	if f.Origin() != nil {
+		// Instantiations of generics do not have
+		// an associated package. We hence look up
+		// the original function for the package.
+		g = f.Origin()
+	}
+	if g.Package() != nil && g.Package().Pkg != nil {
+		return g.Package().Pkg.Path()
+	}
+	return internal.UnknownPackagePath
+}
+
+func pkgModPath(pkg *packages.Package) string {
+	if pkg != nil && pkg.Module != nil {
+		return pkg.Module.Path
+	}
+	return internal.UnknownModulePath
+}
+
+func IsStdPackage(pkg string) bool {
+	if pkg == "" || pkg == internal.UnknownPackagePath {
+		return false
+	}
+	// std packages do not have a "." in their path. For instance, see
+	// Contains in pkgsite/+/refs/heads/master/internal/stdlbib/stdlib.go.
+	if i := strings.IndexByte(pkg, '/'); i != -1 {
+		pkg = pkg[:i]
+	}
+	return !strings.Contains(pkg, ".")
+}
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/vulncheck.go b/vendor/golang.org/x/vuln/internal/vulncheck/vulncheck.go
new file mode 100644
index 0000000..198fffe
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/vulncheck.go
@@ -0,0 +1,336 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vulncheck
+
+import (
+	"fmt"
+	"go/token"
+	"strings"
+	"time"
+
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/vuln/internal"
+	"golang.org/x/vuln/internal/osv"
+	"golang.org/x/vuln/internal/semver"
+)
+
+const (
+	fetchingVulnsMessage    = "Fetching vulnerabilities from the database..."
+	checkingSrcVulnsMessage = "Checking the code against the vulnerabilities..."
+	checkingBinVulnsMessage = "Checking the binary against the vulnerabilities..."
+)
+
+// Result contains information on detected vulnerabilities.
+// For call graph analysis, it provides information on reachability
+// of vulnerable symbols through entry points of the program.
+type Result struct {
+	// EntryFunctions are a subset of Functions representing vulncheck entry points.
+	EntryFunctions []*FuncNode
+
+	// Vulns contains information on detected vulnerabilities.
+	Vulns []*Vuln
+}
+
+// Vuln provides information on a detected vulnerability. For call
+// graph mode, Vuln will also contain the information on how the
+// vulnerability is reachable in the user call graph.
+type Vuln struct {
+	// OSV contains information on the detected vulnerability in the shared
+	// vulnerability format.
+	//
+	// OSV, Symbol, and Package identify a vulnerability.
+	//
+	// Note that *osv.Entry may describe multiple symbols from multiple
+	// packages.
+	OSV *osv.Entry
+
+	// Symbol is the name of the detected vulnerable function or method.
+	Symbol string
+
+	// CallSink is the FuncNode corresponding to Symbol.
+	//
+	// When analyzing binaries, Symbol is not reachable, or cfg.ScanLevel
+	// is symbol, CallSink will be unavailable and set to nil.
+	CallSink *FuncNode
+
+	// Package of Symbol.
+	//
+	// When the package of symbol is not imported, Package will be
+	// unavailable and set to nil.
+	Package *packages.Package
+}
+
+// A FuncNode describes a function in the call graph.
+type FuncNode struct {
+	// Name is the name of the function.
+	Name string
+
+	// RecvType is the receiver object type of this function, if any.
+	RecvType string
+
+	// Package is the package the function is part of.
+	Package *packages.Package
+
+	// Position describes the position of the function in the file.
+	Pos *token.Position
+
+	// CallSites is a set of call sites where this function is called.
+	CallSites []*CallSite
+}
+
+func (fn *FuncNode) String() string {
+	if fn.RecvType == "" {
+		return fmt.Sprintf("%s.%s", fn.Package.PkgPath, fn.Name)
+	}
+	return fmt.Sprintf("%s.%s", fn.RecvType, fn.Name)
+}
+
+// Receiver returns the FuncNode's receiver, with package path removed.
+// Pointers are preserved if present.
+func (fn *FuncNode) Receiver() string {
+	return strings.Replace(fn.RecvType, fmt.Sprintf("%s.", fn.Package.PkgPath), "", 1)
+}
+
+// A CallSite describes a function call.
+type CallSite struct {
+	// Parent is the enclosing function where the call is made.
+	Parent *FuncNode
+
+	// Name stands for the name of the function (variable) being called.
+	Name string
+
+	// RecvType is the full path of the receiver object type, if any.
+	RecvType string
+
+	// Position describes the position of the function in the file.
+	Pos *token.Position
+
+	// Resolved indicates if the called function can be statically resolved.
+	Resolved bool
+}
+
+// affectingVulns is an internal structure for querying
+// vulnerabilities that apply to the current program
+// and platform under consideration.
+type affectingVulns []*ModVulns
+
+// ModVulns groups vulnerabilities per module.
+type ModVulns struct {
+	Module *packages.Module
+	Vulns  []*osv.Entry
+}
+
+func affectingVulnerabilities(vulns []*ModVulns, os, arch string) affectingVulns {
+	now := time.Now()
+	var filtered affectingVulns
+	for _, mod := range vulns {
+		module := mod.Module
+		modVersion := module.Version
+		if module.Replace != nil {
+			modVersion = module.Replace.Version
+		}
+		// TODO(https://golang.org/issues/49264): if modVersion == "", try vcs?
+		var filteredVulns []*osv.Entry
+		for _, v := range mod.Vulns {
+			// Ignore vulnerabilities that have been withdrawn
+			if v.Withdrawn != nil && v.Withdrawn.Before(now) {
+				continue
+			}
+
+			var filteredAffected []osv.Affected
+			for _, a := range v.Affected {
+				// Vulnerabilities from some databases might contain
+				// information on related but different modules that
+				// were, say, reported in the same CVE. We filter such
+				// information out as it might lead to incorrect results:
+				// Computing a latest fix could consider versions of these
+				// different packages.
+				if a.Module.Path != module.Path {
+					continue
+				}
+				if !affected(modVersion, a) {
+					continue
+				}
+
+				var filteredImports []osv.Package
+				for _, p := range a.EcosystemSpecific.Packages {
+					if matchesPlatform(os, arch, p) {
+						filteredImports = append(filteredImports, p)
+					}
+				}
+				// If we pruned all existing Packages, then the affected is
+				// empty and we can filter it out. Note that Packages can
+				// be empty for vulnerabilities that have no package or
+				// symbol information available.
+				if len(a.EcosystemSpecific.Packages) != 0 && len(filteredImports) == 0 {
+					continue
+				}
+				a.EcosystemSpecific.Packages = filteredImports
+				filteredAffected = append(filteredAffected, a)
+			}
+			if len(filteredAffected) == 0 {
+				continue
+			}
+			// save the non-empty vulnerability with only
+			// affected symbols.
+			newV := *v
+			newV.Affected = filteredAffected
+			filteredVulns = append(filteredVulns, &newV)
+		}
+
+		filtered = append(filtered, &ModVulns{
+			Module: module,
+			Vulns:  filteredVulns,
+		})
+	}
+	return filtered
+}
+
+// affected checks if modVersion is affected by a:
+//   - it is included in one of the affected version ranges
+//   - and module version is not "" and "(devel)"
+func affected(modVersion string, a osv.Affected) bool {
+	const devel = "(devel)"
+	if modVersion == "" || modVersion == devel {
+		// Module version of "" means the module version is not available
+		// and devel means it is in development stage. Either way, we don't
+		// know the exact version so we don't want to spam users with
+		// potential false alarms.
+		return false
+	}
+	return semver.Affects(a.Ranges, modVersion)
+}
+
+func matchesPlatform(os, arch string, e osv.Package) bool {
+	return matchesPlatformComponent(os, e.GOOS) &&
+		matchesPlatformComponent(arch, e.GOARCH)
+}
+
+// matchesPlatformComponent reports whether a GOOS (or GOARCH)
+// matches a list of GOOS (or GOARCH) values from an osv.EcosystemSpecificImport.
+func matchesPlatformComponent(s string, ps []string) bool {
+	// An empty input or an empty GOOS or GOARCH list means "matches everything."
+	if s == "" || len(ps) == 0 {
+		return true
+	}
+	for _, p := range ps {
+		if s == p {
+			return true
+		}
+	}
+	return false
+}
+
+// moduleVulns return vulnerabilities for module. If module is unknown,
+// it figures the module from package importPath. It returns the module
+// whose path is the longest prefix of importPath.
+func (aff affectingVulns) moduleVulns(module, importPath string) *ModVulns {
+	moduleKnown := module != "" && module != internal.UnknownModulePath
+
+	isStd := IsStdPackage(importPath)
+	var mostSpecificMod *ModVulns // for the case where !moduleKnown
+	for _, mod := range aff {
+		md := mod
+		if isStd && mod.Module.Path == internal.GoStdModulePath {
+			// Standard library packages do not have an associated module,
+			// so we relate them to the artificial stdlib module.
+			return md
+		}
+
+		if moduleKnown {
+			if mod.Module.Path == module {
+				// If we know exactly which module we need,
+				// return its vulnerabilities.
+				return md
+			}
+		} else if strings.HasPrefix(importPath, md.Module.Path) {
+			// If module is unknown, we try to figure it out from importPath.
+			// We take the module whose path has the longest match to importPath.
+			// TODO: do matching based on path components.
+			if mostSpecificMod == nil || len(mostSpecificMod.Module.Path) < len(md.Module.Path) {
+				mostSpecificMod = md
+			}
+		}
+	}
+	return mostSpecificMod
+}
+
+// ForPackage returns the vulnerabilities for the importPath belonging to
+// module.
+//
+// If module is unknown, ForPackage will resolve it as the most specific
+// prefix of importPath.
+func (aff affectingVulns) ForPackage(module, importPath string) []*osv.Entry {
+	mod := aff.moduleVulns(module, importPath)
+	if mod == nil {
+		return nil
+	}
+
+	if mod.Module.Replace != nil {
+		// standard libraries do not have a module nor replace module
+		importPath = fmt.Sprintf("%s%s", mod.Module.Replace.Path, strings.TrimPrefix(importPath, mod.Module.Path))
+	}
+	vulns := mod.Vulns
+	packageVulns := []*osv.Entry{}
+Vuln:
+	for _, v := range vulns {
+		for _, a := range v.Affected {
+			if len(a.EcosystemSpecific.Packages) == 0 {
+				// no packages means all packages are vulnerable
+				packageVulns = append(packageVulns, v)
+				continue Vuln
+			}
+
+			for _, p := range a.EcosystemSpecific.Packages {
+				if p.Path == importPath {
+					packageVulns = append(packageVulns, v)
+					continue Vuln
+				}
+			}
+		}
+	}
+	return packageVulns
+}
+
+// ForSymbol returns vulnerabilities for symbol in aff.ForPackage(module, importPath).
+func (aff affectingVulns) ForSymbol(module, importPath, symbol string) []*osv.Entry {
+	vulns := aff.ForPackage(module, importPath)
+	if vulns == nil {
+		return nil
+	}
+
+	symbolVulns := []*osv.Entry{}
+vulnLoop:
+	for _, v := range vulns {
+		for _, a := range v.Affected {
+			if len(a.EcosystemSpecific.Packages) == 0 {
+				// no packages means all symbols of all packages are vulnerable
+				symbolVulns = append(symbolVulns, v)
+				continue vulnLoop
+			}
+
+			for _, p := range a.EcosystemSpecific.Packages {
+				if p.Path != importPath {
+					continue
+				}
+				if len(p.Symbols) > 0 && !contains(p.Symbols, symbol) {
+					continue
+				}
+				symbolVulns = append(symbolVulns, v)
+				continue vulnLoop
+			}
+		}
+	}
+	return symbolVulns
+}
+
+func contains(symbols []string, target string) bool {
+	for _, s := range symbols {
+		if s == target {
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/witness.go b/vendor/golang.org/x/vuln/internal/vulncheck/witness.go
new file mode 100644
index 0000000..7bc1858
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/witness.go
@@ -0,0 +1,449 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vulncheck
+
+import (
+	"container/list"
+	"fmt"
+	"go/ast"
+	"go/token"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"unicode"
+
+	"golang.org/x/tools/go/packages"
+)
+
+// CallStack is a call stack starting with a client
+// function or method and ending with a call to a
+// vulnerable symbol.
+type CallStack []StackEntry
+
+// StackEntry is an element of a call stack.
+type StackEntry struct {
+	// Function whose frame is on the stack.
+	Function *FuncNode
+
+	// Call is the call site inducing the next stack frame.
+	// nil when the frame represents the last frame in the stack.
+	Call *CallSite
+}
+
+// sourceCallstacks returns representative call stacks for each
+// vulnerability in res. The returned call stacks are heuristically
+// ordered by how seemingly easy is to understand them: shorter
+// call stacks with less dynamic call sites appear earlier in the
+// returned slices.
+//
+// sourceCallstacks performs a breadth-first search of res.CallGraph
+// starting at the vulnerable symbol and going up until reaching an entry
+// function or method in res.CallGraph.Entries. During this search,
+// each function is visited at most once to avoid potential
+// exponential explosion. Hence, not all call stacks are analyzed.
+func sourceCallstacks(res *Result) map[*Vuln]CallStack {
+	var (
+		wg sync.WaitGroup
+		mu sync.Mutex
+	)
+	stackPerVuln := make(map[*Vuln]CallStack)
+	for _, vuln := range res.Vulns {
+		vuln := vuln
+		wg.Add(1)
+		go func() {
+			cs := sourceCallstack(vuln, res)
+			mu.Lock()
+			stackPerVuln[vuln] = cs
+			mu.Unlock()
+			wg.Done()
+		}()
+	}
+	wg.Wait()
+
+	updateInitPositions(stackPerVuln)
+	return stackPerVuln
+}
+
+// sourceCallstack finds a representative call stack for vuln.
+// This is a shortest unique call stack with the least
+// number of dynamic call sites.
+func sourceCallstack(vuln *Vuln, res *Result) CallStack {
+	vulnSink := vuln.CallSink
+	if vulnSink == nil {
+		return nil
+	}
+
+	entries := make(map[*FuncNode]bool)
+	for _, e := range res.EntryFunctions {
+		entries[e] = true
+	}
+
+	seen := make(map[*FuncNode]bool)
+
+	// Do a BFS from the vuln sink to the entry points
+	// and find the representative call stack. This is
+	// the shortest call stack that goes through the
+	// least number of dynamic call sites. We first
+	// collect all candidate call stacks of the shortest
+	// length and then pick the best one accordingly.
+	var candidates []CallStack
+	candDepth := 0
+	queue := list.New()
+	queue.PushBack(&callChain{f: vulnSink})
+
+	// We want to avoid call stacks that go through
+	// other vulnerable symbols of the same package
+	// for the same vulnerability. In other words,
+	// we want unique call stacks.
+	skipSymbols := make(map[*FuncNode]bool)
+	for _, v := range res.Vulns {
+		if v.CallSink != nil && v != vuln &&
+			v.OSV == vuln.OSV && v.Package == vuln.Package {
+			skipSymbols[v.CallSink] = true
+		}
+	}
+
+	for queue.Len() > 0 {
+		front := queue.Front()
+		c := front.Value.(*callChain)
+		queue.Remove(front)
+
+		f := c.f
+		if seen[f] {
+			continue
+		}
+		seen[f] = true
+
+		// Pick a single call site for each function in determinstic order.
+		// A single call site is sufficient as we visit a function only once.
+		for _, cs := range callsites(f.CallSites, seen) {
+			nStack := &callChain{f: cs.Parent, call: cs, child: c}
+			if !skipSymbols[cs.Parent] {
+				queue.PushBack(nStack)
+			}
+
+			if entries[cs.Parent] {
+				ns := nStack.CallStack()
+				if len(candidates) == 0 || len(ns) == candDepth {
+					// The case where we either have not identified
+					// any call stacks or just found one of the same
+					// length as the previous ones.
+					candidates = append(candidates, ns)
+					candDepth = len(ns)
+				} else {
+					// We just found a candidate call stack whose
+					// length is greater than what we previously
+					// found. We can thus safely disregard this
+					// call stack and stop searching since we won't
+					// be able to find any better candidates.
+					queue.Init() // clear the list, effectively exiting the outer loop
+				}
+			}
+		}
+	}
+
+	// Sort candidate call stacks by their number of dynamic call
+	// sites and return the first one.
+	sort.SliceStable(candidates, func(i int, j int) bool {
+		s1, s2 := candidates[i], candidates[j]
+		if w1, w2 := weight(s1), weight(s2); w1 != w2 {
+			return w1 < w2
+		}
+
+		// At this point, the stableness/determinism of
+		// sorting is guaranteed by the determinism of
+		// the underlying call graph and the call stack
+		// search algorithm.
+		return true
+	})
+	if len(candidates) == 0 {
+		return nil
+	}
+	return candidates[0]
+}
+
+// callsites picks a call site from sites for each non-visited function.
+// For each such function, the smallest (posLess) call site is chosen. The
+// returned slice is sorted by caller functions (funcLess). Assumes callee
+// of each call site is the same.
+func callsites(sites []*CallSite, visited map[*FuncNode]bool) []*CallSite {
+	minCs := make(map[*FuncNode]*CallSite)
+	for _, cs := range sites {
+		if visited[cs.Parent] {
+			continue
+		}
+		if csLess(cs, minCs[cs.Parent]) {
+			minCs[cs.Parent] = cs
+		}
+	}
+
+	var fs []*FuncNode
+	for _, cs := range minCs {
+		fs = append(fs, cs.Parent)
+	}
+	sort.SliceStable(fs, func(i, j int) bool { return funcLess(fs[i], fs[j]) })
+
+	var css []*CallSite
+	for _, f := range fs {
+		css = append(css, minCs[f])
+	}
+	return css
+}
+
+// callChain models a chain of function calls.
+type callChain struct {
+	call  *CallSite // nil for entry points
+	f     *FuncNode
+	child *callChain
+}
+
+// CallStack converts callChain to CallStack type.
+func (c *callChain) CallStack() CallStack {
+	if c == nil {
+		return nil
+	}
+	return append(CallStack{StackEntry{Function: c.f, Call: c.call}}, c.child.CallStack()...)
+}
+
+// weight computes an approximate measure of how easy is to understand the call
+// stack when presented to the client as a witness. The smaller the value, the more
+// understandable the stack is. Currently defined as the number of unresolved
+// call sites in the stack.
+func weight(stack CallStack) int {
+	w := 0
+	for _, e := range stack {
+		if e.Call != nil && !e.Call.Resolved {
+			w += 1
+		}
+	}
+	return w
+}
+
+// csLess compares two call sites by their locations and, if needed,
+// their string representation.
+func csLess(cs1, cs2 *CallSite) bool {
+	if cs2 == nil {
+		return true
+	}
+
+	// fast code path
+	if p1, p2 := cs1.Pos, cs2.Pos; p1 != nil && p2 != nil {
+		if posLess(*p1, *p2) {
+			return true
+		}
+		if posLess(*p2, *p1) {
+			return false
+		}
+		// for sanity, should not occur in practice
+		return fmt.Sprintf("%v.%v", cs1.RecvType, cs2.Name) < fmt.Sprintf("%v.%v", cs2.RecvType, cs2.Name)
+	}
+
+	// code path rarely exercised
+	if cs2.Pos == nil {
+		return true
+	}
+	if cs1.Pos == nil {
+		return false
+	}
+	// should very rarely occur in practice
+	return fmt.Sprintf("%v.%v", cs1.RecvType, cs2.Name) < fmt.Sprintf("%v.%v", cs2.RecvType, cs2.Name)
+}
+
+// posLess compares two positions by their line and column number,
+// and filename if needed.
+func posLess(p1, p2 token.Position) bool {
+	if p1.Line < p2.Line {
+		return true
+	}
+	if p2.Line < p1.Line {
+		return false
+	}
+
+	if p1.Column < p2.Column {
+		return true
+	}
+	if p2.Column < p1.Column {
+		return false
+	}
+
+	return strings.Compare(p1.Filename, p2.Filename) == -1
+}
+
+// funcLess compares two function nodes by locations of
+// corresponding functions and, if needed, their string representation.
+func funcLess(f1, f2 *FuncNode) bool {
+	if p1, p2 := f1.Pos, f2.Pos; p1 != nil && p2 != nil {
+		if posLess(*p1, *p2) {
+			return true
+		}
+		if posLess(*p2, *p1) {
+			return false
+		}
+		// for sanity, should not occur in practice
+		return f1.String() < f2.String()
+	}
+
+	if f2.Pos == nil {
+		return true
+	}
+	if f1.Pos == nil {
+		return false
+	}
+	// should happen only for inits
+	return f1.String() < f2.String()
+}
+
+// updateInitPositions populates non-existing positions of init functions
+// and their respective calls in callStacks (see #51575).
+func updateInitPositions(callStacks map[*Vuln]CallStack) {
+	for _, cs := range callStacks {
+		for i := range cs {
+			updateInitPosition(&cs[i])
+			if i != len(cs)-1 {
+				updateInitCallPosition(&cs[i], cs[i+1])
+			}
+		}
+	}
+}
+
+// updateInitCallPosition updates the position of a call to init in a stack frame, if
+// one already does not exist:
+//
+//	P1.init -> P2.init: position of call to P2.init is the position of "import P2"
+//	statement in P1
+//
+//	P.init -> P.init#d: P.init is an implicit init. We say it calls the explicit
+//	P.init#d at the place of "package P" statement.
+func updateInitCallPosition(curr *StackEntry, next StackEntry) {
+	call := curr.Call
+	if !isInit(next.Function) || (call.Pos != nil && call.Pos.IsValid()) {
+		// Skip non-init functions and inits whose call site position is available.
+		return
+	}
+
+	var pos token.Position
+	if curr.Function.Name == "init" && curr.Function.Package == next.Function.Package {
+		// We have implicit P.init calling P.init#d. Set the call position to
+		// be at "package P" statement position.
+		pos = packageStatementPos(curr.Function.Package)
+	} else {
+		// Choose the beginning of the import statement as the position.
+		pos = importStatementPos(curr.Function.Package, next.Function.Package.PkgPath)
+	}
+
+	call.Pos = &pos
+}
+
+func importStatementPos(pkg *packages.Package, importPath string) token.Position {
+	var importSpec *ast.ImportSpec
+spec:
+	for _, f := range pkg.Syntax {
+		for _, impSpec := range f.Imports {
+			// Import spec paths have quotation marks.
+			impSpecPath, err := strconv.Unquote(impSpec.Path.Value)
+			if err != nil {
+				panic(fmt.Sprintf("import specification: package path has no quotation marks: %v", err))
+			}
+			if impSpecPath == importPath {
+				importSpec = impSpec
+				break spec
+			}
+		}
+	}
+
+	if importSpec == nil {
+		// for sanity, in case of a wild call graph imprecision
+		return token.Position{}
+	}
+
+	// Choose the beginning of the import statement as the position.
+	return pkg.Fset.Position(importSpec.Pos())
+}
+
+func packageStatementPos(pkg *packages.Package) token.Position {
+	if len(pkg.Syntax) == 0 {
+		return token.Position{}
+	}
+	// Choose beginning of the package statement as the position. Pick
+	// the first file since it is as good as any.
+	return pkg.Fset.Position(pkg.Syntax[0].Package)
+}
+
+// updateInitPosition updates the position of P.init function in a stack frame if one
+// is not available. The new position is the position of the "package P" statement.
+func updateInitPosition(se *StackEntry) {
+	fun := se.Function
+	if !isInit(fun) || (fun.Pos != nil && fun.Pos.IsValid()) {
+		// Skip non-init functions and inits whose position is available.
+		return
+	}
+
+	pos := packageStatementPos(fun.Package)
+	fun.Pos = &pos
+}
+
+func isInit(f *FuncNode) bool {
+	// A source init function, or anonymous functions used in inits, will
+	// be named "init#x" by vulncheck (more precisely, ssa), where x is a
+	// positive integer. Implicit inits are named simply "init".
+	return f.Name == "init" || strings.HasPrefix(f.Name, "init#")
+}
+
+// binaryCallstacks computes representative call stacks for binary results.
+func binaryCallstacks(vr *Result) map[*Vuln]CallStack {
+	callstacks := map[*Vuln]CallStack{}
+	for _, vv := range uniqueVulns(vr.Vulns) {
+		f := &FuncNode{Package: vv.Package, Name: vv.Symbol}
+		parts := strings.Split(vv.Symbol, ".")
+		if len(parts) != 1 {
+			f.RecvType = parts[0]
+			f.Name = parts[1]
+		}
+		callstacks[vv] = CallStack{StackEntry{Function: f}}
+	}
+	return callstacks
+}
+
+// uniqueVulns does for binary mode what sourceCallstacks does for source mode.
+// It tries not to report redundant symbols. Since there are no call stacks in
+// binary mode, the following approximate approach is used. Do not report unexported
+// symbols for a  triple if there are some exported symbols.
+// Otherwise, report all unexported symbols to avoid not reporting anything.
+func uniqueVulns(vulns []*Vuln) []*Vuln {
+	type key struct {
+		id  string
+		pkg string
+		mod string
+	}
+	hasExported := make(map[key]bool)
+	for _, v := range vulns {
+		if isExported(v.Symbol) {
+			k := key{id: v.OSV.ID, pkg: v.Package.PkgPath, mod: v.Package.Module.Path}
+			hasExported[k] = true
+		}
+	}
+
+	var uniques []*Vuln
+	for _, v := range vulns {
+		k := key{id: v.OSV.ID, pkg: v.Package.PkgPath, mod: v.Package.Module.Path}
+		if isExported(v.Symbol) || !hasExported[k] {
+			uniques = append(uniques, v)
+		}
+	}
+	return uniques
+}
+
+// isExported checks if the symbol is exported. Assumes that the
+// symbol is of the form "identifier", "identifier1.identifier2",
+// or "identifier.".
+func isExported(symbol string) bool {
+	parts := strings.Split(symbol, ".")
+	last := parts[len(parts)-1]
+	if last == "" { // case for "identifier."
+		return false
+	}
+	return unicode.IsUpper(rune(last[0]))
+}
diff --git a/vendor/golang.org/x/vuln/internal/web/url.go b/vendor/golang.org/x/vuln/internal/web/url.go
new file mode 100644
index 0000000..dadc6b4
--- /dev/null
+++ b/vendor/golang.org/x/vuln/internal/web/url.go
@@ -0,0 +1,143 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code copied from
+// https://github.com/golang/go/blob/2ebe77a2fda1ee9ff6fd9a3e08933ad1ebaea039/src/cmd/go/internal/web/url.go
+// TODO(https://go.dev/issue/32456): if accepted, use the new API.
+
+package web
+
+import (
+	"errors"
+	"net/url"
+	"path/filepath"
+	"runtime"
+	"strings"
+)
+
+var errNotAbsolute = errors.New("path is not absolute")
+
+// URLToFilePath converts a file-scheme url to a file path.
+func URLToFilePath(u *url.URL) (string, error) {
+	if u.Scheme != "file" {
+		return "", errors.New("non-file URL")
+	}
+
+	checkAbs := func(path string) (string, error) {
+		if !filepath.IsAbs(path) {
+			return "", errNotAbsolute
+		}
+		return path, nil
+	}
+
+	if u.Path == "" {
+		if u.Host != "" || u.Opaque == "" {
+			return "", errors.New("file URL missing path")
+		}
+		return checkAbs(filepath.FromSlash(u.Opaque))
+	}
+
+	path, err := convertFileURLPath(u.Host, u.Path)
+	if err != nil {
+		return path, err
+	}
+	return checkAbs(path)
+}
+
+// URLFromFilePath converts the given absolute path to a URL.
+func URLFromFilePath(path string) (*url.URL, error) {
+	if !filepath.IsAbs(path) {
+		return nil, errNotAbsolute
+	}
+
+	// If path has a Windows volume name, convert the volume to a host and prefix
+	// per https://blogs.msdn.microsoft.com/ie/2006/12/06/file-uris-in-windows/.
+	if vol := filepath.VolumeName(path); vol != "" {
+		if strings.HasPrefix(vol, `\\`) {
+			path = filepath.ToSlash(path[2:])
+			i := strings.IndexByte(path, '/')
+
+			if i < 0 {
+				// A degenerate case.
+				// \\host.example.com (without a share name)
+				// becomes
+				// file://host.example.com/
+				return &url.URL{
+					Scheme: "file",
+					Host:   path,
+					Path:   "/",
+				}, nil
+			}
+
+			// \\host.example.com\Share\path\to\file
+			// becomes
+			// file://host.example.com/Share/path/to/file
+			return &url.URL{
+				Scheme: "file",
+				Host:   path[:i],
+				Path:   filepath.ToSlash(path[i:]),
+			}, nil
+		}
+
+		// C:\path\to\file
+		// becomes
+		// file:///C:/path/to/file
+		return &url.URL{
+			Scheme: "file",
+			Path:   "/" + filepath.ToSlash(path),
+		}, nil
+	}
+
+	// /path/to/file
+	// becomes
+	// file:///path/to/file
+	return &url.URL{
+		Scheme: "file",
+		Path:   filepath.ToSlash(path),
+	}, nil
+}
+
+func convertFileURLPath(host, path string) (string, error) {
+	if runtime.GOOS == "windows" {
+		return convertFileURLPathWindows(host, path)
+	}
+	switch host {
+	case "", "localhost":
+	default:
+		return "", errors.New("file URL specifies non-local host")
+	}
+	return filepath.FromSlash(path), nil
+}
+
+func convertFileURLPathWindows(host, path string) (string, error) {
+	if len(path) == 0 || path[0] != '/' {
+		return "", errNotAbsolute
+	}
+
+	path = filepath.FromSlash(path)
+
+	// We interpret Windows file URLs per the description in
+	// https://blogs.msdn.microsoft.com/ie/2006/12/06/file-uris-in-windows/.
+
+	// The host part of a file URL (if any) is the UNC volume name,
+	// but RFC 8089 reserves the authority "localhost" for the local machine.
+	if host != "" && host != "localhost" {
+		// A common "legacy" format omits the leading slash before a drive letter,
+		// encoding the drive letter as the host instead of part of the path.
+		// (See https://blogs.msdn.microsoft.com/freeassociations/2005/05/19/the-bizarre-and-unhappy-story-of-file-urls/.)
+		// We do not support that format, but we should at least emit a more
+		// helpful error message for it.
+		if filepath.VolumeName(host) != "" {
+			return "", errors.New("file URL encodes volume in host field: too few slashes?")
+		}
+		return `\\` + host + path, nil
+	}
+
+	// If host is empty, path must contain an initial slash followed by a
+	// drive letter and path. Remove the slash and verify that the path is valid.
+	if vol := filepath.VolumeName(path[1:]); vol == "" || strings.HasPrefix(vol, `\\`) {
+		return "", errors.New("file URL missing drive letter")
+	}
+	return path[1:], nil
+}
diff --git a/vendor/golang.org/x/vuln/scan/scan.go b/vendor/golang.org/x/vuln/scan/scan.go
new file mode 100644
index 0000000..459fc36
--- /dev/null
+++ b/vendor/golang.org/x/vuln/scan/scan.go
@@ -0,0 +1,116 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package scan provides functionality for running govulncheck.
+
+See [cmd/govulncheck/main.go] as a usage example.
+
+[cmd/govulncheck/main.go]: https://go.googlesource.com/vuln/+/master/cmd/govulncheck/main.go
+*/
+package scan
+
+import (
+	"context"
+	"errors"
+	"io"
+	"os"
+
+	"golang.org/x/vuln/internal/scan"
+)
+
+// Cmd represents an external govulncheck command being prepared or run,
+// similar to exec.Cmd.
+type Cmd struct {
+	// Stdin specifies the standard input. If provided, it is expected to be
+	// the output of govulncheck -json.
+	Stdin io.Reader
+
+	// Stdout specifies the standard output. If nil, Run connects os.Stdout.
+	Stdout io.Writer
+
+	// Stderr specifies the standard error. If nil, Run connects os.Stderr.
+	Stderr io.Writer
+
+	// Env is the environment to use.
+	// If Env is nil, the current environment is used.
+	// As in os/exec's Cmd, only the last value in the slice for
+	// each environment key is used. To specify the setting of only
+	// a few variables, append to the current environment, as in:
+	//
+	//	opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386")
+	//
+	Env []string
+
+	ctx  context.Context
+	args []string
+	done chan struct{}
+	err  error
+}
+
+// Command returns the Cmd struct to execute govulncheck with the given
+// arguments.
+func Command(ctx context.Context, arg ...string) *Cmd {
+	return &Cmd{
+		ctx:  ctx,
+		args: arg,
+	}
+}
+
+// Start starts the specified command but does not wait for it to complete.
+//
+// After a successful call to Start the Wait method must be called in order to
+// release associated system resources.
+func (c *Cmd) Start() error {
+	if c.done != nil {
+		return errors.New("vuln: already started")
+	}
+	if c.Stdin == nil {
+		c.Stdin = os.Stdin
+	}
+	if c.Stdout == nil {
+		c.Stdout = os.Stdout
+	}
+	if c.Stderr == nil {
+		c.Stderr = os.Stderr
+	}
+	if c.Env == nil {
+		c.Env = os.Environ()
+	}
+	c.done = make(chan struct{})
+	go func() {
+		defer close(c.done)
+		c.err = c.scan()
+	}()
+	return nil
+}
+
+// Wait waits for the command to exit. The command must have been started by
+// Start.
+//
+// If the command fails to run or does not complete successfully, the returned
+// error wraps an error implementing:
+//
+//	interface {
+//		ExitCode() int
+//	}
+//
+// Callers can use errors.As to retrieve the exit code. Other errors may be
+// returned for other problems (e.g. I/O issues).
+//
+// Wait releases any resources associated with the Cmd.
+func (c *Cmd) Wait() error {
+	if c.done == nil {
+		return errors.New("vuln: start must be called before wait")
+	}
+	<-c.done
+	return c.err
+}
+
+func (c *Cmd) scan() error {
+	if err := c.ctx.Err(); err != nil {
+		return err
+	}
+	return scan.RunGovulncheck(c.ctx, c.Env, c.Stdin, c.Stdout, c.Stderr, c.args)
+}
diff --git a/vendor/honnef.co/go/tools/LICENSE b/vendor/honnef.co/go/tools/LICENSE
new file mode 100644
index 0000000..dfd0314
--- /dev/null
+++ b/vendor/honnef.co/go/tools/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2016 Dominik Honnef
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/honnef.co/go/tools/LICENSE-THIRD-PARTY b/vendor/honnef.co/go/tools/LICENSE-THIRD-PARTY
new file mode 100644
index 0000000..f2c0fa9
--- /dev/null
+++ b/vendor/honnef.co/go/tools/LICENSE-THIRD-PARTY
@@ -0,0 +1,121 @@
+Staticcheck and its related tools make use of third party projects,
+either by reusing their code, or by statically linking them into
+resulting binaries. These projects are:
+
+* The Go Programming Language - https://golang.org/
+  golang.org/x/mod - https://github.com/golang/mod
+  golang.org/x/tools - https://github.com/golang/tools
+  golang.org/x/sys - https://github.com/golang/sys
+  golang.org/x/xerrors - https://github.com/golang/xerrors
+
+    Copyright (c) 2009 The Go Authors. All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are
+    met:
+
+       * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above
+    copyright notice, this list of conditions and the following disclaimer
+    in the documentation and/or other materials provided with the
+    distribution.
+       * Neither the name of Google Inc. nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+* github.com/BurntSushi/toml - https://github.com/BurntSushi/toml
+
+    The MIT License (MIT)
+
+    Copyright (c) 2013 TOML authors
+
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+
+* gogrep - https://github.com/mvdan/gogrep
+
+    Copyright (c) 2017, Daniel Martí. All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are
+    met:
+
+       * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above
+    copyright notice, this list of conditions and the following disclaimer
+    in the documentation and/or other materials provided with the
+    distribution.
+       * Neither the name of the copyright holder nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+* gosmith - https://github.com/dvyukov/gosmith
+
+    Copyright (c) 2014 Dmitry Vyukov. All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are
+    met:
+
+       * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above
+    copyright notice, this list of conditions and the following disclaimer
+    in the documentation and/or other materials provided with the
+    distribution.
+       * The name of Dmitry Vyukov may be used to endorse or promote
+    products derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/honnef.co/go/tools/analysis/callcheck/callcheck.go b/vendor/honnef.co/go/tools/analysis/callcheck/callcheck.go
new file mode 100644
index 0000000..3ad6888
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/callcheck/callcheck.go
@@ -0,0 +1,161 @@
+// Package callcheck provides a framework for validating arguments in function calls.
+package callcheck
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/types"
+
+	"golang.org/x/tools/go/analysis"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+)
+
+type Call struct {
+	Pass  *analysis.Pass
+	Instr ir.CallInstruction
+	Args  []*Argument
+
+	Parent *ir.Function
+
+	invalids []string
+}
+
+func (c *Call) Invalid(msg string) {
+	c.invalids = append(c.invalids, msg)
+}
+
+type Argument struct {
+	Value    Value
+	invalids []string
+}
+
+type Value struct {
+	Value ir.Value
+}
+
+func (arg *Argument) Invalid(msg string) {
+	arg.invalids = append(arg.invalids, msg)
+}
+
+type Check func(call *Call)
+
+func Analyzer(rules map[string]Check) func(pass *analysis.Pass) (any, error) {
+	return func(pass *analysis.Pass) (any, error) {
+		return checkCalls(pass, rules)
+	}
+}
+
+func checkCalls(pass *analysis.Pass, rules map[string]Check) (any, error) {
+	cb := func(caller *ir.Function, site ir.CallInstruction, callee *ir.Function) {
+		obj, ok := callee.Object().(*types.Func)
+		if !ok {
+			return
+		}
+
+		r, ok := rules[typeutil.FuncName(obj)]
+		if !ok {
+			return
+		}
+		var args []*Argument
+		irargs := site.Common().Args
+		if callee.Signature.Recv() != nil {
+			irargs = irargs[1:]
+		}
+		for _, arg := range irargs {
+			if iarg, ok := arg.(*ir.MakeInterface); ok {
+				arg = iarg.X
+			}
+			args = append(args, &Argument{Value: Value{arg}})
+		}
+		call := &Call{
+			Pass:   pass,
+			Instr:  site,
+			Args:   args,
+			Parent: site.Parent(),
+		}
+		r(call)
+
+		var astcall *ast.CallExpr
+		switch source := site.Source().(type) {
+		case *ast.CallExpr:
+			astcall = source
+		case *ast.DeferStmt:
+			astcall = source.Call
+		case *ast.GoStmt:
+			astcall = source.Call
+		case nil:
+			// TODO(dh): I am not sure this can actually happen. If it
+			// can't, we should remove this case, and also stop
+			// checking for astcall == nil in the code that follows.
+		default:
+			panic(fmt.Sprintf("unhandled case %T", source))
+		}
+
+		for idx, arg := range call.Args {
+			for _, e := range arg.invalids {
+				if astcall != nil {
+					if idx < len(astcall.Args) {
+						report.Report(pass, astcall.Args[idx], e)
+					} else {
+						// this is an instance of fn1(fn2()) where fn2
+						// returns multiple values. Report the error
+						// at the next-best position that we have, the
+						// first argument. An example of a check that
+						// triggers this is checkEncodingBinaryRules.
+						report.Report(pass, astcall.Args[0], e)
+					}
+				} else {
+					report.Report(pass, site, e)
+				}
+			}
+		}
+		for _, e := range call.invalids {
+			report.Report(pass, call.Instr, e)
+		}
+	}
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		eachCall(fn, cb)
+	}
+	return nil, nil
+}
+
+func eachCall(fn *ir.Function, cb func(caller *ir.Function, site ir.CallInstruction, callee *ir.Function)) {
+	for _, b := range fn.Blocks {
+		for _, instr := range b.Instrs {
+			if site, ok := instr.(ir.CallInstruction); ok {
+				if g := site.Common().StaticCallee(); g != nil {
+					cb(fn, site, g)
+				}
+			}
+		}
+	}
+}
+
+func ExtractConstExpectKind(v Value, kind constant.Kind) *ir.Const {
+	k := extractConst(v.Value)
+	if k == nil || k.Value == nil || k.Value.Kind() != kind {
+		return nil
+	}
+	return k
+}
+
+func ExtractConst(v Value) *ir.Const {
+	return extractConst(v.Value)
+}
+
+func extractConst(v ir.Value) *ir.Const {
+	v = irutil.Flatten(v)
+	switch v := v.(type) {
+	case *ir.Const:
+		return v
+	case *ir.MakeInterface:
+		return extractConst(v.X)
+	default:
+		return nil
+	}
+}
diff --git a/vendor/honnef.co/go/tools/analysis/code/code.go b/vendor/honnef.co/go/tools/analysis/code/code.go
new file mode 100644
index 0000000..64af43c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/code/code.go
@@ -0,0 +1,596 @@
+// Package code answers structural and type questions about Go code.
+package code
+
+import (
+	"fmt"
+	"go/ast"
+	"go/build/constraint"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"go/version"
+	"path/filepath"
+	"slices"
+	"strings"
+
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/facts/purity"
+	"honnef.co/go/tools/analysis/facts/tokenfile"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/knowledge"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+type Positioner interface {
+	Pos() token.Pos
+}
+
+func IsOfStringConvertibleByteSlice(pass *analysis.Pass, expr ast.Expr) bool {
+	typ, ok := pass.TypesInfo.TypeOf(expr).Underlying().(*types.Slice)
+	if !ok {
+		return false
+	}
+	elem := types.Unalias(typ.Elem())
+	if version.Compare(LanguageVersion(pass, expr), "go1.18") >= 0 {
+		// Before Go 1.18, one could not directly convert from []T (where 'type T byte')
+		// to string. See also https://github.com/golang/go/issues/23536.
+		elem = elem.Underlying()
+	}
+	return types.Identical(elem, types.Typ[types.Byte])
+}
+
+func IsOfPointerToTypeWithName(pass *analysis.Pass, expr ast.Expr, name string) bool {
+	ptr, ok := types.Unalias(pass.TypesInfo.TypeOf(expr)).(*types.Pointer)
+	if !ok {
+		return false
+	}
+	return typeutil.IsTypeWithName(ptr.Elem(), name)
+}
+
+func IsOfTypeWithName(pass *analysis.Pass, expr ast.Expr, name string) bool {
+	return typeutil.IsTypeWithName(pass.TypesInfo.TypeOf(expr), name)
+}
+
+func IsInTest(pass *analysis.Pass, node Positioner) bool {
+	// FIXME(dh): this doesn't work for global variables with
+	// initializers
+	f := pass.Fset.File(node.Pos())
+	return f != nil && strings.HasSuffix(f.Name(), "_test.go")
+}
+
+// IsMain reports whether the package being processed is a package
+// main.
+func IsMain(pass *analysis.Pass) bool {
+	return pass.Pkg.Name() == "main"
+}
+
+// IsMainLike reports whether the package being processed is a
+// main-like package. A main-like package is a package that is
+// package main, or that is intended to be used by a tool framework
+// such as cobra to implement a command.
+//
+// Note that this function errs on the side of false positives; it may
+// return true for packages that aren't main-like. IsMainLike is
+// intended for analyses that wish to suppress diagnostics for
+// main-like packages to avoid false positives.
+func IsMainLike(pass *analysis.Pass) bool {
+	if pass.Pkg.Name() == "main" {
+		return true
+	}
+	for _, imp := range pass.Pkg.Imports() {
+		if imp.Path() == "github.com/spf13/cobra" {
+			return true
+		}
+	}
+	return false
+}
+
+func SelectorName(pass *analysis.Pass, expr *ast.SelectorExpr) string {
+	info := pass.TypesInfo
+	sel := info.Selections[expr]
+	if sel == nil {
+		switch x := expr.X.(type) {
+		case *ast.Ident:
+			pkg, ok := info.ObjectOf(x).(*types.PkgName)
+			if !ok {
+				return fmt.Sprintf("(%s).%s", info.TypeOf(x), expr.Sel.Name)
+			}
+			return fmt.Sprintf("%s.%s", pkg.Imported().Path(), expr.Sel.Name)
+		case *ast.SelectorExpr:
+			return fmt.Sprintf("(%s).%s", SelectorName(pass, x), expr.Sel.Name)
+		case *ast.IndexExpr, *ast.IndexListExpr:
+			// A selector on an instantiated generic type, such as pkg.T[int].Field.
+			// These have no entry in info.Selections when the selector was
+			// synthesized from a type expression rather than read from the source.
+			return fmt.Sprintf("(%s).%s", info.TypeOf(x), expr.Sel.Name)
+		default:
+			panic(fmt.Sprintf("unsupported selector: %v", expr))
+		}
+	}
+	if v, ok := sel.Obj().(*types.Var); ok && v.IsField() {
+		return fmt.Sprintf("(%s).%s", typeutil.DereferenceR(sel.Recv()), sel.Obj().Name())
+	} else {
+		return fmt.Sprintf("(%s).%s", sel.Recv(), sel.Obj().Name())
+	}
+}
+
+func IsNil(pass *analysis.Pass, expr ast.Expr) bool {
+	return pass.TypesInfo.Types[expr].IsNil()
+}
+
+func BoolConst(pass *analysis.Pass, expr ast.Expr) bool {
+	val := pass.TypesInfo.ObjectOf(expr.(*ast.Ident)).(*types.Const).Val()
+	return constant.BoolVal(val)
+}
+
+func IsBoolConst(pass *analysis.Pass, expr ast.Expr) bool {
+	// We explicitly don't support typed bools because more often than
+	// not, custom bool types are used as binary enums and the explicit
+	// comparison is desired. We err on the side of false negatives and
+	// treat aliases like other custom types.
+
+	ident, ok := expr.(*ast.Ident)
+	if !ok {
+		return false
+	}
+	obj := pass.TypesInfo.ObjectOf(ident)
+	c, ok := obj.(*types.Const)
+	if !ok {
+		return false
+	}
+	basic, ok := c.Type().(*types.Basic)
+	if !ok {
+		return false
+	}
+	if basic.Kind() != types.UntypedBool && basic.Kind() != types.Bool {
+		return false
+	}
+	return true
+}
+
+func ExprToInt(pass *analysis.Pass, expr ast.Expr) (int64, bool) {
+	tv := pass.TypesInfo.Types[expr]
+	if tv.Value == nil {
+		return 0, false
+	}
+	if tv.Value.Kind() != constant.Int {
+		return 0, false
+	}
+	return constant.Int64Val(tv.Value)
+}
+
+func ExprToString(pass *analysis.Pass, expr ast.Expr) (string, bool) {
+	val := pass.TypesInfo.Types[expr].Value
+	if val == nil {
+		return "", false
+	}
+	if val.Kind() != constant.String {
+		return "", false
+	}
+	return constant.StringVal(val), true
+}
+
+func CallName(pass *analysis.Pass, call *ast.CallExpr) string {
+	// See the comment in typeutil.FuncName for why this doesn't require special handling
+	// of aliases.
+
+	fun := ast.Unparen(call.Fun)
+
+	// Instantiating a function cannot return another generic function, so doing this once is enough
+	switch idx := fun.(type) {
+	case *ast.IndexExpr:
+		fun = idx.X
+	case *ast.IndexListExpr:
+		fun = idx.X
+	}
+
+	// (foo)[T] is not a valid instantiation, so no need to unparen again.
+
+	switch fun := fun.(type) {
+	case *ast.SelectorExpr:
+		fn, ok := pass.TypesInfo.ObjectOf(fun.Sel).(*types.Func)
+		if !ok {
+			return ""
+		}
+		return typeutil.FuncName(fn)
+	case *ast.Ident:
+		obj := pass.TypesInfo.ObjectOf(fun)
+		switch obj := obj.(type) {
+		case *types.Func:
+			return typeutil.FuncName(obj)
+		case *types.Builtin:
+			return obj.Name()
+		default:
+			return ""
+		}
+	default:
+		return ""
+	}
+}
+
+func IsCallTo(pass *analysis.Pass, node ast.Node, name string) bool {
+	// See the comment in typeutil.FuncName for why this doesn't require special handling
+	// of aliases.
+
+	call, ok := node.(*ast.CallExpr)
+	if !ok {
+		return false
+	}
+	return CallName(pass, call) == name
+}
+
+func IsCallToAny(pass *analysis.Pass, node ast.Node, names ...string) bool {
+	// See the comment in typeutil.FuncName for why this doesn't require special handling
+	// of aliases.
+
+	call, ok := node.(*ast.CallExpr)
+	if !ok {
+		return false
+	}
+	q := CallName(pass, call)
+	return slices.Contains(names, q)
+}
+
+func File(pass *analysis.Pass, node Positioner) *ast.File {
+	m := pass.ResultOf[tokenfile.Analyzer].(map[*token.File]*ast.File)
+	return m[pass.Fset.File(node.Pos())]
+}
+
+// BuildConstraints returns the build constraints for file f. It considers both //go:build lines as well as
+// GOOS and GOARCH in file names.
+func BuildConstraints(pass *analysis.Pass, f *ast.File) (constraint.Expr, bool) {
+	var expr constraint.Expr
+	for _, cmt := range f.Comments {
+		if len(cmt.List) == 0 {
+			continue
+		}
+		for _, el := range cmt.List {
+			if el.Pos() > f.Package {
+				break
+			}
+			if line := el.Text; strings.HasPrefix(line, "//go:build") {
+				var err error
+				expr, err = constraint.Parse(line)
+				if err != nil {
+					expr = nil
+				}
+				break
+			}
+		}
+	}
+
+	name := pass.Fset.PositionFor(f.Pos(), false).Filename
+	oexpr := constraintsFromName(name)
+	if oexpr != nil {
+		if expr == nil {
+			expr = oexpr
+		} else {
+			expr = &constraint.AndExpr{X: expr, Y: oexpr}
+		}
+	}
+
+	return expr, expr != nil
+}
+
+func constraintsFromName(name string) constraint.Expr {
+	name = filepath.Base(name)
+	name = strings.TrimSuffix(name, ".go")
+	name = strings.TrimSuffix(name, "_test")
+	var goos, goarch string
+	switch strings.Count(name, "_") {
+	case 0:
+		// No GOOS or GOARCH in the file name.
+	case 1:
+		_, c, _ := strings.Cut(name, "_")
+		if _, ok := knowledge.KnownGOOS[c]; ok {
+			goos = c
+		} else if _, ok := knowledge.KnownGOARCH[c]; ok {
+			goarch = c
+		}
+	default:
+		n := strings.LastIndex(name, "_")
+		if _, ok := knowledge.KnownGOOS[name[n+1:]]; ok {
+			// The file name is *_stuff_GOOS.go
+			goos = name[n+1:]
+		} else if _, ok := knowledge.KnownGOARCH[name[n+1:]]; ok {
+			// The file name is *_GOOS_GOARCH.go or *_stuff_GOARCH.go
+			goarch = name[n+1:]
+			_, c, _ := strings.Cut(name[:n], "_")
+			if _, ok := knowledge.KnownGOOS[c]; ok {
+				// The file name is *_GOOS_GOARCH.go
+				goos = c
+			}
+		} else {
+			// The file name could also be something like foo_windows_nonsense.go — and because nonsense
+			// isn't a known GOARCH, "windows" won't be interpreted as a GOOS, either.
+		}
+	}
+
+	var expr constraint.Expr
+	if goos != "" {
+		expr = &constraint.TagExpr{Tag: goos}
+	}
+	if goarch != "" {
+		if expr == nil {
+			expr = &constraint.TagExpr{Tag: goarch}
+		} else {
+			expr = &constraint.AndExpr{X: expr, Y: &constraint.TagExpr{Tag: goarch}}
+		}
+	}
+	return expr
+}
+
+// IsGenerated reports whether pos is in a generated file. It ignores
+// //line directives.
+func IsGenerated(pass *analysis.Pass, pos token.Pos) bool {
+	_, ok := Generator(pass, pos)
+	return ok
+}
+
+// Generator returns the generator that generated the file containing
+// pos. It ignores //line directives.
+func Generator(pass *analysis.Pass, pos token.Pos) (generated.Generator, bool) {
+	file := pass.Fset.PositionFor(pos, false).Filename
+	m := pass.ResultOf[generated.Analyzer].(map[string]generated.Generator)
+	g, ok := m[file]
+	return g, ok
+}
+
+// MayHaveSideEffects reports whether expr may have side effects. If
+// the purity argument is nil, this function implements a purely
+// syntactic check, meaning that any function call may have side
+// effects, regardless of the called function's body. Otherwise,
+// purity will be consulted to determine the purity of function calls.
+func MayHaveSideEffects(pass *analysis.Pass, expr ast.Expr, purity purity.Result) bool {
+	switch expr := expr.(type) {
+	case *ast.BadExpr:
+		return true
+	case *ast.Ellipsis:
+		return MayHaveSideEffects(pass, expr.Elt, purity)
+	case *ast.FuncLit:
+		// the literal itself cannot have side effects, only calling it
+		// might, which is handled by CallExpr.
+		return false
+	case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
+		// types cannot have side effects
+		return false
+	case *ast.BasicLit:
+		return false
+	case *ast.BinaryExpr:
+		return MayHaveSideEffects(pass, expr.X, purity) || MayHaveSideEffects(pass, expr.Y, purity)
+	case *ast.CallExpr:
+		if purity == nil {
+			return true
+		}
+		switch obj := typeutil.Callee(pass.TypesInfo, expr).(type) {
+		case *types.Func:
+			if _, ok := purity[obj]; !ok {
+				return true
+			}
+		case *types.Builtin:
+			switch obj.Name() {
+			case "len", "cap":
+			default:
+				return true
+			}
+		default:
+			return true
+		}
+		for _, arg := range expr.Args {
+			if MayHaveSideEffects(pass, arg, purity) {
+				return true
+			}
+		}
+		return false
+	case *ast.CompositeLit:
+		if MayHaveSideEffects(pass, expr.Type, purity) {
+			return true
+		}
+		for _, elt := range expr.Elts {
+			if MayHaveSideEffects(pass, elt, purity) {
+				return true
+			}
+		}
+		return false
+	case *ast.Ident:
+		return false
+	case *ast.IndexExpr:
+		return MayHaveSideEffects(pass, expr.X, purity) || MayHaveSideEffects(pass, expr.Index, purity)
+	case *ast.IndexListExpr:
+		// In theory, none of the checks are necessary, as IndexListExpr only involves types. But there is no harm in
+		// being safe.
+		if MayHaveSideEffects(pass, expr.X, purity) {
+			return true
+		}
+		for _, idx := range expr.Indices {
+			if MayHaveSideEffects(pass, idx, purity) {
+				return true
+			}
+		}
+		return false
+	case *ast.KeyValueExpr:
+		return MayHaveSideEffects(pass, expr.Key, purity) || MayHaveSideEffects(pass, expr.Value, purity)
+	case *ast.SelectorExpr:
+		return MayHaveSideEffects(pass, expr.X, purity)
+	case *ast.SliceExpr:
+		return MayHaveSideEffects(pass, expr.X, purity) ||
+			MayHaveSideEffects(pass, expr.Low, purity) ||
+			MayHaveSideEffects(pass, expr.High, purity) ||
+			MayHaveSideEffects(pass, expr.Max, purity)
+	case *ast.StarExpr:
+		return MayHaveSideEffects(pass, expr.X, purity)
+	case *ast.TypeAssertExpr:
+		return MayHaveSideEffects(pass, expr.X, purity)
+	case *ast.UnaryExpr:
+		if MayHaveSideEffects(pass, expr.X, purity) {
+			return true
+		}
+		return expr.Op == token.ARROW || expr.Op == token.AND
+	case *ast.ParenExpr:
+		return MayHaveSideEffects(pass, expr.X, purity)
+	case nil:
+		return false
+	default:
+		panic(fmt.Sprintf("internal error: unhandled type %T", expr))
+	}
+}
+
+// LanguageVersion returns the version of the Go language that node has access to. This
+// might differ from the version of the Go standard library.
+func LanguageVersion(pass *analysis.Pass, node Positioner) string {
+	// As of Go 1.21, two places can specify the minimum Go version:
+	// - 'go' directives in go.mod and go.work files
+	// - individual files by using '//go:build'
+	//
+	// Individual files can upgrade to a higher version than the module version. Individual files
+	// can also downgrade to a lower version, but only if the module version is at least Go 1.21.
+	//
+	// The restriction on downgrading doesn't matter to us. All language changes before Go 1.22 will
+	// not type-check on versions that are too old, and thus never reach our analyzes. In practice,
+	// such ineffective downgrading will always be useless, as the compiler will not restrict the
+	// language features used, and doesn't ever rely on minimum versions to restrict the use of the
+	// standard library. However, for us, both choices (respecting or ignoring ineffective
+	// downgrading) have equal complexity, but only respecting it has a non-zero chance of reducing
+	// noisy positives.
+	//
+	// The minimum Go versions are exposed via go/ast.File.GoVersion and go/types.Package.GoVersion.
+	// ast.File's version is populated by the parser, whereas types.Package's version is populated
+	// from the Go version specified in the types.Config, which is set by our package loader, based
+	// on the module information provided by go/packages, via 'go list -json'.
+	//
+	// As of Go 1.21, standard library packages do not present themselves as modules, and thus do
+	// not have a version set on their types.Package. In this case, we fall back to the version
+	// provided by our '-go' flag. In most cases, '-go' defaults to 'module', which falls back to
+	// the Go version that Staticcheck was built with when no module information exists. In the
+	// future, the standard library will hopefully be a proper module (see
+	// https://github.com/golang/go/issues/61174#issuecomment-1622471317). In that case, the version
+	// of standard library packages will match that of the used Go version. At that point,
+	// Staticcheck will refuse to work with Go versions that are too new, to avoid misinterpreting
+	// code due to language changes.
+	//
+	// We also lack module information when building in GOPATH mode. In this case, the implied
+	// language version is at most Go 1.21, as per https://github.com/golang/go/issues/60915. We
+	// don't handle this yet, and it will not matter until Go 1.22.
+	//
+	// It is not clear how per-file downgrading behaves in GOPATH mode. On the one hand, no module
+	// version at all is provided, which should preclude per-file downgrading. On the other hand,
+	// https://github.com/golang/go/issues/60915 suggests that the language version is at most 1.21
+	// in GOPATH mode, which would allow per-file downgrading. Again it doesn't affect us, as all
+	// relevant language changes before Go 1.22 will lead to type-checking failures and never reach
+	// us.
+	//
+	// Per-file upgrading is permitted in GOPATH mode.
+
+	// If the file has its own Go version, we will return that. Otherwise, we default to
+	// the type checker's GoVersion, which is populated from either the Go module, or from
+	// our '-go' flag.
+	return pass.TypesInfo.FileVersions[File(pass, node)]
+}
+
+// StdlibVersion returns the version of the Go standard library that node can expect to
+// have access to. This might differ from the language version for versions of Go older
+// than 1.21.
+func StdlibVersion(pass *analysis.Pass, node Positioner) string {
+	// The Go version as specified in go.mod or via the '-go' flag
+	n := pass.Pkg.GoVersion()
+
+	f := File(pass, node)
+	if f == nil {
+		panic(fmt.Sprintf("no file found for node with position %s", pass.Fset.PositionFor(node.Pos(), false)))
+	}
+
+	if nf := f.GoVersion; nf != "" {
+		if version.Compare(n, "go1.21") == -1 {
+			// Before Go 1.21, the Go version set in go.mod specified the maximum language
+			// version available to the module. It wasn't uncommon to set the version to
+			// Go 1.20 but restrict usage of 1.20 functionality (both language and stdlib)
+			// to files tagged for 1.20, and supporting a lower version overall. As such,
+			// a file tagged lower than the module version couldn't expect to have access
+			// to the standard library of the version set in go.mod.
+			//
+			// At the same time, a file tagged higher than the module version, while not
+			// able to use newer language features, would still have been able to use a
+			// newer standard library.
+			//
+			// While Go 1.21's behavior has been backported to 1.19.11 and 1.20.6, users'
+			// expectations have not.
+			return nf
+		} else {
+			// Go 1.21 and newer refuse to build modules that depend on versions newer
+			// than the used version of the Go toolchain. This means that in a 1.22 module
+			// with a file tagged as 1.17, the file can expect to have access to 1.22's
+			// standard library (but not to 1.22 language features). A file tagged with a
+			// version higher than the minimum version has access to the newer standard
+			// library (and language features.)
+			//
+			// Do note that strictly speaking we're conflating the Go version and the
+			// module version in our check. Nothing is stopping a user from using Go 1.17
+			// (which didn't implement the new rules for versions in go.mod) to build a Go
+			// 1.22 module, in which case a file tagged with go1.17 will not have access to the 1.22
+			// standard library. However, we believe that if a module requires 1.21 or
+			// newer, then the author clearly expects the new behavior, and doesn't care
+			// for the old one. Otherwise they would've specified an older version.
+			//
+			// In other words, the module version also specifies what it itself actually means, with
+			// >=1.21 being a minimum version for the toolchain, and <1.21 being a maximum version for
+			// the language.
+
+			if version.Compare(nf, n) == 1 {
+				return nf
+			}
+		}
+	}
+
+	return n
+}
+
+var integerLiteralQ = pattern.MustParse(`(IntegerLiteral tv)`)
+
+func IntegerLiteral(pass *analysis.Pass, node ast.Node) (types.TypeAndValue, bool) {
+	m, ok := Match(pass, integerLiteralQ, node)
+	if !ok {
+		return types.TypeAndValue{}, false
+	}
+	return m.State["tv"].(types.TypeAndValue), true
+}
+
+func IsIntegerLiteral(pass *analysis.Pass, node ast.Node, value constant.Value) bool {
+	tv, ok := IntegerLiteral(pass, node)
+	if !ok {
+		return false
+	}
+	return constant.Compare(tv.Value, token.EQL, value)
+}
+
+// IsMethod reports whether expr is a method call of a named method with signature meth.
+// If name is empty, it is not checked.
+// For now, method expressions (Type.Method(recv, ..)) are not considered method calls.
+func IsMethod(pass *analysis.Pass, expr *ast.SelectorExpr, name string, meth *types.Signature) bool {
+	if name != "" && expr.Sel.Name != name {
+		return false
+	}
+	sel, ok := pass.TypesInfo.Selections[expr]
+	if !ok || sel.Kind() != types.MethodVal {
+		return false
+	}
+	return types.Identical(sel.Type(), meth)
+}
+
+func RefersTo(pass *analysis.Pass, expr ast.Expr, ident types.Object) bool {
+	found := false
+	fn := func(node ast.Node) bool {
+		ident2, ok := node.(*ast.Ident)
+		if !ok {
+			return true
+		}
+		if ident == pass.TypesInfo.ObjectOf(ident2) {
+			found = true
+			return false
+		}
+		return true
+	}
+	ast.Inspect(expr, fn)
+	return found
+}
diff --git a/vendor/honnef.co/go/tools/analysis/code/visit.go b/vendor/honnef.co/go/tools/analysis/code/visit.go
new file mode 100644
index 0000000..18271e9
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/code/visit.go
@@ -0,0 +1,153 @@
+package code
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/format"
+	"go/types"
+	"iter"
+	"slices"
+
+	typeindexanalyzer "honnef.co/go/tools/internal/xtools-internal/analysis/typeindex"
+	"honnef.co/go/tools/internal/xtools-internal/typesinternal/typeindex"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+var RequiredAnalyzers = []*analysis.Analyzer{inspect.Analyzer, typeindexanalyzer.Analyzer}
+
+func Cursor(pass *analysis.Pass) inspector.Cursor {
+	return pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Root()
+}
+
+func Preorder(pass *analysis.Pass, fn func(ast.Node), types ...ast.Node) {
+	pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder(types, fn)
+}
+
+func PreorderStack(pass *analysis.Pass, fn func(ast.Node, []ast.Node), types ...ast.Node) {
+	pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).WithStack(types, func(n ast.Node, push bool, stack []ast.Node) (proceed bool) {
+		if push {
+			fn(n, stack)
+		}
+		return true
+	})
+}
+
+func Matches(pass *analysis.Pass, qs ...pattern.Pattern) iter.Seq2[ast.Node, *pattern.Matcher] {
+	return func(yield func(ast.Node, *pattern.Matcher) bool) {
+		for _, q := range qs {
+			if !CouldMatchAny(pass, q) {
+				continue
+			}
+
+			if len(q.RootCallSymbols) != 0 {
+				index := pass.ResultOf[typeindexanalyzer.Analyzer].(*typeindex.Index)
+				for _, isym := range q.RootCallSymbols {
+					var obj types.Object
+					if isym.Type == "" {
+						obj = index.Object(isym.Path, isym.Ident)
+					} else {
+						obj = index.Selection(isym.Path, isym.Type, isym.Ident)
+					}
+					for c := range index.Calls(obj) {
+						node := c.Node()
+						if m, ok := Match(pass, q, node); ok {
+							if !yield(node, m) {
+								return
+							}
+						}
+					}
+				}
+			} else {
+				ins := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+				fn := func(node ast.Node, push bool) bool {
+					if !push {
+						return true
+					}
+
+					if m, ok := Match(pass, q, node); ok {
+						return yield(node, m)
+					}
+					return true
+				}
+				ins.Nodes(q.EntryNodes, fn)
+			}
+		}
+	}
+}
+
+func Match(pass *analysis.Pass, q pattern.Pattern, node ast.Node) (*pattern.Matcher, bool) {
+	// Note that we ignore q.Relevant – callers of Match usually use
+	// AST inspectors that already filter on nodes we're interested
+	// in.
+	m := &pattern.Matcher{TypesInfo: pass.TypesInfo}
+	ok := m.Match(q, node)
+	return m, ok
+}
+
+func CouldMatchAny(pass *analysis.Pass, qs ...pattern.Pattern) bool {
+	index := pass.ResultOf[typeindexanalyzer.Analyzer].(*typeindex.Index)
+	var do func(node pattern.Node) bool
+	do = func(node pattern.Node) bool {
+		switch node := node.(type) {
+		case pattern.Any:
+			return true
+		case pattern.Or:
+			return slices.ContainsFunc(node.Nodes, do)
+		case pattern.And:
+			for _, child := range node.Nodes {
+				if !do(child) {
+					return false
+				}
+			}
+			return true
+		case pattern.IndexSymbol:
+			if node.Type == "" {
+				return index.Object(node.Path, node.Ident) != nil
+			} else {
+				return index.Selection(node.Path, node.Type, node.Ident) != nil
+			}
+		default:
+			panic(fmt.Sprintf("internal error: unexpected type %T", node))
+		}
+	}
+
+	for _, q := range qs {
+		if do(q.SymbolsPattern) {
+			return true
+		}
+	}
+	return false
+}
+
+func MatchAndEdit(pass *analysis.Pass, before, after pattern.Pattern, node ast.Node) (*pattern.Matcher, []analysis.TextEdit, bool) {
+	m, ok := Match(pass, before, node)
+	if !ok {
+		return m, nil, false
+	}
+	r := pattern.NodeToAST(after.Root, m.State)
+	buf := &bytes.Buffer{}
+	format.Node(buf, pass.Fset, r)
+	edit := []analysis.TextEdit{{
+		Pos:     node.Pos(),
+		End:     node.End(),
+		NewText: buf.Bytes(),
+	}}
+	return m, edit, true
+}
+
+func EditMatch(pass *analysis.Pass, node ast.Node, m *pattern.Matcher, after pattern.Pattern) []analysis.TextEdit {
+	r := pattern.NodeToAST(after.Root, m.State)
+	buf := &bytes.Buffer{}
+	format.Node(buf, pass.Fset, r)
+	edit := []analysis.TextEdit{{
+		Pos:     node.Pos(),
+		End:     node.End(),
+		NewText: buf.Bytes(),
+	}}
+	return edit
+}
diff --git a/vendor/honnef.co/go/tools/analysis/dfa/dense/flow.go b/vendor/honnef.co/go/tools/analysis/dfa/dense/flow.go
new file mode 100644
index 0000000..efa573c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/dfa/dense/flow.go
@@ -0,0 +1,60 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package flow implements a monotone flow analysis framework.
+package dense
+
+import (
+	"cmp"
+	"slices"
+
+	"honnef.co/go/tools/internal/xtools-internal/graph"
+)
+
+const debug = false
+
+// Analysis is the result of a monotone analysis. Fact is the type of elements
+// in the analysis semilattice, and represents the outcome of the analysis at
+// every node and edge.
+type Analysis[Fact any, NodeID comparable] struct {
+	nodeMap *graph.Index[NodeID]
+	ins     []Fact           // By NodeID
+	edges   []edgeFact[Fact] // Sorted by (from, to)
+}
+
+// In returns the analysis fact on entry to nid. This is the merge of the facts
+// on all incoming edges.
+func (a *Analysis[Fact, NodeID]) In(nid NodeID) Fact {
+	return a.ins[a.nodeMap.Index(nid)]
+}
+
+// Edge returns the analysis fact propagated on edge from ==> to.
+func (a *Analysis[Fact, NodeID]) Edge(from, to NodeID) Fact {
+	i, found := slices.BinarySearchFunc(a.edges, a.edge(from, to), edgeFact[Fact].compare)
+	if !found {
+		panic("no such edge")
+	}
+	return a.edges[i].fact
+}
+
+func (a *Analysis[Fact, NodeID]) edge(from, to NodeID) edge {
+	fromNum, toNum := a.nodeMap.Index(from), a.nodeMap.Index(to)
+	return edge{fromNum, toNum}
+}
+
+type edge struct {
+	from, to int
+}
+
+func (e edge) compare(f edge) int {
+	if v := cmp.Compare(e.from, f.from); v != 0 {
+		return v
+	}
+	return cmp.Compare(e.to, f.to)
+}
+
+type edgeFact[Fact any] struct {
+	edge
+	fact Fact
+}
diff --git a/vendor/honnef.co/go/tools/analysis/dfa/dense/forward.go b/vendor/honnef.co/go/tools/analysis/dfa/dense/forward.go
new file mode 100644
index 0000000..7837f64
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/dfa/dense/forward.go
@@ -0,0 +1,271 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dense
+
+import (
+	"container/heap"
+	"log"
+	"slices"
+
+	"honnef.co/go/tools/analysis/dfa"
+	"honnef.co/go/tools/internal/xtools-internal/graph"
+)
+
+// Forward performs a forward monotone analysis over a control flow graph.
+//
+// The entry map provides initial state for entry blocks (blocks with zero
+// predecessors). For each edge, it calls transfer(fact, edge), where fact is
+// the analysis state on entry to edge.Pred. The transfer function must return
+// the outgoing analysis state of the edge (which may be fact, if the edge has
+// no effect on the  analysis state).
+func Forward[L dfa.Semilattice[Fact], Fact any, NodeID comparable](g graph.Graph[NodeID], entry map[NodeID]Fact, transfer func(from, to NodeID, fact Fact) Fact) *Analysis[Fact, NodeID] {
+	cg, nodeMap := graph.Compact(g)
+
+	nNodes := cg.NumNodes()
+	fb := &fwdBuilder[L, Fact, NodeID]{
+		cfg:      cg,
+		nodeMap:  nodeMap,
+		transfer: transfer,
+		blocks:   make([]blockInfo[Fact], nNodes),
+	}
+	fb.queue.init(cg)
+
+	// Initialize each node.
+	totalEdges := 0
+	for ni := range nNodes {
+		b := &fb.blocks[ni]
+
+		// Construct back-edges.
+		//
+		// I experimented with making Graph support iterating over in-edges, but
+		// in practice that just meant each Graph implementation had a copy of
+		// this logic. So instead we keep Graph as simple as possible and
+		// compute the auxiliary data in the algorithm. One drawback of this is
+		// that, for the [Transpose] graph, this information is redundant with
+		// the underlying graph. We could potentially special-case that.
+		outs := 0
+		for succID := range cg.Out(ni) {
+			succ := &fb.blocks[succID]
+			succ.preds = append(succ.preds, blockEdge{ni, outs})
+			outs++
+			totalEdges++
+		}
+
+		// Initialize in & out states.
+		fact, ok := entry[nodeMap.Value(ni)]
+		if !ok {
+			fact = fb.l.Ident()
+		}
+		b.in = fact
+		b.out = slices.Repeat([]Fact{fb.l.Ident()}, outs)
+
+		// Enqueue block.
+		//
+		// It's tempting to enqueue only the entry blocks, but this is wrong.
+		// The entry map may be empty if there are no interesting entry states,
+		// but the transfer function may still introduce interesting states
+		// anywhere.
+		b.dirty = true
+		fb.queue.enqueue(ni)
+	}
+
+	// Propagate over blocks.
+	fb.propagate()
+
+	// Collect the final analysis results.
+	a := Analysis[Fact, NodeID]{
+		nodeMap: nodeMap,
+		ins:     make([]Fact, nNodes),
+		edges:   make([]edgeFact[Fact], 0, totalEdges),
+	}
+	for pred := range nNodes {
+		a.ins[pred] = fb.blocks[pred].in
+		i := 0
+		for succ := range cg.Out(pred) {
+			edge := edge{pred, succ}
+			a.edges = append(a.edges, edgeFact[Fact]{edge, fb.blocks[pred].out[i]})
+			i++
+		}
+	}
+	slices.SortFunc(a.edges, func(a, b edgeFact[Fact]) int { return a.edge.compare(b.edge) })
+	return &a
+}
+
+// fwdBuilder is the state used during [Forward] analysis.
+type fwdBuilder[L dfa.Semilattice[Fact], Fact any, NodeID comparable] struct {
+	l L // Lattice
+
+	cfg     graph.Graph[int]     // Control flow graph (compact)
+	nodeMap *graph.Index[NodeID] // Map from cfg to original NodeIDs
+
+	// transfer is the edge transfer function.
+	transfer func(from, to NodeID, fact Fact) Fact
+
+	blocks []blockInfo[Fact]
+
+	queue nodeHeap
+}
+
+type blockInfo[Fact any] struct {
+	dirty bool // The in fact has never been propagated.
+
+	preds []blockEdge
+
+	in  Fact
+	out []Fact // Corresponds to i'th out edge
+}
+
+type blockEdge struct {
+	node int
+	i    int // Out edge index
+}
+
+// nodeHeap implements a heap of NodeIDs, ordered topologically.
+//
+// We use this ordering so forward analysis converges more quickly.
+type nodeHeap struct {
+	heap        []int   // Remaining nodes in the current sweep
+	deferred    []int   // Nodes of next sweep
+	inQueue     []int64 // Bitmap over node IDs
+	prio        []int   // NodeID -> priority
+	currentPrio int     // Priority of last dequeued node, or -1
+}
+
+func (h *nodeHeap) init(g graph.Graph[int]) {
+	nNodes := g.NumNodes()
+	*h = nodeHeap{
+		inQueue:     make([]int64, (nNodes+63)/64),
+		prio:        make([]int, nNodes),
+		currentPrio: -1,
+	}
+	for p, nid := range graph.ReversePostorder(g) {
+		h.prio[nid] = p
+	}
+}
+
+func (h *nodeHeap) enqueue(nid int) {
+	if h.inQueue[nid/64]&(1<<(nid%64)) != 0 {
+		return
+	}
+	h.inQueue[nid/64] |= 1 << (nid % 64)
+
+	if h.currentPrio >= 0 && h.prio[nid] <= h.currentPrio {
+		// This is a retreating edge, self-edge, or other update to a node
+		// already passed in this sweep. Coalesce it into the next sweep.
+		h.deferred = append(h.deferred, nid)
+	} else {
+		heap.Push(h, nid)
+	}
+}
+
+func (h *nodeHeap) dequeue() int {
+	if len(h.heap) == 0 {
+		// Start the next RPO sweep.
+		h.heap, h.deferred = h.deferred, h.heap[:0]
+		h.currentPrio = -1
+		heap.Init(h)
+	}
+
+	nid := h.heap[0]
+	heap.Pop(h)
+	h.inQueue[nid/64] &^= 1 << (nid % 64)
+	h.currentPrio = h.prio[nid]
+	return nid
+}
+
+func (h *nodeHeap) pending() bool     { return len(h.heap) != 0 || len(h.deferred) != 0 }
+func (h nodeHeap) Len() int           { return len(h.heap) }
+func (h nodeHeap) Less(i, j int) bool { return h.prio[h.heap[i]] < h.prio[h.heap[j]] }
+func (h nodeHeap) Swap(i, j int)      { h.heap[i], h.heap[j] = h.heap[j], h.heap[i] }
+func (h *nodeHeap) Push(x any)        { h.heap = append(h.heap, x.(int)) }
+func (h *nodeHeap) Pop() any {
+	n := len(h.heap)
+	x := h.heap[n-1]
+	h.heap = h.heap[:n-1]
+	return x
+}
+
+func (fb *fwdBuilder[L, Fact, NodeID]) merge(a, b Fact) Fact {
+	if fb.l.Equals(a, b) {
+		return a
+	}
+	return fb.l.Merge(a, b)
+}
+
+func (fb *fwdBuilder[L, Fact, NodeID]) propagate() {
+	for fb.queue.pending() {
+		bi := fb.queue.dequeue()
+		block := &fb.blocks[bi]
+
+		// Merge predecessor facts to compute updated "in" fact.
+		var in Fact
+		first := true
+		for _, edge := range block.preds {
+			pred := &fb.blocks[edge.node]
+			var edgeFact Fact
+			if pred.dirty {
+				// We haven't visited this predecessor yet, so it doesn't have
+				// meaningful out facts.
+				edgeFact = fb.l.Ident()
+			} else {
+				edgeFact = pred.out[edge.i]
+			}
+			if first {
+				if debug {
+					log.Printf("propagate to node %d", bi)
+				}
+				in = edgeFact
+				first = false
+			} else {
+				in = fb.merge(in, edgeFact)
+			}
+			if debug {
+				log.Printf("  from node %d: %v", edge.node, edgeFact)
+			}
+		}
+		if first {
+			// No predecessors.
+			if debug {
+				log.Printf("node %d gets initial state", bi)
+			}
+			in = block.in
+		}
+
+		if !block.dirty && fb.l.Equals(in, block.in) {
+			// No change to block input, which means the transfer function
+			// results also won't change from the last time we ran it.
+			if debug {
+				log.Printf("  initial state unchanged: %v", in)
+			}
+			continue
+		}
+		if debug {
+			log.Printf("  new initial state: %v", in)
+		}
+		block.in = in
+
+		// Apply transfer function.
+		predID := fb.nodeMap.Value(bi)
+		i := 0
+		for succNum := range fb.cfg.Out(bi) {
+			edgeFact := fb.transfer(predID, fb.nodeMap.Value(succNum), in)
+			if block.dirty || !fb.l.Equals(block.out[i], edgeFact) {
+				// Out fact changed, so recompute the target block.
+				if debug {
+					log.Printf("  to node %d: %v", succNum, edgeFact)
+				}
+				block.out[i] = edgeFact
+				fb.queue.enqueue(succNum)
+			} else {
+				if debug {
+					log.Printf("  to node %d: no change", succNum)
+				}
+			}
+			i++
+		}
+
+		block.dirty = false
+	}
+}
diff --git a/vendor/honnef.co/go/tools/analysis/dfa/dot.go b/vendor/honnef.co/go/tools/analysis/dfa/dot.go
new file mode 100644
index 0000000..1895aa8
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/dfa/dot.go
@@ -0,0 +1,48 @@
+package dfa
+
+import (
+	"fmt"
+	"strings"
+)
+
+// Dot returns a directed graph in [Graphviz] format that represents the finite
+// join-semilattice ⟨S, ≤⟩. Vertices represent elements in S and edges
+// represent the ≤ relation between elements. We map from ⟨S, ∨⟩ to ⟨S, ≤⟩ by
+// computing x ∨ y for all elements in [S]², where x ≤ y iff x ∨ y == y.
+//
+// The resulting graph can be filtered through [tred] to compute the transitive
+// reduction of the graph, the visualisation of which corresponds to the Hasse
+// diagram of the semilattice.
+//
+// [Graphviz]: https://graphviz.org/
+// [tred]: https://graphviz.org/docs/cli/tred/
+func Dot[L Semilattice[Elem], Elem any](states []Elem) string {
+	var sb strings.Builder
+	sb.WriteString("digraph{\n")
+	sb.WriteString("rankdir=\"BT\"\n")
+
+	for i, v := range states {
+		if vs, ok := any(v).(fmt.Stringer); ok {
+			fmt.Fprintf(&sb, "n%d [label=%q]\n", i, vs)
+		} else {
+			fmt.Fprintf(&sb, "n%d [label=%q]\n", i, fmt.Sprintf("%v", v))
+		}
+	}
+
+	var l L
+
+	for dx, x := range states {
+		for dy, y := range states {
+			if dx == dy {
+				continue
+			}
+
+			if l.Equals(l.Merge(x, y), y) {
+				fmt.Fprintf(&sb, "n%d -> n%d\n", dx, dy)
+			}
+		}
+	}
+
+	sb.WriteString("}")
+	return sb.String()
+}
diff --git a/vendor/honnef.co/go/tools/analysis/dfa/lattice.go b/vendor/honnef.co/go/tools/analysis/dfa/lattice.go
new file mode 100644
index 0000000..672875b
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/dfa/lattice.go
@@ -0,0 +1,147 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dfa
+
+import (
+	"fmt"
+	"maps"
+	"slices"
+)
+
+// A Semilattice describes a bounded semilattice over Elem.
+// That is, a partial order over values of type Elem, with a binary
+// Merge operator and an identity element.
+//
+// This is typically implemented by a stateless type, and acts as a factory for
+// lattice elements.
+type Semilattice[Elem any] interface {
+	// Ident returns the identity element of this lattice, that is the unit of
+	// the Merge operation.
+	Ident() Elem
+
+	// Equals returns whether a and b are the same element.
+	Equals(a, b Elem) bool
+
+	// Merge combines two lattice values, such as the two possible values of a
+	// variable at the end of an if/else statement.
+	//
+	// Merge must satisfy the following identities, where we use ∧ for Merge, =
+	// for Equals, and 𝟏 for Ident:
+	//
+	// - Associativity: x ∧ (y ∧ z) = (x ∧ y) ∧ z
+	// - Commutativity: x ∧ y = y ∧ x
+	// - Idempotency: x ∧ x = x
+	// - Identity: x ∧ 𝟏 = x
+	Merge(a, b Elem) Elem
+}
+
+// A MapLattice implements [Semilattice][map[Key]Elem]. The values in the map
+// are themselves defined by [Semilattice] L.
+//
+// Any elements missing from the map are implicitly L's identity element, and
+// L's identity element never appears as a value in the map.
+//
+// For densely numbered keys, consider using [DenseMapLattice] instead.
+type MapLattice[Key comparable, Elem any, L Semilattice[Elem]] struct {
+	l L
+}
+
+func (m MapLattice[Key, Elem, L]) Ident() map[Key]Elem {
+	return nil
+}
+
+func (m MapLattice[Key, Elem, L]) Equals(a, b map[Key]Elem) bool {
+	return maps.EqualFunc(a, b, m.l.Equals)
+}
+
+func (m MapLattice[Key, Elem, L]) Merge(a, b map[Key]Elem) map[Key]Elem {
+	if len(a) == 0 {
+		return b
+	} else if len(b) == 0 {
+		return a
+	}
+
+	// We need to consider the union of keys in a and b.
+	out := make(map[Key]Elem)
+	id := m.l.Ident()
+	for k, av := range a {
+		bv, ok := b[k]
+		if !ok {
+			// Because Merge(x, Ident()) == x, we can skip calling L.Merge.
+			out[k] = av
+			continue
+		}
+
+		w := m.l.Merge(av, bv)
+		if m.l.Equals(w, id) {
+			// In a semilattice, Merge(x, y) = Ident is only possible when x ==
+			// Ident and y == Ident.
+			panic(fmt.Sprintf(
+				"%T is not a semilattice: Merge(%v, %v) returned Ident for non-Ident arguments",
+				m.l, av, bv))
+		}
+		out[k] = w
+	}
+	// We considered keys that are only in a, and in both a and b. Now we just
+	// need to handle keys that are only in b.
+	for k, v2 := range b {
+		if _, ok := a[k]; !ok {
+			out[k] = v2
+		}
+	}
+
+	return out
+}
+
+// A DenseMapLattice implements [Semilattice][[]Elem]. It is like a [MapLattice]
+// that is indexed by integers. The values in the map are themselves defined by
+// [Semilattice] L.
+//
+// Unlike [MapLattice], L's identity element may appear as a value in the map,
+// to allow for gaps in the numbering of keys when the identity element is
+// Elem's zero value.
+type DenseMapLattice[Elem any, L Semilattice[Elem]] struct {
+	l L
+}
+
+func (s DenseMapLattice[Elem, L]) Ident() []Elem {
+	return nil
+}
+
+func (s DenseMapLattice[Elem, L]) Equals(a, b []Elem) bool {
+	nmin := min(len(a), len(b))
+	ident := s.l.Ident()
+
+	// Check that up to nmin, all elements in a and b match. If one of a or b
+	// is longer, then its tail nmin:nmax must only contain identity elements.
+	return slices.EqualFunc(a[:nmin], b[:nmin], s.l.Equals) &&
+		!slices.ContainsFunc(a[nmin:], func(e Elem) bool {
+			return !s.l.Equals(e, ident)
+		}) &&
+		!slices.ContainsFunc(b[nmin:], func(e Elem) bool {
+			return !s.l.Equals(e, ident)
+		})
+}
+
+func (s DenseMapLattice[Elem, L]) Merge(a, b []Elem) []Elem {
+	if len(a) == 0 {
+		return b
+	} else if len(b) == 0 {
+		return a
+	}
+	out := make([]Elem, max(len(a), len(b)))
+	for k := range max(len(a), len(b)) {
+		av := s.l.Ident()
+		bv := s.l.Ident()
+		if k < len(a) {
+			av = a[k]
+		}
+		if k < len(b) {
+			bv = b[k]
+		}
+		out[k] = s.l.Merge(av, bv)
+	}
+	return out
+}
diff --git a/vendor/honnef.co/go/tools/analysis/edit/edit.go b/vendor/honnef.co/go/tools/analysis/edit/edit.go
new file mode 100644
index 0000000..b118bdc
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/edit/edit.go
@@ -0,0 +1,83 @@
+// Package edit contains helpers for creating suggested fixes.
+package edit
+
+import (
+	"bytes"
+	"go/ast"
+	"go/format"
+	"go/token"
+
+	"golang.org/x/tools/go/analysis"
+	"honnef.co/go/tools/pattern"
+)
+
+// Ranger describes values that have a start and end position.
+// In most cases these are either ast.Node or manually constructed ranges.
+type Ranger interface {
+	Pos() token.Pos
+	End() token.Pos
+}
+
+// Range implements the Ranger interface.
+type Range [2]token.Pos
+
+func (r Range) Pos() token.Pos { return r[0] }
+func (r Range) End() token.Pos { return r[1] }
+
+// ReplaceWithString replaces a range with a string.
+func ReplaceWithString(old Ranger, new string) analysis.TextEdit {
+	return analysis.TextEdit{
+		Pos:     old.Pos(),
+		End:     old.End(),
+		NewText: []byte(new),
+	}
+}
+
+// ReplaceWithNode replaces a range with an AST node.
+func ReplaceWithNode(fset *token.FileSet, old Ranger, new ast.Node) analysis.TextEdit {
+	buf := &bytes.Buffer{}
+	if err := format.Node(buf, fset, new); err != nil {
+		panic("internal error: " + err.Error())
+	}
+	return analysis.TextEdit{
+		Pos:     old.Pos(),
+		End:     old.End(),
+		NewText: buf.Bytes(),
+	}
+}
+
+// ReplaceWithPattern replaces a range with the result of executing a pattern.
+func ReplaceWithPattern(fset *token.FileSet, old Ranger, new pattern.Pattern, state pattern.State) analysis.TextEdit {
+	r := pattern.NodeToAST(new.Root, state)
+	buf := &bytes.Buffer{}
+	format.Node(buf, fset, r)
+	return analysis.TextEdit{
+		Pos:     old.Pos(),
+		End:     old.End(),
+		NewText: buf.Bytes(),
+	}
+}
+
+// Delete deletes a range of code.
+func Delete(old Ranger) analysis.TextEdit {
+	return analysis.TextEdit{
+		Pos:     old.Pos(),
+		End:     old.End(),
+		NewText: nil,
+	}
+}
+
+func Fix(msg string, edits ...analysis.TextEdit) analysis.SuggestedFix {
+	return analysis.SuggestedFix{
+		Message:   msg,
+		TextEdits: edits,
+	}
+}
+
+// Selector creates a new selector expression.
+func Selector(x, sel string) *ast.SelectorExpr {
+	return &ast.SelectorExpr{
+		X:   &ast.Ident{Name: x},
+		Sel: &ast.Ident{Name: sel},
+	}
+}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/deprecated/deprecated.go b/vendor/honnef.co/go/tools/analysis/facts/deprecated/deprecated.go
new file mode 100644
index 0000000..03c0621
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/facts/deprecated/deprecated.go
@@ -0,0 +1,154 @@
+package deprecated
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+	"reflect"
+	"strings"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+type IsDeprecated struct{ Msg string }
+
+func (*IsDeprecated) AFact()           {}
+func (d *IsDeprecated) String() string { return "Deprecated: " + d.Msg }
+
+type Result struct {
+	Objects  map[types.Object]*IsDeprecated
+	Packages map[*types.Package]*IsDeprecated
+}
+
+var Analyzer = &analysis.Analyzer{
+	Name:       "fact_deprecated",
+	Doc:        "Mark deprecated objects",
+	Run:        deprecated,
+	FactTypes:  []analysis.Fact{(*IsDeprecated)(nil)},
+	ResultType: reflect.TypeFor[Result](),
+}
+
+func deprecated(pass *analysis.Pass) (any, error) {
+	var names []*ast.Ident
+
+	extractDeprecatedMessage := func(docs []*ast.CommentGroup) string {
+		for _, doc := range docs {
+			if doc == nil {
+				continue
+			}
+			parts := strings.SplitSeq(doc.Text(), "\n\n")
+			for part := range parts {
+				if !strings.HasPrefix(part, "Deprecated: ") {
+					continue
+				}
+				alt := part[len("Deprecated: "):]
+				alt = strings.Replace(alt, "\n", " ", -1)
+				return alt
+			}
+		}
+		return ""
+	}
+
+	doDocs := func(names []*ast.Ident, docs []*ast.CommentGroup) {
+		alt := extractDeprecatedMessage(docs)
+		if alt == "" {
+			return
+		}
+
+		for _, name := range names {
+			obj := pass.TypesInfo.ObjectOf(name)
+			pass.ExportObjectFact(obj, &IsDeprecated{alt})
+		}
+	}
+
+	var docs []*ast.CommentGroup
+	for _, f := range pass.Files {
+		docs = append(docs, f.Doc)
+	}
+	if alt := extractDeprecatedMessage(docs); alt != "" {
+		// Don't mark package syscall as deprecated, even though
+		// it is. A lot of people still use it for simple
+		// constants like SIGKILL, and I am not comfortable
+		// telling them to use x/sys for that.
+		if pass.Pkg.Path() != "syscall" {
+			pass.ExportPackageFact(&IsDeprecated{alt})
+		}
+	}
+
+	docs = docs[:0]
+	for _, f := range pass.Files {
+		fn := func(node ast.Node) bool {
+			if node == nil {
+				return true
+			}
+			var ret bool
+			switch node := node.(type) {
+			case *ast.GenDecl:
+				switch node.Tok {
+				case token.TYPE, token.CONST, token.VAR:
+					docs = append(docs, node.Doc)
+					for i := range node.Specs {
+						switch n := node.Specs[i].(type) {
+						case *ast.ValueSpec:
+							names = append(names, n.Names...)
+						case *ast.TypeSpec:
+							names = append(names, n.Name)
+						}
+					}
+					ret = true
+				default:
+					return false
+				}
+			case *ast.FuncDecl:
+				docs = append(docs, node.Doc)
+				names = []*ast.Ident{node.Name}
+				ret = false
+			case *ast.TypeSpec:
+				docs = append(docs, node.Doc)
+				names = []*ast.Ident{node.Name}
+				ret = true
+			case *ast.ValueSpec:
+				docs = append(docs, node.Doc)
+				names = node.Names
+				ret = false
+			case *ast.File:
+				return true
+			case *ast.StructType:
+				for _, field := range node.Fields.List {
+					doDocs(field.Names, []*ast.CommentGroup{field.Doc})
+				}
+				return false
+			case *ast.InterfaceType:
+				for _, field := range node.Methods.List {
+					doDocs(field.Names, []*ast.CommentGroup{field.Doc})
+				}
+				return false
+			default:
+				return false
+			}
+			if len(names) == 0 || len(docs) == 0 {
+				return ret
+			}
+			doDocs(names, docs)
+
+			docs = docs[:0]
+			names = nil
+			return ret
+		}
+		ast.Inspect(f, fn)
+	}
+
+	out := Result{
+		Objects:  map[types.Object]*IsDeprecated{},
+		Packages: map[*types.Package]*IsDeprecated{},
+	}
+
+	for _, fact := range pass.AllObjectFacts() {
+		out.Objects[fact.Object] = fact.Fact.(*IsDeprecated)
+	}
+	for _, fact := range pass.AllPackageFacts() {
+		out.Packages[fact.Package] = fact.Fact.(*IsDeprecated)
+	}
+
+	return out, nil
+}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/directives/directives.go b/vendor/honnef.co/go/tools/analysis/facts/directives/directives.go
new file mode 100644
index 0000000..467527b
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/facts/directives/directives.go
@@ -0,0 +1,20 @@
+package directives
+
+import (
+	"reflect"
+
+	"golang.org/x/tools/go/analysis"
+	"honnef.co/go/tools/analysis/lint"
+)
+
+func directives(pass *analysis.Pass) (any, error) {
+	return lint.ParseDirectives(pass.Files, pass.Fset), nil
+}
+
+var Analyzer = &analysis.Analyzer{
+	Name:             "directives",
+	Doc:              "extracts linter directives",
+	Run:              directives,
+	RunDespiteErrors: true,
+	ResultType:       reflect.TypeFor[[]lint.Directive](),
+}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/generated/generated.go b/vendor/honnef.co/go/tools/analysis/facts/generated/generated.go
new file mode 100644
index 0000000..301ad0e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/facts/generated/generated.go
@@ -0,0 +1,97 @@
+package generated
+
+import (
+	"bufio"
+	"bytes"
+	"io"
+	"os"
+	"reflect"
+	"strings"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+type Generator int
+
+// A list of known generators we can detect
+const (
+	Unknown Generator = iota
+	Goyacc
+	Cgo
+	Stringer
+	ProtocGenGo
+)
+
+var (
+	// used by cgo before Go 1.11
+	oldCgo = []byte("// Created by cgo - DO NOT EDIT")
+	prefix = []byte("// Code generated ")
+	suffix = []byte(" DO NOT EDIT.")
+	nl     = []byte("\n")
+	crnl   = []byte("\r\n")
+)
+
+func isGenerated(path string) (Generator, bool) {
+	f, err := os.Open(path)
+	if err != nil {
+		return 0, false
+	}
+	defer f.Close()
+	br := bufio.NewReader(f)
+	for {
+		s, err := br.ReadBytes('\n')
+		if err != nil && err != io.EOF {
+			return 0, false
+		}
+		s = bytes.TrimSuffix(s, crnl)
+		s = bytes.TrimSuffix(s, nl)
+		if bytes.HasPrefix(s, prefix) && bytes.HasSuffix(s, suffix) {
+			if len(s)-len(suffix) < len(prefix) {
+				return Unknown, true
+			}
+
+			text := string(s[len(prefix) : len(s)-len(suffix)])
+			switch text {
+			case "by goyacc.":
+				return Goyacc, true
+			case "by cmd/cgo;":
+				return Cgo, true
+			case "by protoc-gen-go.":
+				return ProtocGenGo, true
+			}
+			if strings.HasPrefix(text, `by "stringer `) {
+				return Stringer, true
+			}
+			if strings.HasPrefix(text, `by goyacc `) {
+				return Goyacc, true
+			}
+
+			return Unknown, true
+		}
+		if bytes.Equal(s, oldCgo) {
+			return Cgo, true
+		}
+		if err == io.EOF {
+			break
+		}
+	}
+	return 0, false
+}
+
+var Analyzer = &analysis.Analyzer{
+	Name: "isgenerated",
+	Doc:  "annotate file names that have been code generated",
+	Run: func(pass *analysis.Pass) (any, error) {
+		m := map[string]Generator{}
+		for _, f := range pass.Files {
+			path := pass.Fset.PositionFor(f.Pos(), false).Filename
+			g, ok := isGenerated(path)
+			if ok {
+				m[path] = g
+			}
+		}
+		return m, nil
+	},
+	RunDespiteErrors: true,
+	ResultType:       reflect.TypeFor[map[string]Generator](),
+}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go b/vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go
new file mode 100644
index 0000000..3d267fd
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go
@@ -0,0 +1,884 @@
+package nilness
+
+import (
+	"fmt"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"reflect"
+	"slices"
+	"strings"
+
+	"honnef.co/go/tools/analysis/dfa"
+	"honnef.co/go/tools/analysis/dfa/dense"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/exp/typeparams"
+	"golang.org/x/tools/go/analysis"
+)
+
+// TODO(dh): The analysis is currently entirely forward, which means that for
+//
+// 	x := s[:0]
+// 	y := s[:1]
+// 	z := s[:0]
+//
+// x will have MaybeNil at every program point and s will have MaybeNil before
+// execution of y, even though executing y without panicing tells us that s has
+// been non-nil for all 3 instructions.
+
+type nilnessFact struct {
+	Rets []ValueNilness
+}
+
+func (*nilnessFact) AFact() {}
+func (fact *nilnessFact) String() string {
+	return fmt.Sprintf("nilness: %v", fact.Rets)
+}
+
+type ValueNilness struct {
+	// Undefined for non-interface values and dynamically nil interface values.
+	// For interface values, whether the stored value may be nil.
+	// Even when Outer == MaybeNil, Inner may still offer precise information
+	// for the cases when Outer is dynamically not nil. For example, {NeverNil,
+	// MaybeNil} states that the interface value might be nil, but if it isn't,
+	// it will definitely contain a non-nil value.
+	Inner Nilness
+	// For non-interface values, whether the value may be nil.
+	// For interface values, whether the interface value may be nil.
+	Outer Nilness
+}
+
+type Result struct {
+	m map[*types.Func][]ValueNilness
+}
+
+var Analysis = &analysis.Analyzer{
+	Name:       "nilness",
+	Doc:        "Annotates return values with their nilness",
+	Run:        run,
+	Requires:   []*analysis.Analyzer{buildir.Analyzer},
+	FactTypes:  []analysis.Fact{(*nilnessFact)(nil)},
+	ResultType: reflect.TypeFor[*Result](),
+}
+
+// Nilness returns nilness information for return value ret of fn.
+func (r *Result) Nilness(fn *types.Func, ret int) ValueNilness {
+	typ := fn.Type().(*types.Signature).Results().At(ret).Type()
+	if !typeutil.MaybePointerLike(typ) {
+		return ValueNilness{Outer: NeverNil}
+	}
+	if len(r.m[fn]) == 0 {
+		return ValueNilness{Inner: MaybeNil, Outer: MaybeNil}
+	}
+
+	return normalize(r.m[fn][ret], typ)
+}
+
+func normalize(v ValueNilness, typ types.Type) ValueNilness {
+	if v.Inner == 0 || !types.IsInterface(typ) {
+		v.Inner = MaybeNil
+	}
+	if v.Outer == 0 {
+		v.Outer = MaybeNil
+	}
+	return v
+}
+
+func run(pass *analysis.Pass) (any, error) {
+	seen := map[*ir.Function]struct{}{}
+	out := &Result{
+		m: map[*types.Func][]ValueNilness{},
+	}
+
+	// TODO(dh): instead of recursion and giving up on mutual recursion, we
+	// should compute the DFA over the call graph, at least until we have
+	// proper function summaries.
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		impl(pass, fn, seen)
+	}
+
+	for _, fact := range pass.AllObjectFacts() {
+		out.m[fact.Object.(*types.Func)] = fact.Fact.(*nilnessFact).Rets
+	}
+
+	return out, nil
+}
+
+type Nilness uint8
+
+func (n Nilness) IsGlobal() bool {
+	return n == AlwaysNilGlobal || n == MaybeNilGlobal
+}
+
+const (
+	// The value is never nil.
+	NeverNil Nilness = iota + 1
+	// The value is always nil.
+	AlwaysNil
+	// The value might be nil, but only because of the value of a global
+	// variable.
+	MaybeNilGlobal
+	// The value might be nil.
+	MaybeNil
+	// The value is always nil and loaded from a global
+	AlwaysNilGlobal
+)
+
+func (n Nilness) String() string {
+	switch n {
+	case 0:
+		return "NoNilness"
+	case NeverNil:
+		return "NeverNil"
+	case AlwaysNil:
+		return "AlwaysNil"
+	case AlwaysNilGlobal:
+		return "AlwaysNilGlobal"
+	case MaybeNilGlobal:
+		return "MaybeNilGlobal"
+	case MaybeNil:
+		return "MaybeNil"
+	default:
+		return "InvalidNilness"
+	}
+}
+
+type state struct {
+	cloned bool
+	m      []ValueNilness
+	n      numbering
+}
+
+func (s *state) get(v ir.Value) ValueNilness {
+	if !typeutil.MaybePointerLike(v.Type()) {
+		// All non-pointer-like types are always {_ NeverNil}.
+		return ValueNilness{Outer: NeverNil}
+	}
+	num := s.n.number(v)
+	if num < len(s.m) {
+		return s.m[num]
+	}
+
+	switch v.(type) {
+	case *ir.Parameter:
+		return ValueNilness{Inner: MaybeNil, Outer: MaybeNil}
+	case *ir.Builtin:
+		return ValueNilness{Outer: NeverNil}
+	case *ir.FreeVar:
+		return ValueNilness{Inner: MaybeNil, Outer: MaybeNil}
+	case *ir.Function:
+		return ValueNilness{Outer: NeverNil}
+	case *ir.Global:
+		// Globals are addresses, not the values stored in them. The addresses
+		// cannot be nil.
+		return ValueNilness{Outer: NeverNil}
+	}
+
+	return lattice{}.Ident()
+}
+
+func (s *state) set(key ir.Value, value ValueNilness) {
+	if !typeutil.MaybePointerLike(key.Type()) {
+		// No point in recording state for non-pointer-like types. They're
+		// always {_ NeverNil}.
+		return
+	}
+
+	if value == (lattice{}.Ident()) {
+		// No point in storing the default value.
+		return
+	}
+	num := s.n.number(key)
+	if !s.cloned {
+		if num < len(s.m) && s.m[num] == value {
+			// Don't clone if the value already matches.
+			return
+		}
+		s.cloned = true
+		s.m = slices.Clone(s.m)
+	}
+	if num >= len(s.m) {
+		s.m = append(s.m, make([]ValueNilness, num-len(s.m)+1)...)
+	}
+	s.m[num] = value
+}
+
+func (s *state) setInner(key ir.Value, value Nilness) {
+	if !typeutil.MaybePointerLike(key.Type()) {
+		return
+	}
+	if value == (lattice{}.Ident().Inner) {
+		return
+	}
+	num := s.n.number(key)
+	if !s.cloned {
+		if num < len(s.m) && s.m[num].Inner == value {
+			// Don't clone if the value already matches.
+			return
+		}
+		s.cloned = true
+		s.m = slices.Clone(s.m)
+	}
+	if num >= len(s.m) {
+		dflt := s.get(key)
+		s.m = append(s.m, make([]ValueNilness, num-len(s.m)+1)...)
+		s.m[num] = dflt
+	}
+	v := s.m[num]
+	v.Inner = value
+	s.m[num] = v
+}
+
+func (s *state) setOuter(key ir.Value, value Nilness) {
+	if !typeutil.MaybePointerLike(key.Type()) {
+		return
+	}
+	if value == (lattice{}).Ident().Outer {
+		return
+	}
+	num := s.n.number(key)
+	if !s.cloned {
+		if num < len(s.m) && s.m[num].Outer == value {
+			// Don't clone if the value already matches.
+			return
+		}
+		s.cloned = true
+		s.m = slices.Clone(s.m)
+	}
+	if num >= len(s.m) {
+		dflt := s.get(key)
+		s.m = append(s.m, make([]ValueNilness, num-len(s.m)+1)...)
+		s.m[num] = dflt
+	}
+	v := s.m[num]
+	v.Outer = value
+	s.m[num] = v
+}
+
+func defaultNilnessForSignature(pass *analysis.Pass, typ *types.Signature) []ValueNilness {
+	n := typ.Results().Len()
+	if n == 0 {
+		return nil
+	}
+	out := make([]ValueNilness, n)
+	for i := range n {
+		out[i] = defaultNilness(pass, typ.Results().At(i).Type())
+	}
+	return out
+}
+
+func defaultNilness(pass *analysis.Pass, typ types.Type) ValueNilness {
+	if typeutil.MaybePointerLike(typ) {
+		// IsPointerLike handles type parameters with type sets, too.
+		return ValueNilness{MaybeNil, MaybeNil}
+	} else {
+		return ValueNilness{NeverNil, NeverNil}
+	}
+}
+
+func impl(pass *analysis.Pass, fn *ir.Function, seenFns map[*ir.Function]struct{}) []ValueNilness {
+	goto start
+bailout:
+	return defaultNilnessForSignature(pass, fn.Signature)
+
+start:
+	if fn.Signature.Results().Len() == 0 {
+		return nil
+	}
+	if fn.Object() == nil {
+		// TODO(dh): support closures
+		goto bailout
+	}
+	if fact := new(nilnessFact); pass.ImportObjectFact(fn.Object(), fact) {
+		return fact.Rets
+	}
+	if fn.Pkg != pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg {
+		goto bailout
+	}
+	if fn.Blocks == nil {
+		goto bailout
+	}
+	if _, ok := seenFns[fn]; ok {
+		// break recursion
+		goto bailout
+	}
+
+	seenFns[fn] = struct{}{}
+
+	anyPointers := false
+	for ret := range fn.Signature.Results().Variables() {
+		if typeutil.MaybePointerLike(ret.Type()) {
+			anyPointers = true
+			break
+		}
+	}
+
+	if !anyPointers {
+		goto bailout
+	}
+
+	n := numbering{}
+
+	processBlock := func(from, to *ir.BasicBlock, s state) state {
+		handleReturnValue := func(v ir.Value, call *ir.Call, idx int) {
+			typ := call.Common().Signature().Results().At(idx).Type()
+			if !typeutil.MaybePointerLike(typ) {
+				s.setOuter(v, NeverNil)
+				return
+			}
+
+			if callee, ok := call.Call.Value.(*ir.Builtin); ok {
+				switch callee.Name() {
+				case "append":
+					// TODO(dh): if we knew that the varargs had non-zero
+					// length, we'd know that the resulting slice is non-nil.
+					switch an := s.get(call.Call.Args[0]).Outer; an {
+					case MaybeNil, MaybeNilGlobal, NeverNil:
+						s.setOuter(v, an)
+					case AlwaysNil:
+						s.setOuter(v, MaybeNil)
+					case AlwaysNilGlobal:
+						s.setOuter(v, MaybeNilGlobal)
+					}
+				case "UnsafeSlice":
+					// If len is negative, or if ptr is nil and len is not
+					// zero, unsafe.Slice panics. This implies that a non-nil
+					// pointer cannot become nil, and vice versa.
+					s.set(v, s.get(call.Call.Args[0]))
+				case "UnsafeStringData":
+					// TODO(dh): if we had string length information we could
+					// return better information.
+					s.setOuter(v, MaybeNil)
+				case "UnsafeSliceData":
+					// When the slice is non-nil but has zero capacity, the
+					// returned pointer is still non-nil, so we don't have to
+					// worry about that.
+					s.set(v, s.get(call.Call.Args[0]))
+				case "UnsafeAdd":
+					// TODO(dh): a positive addend can never result in a nil pointer.
+
+					// Pointer arithmetic can turn nil pointers into non-nil
+					// ones and vice versa.
+					s.setOuter(v, MaybeNil)
+				case "ssa:deferstack":
+					s.setOuter(v, NeverNil)
+				case "ssa:wrapnilchk":
+					s.setOuter(v, NeverNil)
+				case "recover":
+					s.setOuter(v, MaybeNil)
+				default:
+					panic(fmt.Sprintf("internal error: unhandled builtin %s", callee.Name()))
+				}
+				return
+			}
+
+			callee := call.Common().StaticCallee()
+			if callee == nil {
+				// We don't know which function is being called.
+				s.set(v, ValueNilness{MaybeNil, MaybeNil})
+				return
+			}
+			calleeNilness := impl(pass, callee, seenFns)
+			if len(calleeNilness) > idx {
+				s.set(v, normalize(calleeNilness[idx], typ))
+			} else {
+				s.set(v, ValueNilness{MaybeNil, MaybeNil})
+			}
+		}
+
+		for _, instr := range from.Instrs {
+			// It is tempting to return early when instr is an ir.Value that
+			// doesn't have pointer type. However, instructions like ir.Load
+			// tell us something about the value being operated on.
+
+			switch v := instr.(type) {
+			case *ir.Convert:
+				s.set(v, s.get(v.X))
+			case *ir.SliceToArrayPointer:
+				// Go does not currently allow (*T)(s) where T is a type
+				// parameter with a type set consisting of array types, but it
+				// does allow (T)(s) where T is a type parameter with a type
+				// set consisting of pointers to array types.
+
+				allNonZero := typeutil.All(v.Type(), func(term *types.Term) bool {
+					ptr := term.Type().Underlying().(*types.Pointer).Elem()
+					return typeutil.All(ptr, func(innerTerm *types.Term) bool {
+						return innerTerm.Type().Underlying().(*types.Array).Len() != 0
+					})
+				})
+
+				if allNonZero {
+					// converting a slice to an array pointer of length > 0
+					// panics if the slice is nil
+					s.setOuter(v, NeverNil)
+					s.setOuter(v.X, NeverNil)
+				} else {
+					s.set(v, s.get(v.X))
+				}
+			case *ir.SliceToArray:
+				// Pretty much the same logic as SliceToArrayPointer, minus the
+				// pointer.
+
+				allNonZero := typeutil.All(v.Type(), func(term *types.Term) bool {
+					return term.Type().Underlying().(*types.Array).Len() != 0
+				})
+
+				if allNonZero {
+					// converting a slice to an array of length > 0
+					// panics if the slice is nil
+					s.setOuter(v.X, NeverNil)
+				}
+			case *ir.Slice:
+				if typeutil.All(v.X.Type(), typeutil.IsType[*types.Array]) {
+					// Slicing arrays never results in a nil slice.
+					s.setOuter(v, NeverNil)
+					continue
+				}
+
+				// checkBound returns true if one of the bounds (low, high,
+				// capacity) has non-zero value.
+				checkBound := func(v ir.Value) bool {
+					if v == nil {
+						return false
+					}
+					// TODO(dh): this is where integration with constant
+					// propagation and value range analysis would be useful.
+					if k, ok := v.(*ir.Const); ok {
+						kv, ok := constant.Int64Val(k.Value)
+						return !ok || kv != 0
+					}
+					return false
+				}
+				if checkBound(v.Low) || checkBound(v.High) || checkBound(v.Max) {
+					// One of the indices is non-zero, which means slicing can
+					// only succeed if the slicee is not nil.
+					s.setOuter(v, NeverNil)
+					s.setOuter(v.X, NeverNil)
+				} else {
+					// The new slice is as nilly as the slicee.
+					s.set(v, s.get(v.X))
+				}
+
+			case *ir.If:
+				cond := v.Cond
+				binop, ok := cond.(*ir.BinOp)
+				if !ok {
+					continue
+				}
+				isNil := func(v ir.Value) bool {
+					k, ok := v.(*ir.Const)
+					if !ok {
+						return false
+					}
+					return k.IsNil()
+				}
+				var target ir.Value
+				if isNil(binop.X) {
+					target = binop.Y
+				} else if isNil(binop.Y) {
+					target = binop.X
+				} else {
+					continue
+				}
+				op := binop.Op
+				if to != from.Succs[0] {
+					// we're in the false branch, negate op
+					switch op {
+					case token.EQL:
+						op = token.NEQ
+					case token.NEQ:
+						op = token.EQL
+					default:
+						panic(fmt.Sprintf("internal error: unhandled token %v", op))
+					}
+				}
+				switch op {
+				case token.EQL:
+					if s.get(target).Outer.IsGlobal() {
+						s.setOuter(target, AlwaysNilGlobal)
+					} else {
+						s.setOuter(target, AlwaysNil)
+					}
+				case token.NEQ:
+					s.setOuter(target, NeverNil)
+				default:
+					panic(fmt.Sprintf("internal error: unhandled token %v", op))
+				}
+
+				// TODO(dh): also handle comparison of two non-nil values. The
+				// true branch of neverNil == nilly makes the nilly value neverNil.
+			case *ir.ChangeType:
+				s.set(v, s.get(v.X))
+			case *ir.MultiConvert:
+				s.set(v, s.get(v.X))
+			case *ir.Load:
+				if _, ok := v.X.(*ir.Global); ok {
+					s.set(v, ValueNilness{MaybeNilGlobal, MaybeNilGlobal})
+				} else {
+					s.set(v, ValueNilness{MaybeNil, MaybeNil})
+				}
+				s.setOuter(v.X, NeverNil)
+			case *ir.FieldAddr:
+				s.setOuter(v.X, NeverNil)
+				s.setOuter(v, NeverNil)
+			case *ir.IndexAddr:
+				s.setOuter(v.X, NeverNil)
+				s.setOuter(v, NeverNil)
+			case *ir.Alloc, *ir.MakeMap, *ir.MakeSlice, *ir.MakeClosure, *ir.MakeChan:
+				s.setOuter(v.(ir.Value), NeverNil)
+			case *ir.MapUpdate:
+				s.setOuter(v.Map, NeverNil)
+			case *ir.Store:
+				s.setOuter(v.Addr, NeverNil)
+			case ir.CallInstruction:
+				// go/defer/calling a nil function fatals/panics
+				if !v.Common().IsInvoke() {
+					s.setOuter(v.Common().Value, NeverNil)
+				}
+				_, ok := v.(*ir.Call)
+				if !ok {
+					// Defer and Go don't produce values
+					continue
+				}
+				if v.Common().Signature().Results().Len() != 1 {
+					// If the called function doesn't return any values then we
+					// don't care about it. If it has more than one return
+					// value, they'll be handled by Extract.
+					continue
+				}
+
+				handleReturnValue(v.(ir.Value), v.(*ir.Call), 0)
+			case *ir.Send:
+				s.setOuter(v.Chan, NeverNil)
+			case *ir.Recv:
+				s.setOuter(v.Chan, NeverNil)
+				s.set(v, ValueNilness{MaybeNil, MaybeNil})
+			case *ir.MakeInterface:
+				s.set(v, ValueNilness{
+					Inner: s.get(v.X).Outer,
+					Outer: NeverNil,
+				})
+			case *ir.ChangeInterface:
+				s.set(v, s.get(v.X))
+			case *ir.TypeAssert:
+				if !v.CommaOk {
+					// The interface value cannot have been nil, or the type
+					// assertion would have panicked.
+					s.setOuter(v.X, NeverNil)
+
+					if types.IsInterface(v.Type()) && !typeparams.IsTypeParam(v.Type()) {
+						// Type asserting to another interface doesn't succeed
+						// if the assertee was nil. It also results in a new
+						// interface value.
+						s.setOuter(v, NeverNil)
+						s.setInner(v, s.get(v.X).Inner)
+					} else {
+						// We've extracted the interface value's inner value.
+						s.setOuter(v, s.get(v.X).Inner)
+					}
+				} else {
+					// In a comma-ok type assertion, the return type is a
+					// tuple. There'll be Extract instructions getting the
+					// individual values, to which we'll attach the nilness
+					// info.
+				}
+			case *ir.TypeSwitch:
+				// Handled in Extract
+			case *ir.MapLookup:
+				if s.get(v.X).Outer == AlwaysNil {
+					s.set(v, ValueNilness{AlwaysNil, AlwaysNil})
+				} else if s.get(v.X).Outer == AlwaysNilGlobal {
+					s.set(v, ValueNilness{AlwaysNilGlobal, AlwaysNilGlobal})
+				} else {
+					s.set(v, ValueNilness{MaybeNil, MaybeNil})
+				}
+			case *ir.Field:
+				s.set(v.X, ValueNilness{NeverNil, NeverNil})
+				s.set(v, ValueNilness{MaybeNil, MaybeNil})
+			case *ir.Index:
+				s.set(v.X, ValueNilness{NeverNil, NeverNil})
+				s.set(v, ValueNilness{MaybeNil, MaybeNil})
+
+			case *ir.Extract:
+				switch tuple := v.Tuple.(type) {
+				case *ir.TypeAssert:
+					// When we get here, the type assertion used the comma-ok
+					// form, and we don't yet know anything about the result of
+					// the type assertion.
+					if v.Index == 0 {
+						s.set(v, ValueNilness{MaybeNil, MaybeNil})
+					}
+
+					// TODO(dh): We should set v's nilness in the true and
+					// false branches of checks on the ok value. However, ok can be
+					// used in arbitrary ways, and we're also not set up to handle
+					// relational facts (ok being true or false affects the value
+					// of the other Extract).
+
+				case *ir.Call:
+					handleReturnValue(v, tuple, v.Index)
+
+				case *ir.TypeSwitch:
+					if v.Index == 0 {
+						// Index 0 is an integer and not interesting.
+						continue
+					}
+					idx := v.Index - 1
+					if idx >= len(tuple.Conds) {
+						// Default branch
+
+						// If there is an untyped nil case, then being in the
+						// default branch tells us that the interface value
+						// isn't nil.
+						hasNil := slices.ContainsFunc(tuple.Conds, func(typ types.Type) bool {
+							if typ, ok := typ.(*types.Basic); ok && typ.Kind() == types.UntypedNil {
+								return true
+							}
+							return false
+						})
+						if hasNil {
+							s.setOuter(tuple.Tag, NeverNil)
+						} else {
+							s.setOuter(tuple.Tag, MaybeNil)
+						}
+						s.setOuter(v, s.get(tuple.Tag).Inner)
+					} else {
+						// There is no Extract for the 'untyped nil' case,
+						// which means that executing any Extract from a type
+						// switch implies that the switched-over value wasn't a
+						// nil interface value.
+						s.setOuter(tuple.Tag, NeverNil)
+						typ := tuple.Conds[idx]
+						if types.IsInterface(typ) && !typeparams.IsTypeParam(typ) {
+							// Succesfully type asserting to an interface type
+							// always produces a non-nil interface value.
+							s.setInner(v, s.get(tuple.Tag).Inner)
+							s.setOuter(v, NeverNil)
+						} else {
+							s.setOuter(v, s.get(tuple.Tag).Inner)
+						}
+					}
+				default:
+					s.set(v, ValueNilness{MaybeNil, MaybeNil})
+				}
+			case *ir.Select:
+				if v.Blocking && len(v.States) == 1 {
+					// If the select doesn't have a default branch and only has
+					// one state, that state's channel cannot have been nil if
+					// we finished execution the select.
+					s.setOuter(v.States[0].Chan, NeverNil)
+				}
+			case *ir.Jump, *ir.BlankStore, *ir.Phi,
+				*ir.Panic, *ir.Return, *ir.RunDefers, *ir.Unreachable, *ir.ConstantSwitch,
+				*ir.UnOp, *ir.BinOp, *ir.CompositeValue, *ir.Range, *ir.Next:
+			default:
+				posn := pass.Fset.PositionFor(v.Pos(), false)
+				panic(fmt.Sprintf("internal error: unhandled type %T at %s", v, posn))
+			}
+		}
+		return s
+	}
+
+	processPhis := func(b *ir.BasicBlock, i int, s state) state {
+		for _, instr := range b.Instrs {
+			if instr, ok := instr.(*ir.Phi); ok {
+				s.set(instr, s.get(instr.Edges[i]))
+			} else {
+				break
+			}
+		}
+		return s
+	}
+
+	// Populate default state for non-instruction values we encounter. We
+	// cannot defer this logic to state.get because control flow merges use
+	// simple merges of lattice values and won't know about value-specific
+	// defaults.
+	entrys := state{cloned: true, n: n}
+	for _, param := range fn.Params {
+		if typeutil.MaybePointerLike(param.Type()) {
+			entrys.set(param, ValueNilness{Inner: MaybeNil, Outer: MaybeNil})
+		} else {
+			// We never track nilness for value types, so they don't have to be
+			// present in the entry state, either.
+		}
+	}
+	if strings.HasPrefix(fn.Synthetic, "bound method wrapper") {
+		// This is a bound method and the bound receiver might be nil
+		for _, fvar := range fn.FreeVars {
+			entrys.set(fvar, ValueNilness{Outer: MaybeNil})
+		}
+	} else {
+		// This is a closure, and closed over variables are allocs, which
+		// cannot be nil.
+		for _, fvar := range fn.FreeVars {
+			entrys.set(fvar, ValueNilness{Outer: NeverNil})
+		}
+	}
+	var ops []*ir.Value
+	for _, b := range fn.Blocks {
+		for _, instr := range b.Instrs {
+			ops = instr.Operands(ops[:0])
+			for _, pop := range ops {
+				if op, ok := (*pop).(*ir.Const); ok {
+					if op.IsNil() {
+						entrys.set(op, ValueNilness{Inner: AlwaysNil, Outer: AlwaysNil})
+					} else if typeutil.MaybePointerLike(op.Type()) {
+						entrys.set(op, ValueNilness{Inner: MaybeNil, Outer: MaybeNil})
+					} else {
+						entrys.set(op, ValueNilness{Inner: NeverNil, Outer: NeverNil})
+					}
+				}
+			}
+		}
+	}
+	res := dense.Forward[dfa.DenseMapLattice[ValueNilness, lattice]](
+		fn,
+		map[int][]ValueNilness{0: entrys.m},
+		func(fromID, toID int, in []ValueNilness) []ValueNilness {
+			from := fn.Blocks[fromID]
+			to := fn.Blocks[toID]
+			s := state{n: n, m: in}
+			s = processBlock(from, to, s)
+			i := slices.Index(to.Preds, from)
+			s = processPhis(to, i, s)
+			return s.m
+		},
+	)
+
+	retNilness := make([]ValueNilness, fn.Signature.Results().Len())
+	for b := range fn.Returns() {
+		ret := b.Control().(*ir.Return)
+		s := state{n: n, m: res.In(b.Index)}
+		s = processBlock(b, nil, s)
+		for i, res := range ret.Results {
+			retNilness[i] = lattice{}.Merge(retNilness[i], s.get(res))
+		}
+	}
+
+	interesting := false
+	for i := range retNilness {
+		typ := fn.Signature.Results().At(i).Type()
+		if !typeutil.MaybePointerLike(typ) {
+			retNilness[i] = ValueNilness{NeverNil, NeverNil}
+			continue
+		}
+		retNilness[i] = normalize(retNilness[i], typ)
+		if retNilness[i] != (ValueNilness{MaybeNil, MaybeNil}) {
+			interesting = true
+		}
+	}
+
+	if interesting {
+		pass.ExportObjectFact(fn.Object(), &nilnessFact{retNilness})
+	}
+
+	return retNilness
+}
+
+type lattice struct{}
+
+var _ dfa.Semilattice[ValueNilness] = lattice{}
+
+// Equals implements [dfa.Semilattice].
+func (l lattice) Equals(a, b ValueNilness) bool {
+	return a == b
+}
+
+// Ident implements [dfa.Semilattice].
+func (l lattice) Ident() ValueNilness {
+	return ValueNilness{}
+}
+
+var latticeMerge = [6][6]Nilness{
+	0: {
+		0:               0,
+		NeverNil:        NeverNil,
+		AlwaysNil:       AlwaysNil,
+		AlwaysNilGlobal: AlwaysNilGlobal,
+		MaybeNilGlobal:  MaybeNilGlobal,
+		MaybeNil:        MaybeNil,
+	},
+	NeverNil: {
+		0:               NeverNil,
+		NeverNil:        NeverNil,
+		AlwaysNil:       MaybeNil,
+		AlwaysNilGlobal: MaybeNilGlobal,
+		MaybeNilGlobal:  MaybeNilGlobal,
+		MaybeNil:        MaybeNil,
+	},
+	AlwaysNil: {
+		0:               AlwaysNil,
+		NeverNil:        MaybeNil,
+		AlwaysNil:       AlwaysNil,
+		AlwaysNilGlobal: AlwaysNil,
+		MaybeNilGlobal:  MaybeNil,
+		MaybeNil:        MaybeNil,
+	},
+	AlwaysNilGlobal: {
+		0:               AlwaysNilGlobal,
+		NeverNil:        MaybeNilGlobal,
+		AlwaysNil:       AlwaysNil,
+		AlwaysNilGlobal: AlwaysNilGlobal,
+		MaybeNilGlobal:  MaybeNilGlobal,
+		MaybeNil:        MaybeNil,
+	},
+	MaybeNilGlobal: {
+		0:               MaybeNilGlobal,
+		NeverNil:        MaybeNilGlobal,
+		AlwaysNil:       MaybeNil,
+		AlwaysNilGlobal: MaybeNilGlobal,
+		MaybeNilGlobal:  MaybeNilGlobal,
+		MaybeNil:        MaybeNil,
+	},
+	MaybeNil: {
+		0:               MaybeNil,
+		NeverNil:        MaybeNil,
+		AlwaysNil:       MaybeNil,
+		AlwaysNilGlobal: MaybeNil,
+		MaybeNilGlobal:  MaybeNil,
+		MaybeNil:        MaybeNil,
+	},
+}
+
+// Merge implements [dfa.Semilattice].
+func (l lattice) Merge(a, b ValueNilness) ValueNilness {
+	o := latticeMerge[a.Outer][b.Outer]
+	i := latticeMerge[a.Inner][b.Inner]
+
+	// When an interface value is always nil, then there is no stored value and
+	// Inner is technically undefined, regardless of what concrete nilness
+	// value was assigned to it.
+	//
+	// For example, {AlwaysNil, AlwaysNil} ∨ {NeverNil, NeverNil} should
+	// produce {NeverNil, MaybeNil} instead of {MaybeNil, MaybeNil}, to denote
+	// that when the interface value isn't nil, the stored value is never nil.
+	//
+	// {AlwaysNilGlobal, _} v {AlwaysNil, _}, however, should result in
+	// {AlwaysNil, _}, regardless of the outer value.
+	if i != AlwaysNil && i != AlwaysNilGlobal {
+		if a.Outer == AlwaysNil || a.Outer == AlwaysNilGlobal {
+			i = b.Inner
+		} else if b.Outer == AlwaysNil || b.Outer == AlwaysNilGlobal {
+			i = a.Inner
+		}
+	}
+	return ValueNilness{
+		Inner: i,
+		Outer: o,
+	}
+}
+
+type numbering map[ir.Value]int
+
+func (n numbering) number(v ir.Value) int {
+	i, ok := n[v]
+	if !ok {
+		i = len(n)
+		n[v] = i
+	}
+	return i
+}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/purity/purity.go b/vendor/honnef.co/go/tools/analysis/facts/purity/purity.go
new file mode 100644
index 0000000..92c7f28
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/facts/purity/purity.go
@@ -0,0 +1,264 @@
+package purity
+
+// TODO(dh): we should split this into two facts, one tracking actual purity, and one tracking side-effects. A function
+// that returns a heap allocation isn't pure, but it may be free of side effects.
+
+import (
+	"go/types"
+	"reflect"
+
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+type IsPure struct{}
+
+func (*IsPure) AFact()           {}
+func (d *IsPure) String() string { return "is pure" }
+
+type Result map[*types.Func]*IsPure
+
+var Analyzer = &analysis.Analyzer{
+	Name:       "fact_purity",
+	Doc:        "Mark pure functions",
+	Run:        purity,
+	Requires:   []*analysis.Analyzer{buildir.Analyzer},
+	FactTypes:  []analysis.Fact{(*IsPure)(nil)},
+	ResultType: reflect.TypeFor[Result](),
+}
+
+var pureStdlib = map[string]struct{}{
+	"errors.New":                      {},
+	"fmt.Errorf":                      {},
+	"fmt.Sprintf":                     {},
+	"fmt.Sprint":                      {},
+	"sort.Reverse":                    {},
+	"strings.Map":                     {},
+	"strings.Repeat":                  {},
+	"strings.Replace":                 {},
+	"strings.Title":                   {},
+	"strings.ToLower":                 {},
+	"strings.ToLowerSpecial":          {},
+	"strings.ToTitle":                 {},
+	"strings.ToTitleSpecial":          {},
+	"strings.ToUpper":                 {},
+	"strings.ToUpperSpecial":          {},
+	"strings.Trim":                    {},
+	"strings.TrimFunc":                {},
+	"strings.TrimLeft":                {},
+	"strings.TrimLeftFunc":            {},
+	"strings.TrimPrefix":              {},
+	"strings.TrimRight":               {},
+	"strings.TrimRightFunc":           {},
+	"strings.TrimSpace":               {},
+	"strings.TrimSuffix":              {},
+	"(*net/http.Request).WithContext": {},
+	"time.Now":                        {},
+	"time.Parse":                      {},
+	"time.ParseInLocation":            {},
+	"time.Unix":                       {},
+	"time.UnixMicro":                  {},
+	"time.UnixMilli":                  {},
+	"(time.Time).Add":                 {},
+	"(time.Time).AddDate":             {},
+	"(time.Time).After":               {},
+	"(time.Time).Before":              {},
+	"(time.Time).Clock":               {},
+	"(time.Time).Compare":             {},
+	"(time.Time).Date":                {},
+	"(time.Time).Day":                 {},
+	"(time.Time).Equal":               {},
+	"(time.Time).Format":              {},
+	"(time.Time).GoString":            {},
+	"(time.Time).GobEncode":           {},
+	"(time.Time).Hour":                {},
+	"(time.Time).ISOWeek":             {},
+	"(time.Time).In":                  {},
+	"(time.Time).IsDST":               {},
+	"(time.Time).IsZero":              {},
+	"(time.Time).Local":               {},
+	"(time.Time).Location":            {},
+	"(time.Time).MarshalBinary":       {},
+	"(time.Time).MarshalJSON":         {},
+	"(time.Time).MarshalText":         {},
+	"(time.Time).Minute":              {},
+	"(time.Time).Month":               {},
+	"(time.Time).Nanosecond":          {},
+	"(time.Time).Round":               {},
+	"(time.Time).Second":              {},
+	"(time.Time).String":              {},
+	"(time.Time).Sub":                 {},
+	"(time.Time).Truncate":            {},
+	"(time.Time).UTC":                 {},
+	"(time.Time).Unix":                {},
+	"(time.Time).UnixMicro":           {},
+	"(time.Time).UnixMilli":           {},
+	"(time.Time).UnixNano":            {},
+	"(time.Time).Weekday":             {},
+	"(time.Time).Year":                {},
+	"(time.Time).YearDay":             {},
+	"(time.Time).Zone":                {},
+	"(time.Time).ZoneBounds":          {},
+}
+
+func purity(pass *analysis.Pass) (any, error) {
+	seen := map[*ir.Function]struct{}{}
+	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
+	var check func(fn *ir.Function) (ret bool)
+	check = func(fn *ir.Function) (ret bool) {
+		if fn.Object() == nil {
+			// TODO(dh): support closures
+			return false
+		}
+		if pass.ImportObjectFact(fn.Object(), new(IsPure)) {
+			return true
+		}
+		if fn.Pkg != irpkg {
+			// Function is in another package but wasn't marked as
+			// pure, ergo it isn't pure
+			return false
+		}
+		// Break recursion
+		if _, ok := seen[fn]; ok {
+			return false
+		}
+
+		seen[fn] = struct{}{}
+		defer func() {
+			if ret {
+				pass.ExportObjectFact(fn.Object(), &IsPure{})
+			}
+		}()
+
+		if irutil.IsStub(fn) {
+			return false
+		}
+
+		if _, ok := pureStdlib[fn.Object().(*types.Func).FullName()]; ok {
+			return true
+		}
+
+		if fn.Signature.Results().Len() == 0 {
+			// A function with no return values is empty or is doing some
+			// work we cannot see (for example because of build tags);
+			// don't consider it pure.
+			return false
+		}
+
+		var isBasic func(typ types.Type) bool
+		isBasic = func(typ types.Type) bool {
+			switch u := typ.Underlying().(type) {
+			case *types.Basic:
+				return true
+			case *types.Struct:
+				for field := range u.Fields() {
+					if !isBasic(field.Type()) {
+						return false
+					}
+				}
+				return true
+			default:
+				return false
+			}
+		}
+
+		for _, param := range fn.Params {
+			// TODO(dh): this may not be strictly correct. pure code can, to an extent, operate on non-basic types.
+			if !isBasic(param.Type()) {
+				return false
+			}
+		}
+
+		// Don't consider external functions pure.
+		if fn.Blocks == nil {
+			return false
+		}
+		checkCall := func(common *ir.CallCommon) bool {
+			if common.IsInvoke() {
+				return false
+			}
+			builtin, ok := common.Value.(*ir.Builtin)
+			if !ok {
+				if common.StaticCallee() != fn {
+					if common.StaticCallee() == nil {
+						return false
+					}
+					if !check(common.StaticCallee()) {
+						return false
+					}
+				}
+			} else {
+				switch builtin.Name() {
+				case "len", "cap":
+				default:
+					return false
+				}
+			}
+			return true
+		}
+
+		var isStackAddr func(ir.Value) bool
+		isStackAddr = func(v ir.Value) bool {
+			switch v := v.(type) {
+			case *ir.Alloc:
+				return !v.Heap
+			case *ir.FieldAddr:
+				return isStackAddr(v.X)
+			default:
+				return false
+			}
+		}
+		for _, b := range fn.Blocks {
+			for _, ins := range b.Instrs {
+				switch ins := ins.(type) {
+				case *ir.Call:
+					if !checkCall(ins.Common()) {
+						return false
+					}
+				case *ir.Defer:
+					if !checkCall(&ins.Call) {
+						return false
+					}
+				case *ir.Select:
+					return false
+				case *ir.Send:
+					return false
+				case *ir.Go:
+					return false
+				case *ir.Panic:
+					return false
+				case *ir.Store:
+					if !isStackAddr(ins.Addr) {
+						return false
+					}
+				case *ir.FieldAddr:
+					if !isStackAddr(ins.X) {
+						return false
+					}
+				case *ir.Alloc:
+					// TODO(dh): make use of proper escape analysis
+					if ins.Heap {
+						return false
+					}
+				case *ir.Load:
+					if !isStackAddr(ins.X) {
+						return false
+					}
+				}
+			}
+		}
+		return true
+	}
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		check(fn)
+	}
+
+	out := Result{}
+	for _, fact := range pass.AllObjectFacts() {
+		out[fact.Object.(*types.Func)] = fact.Fact.(*IsPure)
+	}
+	return out, nil
+}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/tokenfile/token.go b/vendor/honnef.co/go/tools/analysis/facts/tokenfile/token.go
new file mode 100644
index 0000000..3618c89
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/facts/tokenfile/token.go
@@ -0,0 +1,24 @@
+package tokenfile
+
+import (
+	"go/ast"
+	"go/token"
+	"reflect"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var Analyzer = &analysis.Analyzer{
+	Name: "tokenfileanalyzer",
+	Doc:  "creates a mapping of *token.File to *ast.File",
+	Run: func(pass *analysis.Pass) (any, error) {
+		m := map[*token.File]*ast.File{}
+		for _, af := range pass.Files {
+			tf := pass.Fset.File(af.Pos())
+			m[tf] = af
+		}
+		return m, nil
+	},
+	RunDespiteErrors: true,
+	ResultType:       reflect.TypeFor[map[*token.File]*ast.File](),
+}
diff --git a/vendor/honnef.co/go/tools/analysis/lint/lint.go b/vendor/honnef.co/go/tools/analysis/lint/lint.go
new file mode 100644
index 0000000..c82bc24
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/lint/lint.go
@@ -0,0 +1,221 @@
+// Package lint provides abstractions on top of go/analysis.
+// These abstractions add extra information to analyzes, such as structured documentation and severities.
+package lint
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strings"
+
+	"golang.org/x/tools/go/analysis"
+	"honnef.co/go/tools/analysis/facts/tokenfile"
+)
+
+// Analyzer wraps a go/analysis.Analyzer and provides structured documentation.
+type Analyzer struct {
+	// The analyzer's documentation. Unlike go/analysis.Analyzer.Doc,
+	// this field is structured, providing access to severity, options
+	// etc.
+	Doc      *RawDocumentation
+	Analyzer *analysis.Analyzer
+}
+
+func InitializeAnalyzer(a *Analyzer) *Analyzer {
+	a.Analyzer.Doc = a.Doc.Compile().String()
+	a.Analyzer.URL = "https://staticcheck.dev/docs/checks/#" + a.Analyzer.Name
+	a.Analyzer.Requires = append(a.Analyzer.Requires, tokenfile.Analyzer)
+	return a
+}
+
+// Severity describes the severity of diagnostics reported by an analyzer.
+type Severity int
+
+const (
+	SeverityNone Severity = iota
+	SeverityError
+	SeverityDeprecated
+	SeverityWarning
+	SeverityInfo
+	SeverityHint
+)
+
+// MergeStrategy sets how merge mode should behave for diagnostics of an analyzer.
+type MergeStrategy int
+
+const (
+	MergeIfAny MergeStrategy = iota
+	MergeIfAll
+)
+
+type RawDocumentation struct {
+	Title      string
+	Text       string
+	Before     string
+	After      string
+	Since      string
+	NonDefault bool
+	Options    []string
+	Severity   Severity
+	MergeIf    MergeStrategy
+}
+
+type Documentation struct {
+	Title string
+	Text  string
+
+	TitleMarkdown string
+	TextMarkdown  string
+
+	Before     string
+	After      string
+	Since      string
+	NonDefault bool
+	Options    []string
+	Severity   Severity
+	MergeIf    MergeStrategy
+}
+
+func (doc RawDocumentation) Compile() *Documentation {
+	return &Documentation{
+		Title: strings.TrimSpace(stripMarkdown(doc.Title)),
+		Text:  strings.TrimSpace(stripMarkdown(doc.Text)),
+
+		TitleMarkdown: strings.TrimSpace(toMarkdown(doc.Title)),
+		TextMarkdown:  strings.TrimSpace(toMarkdown(doc.Text)),
+
+		Before:     strings.TrimSpace(doc.Before),
+		After:      strings.TrimSpace(doc.After),
+		Since:      doc.Since,
+		NonDefault: doc.NonDefault,
+		Options:    doc.Options,
+		Severity:   doc.Severity,
+		MergeIf:    doc.MergeIf,
+	}
+}
+
+func toMarkdown(s string) string {
+	return strings.NewReplacer(`\'`, "`", `\"`, "`").Replace(s)
+}
+
+func stripMarkdown(s string) string {
+	return strings.NewReplacer(`\'`, "", `\"`, "'").Replace(s)
+}
+
+func (doc *Documentation) Format(metadata bool) string {
+	return doc.format(false, metadata)
+}
+
+func (doc *Documentation) FormatMarkdown(metadata bool) string {
+	return doc.format(true, metadata)
+}
+
+func (doc *Documentation) format(markdown bool, metadata bool) string {
+	b := &strings.Builder{}
+	if markdown {
+		fmt.Fprintf(b, "%s\n\n", doc.TitleMarkdown)
+		if doc.Text != "" {
+			fmt.Fprintf(b, "%s\n\n", doc.TextMarkdown)
+		}
+	} else {
+		fmt.Fprintf(b, "%s\n\n", doc.Title)
+		if doc.Text != "" {
+			fmt.Fprintf(b, "%s\n\n", doc.Text)
+		}
+	}
+
+	if doc.Before != "" {
+		fmt.Fprintln(b, "Before:")
+		fmt.Fprintln(b, "")
+		for line := range strings.SplitSeq(doc.Before, "\n") {
+			fmt.Fprint(b, "    ", line, "\n")
+		}
+		fmt.Fprintln(b, "")
+		fmt.Fprintln(b, "After:")
+		fmt.Fprintln(b, "")
+		for line := range strings.SplitSeq(doc.After, "\n") {
+			fmt.Fprint(b, "    ", line, "\n")
+		}
+		fmt.Fprintln(b, "")
+	}
+
+	if metadata {
+		fmt.Fprint(b, "Available since\n    ")
+		if doc.Since == "" {
+			fmt.Fprint(b, "unreleased")
+		} else {
+			fmt.Fprintf(b, "%s", doc.Since)
+		}
+		if doc.NonDefault {
+			fmt.Fprint(b, ", non-default")
+		}
+		fmt.Fprint(b, "\n")
+		if len(doc.Options) > 0 {
+			fmt.Fprintf(b, "\nOptions\n")
+			for _, opt := range doc.Options {
+				fmt.Fprintf(b, "    %s", opt)
+			}
+			fmt.Fprint(b, "\n")
+		}
+	}
+
+	return b.String()
+}
+
+func (doc *Documentation) String() string {
+	return doc.Format(true)
+}
+
+// ExhaustiveTypeSwitch panics when called. It can be used to ensure
+// that type switches are exhaustive.
+func ExhaustiveTypeSwitch(v any) {
+	panic(fmt.Sprintf("internal error: unhandled case %T", v))
+}
+
+// A directive is a comment of the form '//lint:
+// [arguments...]'. It represents instructions to the static analysis
+// tool.
+type Directive struct {
+	Command   string
+	Arguments []string
+	Directive *ast.Comment
+	Node      ast.Node
+}
+
+func parseDirective(s string) (cmd string, args []string) {
+	if !strings.HasPrefix(s, "//lint:") {
+		return "", nil
+	}
+	s = strings.TrimPrefix(s, "//lint:")
+	fields := strings.Split(s, " ")
+	return fields[0], fields[1:]
+}
+
+// ParseDirectives extracts all directives from a list of Go files.
+func ParseDirectives(files []*ast.File, fset *token.FileSet) []Directive {
+	var dirs []Directive
+	for _, f := range files {
+		// OPT(dh): in our old code, we skip all the comment map work if we
+		// couldn't find any directives, benchmark if that's actually
+		// worth doing
+		cm := ast.NewCommentMap(fset, f, f.Comments)
+		for node, cgs := range cm {
+			for _, cg := range cgs {
+				for _, c := range cg.List {
+					if !strings.HasPrefix(c.Text, "//lint:") {
+						continue
+					}
+					cmd, args := parseDirective(c.Text)
+					d := Directive{
+						Command:   cmd,
+						Arguments: args,
+						Directive: c,
+						Node:      node,
+					}
+					dirs = append(dirs, d)
+				}
+			}
+		}
+	}
+	return dirs
+}
diff --git a/vendor/honnef.co/go/tools/analysis/report/report.go b/vendor/honnef.co/go/tools/analysis/report/report.go
new file mode 100644
index 0000000..39919a8
--- /dev/null
+++ b/vendor/honnef.co/go/tools/analysis/report/report.go
@@ -0,0 +1,280 @@
+package report
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/format"
+	"go/token"
+	"go/version"
+	"path/filepath"
+	"strconv"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+type Options struct {
+	ShortRange             bool
+	FilterGenerated        bool
+	Fixes                  []analysis.SuggestedFix
+	Related                []analysis.RelatedInformation
+	MinimumLanguageVersion string
+	MaximumLanguageVersion string
+	MinimumStdlibVersion   string
+	MaximumStdlibVersion   string
+}
+
+type Option func(*Options)
+
+func ShortRange() Option {
+	return func(opts *Options) {
+		opts.ShortRange = true
+	}
+}
+
+func FilterGenerated() Option {
+	return func(opts *Options) {
+		opts.FilterGenerated = true
+	}
+}
+
+func Fixes(fixes ...analysis.SuggestedFix) Option {
+	return func(opts *Options) {
+		opts.Fixes = append(opts.Fixes, fixes...)
+	}
+}
+
+func Related(node Positioner, message string) Option {
+	return func(opts *Options) {
+		pos, end, ok := getRange(node, opts.ShortRange)
+		if !ok {
+			return
+		}
+		r := analysis.RelatedInformation{
+			Pos:     pos,
+			End:     end,
+			Message: message,
+		}
+		opts.Related = append(opts.Related, r)
+	}
+}
+
+func MinimumLanguageVersion(vers string) Option {
+	return func(opts *Options) { opts.MinimumLanguageVersion = vers }
+}
+func MaximumLanguageVersion(vers string) Option {
+	return func(opts *Options) { opts.MinimumLanguageVersion = vers }
+}
+func MinimumStdlibVersion(vers string) Option {
+	return func(opts *Options) { opts.MinimumStdlibVersion = vers }
+}
+func MaximumStdlibVersion(vers string) Option {
+	return func(opts *Options) { opts.MaximumStdlibVersion = vers }
+}
+
+type Positioner interface {
+	Pos() token.Pos
+}
+
+type fullPositioner interface {
+	Pos() token.Pos
+	End() token.Pos
+}
+
+type sourcer interface {
+	Source() ast.Node
+}
+
+// shortRange returns the position and end of the main component of an
+// AST node. For nodes that have no body, the short range is identical
+// to the node's Pos and End. For nodes that do have a body, the short
+// range excludes the body.
+func shortRange(node ast.Node) (pos, end token.Pos) {
+	switch node := node.(type) {
+	case *ast.File:
+		return node.Pos(), node.Name.End()
+	case *ast.CaseClause:
+		return node.Pos(), node.Colon + 1
+	case *ast.CommClause:
+		return node.Pos(), node.Colon + 1
+	case *ast.DeferStmt:
+		return node.Pos(), node.Defer + token.Pos(len("defer"))
+	case *ast.ExprStmt:
+		return shortRange(node.X)
+	case *ast.ForStmt:
+		if node.Post != nil {
+			return node.For, node.Post.End()
+		} else if node.Cond != nil {
+			return node.For, node.Cond.End()
+		} else if node.Init != nil {
+			// +1 to catch the semicolon, for gofmt'ed code
+			return node.Pos(), node.Init.End() + 1
+		} else {
+			return node.Pos(), node.For + token.Pos(len("for"))
+		}
+	case *ast.FuncDecl:
+		return node.Pos(), node.Type.End()
+	case *ast.FuncLit:
+		return node.Pos(), node.Type.End()
+	case *ast.GoStmt:
+		if _, ok := ast.Unparen(node.Call.Fun).(*ast.FuncLit); ok {
+			return node.Pos(), node.Go + token.Pos(len("go"))
+		} else {
+			return node.Pos(), node.End()
+		}
+	case *ast.IfStmt:
+		return node.Pos(), node.Cond.End()
+	case *ast.RangeStmt:
+		return node.Pos(), node.X.End()
+	case *ast.SelectStmt:
+		return node.Pos(), node.Pos() + token.Pos(len("select"))
+	case *ast.SwitchStmt:
+		if node.Tag != nil {
+			return node.Pos(), node.Tag.End()
+		} else if node.Init != nil {
+			// +1 to catch the semicolon, for gofmt'ed code
+			return node.Pos(), node.Init.End() + 1
+		} else {
+			return node.Pos(), node.Pos() + token.Pos(len("switch"))
+		}
+	case *ast.TypeSwitchStmt:
+		return node.Pos(), node.Assign.End()
+	default:
+		return node.Pos(), node.End()
+	}
+}
+
+func HasRange(node Positioner) bool {
+	// we don't know if getRange will be called with shortRange set to
+	// true, so make sure that both work.
+	_, _, ok := getRange(node, false)
+	if !ok {
+		return false
+	}
+	_, _, ok = getRange(node, true)
+	return ok
+}
+
+func getRange(node Positioner, short bool) (pos, end token.Pos, ok bool) {
+	switch n := node.(type) {
+	case sourcer:
+		s := n.Source()
+		if s == nil {
+			return 0, 0, false
+		}
+		if short {
+			p, e := shortRange(s)
+			return p, e, true
+		}
+		return s.Pos(), s.End(), true
+	case fullPositioner:
+		if short {
+			p, e := shortRange(n)
+			return p, e, true
+		}
+		return n.Pos(), n.End(), true
+	default:
+		return n.Pos(), token.NoPos, true
+	}
+}
+
+func Report(pass *analysis.Pass, node Positioner, message string, opts ...Option) {
+	cfg := &Options{}
+	for _, opt := range opts {
+		opt(cfg)
+	}
+
+	langVersion := code.LanguageVersion(pass, node)
+	stdlibVersion := code.StdlibVersion(pass, node)
+	if n := cfg.MaximumLanguageVersion; n != "" && version.Compare(n, langVersion) == -1 {
+		return
+	}
+	if n := cfg.MaximumStdlibVersion; n != "" && version.Compare(n, stdlibVersion) == -1 {
+		return
+	}
+	if n := cfg.MinimumLanguageVersion; n != "" && version.Compare(n, langVersion) == 1 {
+		return
+	}
+	if n := cfg.MinimumStdlibVersion; n != "" && version.Compare(n, stdlibVersion) == 1 {
+		return
+	}
+
+	file := DisplayPosition(pass.Fset, node.Pos()).Filename
+	if cfg.FilterGenerated {
+		m := pass.ResultOf[generated.Analyzer].(map[string]generated.Generator)
+		if _, ok := m[file]; ok {
+			return
+		}
+	}
+
+	pos, end, ok := getRange(node, cfg.ShortRange)
+	if !ok {
+		panic(fmt.Sprintf("no valid position for reporting node %v", node))
+	}
+	d := analysis.Diagnostic{
+		Pos:            pos,
+		End:            end,
+		Message:        message,
+		SuggestedFixes: cfg.Fixes,
+		Related:        cfg.Related,
+	}
+	pass.Report(d)
+}
+
+func Render(pass *analysis.Pass, x any) string {
+	var buf bytes.Buffer
+	if err := format.Node(&buf, pass.Fset, x); err != nil {
+		panic(err)
+	}
+	return buf.String()
+}
+
+func RenderArgs(pass *analysis.Pass, args []ast.Expr) string {
+	var ss []string
+	for _, arg := range args {
+		ss = append(ss, Render(pass, arg))
+	}
+	return strings.Join(ss, ", ")
+}
+
+func DisplayPosition(fset *token.FileSet, p token.Pos) token.Position {
+	if p == token.NoPos {
+		return token.Position{}
+	}
+
+	// Only use the adjusted position if it points to another Go file.
+	// This means we'll point to the original file for cgo files, but
+	// we won't point to a YACC grammar file.
+	pos := fset.PositionFor(p, false)
+	adjPos := fset.PositionFor(p, true)
+
+	if filepath.Ext(adjPos.Filename) == ".go" {
+		return adjPos
+	}
+
+	return pos
+}
+
+func Ordinal(n int) string {
+	suffix := "th"
+	if n < 10 || n > 20 {
+		switch n % 10 {
+		case 0:
+			suffix = "th"
+		case 1:
+			suffix = "st"
+		case 2:
+			suffix = "nd"
+		case 3:
+			suffix = "rd"
+		default:
+			suffix = "th"
+		}
+	}
+
+	return strconv.Itoa(n) + suffix
+}
diff --git a/vendor/honnef.co/go/tools/cmd/staticcheck/README.md b/vendor/honnef.co/go/tools/cmd/staticcheck/README.md
new file mode 100644
index 0000000..e5ee3aa
--- /dev/null
+++ b/vendor/honnef.co/go/tools/cmd/staticcheck/README.md
@@ -0,0 +1,15 @@
+# staticcheck
+
+_staticcheck_ offers extensive analysis of Go code, covering a myriad
+of categories. It will detect bugs, suggest code simplifications,
+point out dead code, and more.
+
+## Installation
+
+See [the main README](https://github.com/dominikh/go-tools#installation) for installation instructions.
+
+## Documentation
+
+Detailed documentation can be found on
+[staticcheck.dev](https://staticcheck.dev/docs/).
+
diff --git a/vendor/honnef.co/go/tools/cmd/staticcheck/staticcheck.go b/vendor/honnef.co/go/tools/cmd/staticcheck/staticcheck.go
new file mode 100644
index 0000000..0561740
--- /dev/null
+++ b/vendor/honnef.co/go/tools/cmd/staticcheck/staticcheck.go
@@ -0,0 +1,45 @@
+// staticcheck analyses Go code and makes it better.
+package main
+
+import (
+	"log"
+	"os"
+
+	"honnef.co/go/tools/lintcmd"
+	"honnef.co/go/tools/lintcmd/version"
+	"honnef.co/go/tools/quickfix"
+	"honnef.co/go/tools/simple"
+	"honnef.co/go/tools/staticcheck"
+	"honnef.co/go/tools/stylecheck"
+	"honnef.co/go/tools/unused"
+)
+
+func main() {
+	cmd := lintcmd.NewCommand("staticcheck")
+	cmd.SetVersion(version.Version, version.MachineVersion)
+
+	fs := cmd.FlagSet()
+	debug := fs.String("debug.unused-graph", "", "Write unused's object graph to `file`")
+	qf := fs.Bool("debug.run-quickfix-analyzers", false, "Run quickfix analyzers")
+
+	cmd.ParseFlags(os.Args[1:])
+
+	cmd.AddAnalyzers(simple.Analyzers...)
+	cmd.AddAnalyzers(staticcheck.Analyzers...)
+	cmd.AddAnalyzers(stylecheck.Analyzers...)
+	cmd.AddAnalyzers(unused.Analyzer)
+
+	if *qf {
+		cmd.AddAnalyzers(quickfix.Analyzers...)
+	}
+
+	if *debug != "" {
+		f, err := os.OpenFile(*debug, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+		if err != nil {
+			log.Fatal(err)
+		}
+		unused.Debug = f
+	}
+
+	cmd.Run()
+}
diff --git a/vendor/honnef.co/go/tools/config/config.go b/vendor/honnef.co/go/tools/config/config.go
new file mode 100644
index 0000000..1c47f69
--- /dev/null
+++ b/vendor/honnef.co/go/tools/config/config.go
@@ -0,0 +1,278 @@
+package config
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/token"
+	"os"
+	"path/filepath"
+	"reflect"
+	"strings"
+
+	"github.com/BurntSushi/toml"
+	"golang.org/x/tools/go/analysis"
+)
+
+// Dir looks at a list of absolute file names, which should make up a
+// single package, and returns the path of the directory that may
+// contain a staticcheck.conf file. It returns the empty string if no
+// such directory could be determined, for example because all files
+// were located in Go's build cache.
+func Dir(files []string) string {
+	if len(files) == 0 {
+		return ""
+	}
+	cache, err := os.UserCacheDir()
+	if err != nil {
+		cache = ""
+	}
+	var path string
+	for _, p := range files {
+		// FIXME(dh): using strings.HasPrefix isn't technically
+		// correct, but it should be good enough for now.
+		if cache != "" && strings.HasPrefix(p, cache) {
+			// File in the build cache of the standard Go build system
+			continue
+		}
+		path = p
+		break
+	}
+
+	if path == "" {
+		// The package only consists of generated files.
+		return ""
+	}
+
+	dir := filepath.Dir(path)
+	return dir
+}
+
+func dirAST(files []*ast.File, fset *token.FileSet) string {
+	names := make([]string, len(files))
+	for i, f := range files {
+		names[i] = fset.PositionFor(f.Pos(), true).Filename
+	}
+	return Dir(names)
+}
+
+var Analyzer = &analysis.Analyzer{
+	Name: "config",
+	Doc:  "loads configuration for the current package tree",
+	Run: func(pass *analysis.Pass) (any, error) {
+		dir := dirAST(pass.Files, pass.Fset)
+		if dir == "" {
+			cfg := DefaultConfig
+			return &cfg, nil
+		}
+		cfg, err := Load(dir)
+		if err != nil {
+			return nil, fmt.Errorf("error loading staticcheck.conf: %s", err)
+		}
+		return &cfg, nil
+	},
+	RunDespiteErrors: true,
+	ResultType:       reflect.TypeFor[*Config](),
+}
+
+func For(pass *analysis.Pass) *Config {
+	return pass.ResultOf[Analyzer].(*Config)
+}
+
+func mergeLists(a, b []string) []string {
+	out := make([]string, 0, len(a)+len(b))
+	for _, el := range b {
+		if el == "inherit" {
+			out = append(out, a...)
+		} else {
+			out = append(out, el)
+		}
+	}
+
+	return out
+}
+
+func normalizeList(list []string) []string {
+	if len(list) > 1 {
+		nlist := make([]string, 0, len(list))
+		nlist = append(nlist, list[0])
+		for i, el := range list[1:] {
+			if el != list[i] {
+				nlist = append(nlist, el)
+			}
+		}
+		list = nlist
+	}
+
+	for _, el := range list {
+		if el == "inherit" {
+			// This should never happen, because the default config
+			// should not use "inherit"
+			panic(`unresolved "inherit"`)
+		}
+	}
+
+	return list
+}
+
+func (cfg Config) Merge(ocfg Config) Config {
+	if ocfg.Checks != nil {
+		cfg.Checks = mergeLists(cfg.Checks, ocfg.Checks)
+	}
+	if ocfg.Initialisms != nil {
+		cfg.Initialisms = mergeLists(cfg.Initialisms, ocfg.Initialisms)
+	}
+	if ocfg.DotImportWhitelist != nil {
+		cfg.DotImportWhitelist = mergeLists(cfg.DotImportWhitelist, ocfg.DotImportWhitelist)
+	}
+	if ocfg.HTTPStatusCodeWhitelist != nil {
+		cfg.HTTPStatusCodeWhitelist = mergeLists(cfg.HTTPStatusCodeWhitelist, ocfg.HTTPStatusCodeWhitelist)
+	}
+	return cfg
+}
+
+type Config struct {
+	// TODO(dh): this implementation makes it impossible for external
+	// clients to add their own checkers with configuration. At the
+	// moment, we don't really care about that; we don't encourage
+	// that people use this package. In the future, we may. The
+	// obvious solution would be using map[string]interface{}, but
+	// that's obviously subpar.
+
+	Checks                  []string `toml:"checks"`
+	Initialisms             []string `toml:"initialisms"`
+	DotImportWhitelist      []string `toml:"dot_import_whitelist"`
+	HTTPStatusCodeWhitelist []string `toml:"http_status_code_whitelist"`
+}
+
+func (c Config) String() string {
+	buf := &bytes.Buffer{}
+
+	fmt.Fprintf(buf, "Checks: %#v\n", c.Checks)
+	fmt.Fprintf(buf, "Initialisms: %#v\n", c.Initialisms)
+	fmt.Fprintf(buf, "DotImportWhitelist: %#v\n", c.DotImportWhitelist)
+	fmt.Fprintf(buf, "HTTPStatusCodeWhitelist: %#v", c.HTTPStatusCodeWhitelist)
+
+	return buf.String()
+}
+
+// DefaultConfig is the default configuration.
+// Its initial value describes the majority of the default configuration,
+// but the Checks field can be updated at runtime based on the analyzers being used, to disable non-default checks.
+// For cmd/staticcheck, this is handled by (*lintcmd.Command).Run.
+//
+// Note that DefaultConfig shouldn't be modified while analyzers are executing.
+var DefaultConfig = Config{
+	Checks: []string{"all"},
+	Initialisms: []string{
+		"ACL", "API", "ASCII", "CPU", "CSS", "DNS",
+		"EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID",
+		"IP", "JSON", "QPS", "RAM", "RPC", "SLA",
+		"SMTP", "SQL", "SSH", "TCP", "TLS", "TTL",
+		"UDP", "UI", "GID", "UID", "UUID", "URI",
+		"URL", "UTF8", "VM", "XML", "XMPP", "XSRF",
+		"XSS", "SIP", "RTP", "AMQP", "DB", "TS",
+	},
+	DotImportWhitelist: []string{
+		"simd/archsimd",
+		"github.com/mmcloughlin/avo/build",
+		"github.com/mmcloughlin/avo/operand",
+		"github.com/mmcloughlin/avo/reg",
+	},
+	HTTPStatusCodeWhitelist: []string{"200", "400", "404", "500"},
+}
+
+const ConfigName = "staticcheck.conf"
+
+type ParseError struct {
+	Filename string
+	toml.ParseError
+}
+
+func parseConfigs(dir string) ([]Config, error) {
+	var out []Config
+
+	// TODO(dh): consider stopping at the GOPATH/module boundary
+	for dir != "" {
+		path := filepath.Join(dir, ConfigName)
+		fi, err := os.Stat(path)
+		if os.IsNotExist(err) || (err == nil && !fi.Mode().IsRegular()) {
+			// walk up
+			ndir := filepath.Dir(dir)
+			if ndir == dir {
+				break
+			}
+			dir = ndir
+			continue
+		}
+		if err != nil {
+			return nil, err
+		}
+
+		// There is a small TOCTOU window here, but we're fine with reporting an
+		// error if the source tree is modified concurrently in weird ways while
+		// running Staticcheck.
+		f, err := os.Open(path)
+		if err != nil {
+			return nil, err
+		}
+
+		var cfg Config
+		_, err = toml.NewDecoder(f).Decode(&cfg)
+		f.Close()
+		if err != nil {
+			if err, ok := err.(toml.ParseError); ok {
+				return nil, ParseError{
+					Filename:   filepath.Join(dir, ConfigName),
+					ParseError: err,
+				}
+			}
+			return nil, err
+		}
+		out = append(out, cfg)
+		ndir := filepath.Dir(dir)
+		if ndir == dir {
+			break
+		}
+		dir = ndir
+	}
+	out = append(out, DefaultConfig)
+	if len(out) < 2 {
+		return out, nil
+	}
+	for i := 0; i < len(out)/2; i++ {
+		out[i], out[len(out)-1-i] = out[len(out)-1-i], out[i]
+	}
+	return out, nil
+}
+
+func mergeConfigs(confs []Config) Config {
+	if len(confs) == 0 {
+		// This shouldn't happen because we always have at least a
+		// default config.
+		panic("trying to merge zero configs")
+	}
+	if len(confs) == 1 {
+		return confs[0]
+	}
+	conf := confs[0]
+	for _, oconf := range confs[1:] {
+		conf = conf.Merge(oconf)
+	}
+	return conf
+}
+
+func Load(dir string) (Config, error) {
+	confs, err := parseConfigs(dir)
+	if err != nil {
+		return Config{}, err
+	}
+	conf := mergeConfigs(confs)
+
+	conf.Checks = normalizeList(conf.Checks)
+	conf.Initialisms = normalizeList(conf.Initialisms)
+	conf.DotImportWhitelist = normalizeList(conf.DotImportWhitelist)
+	conf.HTTPStatusCodeWhitelist = normalizeList(conf.HTTPStatusCodeWhitelist)
+
+	return conf, nil
+}
diff --git a/vendor/honnef.co/go/tools/config/example.conf b/vendor/honnef.co/go/tools/config/example.conf
new file mode 100644
index 0000000..acc9d69
--- /dev/null
+++ b/vendor/honnef.co/go/tools/config/example.conf
@@ -0,0 +1,15 @@
+checks = ["all", "-SA9003", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022", "-ST1023"]
+initialisms = ["ACL", "API", "ASCII", "CPU", "CSS", "DNS",
+	"EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID",
+	"IP", "JSON", "QPS", "RAM", "RPC", "SLA",
+	"SMTP", "SQL", "SSH", "TCP", "TLS", "TTL",
+	"UDP", "UI", "GID", "UID", "UUID", "URI",
+	"URL", "UTF8", "VM", "XML", "XMPP", "XSRF",
+	"XSS", "SIP", "RTP", "AMQP", "DB", "TS"]
+dot_import_whitelist = [
+    "simd/archsimd",
+    "github.com/mmcloughlin/avo/build",
+    "github.com/mmcloughlin/avo/operand",
+    "github.com/mmcloughlin/avo/reg",
+]
+http_status_code_whitelist = ["200", "400", "404", "500"]
diff --git a/vendor/honnef.co/go/tools/go/ast/astutil/upstream.go b/vendor/honnef.co/go/tools/go/ast/astutil/upstream.go
new file mode 100644
index 0000000..fc647c4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ast/astutil/upstream.go
@@ -0,0 +1,20 @@
+package astutil
+
+import (
+	"go/ast"
+	"go/token"
+	_ "unsafe"
+
+	"golang.org/x/tools/go/ast/astutil"
+)
+
+type Cursor = astutil.Cursor
+type ApplyFunc = astutil.ApplyFunc
+
+func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node) {
+	return astutil.Apply(root, pre, post)
+}
+
+func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool) {
+	return astutil.PathEnclosingInterval(root, start, end)
+}
diff --git a/vendor/honnef.co/go/tools/go/ast/astutil/util.go b/vendor/honnef.co/go/tools/go/ast/astutil/util.go
new file mode 100644
index 0000000..c23968f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ast/astutil/util.go
@@ -0,0 +1,462 @@
+package astutil
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"reflect"
+	"strings"
+
+	"golang.org/x/tools/go/ast/astutil"
+)
+
+func IsIdent(expr ast.Expr, ident string) bool {
+	id, ok := expr.(*ast.Ident)
+	return ok && id.Name == ident
+}
+
+// isBlank returns whether id is the blank identifier "_".
+// If id == nil, the answer is false.
+func IsBlank(id ast.Expr) bool {
+	ident, _ := id.(*ast.Ident)
+	return ident != nil && ident.Name == "_"
+}
+
+// Deprecated: use code.IsIntegerLiteral instead.
+func IsIntLiteral(expr ast.Expr, literal string) bool {
+	lit, ok := expr.(*ast.BasicLit)
+	return ok && lit.Kind == token.INT && lit.Value == literal
+}
+
+// Deprecated: use IsIntLiteral instead
+func IsZero(expr ast.Expr) bool {
+	return IsIntLiteral(expr, "0")
+}
+
+func Preamble(f *ast.File) string {
+	cutoff := f.Package
+	if f.Doc != nil {
+		cutoff = f.Doc.Pos()
+	}
+	var out []string
+	for _, cmt := range f.Comments {
+		if cmt.Pos() >= cutoff {
+			break
+		}
+		out = append(out, cmt.Text())
+	}
+	return strings.Join(out, "\n")
+}
+
+func GroupSpecs(fset *token.FileSet, specs []ast.Spec) [][]ast.Spec {
+	if len(specs) == 0 {
+		return nil
+	}
+	groups := make([][]ast.Spec, 1)
+	groups[0] = append(groups[0], specs[0])
+
+	for _, spec := range specs[1:] {
+		g := groups[len(groups)-1]
+		if fset.PositionFor(spec.Pos(), false).Line-1 !=
+			fset.PositionFor(g[len(g)-1].End(), false).Line {
+
+			groups = append(groups, nil)
+		}
+
+		groups[len(groups)-1] = append(groups[len(groups)-1], spec)
+	}
+
+	return groups
+}
+
+// CopyExpr creates a deep copy of an expression.
+// It doesn't support copying FuncLits and returns ok == false when encountering one.
+func CopyExpr(node ast.Expr) (ast.Expr, bool) {
+	switch node := node.(type) {
+	case *ast.BasicLit:
+		cp := *node
+		return &cp, true
+	case *ast.BinaryExpr:
+		cp := *node
+		var ok1, ok2 bool
+		cp.X, ok1 = CopyExpr(cp.X)
+		cp.Y, ok2 = CopyExpr(cp.Y)
+		return &cp, ok1 && ok2
+	case *ast.CallExpr:
+		var ok bool
+		cp := *node
+		cp.Fun, ok = CopyExpr(cp.Fun)
+		if !ok {
+			return nil, false
+		}
+		cp.Args = make([]ast.Expr, len(node.Args))
+		for i, v := range node.Args {
+			cp.Args[i], ok = CopyExpr(v)
+			if !ok {
+				return nil, false
+			}
+		}
+		return &cp, true
+	case *ast.CompositeLit:
+		var ok bool
+		cp := *node
+		cp.Type, ok = CopyExpr(cp.Type)
+		if !ok {
+			return nil, false
+		}
+		cp.Elts = make([]ast.Expr, len(node.Elts))
+		for i, v := range node.Elts {
+			cp.Elts[i], ok = CopyExpr(v)
+			if !ok {
+				return nil, false
+			}
+		}
+		return &cp, true
+	case *ast.Ident:
+		cp := *node
+		return &cp, true
+	case *ast.IndexExpr:
+		var ok1, ok2 bool
+		cp := *node
+		cp.X, ok1 = CopyExpr(cp.X)
+		cp.Index, ok2 = CopyExpr(cp.Index)
+		return &cp, ok1 && ok2
+	case *ast.IndexListExpr:
+		var ok bool
+		cp := *node
+		cp.X, ok = CopyExpr(cp.X)
+		if !ok {
+			return nil, false
+		}
+		for i, v := range node.Indices {
+			cp.Indices[i], ok = CopyExpr(v)
+			if !ok {
+				return nil, false
+			}
+		}
+		return &cp, true
+	case *ast.KeyValueExpr:
+		var ok1, ok2 bool
+		cp := *node
+		cp.Key, ok1 = CopyExpr(cp.Key)
+		cp.Value, ok2 = CopyExpr(cp.Value)
+		return &cp, ok1 && ok2
+	case *ast.ParenExpr:
+		var ok bool
+		cp := *node
+		cp.X, ok = CopyExpr(cp.X)
+		return &cp, ok
+	case *ast.SelectorExpr:
+		var ok bool
+		cp := *node
+		cp.X, ok = CopyExpr(cp.X)
+		if !ok {
+			return nil, false
+		}
+		sel, ok := CopyExpr(cp.Sel)
+		if !ok {
+			// this is impossible
+			return nil, false
+		}
+		cp.Sel = sel.(*ast.Ident)
+		return &cp, true
+	case *ast.SliceExpr:
+		var ok1, ok2, ok3, ok4 bool
+		cp := *node
+		cp.X, ok1 = CopyExpr(cp.X)
+		cp.Low, ok2 = CopyExpr(cp.Low)
+		cp.High, ok3 = CopyExpr(cp.High)
+		cp.Max, ok4 = CopyExpr(cp.Max)
+		return &cp, ok1 && ok2 && ok3 && ok4
+	case *ast.StarExpr:
+		var ok bool
+		cp := *node
+		cp.X, ok = CopyExpr(cp.X)
+		return &cp, ok
+	case *ast.TypeAssertExpr:
+		var ok1, ok2 bool
+		cp := *node
+		cp.X, ok1 = CopyExpr(cp.X)
+		cp.Type, ok2 = CopyExpr(cp.Type)
+		return &cp, ok1 && ok2
+	case *ast.UnaryExpr:
+		var ok bool
+		cp := *node
+		cp.X, ok = CopyExpr(cp.X)
+		return &cp, ok
+	case *ast.MapType:
+		var ok1, ok2 bool
+		cp := *node
+		cp.Key, ok1 = CopyExpr(cp.Key)
+		cp.Value, ok2 = CopyExpr(cp.Value)
+		return &cp, ok1 && ok2
+	case *ast.ArrayType:
+		var ok1, ok2 bool
+		cp := *node
+		cp.Len, ok1 = CopyExpr(cp.Len)
+		cp.Elt, ok2 = CopyExpr(cp.Elt)
+		return &cp, ok1 && ok2
+	case *ast.Ellipsis:
+		var ok bool
+		cp := *node
+		cp.Elt, ok = CopyExpr(cp.Elt)
+		return &cp, ok
+	case *ast.InterfaceType:
+		cp := *node
+		return &cp, true
+	case *ast.StructType:
+		cp := *node
+		return &cp, true
+	case *ast.FuncLit, *ast.FuncType:
+		// TODO(dh): implement copying of function literals and types.
+		return nil, false
+	case *ast.ChanType:
+		var ok bool
+		cp := *node
+		cp.Value, ok = CopyExpr(cp.Value)
+		return &cp, ok
+	case nil:
+		return nil, true
+	default:
+		panic(fmt.Sprintf("unreachable: %T", node))
+	}
+}
+
+func Equal(a, b ast.Node) bool {
+	if a == b {
+		return true
+	}
+	if a == nil || b == nil {
+		return false
+	}
+	if reflect.TypeOf(a) != reflect.TypeOf(b) {
+		return false
+	}
+
+	switch a := a.(type) {
+	case *ast.BasicLit:
+		b := b.(*ast.BasicLit)
+		return a.Kind == b.Kind && a.Value == b.Value
+	case *ast.BinaryExpr:
+		b := b.(*ast.BinaryExpr)
+		return Equal(a.X, b.X) && a.Op == b.Op && Equal(a.Y, b.Y)
+	case *ast.CallExpr:
+		b := b.(*ast.CallExpr)
+		if len(a.Args) != len(b.Args) {
+			return false
+		}
+		for i, arg := range a.Args {
+			if !Equal(arg, b.Args[i]) {
+				return false
+			}
+		}
+		return Equal(a.Fun, b.Fun) &&
+			(a.Ellipsis == token.NoPos && b.Ellipsis == token.NoPos || a.Ellipsis != token.NoPos && b.Ellipsis != token.NoPos)
+	case *ast.CompositeLit:
+		b := b.(*ast.CompositeLit)
+		if len(a.Elts) != len(b.Elts) {
+			return false
+		}
+		for i, elt := range b.Elts {
+			if !Equal(elt, b.Elts[i]) {
+				return false
+			}
+		}
+		return Equal(a.Type, b.Type) && a.Incomplete == b.Incomplete
+	case *ast.Ident:
+		b := b.(*ast.Ident)
+		return a.Name == b.Name
+	case *ast.IndexExpr:
+		b := b.(*ast.IndexExpr)
+		return Equal(a.X, b.X) && Equal(a.Index, b.Index)
+	case *ast.IndexListExpr:
+		b := b.(*ast.IndexListExpr)
+		if len(a.Indices) != len(b.Indices) {
+			return false
+		}
+		for i, v := range a.Indices {
+			if !Equal(v, b.Indices[i]) {
+				return false
+			}
+		}
+		return Equal(a.X, b.X)
+	case *ast.KeyValueExpr:
+		b := b.(*ast.KeyValueExpr)
+		return Equal(a.Key, b.Key) && Equal(a.Value, b.Value)
+	case *ast.ParenExpr:
+		b := b.(*ast.ParenExpr)
+		return Equal(a.X, b.X)
+	case *ast.SelectorExpr:
+		b := b.(*ast.SelectorExpr)
+		return Equal(a.X, b.X) && Equal(a.Sel, b.Sel)
+	case *ast.SliceExpr:
+		b := b.(*ast.SliceExpr)
+		return Equal(a.X, b.X) && Equal(a.Low, b.Low) && Equal(a.High, b.High) && Equal(a.Max, b.Max) && a.Slice3 == b.Slice3
+	case *ast.StarExpr:
+		b := b.(*ast.StarExpr)
+		return Equal(a.X, b.X)
+	case *ast.TypeAssertExpr:
+		b := b.(*ast.TypeAssertExpr)
+		return Equal(a.X, b.X) && Equal(a.Type, b.Type)
+	case *ast.UnaryExpr:
+		b := b.(*ast.UnaryExpr)
+		return a.Op == b.Op && Equal(a.X, b.X)
+	case *ast.MapType:
+		b := b.(*ast.MapType)
+		return Equal(a.Key, b.Key) && Equal(a.Value, b.Value)
+	case *ast.ArrayType:
+		b := b.(*ast.ArrayType)
+		return Equal(a.Len, b.Len) && Equal(a.Elt, b.Elt)
+	case *ast.Ellipsis:
+		b := b.(*ast.Ellipsis)
+		return Equal(a.Elt, b.Elt)
+	case *ast.InterfaceType:
+		b := b.(*ast.InterfaceType)
+		return a.Incomplete == b.Incomplete && Equal(a.Methods, b.Methods)
+	case *ast.StructType:
+		b := b.(*ast.StructType)
+		return a.Incomplete == b.Incomplete && Equal(a.Fields, b.Fields)
+	case *ast.FuncLit:
+		// TODO(dh): support function literals
+		return false
+	case *ast.ChanType:
+		b := b.(*ast.ChanType)
+		return a.Dir == b.Dir && (a.Arrow == token.NoPos && b.Arrow == token.NoPos || a.Arrow != token.NoPos && b.Arrow != token.NoPos)
+	case *ast.FieldList:
+		b := b.(*ast.FieldList)
+		if len(a.List) != len(b.List) {
+			return false
+		}
+		for i, fieldA := range a.List {
+			if !Equal(fieldA, b.List[i]) {
+				return false
+			}
+		}
+		return true
+	case *ast.Field:
+		b := b.(*ast.Field)
+		if len(a.Names) != len(b.Names) {
+			return false
+		}
+		for j, name := range a.Names {
+			if !Equal(name, b.Names[j]) {
+				return false
+			}
+		}
+		if !Equal(a.Type, b.Type) || !Equal(a.Tag, b.Tag) {
+			return false
+		}
+		return true
+	default:
+		panic(fmt.Sprintf("unreachable: %T", a))
+	}
+}
+
+func NegateDeMorgan(expr ast.Expr, recursive bool) ast.Expr {
+	switch expr := expr.(type) {
+	case *ast.BinaryExpr:
+		var out ast.BinaryExpr
+		switch expr.Op {
+		case token.EQL:
+			out.X = expr.X
+			out.Op = token.NEQ
+			out.Y = expr.Y
+		case token.LSS:
+			out.X = expr.X
+			out.Op = token.GEQ
+			out.Y = expr.Y
+		case token.GTR:
+			out.X = expr.X
+			out.Op = token.LEQ
+			out.Y = expr.Y
+		case token.NEQ:
+			out.X = expr.X
+			out.Op = token.EQL
+			out.Y = expr.Y
+		case token.LEQ:
+			out.X = expr.X
+			out.Op = token.GTR
+			out.Y = expr.Y
+		case token.GEQ:
+			out.X = expr.X
+			out.Op = token.LSS
+			out.Y = expr.Y
+
+		case token.LAND:
+			out.X = NegateDeMorgan(expr.X, recursive)
+			out.Op = token.LOR
+			out.Y = NegateDeMorgan(expr.Y, recursive)
+		case token.LOR:
+			out.X = NegateDeMorgan(expr.X, recursive)
+			out.Op = token.LAND
+			out.Y = NegateDeMorgan(expr.Y, recursive)
+		}
+		return &out
+
+	case *ast.ParenExpr:
+		if recursive {
+			return &ast.ParenExpr{
+				X: NegateDeMorgan(expr.X, recursive),
+			}
+		} else {
+			return &ast.UnaryExpr{
+				Op: token.NOT,
+				X:  expr,
+			}
+		}
+
+	case *ast.UnaryExpr:
+		if expr.Op == token.NOT {
+			return expr.X
+		} else {
+			return &ast.UnaryExpr{
+				Op: token.NOT,
+				X:  expr,
+			}
+		}
+
+	default:
+		return &ast.UnaryExpr{
+			Op: token.NOT,
+			X:  expr,
+		}
+	}
+}
+
+func SimplifyParentheses(node ast.Expr) ast.Expr {
+	var changed bool
+	// XXX accept list of ops to operate on
+	// XXX copy AST node, don't modify in place
+	post := func(c *astutil.Cursor) bool {
+		out := c.Node()
+		if paren, ok := c.Node().(*ast.ParenExpr); ok {
+			out = paren.X
+		}
+
+		if binop, ok := out.(*ast.BinaryExpr); ok {
+			if right, ok := binop.Y.(*ast.BinaryExpr); ok && binop.Op == right.Op {
+				// XXX also check that Op is associative
+
+				root := binop
+				pivot := root.Y.(*ast.BinaryExpr)
+				root.Y = pivot.X
+				pivot.X = root
+				root = pivot
+				out = root
+			}
+		}
+
+		if out != c.Node() {
+			changed = true
+			c.Replace(out)
+		}
+		return true
+	}
+
+	for changed = true; changed; {
+		changed = false
+		node = astutil.Apply(node, nil, post).(ast.Expr)
+	}
+
+	return node
+}
diff --git a/vendor/honnef.co/go/tools/go/buildid/UPSTREAM b/vendor/honnef.co/go/tools/go/buildid/UPSTREAM
new file mode 100644
index 0000000..27d414e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/buildid/UPSTREAM
@@ -0,0 +1,5 @@
+This package extracts buildid.go and note.go from cmd/internal/buildid/.
+
+We have modified it to remove support for AIX big archive files, to cut down on our dependencies.
+
+The last upstream commit we've looked at was: d3ddc4854429185e6e06ca1f7628bb790404abb5
diff --git a/vendor/honnef.co/go/tools/go/buildid/buildid.go b/vendor/honnef.co/go/tools/go/buildid/buildid.go
new file mode 100644
index 0000000..27e1c44
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/buildid/buildid.go
@@ -0,0 +1,238 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package buildid
+
+import (
+	"bytes"
+	"debug/elf"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"strconv"
+	"strings"
+)
+
+var errBuildIDMalformed = fmt.Errorf("malformed object file")
+
+var (
+	bangArch = []byte("!")
+	pkgdef   = []byte("__.PKGDEF")
+	goobject = []byte("go object ")
+	buildid  = []byte("build id ")
+)
+
+// ReadFile reads the build ID from an archive or executable file.
+func ReadFile(name string) (id string, err error) {
+	f, err := os.Open(name)
+	if err != nil {
+		return "", err
+	}
+	defer f.Close()
+
+	buf := make([]byte, 8)
+	if _, err := f.ReadAt(buf, 0); err != nil {
+		return "", err
+	}
+	if string(buf) != "!\n" {
+		if string(buf) == "\n" {
+			return "", errors.New("unsupported")
+		}
+		return readBinary(name, f)
+	}
+
+	// Read just enough of the target to fetch the build ID.
+	// The archive is expected to look like:
+	//
+	//	!
+	//	__.PKGDEF       0           0     0     644     7955      `
+	//	go object darwin amd64 devel X:none
+	//	build id "b41e5c45250e25c9fd5e9f9a1de7857ea0d41224"
+	//
+	// The variable-sized strings are GOOS, GOARCH, and the experiment list (X:none).
+	// Reading the first 1024 bytes should be plenty.
+	data := make([]byte, 1024)
+	n, err := io.ReadFull(f, data)
+	if err != nil && n == 0 {
+		return "", err
+	}
+
+	tryGccgo := func() (string, error) {
+		return readGccgoArchive(name, f)
+	}
+
+	// Archive header.
+	for i := 0; ; i++ { // returns during i==3
+		j := bytes.IndexByte(data, '\n')
+		if j < 0 {
+			return tryGccgo()
+		}
+		line := data[:j]
+		data = data[j+1:]
+		switch i {
+		case 0:
+			if !bytes.Equal(line, bangArch) {
+				return tryGccgo()
+			}
+		case 1:
+			if !bytes.HasPrefix(line, pkgdef) {
+				return tryGccgo()
+			}
+		case 2:
+			if !bytes.HasPrefix(line, goobject) {
+				return tryGccgo()
+			}
+		case 3:
+			if !bytes.HasPrefix(line, buildid) {
+				// Found the object header, just doesn't have a build id line.
+				// Treat as successful, with empty build id.
+				return "", nil
+			}
+			id, err := strconv.Unquote(string(line[len(buildid):]))
+			if err != nil {
+				return tryGccgo()
+			}
+			return id, nil
+		}
+	}
+}
+
+// readGccgoArchive tries to parse the archive as a standard Unix
+// archive file, and fetch the build ID from the _buildid.o entry.
+// The _buildid.o entry is written by (*Builder).gccgoBuildIDELFFile
+// in cmd/go/internal/work/exec.go.
+func readGccgoArchive(name string, f *os.File) (string, error) {
+	bad := func() (string, error) {
+		return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed}
+	}
+
+	off := int64(8)
+	for {
+		if _, err := f.Seek(off, io.SeekStart); err != nil {
+			return "", err
+		}
+
+		// TODO(iant): Make a debug/ar package, and use it
+		// here and in cmd/link.
+		var hdr [60]byte
+		if _, err := io.ReadFull(f, hdr[:]); err != nil {
+			if err == io.EOF {
+				// No more entries, no build ID.
+				return "", nil
+			}
+			return "", err
+		}
+		off += 60
+
+		sizeStr := strings.TrimSpace(string(hdr[48:58]))
+		size, err := strconv.ParseInt(sizeStr, 0, 64)
+		if err != nil {
+			return bad()
+		}
+
+		name := strings.TrimSpace(string(hdr[:16]))
+		if name == "_buildid.o/" {
+			sr := io.NewSectionReader(f, off, size)
+			e, err := elf.NewFile(sr)
+			if err != nil {
+				return bad()
+			}
+			s := e.Section(".go.buildid")
+			if s == nil {
+				return bad()
+			}
+			data, err := s.Data()
+			if err != nil {
+				return bad()
+			}
+			return string(data), nil
+		}
+
+		off += size
+		if off&1 != 0 {
+			off++
+		}
+	}
+}
+
+var (
+	goBuildPrefix = []byte("\xff Go build ID: \"")
+	goBuildEnd    = []byte("\"\n \xff")
+
+	elfPrefix = []byte("\x7fELF")
+
+	machoPrefixes = [][]byte{
+		{0xfe, 0xed, 0xfa, 0xce},
+		{0xfe, 0xed, 0xfa, 0xcf},
+		{0xce, 0xfa, 0xed, 0xfe},
+		{0xcf, 0xfa, 0xed, 0xfe},
+	}
+)
+
+var readSize = 32 * 1024 // changed for testing
+
+// readBinary reads the build ID from a binary.
+//
+// ELF binaries store the build ID in a proper PT_NOTE section.
+//
+// Other binary formats are not so flexible. For those, the linker
+// stores the build ID as non-instruction bytes at the very beginning
+// of the text segment, which should appear near the beginning
+// of the file. This is clumsy but fairly portable. Custom locations
+// can be added for other binary types as needed, like we did for ELF.
+func readBinary(name string, f *os.File) (id string, err error) {
+	// Read the first 32 kB of the binary file.
+	// That should be enough to find the build ID.
+	// In ELF files, the build ID is in the leading headers,
+	// which are typically less than 4 kB, not to mention 32 kB.
+	// In Mach-O files, there's no limit, so we have to parse the file.
+	// On other systems, we're trying to read enough that
+	// we get the beginning of the text segment in the read.
+	// The offset where the text segment begins in a hello
+	// world compiled for each different object format today:
+	//
+	//	Plan 9: 0x20
+	//	Windows: 0x600
+	//
+	data := make([]byte, readSize)
+	_, err = io.ReadFull(f, data)
+	if err == io.ErrUnexpectedEOF {
+		err = nil
+	}
+	if err != nil {
+		return "", err
+	}
+
+	if bytes.HasPrefix(data, elfPrefix) {
+		return readELF(name, f, data)
+	}
+	for _, m := range machoPrefixes {
+		if bytes.HasPrefix(data, m) {
+			return readMacho(name, f, data)
+		}
+	}
+	return readRaw(name, data)
+}
+
+// readRaw finds the raw build ID stored in text segment data.
+func readRaw(name string, data []byte) (id string, err error) {
+	i := bytes.Index(data, goBuildPrefix)
+	if i < 0 {
+		// Missing. Treat as successful but build ID empty.
+		return "", nil
+	}
+
+	j := bytes.Index(data[i+len(goBuildPrefix):], goBuildEnd)
+	if j < 0 {
+		return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed}
+	}
+
+	quoted := data[i+len(goBuildPrefix)-1 : i+len(goBuildPrefix)+j+1]
+	id, err = strconv.Unquote(string(quoted))
+	if err != nil {
+		return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed}
+	}
+	return id, nil
+}
diff --git a/vendor/honnef.co/go/tools/go/buildid/note.go b/vendor/honnef.co/go/tools/go/buildid/note.go
new file mode 100644
index 0000000..7971e91
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/buildid/note.go
@@ -0,0 +1,204 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package buildid
+
+import (
+	"bytes"
+	"debug/elf"
+	"debug/macho"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"os"
+)
+
+func readAligned4(r io.Reader, sz int32) ([]byte, error) {
+	full := (sz + 3) &^ 3
+	data := make([]byte, full)
+	_, err := io.ReadFull(r, data)
+	if err != nil {
+		return nil, err
+	}
+	data = data[:sz]
+	return data, nil
+}
+
+func ReadELFNote(filename, name string, typ int32) ([]byte, error) {
+	f, err := elf.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	for _, sect := range f.Sections {
+		if sect.Type != elf.SHT_NOTE {
+			continue
+		}
+		r := sect.Open()
+		for {
+			var namesize, descsize, noteType int32
+			err = binary.Read(r, f.ByteOrder, &namesize)
+			if err != nil {
+				if err == io.EOF {
+					break
+				}
+				return nil, fmt.Errorf("read namesize failed: %v", err)
+			}
+			err = binary.Read(r, f.ByteOrder, &descsize)
+			if err != nil {
+				return nil, fmt.Errorf("read descsize failed: %v", err)
+			}
+			err = binary.Read(r, f.ByteOrder, ¬eType)
+			if err != nil {
+				return nil, fmt.Errorf("read type failed: %v", err)
+			}
+			noteName, err := readAligned4(r, namesize)
+			if err != nil {
+				return nil, fmt.Errorf("read name failed: %v", err)
+			}
+			desc, err := readAligned4(r, descsize)
+			if err != nil {
+				return nil, fmt.Errorf("read desc failed: %v", err)
+			}
+			if name == string(noteName) && typ == noteType {
+				return desc, nil
+			}
+		}
+	}
+	return nil, nil
+}
+
+var elfGoNote = []byte("Go\x00\x00")
+var elfGNUNote = []byte("GNU\x00")
+
+// The Go build ID is stored in a note described by an ELF PT_NOTE prog
+// header. The caller has already opened filename, to get f, and read
+// at least 4 kB out, in data.
+func readELF(name string, f *os.File, data []byte) (buildid string, err error) {
+	// Assume the note content is in the data, already read.
+	// Rewrite the ELF header to set shnum to 0, so that we can pass
+	// the data to elf.NewFile and it will decode the Prog list but not
+	// try to read the section headers and the string table from disk.
+	// That's a waste of I/O when all we care about is the Prog list
+	// and the one ELF note.
+	switch elf.Class(data[elf.EI_CLASS]) {
+	case elf.ELFCLASS32:
+		data[48] = 0
+		data[49] = 0
+	case elf.ELFCLASS64:
+		data[60] = 0
+		data[61] = 0
+	}
+
+	const elfGoBuildIDTag = 4
+	const gnuBuildIDTag = 3
+
+	ef, err := elf.NewFile(bytes.NewReader(data))
+	if err != nil {
+		return "", &os.PathError{Path: name, Op: "parse", Err: err}
+	}
+	var gnu string
+	for _, p := range ef.Progs {
+		if p.Type != elf.PT_NOTE || p.Filesz < 16 {
+			continue
+		}
+
+		var note []byte
+		if p.Off+p.Filesz < uint64(len(data)) {
+			note = data[p.Off : p.Off+p.Filesz]
+		} else {
+			// For some linkers, such as the Solaris linker,
+			// the buildid may not be found in data (which
+			// likely contains the first 16kB of the file)
+			// or even the first few megabytes of the file
+			// due to differences in note segment placement;
+			// in that case, extract the note data manually.
+			_, err = f.Seek(int64(p.Off), io.SeekStart)
+			if err != nil {
+				return "", err
+			}
+
+			note = make([]byte, p.Filesz)
+			_, err = io.ReadFull(f, note)
+			if err != nil {
+				return "", err
+			}
+		}
+
+		filesz := p.Filesz
+		off := p.Off
+		for filesz >= 16 {
+			nameSize := ef.ByteOrder.Uint32(note)
+			valSize := ef.ByteOrder.Uint32(note[4:])
+			tag := ef.ByteOrder.Uint32(note[8:])
+			nname := note[12:16]
+			if nameSize == 4 && 16+valSize <= uint32(len(note)) && tag == elfGoBuildIDTag && bytes.Equal(nname, elfGoNote) {
+				return string(note[16 : 16+valSize]), nil
+			}
+
+			if nameSize == 4 && 16+valSize <= uint32(len(note)) && tag == gnuBuildIDTag && bytes.Equal(nname, elfGNUNote) {
+				gnu = string(note[16 : 16+valSize])
+			}
+
+			nameSize = (nameSize + 3) &^ 3
+			valSize = (valSize + 3) &^ 3
+			notesz := uint64(12 + nameSize + valSize)
+			if filesz <= notesz {
+				break
+			}
+			off += notesz
+			align := p.Align
+			alignedOff := (off + align - 1) &^ (align - 1)
+			notesz += alignedOff - off
+			off = alignedOff
+			filesz -= notesz
+			note = note[notesz:]
+		}
+	}
+
+	// If we didn't find a Go note, use a GNU note if available.
+	// This is what gccgo uses.
+	if gnu != "" {
+		return gnu, nil
+	}
+
+	// No note. Treat as successful but build ID empty.
+	return "", nil
+}
+
+// The Go build ID is stored at the beginning of the Mach-O __text segment.
+// The caller has already opened filename, to get f, and read a few kB out, in data.
+// Sadly, that's not guaranteed to hold the note, because there is an arbitrary amount
+// of other junk placed in the file ahead of the main text.
+func readMacho(name string, f *os.File, data []byte) (buildid string, err error) {
+	// If the data we want has already been read, don't worry about Mach-O parsing.
+	// This is both an optimization and a hedge against the Mach-O parsing failing
+	// in the future due to, for example, the name of the __text section changing.
+	if b, err := readRaw(name, data); b != "" && err == nil {
+		return b, err
+	}
+
+	mf, err := macho.NewFile(f)
+	if err != nil {
+		return "", &os.PathError{Path: name, Op: "parse", Err: err}
+	}
+
+	sect := mf.Section("__text")
+	if sect == nil {
+		// Every binary has a __text section. Something is wrong.
+		return "", &os.PathError{Path: name, Op: "parse", Err: fmt.Errorf("cannot find __text section")}
+	}
+
+	// It should be in the first few bytes, but read a lot just in case,
+	// especially given our past problems on OS X with the build ID moving.
+	// There shouldn't be much difference between reading 4kB and 32kB:
+	// the hard part is getting to the data, not transferring it.
+	n := min(sect.Size, uint64(readSize))
+	buf := make([]byte, n)
+	if _, err := f.ReadAt(buf, int64(sect.Offset)); err != nil {
+		return "", err
+	}
+
+	return readRaw(name, buf)
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/LICENSE b/vendor/honnef.co/go/tools/go/ir/LICENSE
new file mode 100644
index 0000000..aee4804
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+Copyright (c) 2016 Dominik Honnef. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/honnef.co/go/tools/go/ir/block.go b/vendor/honnef.co/go/tools/go/ir/block.go
new file mode 100644
index 0000000..44399c7
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/block.go
@@ -0,0 +1,133 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"fmt"
+	"go/ast"
+)
+
+// This file implements the BasicBlock type.
+
+// addEdge adds a control-flow graph edge from from to to.
+func addEdge(from, to *BasicBlock) {
+	from.Succs = append(from.Succs, to)
+	to.Preds = append(to.Preds, from)
+}
+
+// Control returns the last instruction in the block.
+func (b *BasicBlock) Control() Instruction {
+	if len(b.Instrs) == 0 {
+		return nil
+	}
+	return b.Instrs[len(b.Instrs)-1]
+}
+
+// Parent returns the function that contains block b.
+func (b *BasicBlock) Parent() *Function { return b.parent }
+
+func (b *BasicBlock) Reaches(o *BasicBlock) bool {
+	return b.SCC.reachable.Bit(o.SCC.Index) != 0
+}
+
+// String returns a human-readable label of this block.
+// It is not guaranteed unique within the function.
+func (b *BasicBlock) String() string {
+	return fmt.Sprintf("%d", b.Index)
+}
+
+// emit appends an instruction to the current basic block.
+// If the instruction defines a Value, it is returned.
+func (b *BasicBlock) emit(i Instruction, source ast.Node) Value {
+	i.setSource(source)
+	i.setBlock(b)
+	b.Instrs = append(b.Instrs, i)
+	v, _ := i.(Value)
+	return v
+}
+
+// predIndex returns the i such that b.Preds[i] == c or panics if
+// there is none.
+func (b *BasicBlock) predIndex(c *BasicBlock) int {
+	for i, pred := range b.Preds {
+		if pred == c {
+			return i
+		}
+	}
+	panic(fmt.Sprintf("no edge %s -> %s", c, b))
+}
+
+// hasPhi returns true if b.Instrs contains φ-nodes.
+func (b *BasicBlock) hasPhi() bool {
+	_, ok := b.Instrs[0].(*Phi)
+	return ok
+}
+
+func (b *BasicBlock) Phis() []Instruction {
+	return b.phis()
+}
+
+// phis returns the prefix of b.Instrs containing all the block's φ-nodes.
+func (b *BasicBlock) phis() []Instruction {
+	for i, instr := range b.Instrs {
+		if _, ok := instr.(*Phi); !ok {
+			return b.Instrs[:i]
+		}
+	}
+	return nil // unreachable in well-formed blocks
+}
+
+// replacePred replaces all occurrences of p in b's predecessor list with q.
+// Ordinarily there should be at most one.
+func (b *BasicBlock) replacePred(p, q *BasicBlock) {
+	for i, pred := range b.Preds {
+		if pred == p {
+			b.Preds[i] = q
+		}
+	}
+}
+
+// replaceSucc replaces all occurrences of p in b's successor list with q.
+// Ordinarily there should be at most one.
+func (b *BasicBlock) replaceSucc(p, q *BasicBlock) {
+	for i, succ := range b.Succs {
+		if succ == p {
+			b.Succs[i] = q
+		}
+	}
+}
+
+// removePred removes all occurrences of p in b's
+// predecessor list and φ-nodes.
+// Ordinarily there should be at most one.
+func (b *BasicBlock) removePred(p *BasicBlock) {
+	phis := b.phis()
+
+	// We must preserve edge order for φ-nodes.
+	j := 0
+	for i, pred := range b.Preds {
+		if pred != p {
+			b.Preds[j] = b.Preds[i]
+			// Strike out φ-edge too.
+			for _, instr := range phis {
+				phi := instr.(*Phi)
+				phi.Edges[j] = phi.Edges[i]
+			}
+			j++
+		}
+	}
+	// Nil out b.Preds[j:] and φ-edges[j:] to aid GC.
+	for i := j; i < len(b.Preds); i++ {
+		b.Preds[i] = nil
+		for _, instr := range phis {
+			instr.(*Phi).Edges[i] = nil
+		}
+	}
+	b.Preds = b.Preds[:j]
+	for _, instr := range phis {
+		phi := instr.(*Phi)
+		phi.Edges = phi.Edges[:j]
+	}
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/blockopt.go b/vendor/honnef.co/go/tools/go/ir/blockopt.go
new file mode 100644
index 0000000..de6ac9a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/blockopt.go
@@ -0,0 +1,194 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// Simple block optimizations to simplify the control flow graph.
+
+// TODO(adonovan): opt: instead of creating several "unreachable" blocks
+// per function in the Builder, reuse a single one (e.g. at Blocks[1])
+// to reduce garbage.
+
+import (
+	"fmt"
+	"os"
+)
+
+// If true, perform sanity checking and show progress at each
+// successive iteration of optimizeBlocks.  Very verbose.
+const debugBlockOpt = false
+
+// markReachable sets Index=-1 for all blocks reachable from b.
+func markReachable(b *BasicBlock) {
+	b.gaps = -1
+	for _, succ := range b.Succs {
+		if succ.gaps == 0 {
+			markReachable(succ)
+		}
+	}
+}
+
+// deleteUnreachableBlocks marks all reachable blocks of f and
+// eliminates (nils) all others, including possibly cyclic subgraphs.
+func deleteUnreachableBlocks(f *Function) {
+	const white, black = 0, -1
+	// We borrow b.gaps temporarily as the mark bit.
+	for _, b := range f.Blocks {
+		b.gaps = white
+	}
+	markReachable(f.Blocks[0])
+	if f.Recover != nil {
+		markReachable(f.Recover)
+	}
+	for i, b := range f.Blocks {
+		if b.gaps == white {
+			for _, c := range b.Succs {
+				if c.gaps == black {
+					c.removePred(b) // delete white->black edge
+				}
+			}
+			if debugBlockOpt {
+				fmt.Fprintln(os.Stderr, "unreachable", b)
+			}
+			f.Blocks[i] = nil // delete b
+		}
+	}
+	f.removeNilBlocks()
+}
+
+// jumpThreading attempts to apply simple jump-threading to block b,
+// in which a->b->c become a->c if b is just a Jump.
+// The result is true if the optimization was applied.
+func jumpThreading(f *Function, b *BasicBlock) bool {
+	if b.Index == 0 {
+		return false // don't apply to entry block
+	}
+	if len(b.Instrs) == 0 {
+		return false
+	}
+	for _, pred := range b.Preds {
+		switch pred.Control().(type) {
+		case *ConstantSwitch:
+			// don't optimize away the head blocks of switch statements
+			return false
+		}
+	}
+	if _, ok := b.Instrs[0].(*Jump); !ok {
+		return false // not just a jump
+	}
+	c := b.Succs[0]
+	if c == b {
+		return false // don't apply to degenerate jump-to-self.
+	}
+	if c.hasPhi() {
+		return false // not sound without more effort
+	}
+	for j, a := range b.Preds {
+		a.replaceSucc(b, c)
+
+		// If a now has two edges to c, replace its degenerate If by Jump.
+		if len(a.Succs) == 2 && a.Succs[0] == c && a.Succs[1] == c {
+			jump := new(Jump)
+			jump.setBlock(a)
+			a.Instrs[len(a.Instrs)-1] = jump
+			a.Succs = a.Succs[:1]
+			c.removePred(b)
+		} else {
+			if j == 0 {
+				c.replacePred(b, a)
+			} else {
+				c.Preds = append(c.Preds, a)
+			}
+		}
+
+		if debugBlockOpt {
+			fmt.Fprintln(os.Stderr, "jumpThreading", a, b, c)
+		}
+	}
+	f.Blocks[b.Index] = nil // delete b
+	return true
+}
+
+// fuseBlocks attempts to apply the block fusion optimization to block
+// a, in which a->b becomes ab if len(a.Succs)==len(b.Preds)==1.
+// The result is true if the optimization was applied.
+func fuseBlocks(f *Function, a *BasicBlock) bool {
+	if len(a.Succs) != 1 {
+		return false
+	}
+	b := a.Succs[0]
+	if len(b.Preds) != 1 {
+		return false
+	}
+	if _, ok := a.Instrs[len(a.Instrs)-1].(*Panic); ok {
+		// panics aren't simple jumps, they have side effects.
+		return false
+	}
+
+	// Degenerate &&/|| ops may result in a straight-line CFG
+	// containing φ-nodes. (Ideally we'd replace such them with
+	// their sole operand but that requires Referrers, built later.)
+	if b.hasPhi() {
+		return false // not sound without further effort
+	}
+
+	// Eliminate jump at end of A, then copy all of B across.
+	a.Instrs = append(a.Instrs[:len(a.Instrs)-1], b.Instrs...)
+	for _, instr := range b.Instrs {
+		instr.setBlock(a)
+	}
+
+	// A inherits B's successors
+	a.Succs = append(a.succs2[:0], b.Succs...)
+
+	// Fix up Preds links of all successors of B.
+	for _, c := range b.Succs {
+		c.replacePred(b, a)
+	}
+
+	if debugBlockOpt {
+		fmt.Fprintln(os.Stderr, "fuseBlocks", a, b)
+	}
+
+	f.Blocks[b.Index] = nil // delete b
+	return true
+}
+
+// optimizeBlocks() performs some simple block optimizations on a
+// completed function: dead block elimination, block fusion, jump
+// threading.
+func optimizeBlocks(f *Function) {
+	deleteUnreachableBlocks(f)
+
+	// Loop until no further progress.
+	changed := true
+	for changed {
+		changed = false
+
+		if debugBlockOpt {
+			f.WriteTo(os.Stderr)
+			mustSanityCheck(f, nil)
+		}
+
+		for _, b := range f.Blocks {
+			// f.Blocks will temporarily contain nils to indicate
+			// deleted blocks; we remove them at the end.
+			if b == nil {
+				continue
+			}
+
+			// Fuse blocks.  b->c becomes bc.
+			if fuseBlocks(f, b) {
+				changed = true
+			}
+
+			// a->b->c becomes a->c if b contains only a Jump.
+			if jumpThreading(f, b) {
+				changed = true
+				continue // (b was disconnected)
+			}
+		}
+	}
+	f.removeNilBlocks()
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/builder.go b/vendor/honnef.co/go/tools/go/ir/builder.go
new file mode 100644
index 0000000..46edb70
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/builder.go
@@ -0,0 +1,3634 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file defines the builder, which builds SSA-form IR for function bodies.
+//
+// SSA construction has two phases, "create" and "build". First, one
+// or more packages are created in any order by a sequence of calls to
+// CreatePackage, either from syntax or from mere type information.
+// Each created package has a complete set of Members (const, var,
+// type, func) that can be accessed through methods like
+// Program.FuncValue.
+//
+// It is not necessary to call CreatePackage for all dependencies of
+// each syntax package, only for its direct imports. (In future
+// perhaps even this restriction may be lifted.)
+//
+// Second, packages created from syntax are built, by one or more
+// calls to Package.Build, which may be concurrent; or by a call to
+// Program.Build, which builds all packages in parallel. Building
+// traverses the type-annotated syntax tree of each function body and
+// creates SSA-form IR, a control-flow graph of instructions,
+// populating fields such as Function.Body, .Params, and others.
+//
+// Building may create additional methods, including:
+// - wrapper methods (e.g. for embedding, or implicit &recv)
+// - bound method closures (e.g. for use(recv.f))
+// - thunks (e.g. for use(I.f) or use(T.f))
+// - generic instances (e.g. to produce f[int] from f[any]).
+// As these methods are created, they are added to the build queue,
+// and then processed in turn, until a fixed point is reached,
+// Since these methods might belong to packages that were not
+// created (by a call to CreatePackage), their Pkg field is unset.
+//
+// Instances of generic functions may be either instantiated (f[int]
+// is a copy of f[T] with substitutions) or wrapped (f[int] delegates
+// to f[T]), depending on the availability of generic syntax and the
+// InstantiateGenerics mode flag.
+//
+// Each package has an initializer function named "init" that calls
+// the initializer functions of each direct import, computes and
+// assigns the initial value of each global variable, and calls each
+// source-level function named "init". (These generate SSA functions
+// named "init#1", "init#2", etc.)
+//
+// Runtime types
+//
+// Each MakeInterface operation is a conversion from a non-interface
+// type to an interface type. The semantics of this operation requires
+// a runtime type descriptor, which is the type portion of an
+// interface, and the value abstracted by reflect.Type.
+//
+// The program accumulates all non-parameterized types that are
+// encountered as MakeInterface operands, along with all types that
+// may be derived from them using reflection. This set is available as
+// Program.RuntimeTypes, and the methods of these types may be
+// reachable via interface calls or reflection even if they are never
+// referenced from the SSA IR. (In practice, algorithms such as RTA
+// that compute reachability from package main perform their own
+// tracking of runtime types at a finer grain, so this feature is not
+// very useful.)
+//
+// Function literals
+//
+// Anonymous functions must be built as soon as they are encountered,
+// as it may affect locals of the enclosing function, but they are not
+// marked 'built' until the end of the outermost enclosing function.
+// (Among other things, this causes them to be logged in top-down order.)
+//
+// The Function.build fields determines the algorithm for building the
+// function body. It is cleared to mark that building is complete.
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"os"
+	"runtime"
+	"slices"
+	"sync"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/xtools-internal/versions"
+
+	"golang.org/x/exp/typeparams"
+)
+
+var (
+	varOk    = newVar("ok", tBool)
+	varIndex = newVar("index", tInt)
+
+	// Type constants.
+	tBool       = types.Typ[types.Bool]
+	tByte       = types.Typ[types.Byte]
+	tRune       = types.Universe.Lookup("rune").Type() // prints as "rune" (Typ[Rune] is same as Int32)
+	tInt        = types.Typ[types.Int]
+	tInvalid    = types.Typ[types.Invalid]
+	tString     = types.Typ[types.String]
+	tUntypedNil = types.Typ[types.UntypedNil]
+	tEface      = types.NewInterfaceType(nil, nil).Complete()
+	tDeferStack = types.NewPointer(typeutil.NewDeferStack())
+
+	vOne      = intConst(1, nil)
+	vTrue     = NewConst(constant.MakeBool(true), tBool, nil)
+	vNoReturn = NewConst(constant.MakeString("noreturn"), tString, nil)
+
+	jReady        = intConst(0, nil)  // range-over-func jump is READY
+	jBusy         = intConst(-1, nil) // range-over-func jump is BUSY
+	jDone         = intConst(-2, nil) // range-over-func jump is DONE
+	jDroppedPanic = stringConst("iterator call did not preserve panic", nil)
+	jLateYield    = stringConst("yield function called after range loop exit", nil)
+
+	vDeferStack = &Builtin{
+		name: "ssa:deferstack",
+		sig:  types.NewSignatureType(nil, nil, nil, nil, types.NewTuple(anonVar(tDeferStack)), false),
+	}
+)
+
+// builder holds state associated with the package currently being built.
+// Its methods contain all the logic for AST-to-IR conversion.
+//
+// All Functions belong to the same Program.
+//
+// builders are not thread-safe.
+type builder struct {
+	fns []*Function // Functions that have finished their CREATE phases.
+
+	finished int // finished is the length of the prefix of fns containing built functions.
+
+	// The task of building shared functions within the builder.
+	// Shared functions are ones the builder may either create or lookup.
+	// These may be built by other builders in parallel.
+	// The task is done when the builder has finished iterating, and it
+	// waits for all shared functions to finish building.
+	// nil implies there are no hared functions to wait on.
+	buildshared *task
+}
+
+// shared is done when the builder has built all of the
+// enqueued functions to a fixed-point.
+func (b *builder) shared() *task {
+	if b.buildshared == nil { // lazily-initialize
+		b.buildshared = &task{done: make(chan unit)}
+	}
+	return b.buildshared
+}
+
+// enqueue fn to be built by the builder.
+func (b *builder) enqueue(fn *Function) {
+	b.fns = append(b.fns, fn)
+}
+
+// waitForSharedFunction indicates that the builder should wait until
+// the potentially shared function fn has finished building.
+//
+// This should include any functions that may be built by other
+// builders.
+func (b *builder) waitForSharedFunction(fn *Function) {
+	// Check whether fn is already built before calling b.shared(),
+	// which allocates a task and a channel that b.iterate() would
+	// then have to close and wait on. The common case, a lookup of
+	// a method that was created and built long ago, needs neither.
+	if t := fn.buildshared; t != nil && !t.isTransitivelyDone() { // maybe need to wait?
+		b.shared().addEdge(t)
+	}
+}
+
+// cond emits to fn code to evaluate boolean condition e and jump
+// to t or f depending on its value, performing various simplifications.
+//
+// Postcondition: fn.currentBlock is nil.
+func (b *builder) cond(fn *Function, e ast.Expr, t, f *BasicBlock) *If {
+	switch e := e.(type) {
+	case *ast.ParenExpr:
+		return b.cond(fn, e.X, t, f)
+
+	case *ast.BinaryExpr:
+		switch e.Op {
+		case token.LAND:
+			ltrue := fn.newBasicBlock("cond.true")
+			b.cond(fn, e.X, ltrue, f)
+			fn.currentBlock = ltrue
+			return b.cond(fn, e.Y, t, f)
+
+		case token.LOR:
+			lfalse := fn.newBasicBlock("cond.false")
+			b.cond(fn, e.X, t, lfalse)
+			fn.currentBlock = lfalse
+			return b.cond(fn, e.Y, t, f)
+		}
+
+	case *ast.UnaryExpr:
+		if e.Op == token.NOT {
+			return b.cond(fn, e.X, f, t)
+		}
+	}
+
+	// A traditional compiler would simplify "if false" (etc) here
+	// but we do not, for better fidelity to the source code.
+	//
+	// The value of a constant condition may be platform-specific,
+	// and may cause blocks that are reachable in some configuration
+	// to be hidden from subsequent analyses such as bug-finding tools.
+	return emitIf(fn, b.expr(fn, e), t, f, e)
+}
+
+// logicalBinop emits code to fn to evaluate e, a &&- or
+// ||-expression whose reified boolean value is wanted.
+// The value is returned.
+func (b *builder) logicalBinop(fn *Function, e *ast.BinaryExpr) Value {
+	rhs := fn.newBasicBlock("binop.rhs")
+	done := fn.newBasicBlock("binop.done")
+
+	// T(e) = T(e.X) = T(e.Y) after untyped constants have been
+	// eliminated.
+	// TODO(adonovan): not true; MyBool==MyBool yields UntypedBool.
+	t := fn.typeOf(e)
+
+	var short Value // value of the short-circuit path
+	switch e.Op {
+	case token.LAND:
+		b.cond(fn, e.X, rhs, done)
+		short = NewConst(constant.MakeBool(false), t, e)
+
+	case token.LOR:
+		b.cond(fn, e.X, done, rhs)
+		short = NewConst(constant.MakeBool(true), t, e)
+	}
+
+	// Is rhs unreachable?
+	if rhs.Preds == nil {
+		// Simplify false&&y to false, true||y to true.
+		fn.currentBlock = done
+		return short
+	}
+
+	// Is done unreachable?
+	if done.Preds == nil {
+		// Simplify true&&y (or false||y) to y.
+		fn.currentBlock = rhs
+		return b.expr(fn, e.Y)
+	}
+
+	// All edges from e.X to done carry the short-circuit value.
+	var edges []Value
+	for range done.Preds {
+		edges = append(edges, short)
+	}
+
+	// The edge from e.Y to done carries the value of e.Y.
+	fn.currentBlock = rhs
+	edges = append(edges, b.expr(fn, e.Y))
+	emitJump(fn, done, e)
+	fn.currentBlock = done
+
+	phi := &Phi{Edges: edges}
+	phi.typ = t
+	phi.comment = e.Op.String()
+	return done.emit(phi, e)
+}
+
+// exprN lowers a multi-result expression e to IR form, emitting code
+// to fn and returning a single Value whose type is a *types.Tuple.
+// The caller must access the components via Extract.
+//
+// Multi-result expressions include CallExprs in a multi-value
+// assignment or return statement, and "value,ok" uses of
+// TypeAssertExpr, IndexExpr (when X is a map), and Recv.
+func (b *builder) exprN(fn *Function, e ast.Expr) Value {
+	typ := fn.typeOf(e).(*types.Tuple)
+	switch e := e.(type) {
+	case *ast.ParenExpr:
+		return b.exprN(fn, e.X)
+
+	case *ast.CallExpr:
+		// Currently, no built-in function nor type conversion
+		// has multiple results, so we can avoid some of the
+		// cases for single-valued CallExpr.
+		var c Call
+		b.setCall(fn, e, &c.Call)
+		c.typ = typ
+		return emitCall(fn, &c, e)
+
+	case *ast.IndexExpr:
+		mapt := typeutil.CoreType(fn.typeOf(e.X)).(*types.Map) // ,ok must be a map.
+		lookup := &MapLookup{
+			X:       b.expr(fn, e.X),
+			Index:   emitConv(fn, b.expr(fn, e.Index), mapt.Key(), e),
+			CommaOk: true,
+		}
+		lookup.setType(typ)
+		return fn.emit(lookup, e)
+
+	case *ast.TypeAssertExpr:
+		return emitTypeTest(fn, b.expr(fn, e.X), typ.At(0).Type(), e)
+
+	case *ast.UnaryExpr: // must be receive <-
+		return emitRecv(fn, b.expr(fn, e.X), true, typ, e)
+	}
+	panic(fmt.Sprintf("exprN(%T) in %s", e, fn))
+}
+
+// builtin emits to fn IR instructions to implement a call to the
+// built-in function obj with the specified arguments
+// and return type.  It returns the value defined by the result.
+//
+// The result is nil if no special handling was required; in this case
+// the caller should treat this like an ordinary library function
+// call.
+func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ types.Type, source ast.Node) Value {
+	typ = fn.typ(typ)
+	switch obj.Name() {
+	case "make":
+		switch ct := typeutil.CoreType(typ).(type) {
+		case *types.Slice:
+			n := b.expr(fn, args[1])
+			m := n
+			if len(args) == 3 {
+				m = b.expr(fn, args[2])
+			}
+			if m, ok := m.(*Const); ok {
+				// treat make([]T, n, m) as new([m]T)[:n]
+				cap := m.Int64()
+				at := types.NewArray(ct.Elem(), cap)
+				v := &Slice{
+					X:    emitNew(fn, at, source, "makeslice"),
+					High: n,
+				}
+				v.setType(typ)
+				return fn.emit(v, source)
+			}
+			v := &MakeSlice{
+				Len: n,
+				Cap: m,
+			}
+			v.setType(typ)
+			return fn.emit(v, source)
+
+		case *types.Map:
+			var res Value
+			if len(args) == 2 {
+				res = b.expr(fn, args[1])
+			}
+			v := &MakeMap{Reserve: res}
+			v.setType(typ)
+			return fn.emit(v, source)
+
+		case *types.Chan:
+			var sz Value = intConst(0, source)
+			if len(args) == 2 {
+				sz = b.expr(fn, args[1])
+			}
+			v := &MakeChan{Size: sz}
+			v.setType(typ)
+			return fn.emit(v, source)
+
+		default:
+			lint.ExhaustiveTypeSwitch(typ.Underlying())
+		}
+
+	case "new":
+		alloc := emitNew(fn, deref(typ), source, "new")
+		if !fn.info.Types[args[0]].IsType() {
+			// new(expr), requires go1.26
+			v := b.expr(fn, args[0])
+			emitStore(fn, alloc, v, source)
+		}
+		return alloc
+
+	case "len", "cap":
+		// Special case: len or cap of an array or *array is based on the type, not the value which may be nil. We must
+		// still evaluate the value, though. (If it was side-effect free, the whole call would have been
+		// constant-folded.)
+		//
+		// For example, for len(gen()), we need to evaluate gen() for its side-effects, but don't need the returned
+		// value to determine the length of the array, which is constant.
+		//
+		// Technically this shouldn't apply to type parameters because their length/capacity is never constant. We still
+		// choose to treat them as constant so that users of the IR get the practically constant length for free.
+		t := typeutil.CoreType(deref(fn.typeOf(args[0])))
+		if at, ok := t.(*types.Array); ok {
+			b.expr(fn, args[0]) // for effects only
+			return intConst(at.Len(), args[0])
+		}
+		// Otherwise treat as normal.
+
+	case "panic":
+		fn.emit(&Panic{
+			X: emitConv(fn, b.expr(fn, args[0]), tEface, source),
+		}, source)
+		fn.currentBlock = fn.newBasicBlock("unreachable")
+		return vTrue // any non-nil Value will do
+	}
+	return nil // treat all others as a regular function call
+}
+
+// addr lowers a single-result addressable expression e to IR form,
+// emitting code to fn and returning the location (an lvalue) defined
+// by the expression.
+//
+// If escaping is true, addr marks the base variable of the
+// addressable expression e as being a potentially escaping pointer
+// value.  For example, in this code:
+//
+//	a := A{
+//	  b: [1]B{B{c: 1}}
+//	}
+//	return &a.b[0].c
+//
+// the application of & causes a.b[0].c to have its address taken,
+// which means that ultimately the local variable a must be
+// heap-allocated.  This is a simple but very conservative escape
+// analysis.
+//
+// Operations forming potentially escaping pointers include:
+// - &x, including when implicit in method call or composite literals.
+// - a[:] iff a is an array (not *array)
+// - references to variables in lexically enclosing functions.
+func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue {
+	switch e := e.(type) {
+	case *ast.Ident:
+		if isBlankIdent(e) {
+			return blank{}
+		}
+		obj := fn.objectOf(e).(*types.Var)
+		var v Value
+		if g := fn.Prog.packageLevelMember(obj); g != nil {
+			v = g.(*Global) // var (address)
+		} else {
+			v = fn.lookup(obj, escaping)
+		}
+		return &address{addr: v, expr: e}
+
+	case *ast.CompositeLit:
+		t := deref(fn.typeOf(e))
+		var v *Alloc
+		if escaping {
+			v = emitNew(fn, t, e, "complit")
+		} else {
+			v = emitLocal(fn, t, e, "complit")
+		}
+		var sb storebuf
+		b.compLit(fn, v, e, true, &sb)
+		sb.emit(fn)
+		return &address{addr: v, expr: e}
+
+	case *ast.ParenExpr:
+		return b.addr(fn, e.X, escaping)
+
+	case *ast.SelectorExpr:
+		sel := fn.selection(e)
+		if sel == nil {
+			// qualified identifier
+			return b.addr(fn, e.Sel, escaping)
+		}
+		if sel.kind != types.FieldVal {
+			panic(sel)
+		}
+		wantAddr := true
+		v := b.receiver(fn, e.X, wantAddr, escaping, sel, e)
+		index := sel.index[len(sel.index)-1]
+		fld := fieldOf(deref(v.Type()), index) // v is an addr.
+
+		// Due to the two phases of resolving AssignStmt, a panic from x.f = p()
+		// when x is nil is required to come after the side-effects of
+		// evaluating x and p().
+		emit := func(fn *Function) Value {
+			return emitFieldSelection(fn, v, index, true, e.Sel)
+		}
+		return &lazyAddress{addr: emit, t: fld.Type(), expr: e.Sel}
+
+	case *ast.IndexExpr:
+		xt := fn.typeOf(e.X)
+		elem, mode := indexType(xt)
+		var x Value
+		var et types.Type
+		switch mode {
+		case ixArrVar: // array, array|slice, array|*array, or array|*array|slice.
+			x = b.addr(fn, e.X, escaping).address(fn)
+			et = types.NewPointer(elem)
+		case ixVar: // *array, slice, *array|slice
+			x = b.expr(fn, e.X)
+			et = types.NewPointer(elem)
+		case ixMap:
+			mt := typeutil.CoreType(xt).(*types.Map)
+			return &element{
+				m: b.expr(fn, e.X),
+				k: emitConv(fn, b.expr(fn, e.Index), mt.Key(), e.Index),
+				t: mt.Elem(),
+			}
+		default:
+			panic("unexpected container type in IndexExpr: " + xt.String())
+		}
+		index := b.expr(fn, e.Index)
+		if isUntyped(index.Type()) {
+			index = emitConv(fn, index, tInt, e.Index)
+		}
+
+		// Due to the two phases of resolving AssignStmt, a panic from x[i] = p()
+		// when x is nil or i is out-of-bounds is required to come after the
+		// side-effects of evaluating x, i and p().
+		emit := func(fn *Function) Value {
+			v := &IndexAddr{
+				X:     x,
+				Index: index,
+			}
+			v.setType(et)
+			return fn.emit(v, e)
+		}
+		return &lazyAddress{addr: emit, t: deref(et), expr: e}
+
+	case *ast.StarExpr:
+		return &address{addr: b.expr(fn, e.X), expr: e}
+	}
+
+	panic(fmt.Sprintf("unexpected address expression: %T", e))
+}
+
+type store struct {
+	lhs    lvalue
+	rhs    Value
+	source ast.Node
+
+	// if debugRef is set no other fields will be set
+	debugRef *debugRef
+}
+
+type storebuf struct{ stores []store }
+
+func (sb *storebuf) store(lhs lvalue, rhs Value, source ast.Node) {
+	sb.stores = append(sb.stores, store{lhs, rhs, source, nil})
+}
+
+func (sb *storebuf) storeDebugRef(ref *debugRef) {
+	sb.stores = append(sb.stores, store{debugRef: ref})
+}
+
+func (sb *storebuf) emit(fn *Function) {
+	for _, s := range sb.stores {
+		if s.debugRef == nil {
+			s.lhs.store(fn, s.rhs, s.source)
+		} else {
+			fn.emit(s.debugRef, nil)
+		}
+	}
+}
+
+// assign emits to fn code to initialize the lvalue loc with the value
+// of expression e.  If isZero is true, assign assumes that loc holds
+// the zero value for its type.
+//
+// This is equivalent to loc.store(fn, b.expr(fn, e)), but may generate
+// better code in some cases, e.g., for composite literals in an
+// addressable location.
+//
+// If sb is not nil, assign generates code to evaluate expression e, but
+// not to update loc.  Instead, the necessary stores are appended to the
+// storebuf sb so that they can be executed later.  This allows correct
+// in-place update of existing variables when the RHS is a composite
+// literal that may reference parts of the LHS.
+func (b *builder) assign(fn *Function, loc lvalue, e ast.Expr, isZero bool, sb *storebuf, source ast.Node) {
+	// Can we initialize it in place?
+	if e, ok := ast.Unparen(e).(*ast.CompositeLit); ok {
+		// A CompositeLit never evaluates to a pointer,
+		// so if the type of the location is a pointer,
+		// an &-operation is implied.
+		if _, ok := loc.(blank); !ok { // avoid calling blank.typ()
+			if isPointerCore(loc.typ()) {
+				// Example input that hits this code:
+				//
+				// 	type S1 struct{ X int }
+				// 	x := []*S1{
+				// 		{1}, // <-- & is implied
+				// 	}
+				// 	_ = x
+				ptr := b.addr(fn, e, true).address(fn)
+				// copy address
+				if sb != nil {
+					sb.store(loc, ptr, source)
+				} else {
+					loc.store(fn, ptr, source)
+				}
+				return
+			}
+		}
+
+		if _, ok := loc.(*address); ok {
+			if types.IsInterface(loc.typ()) && !typeparams.IsTypeParam(loc.typ()) {
+				// e.g. var x interface{} = T{...}
+				// Can't in-place initialize an interface value.
+				// Fall back to copying.
+			} else {
+				// x = T{...} or x := T{...}
+				addr := loc.address(fn)
+				if sb != nil {
+					b.compLit(fn, addr, e, isZero, sb)
+				} else {
+					var sb storebuf
+					b.compLit(fn, addr, e, isZero, &sb)
+					sb.emit(fn)
+				}
+
+				// Subtle: emit debug ref for aggregate types only;
+				// slice and map are handled by store ops in compLit.
+				switch typeutil.CoreType(loc.typ()).(type) {
+				case *types.Struct, *types.Array:
+					if sb != nil {
+						// Make sure we don't emit DebugRefs before the store has actually occurred
+						if ref := makeDebugRef(fn, e, addr, true); ref != nil {
+							sb.storeDebugRef(ref)
+						}
+					} else {
+						emitDebugRef(fn, e, addr, true)
+					}
+				}
+
+				return
+			}
+		}
+	}
+
+	// simple case: just copy
+	rhs := b.expr(fn, e)
+	if sb != nil {
+		sb.store(loc, rhs, source)
+	} else {
+		loc.store(fn, rhs, source)
+	}
+}
+
+// expr lowers a single-result expression e to IR form, emitting code
+// to fn and returning the Value defined by the expression.
+func (b *builder) expr(fn *Function, e ast.Expr) Value {
+	e = ast.Unparen(e)
+
+	tv := fn.info.Types[e]
+
+	// Is expression a constant?
+	if tv.Value != nil {
+		return NewConst(tv.Value, fn.typ(tv.Type), e)
+	}
+
+	var v Value
+	if tv.Addressable() {
+		// Prefer pointer arithmetic ({Index,Field}Addr) followed
+		// by Load over subelement extraction (e.g. Index, Field),
+		// to avoid large copies.
+		v = b.addr(fn, e, false).load(fn, e)
+	} else {
+		v = b.expr0(fn, e, tv)
+	}
+	if fn.debugInfo() {
+		emitDebugRef(fn, e, v, false)
+	}
+	return v
+}
+
+func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value {
+	switch e := e.(type) {
+	case *ast.BasicLit:
+		panic("non-constant BasicLit") // unreachable
+
+	case *ast.FuncLit:
+		/* function literal */
+		fn2 := &Function{
+			name:           fmt.Sprintf("%s$%d", fn.Name(), 1+len(fn.AnonFuncs)),
+			Signature:      fn.typeOf(e.Type).(*types.Signature),
+			pos:            e.Type.Func,
+			parent:         fn,
+			anonIdx:        int32(len(fn.AnonFuncs)),
+			Pkg:            fn.Pkg,
+			Prog:           fn.Prog,
+			syntax:         e,
+			info:           fn.info,
+			goversion:      fn.goversion,
+			build:          (*builder).buildFromSyntax,
+			topLevelOrigin: nil,               // use anonIdx to lookup an anon instance's origin.
+			recvtypeparams: fn.recvtypeparams, // share the parent's receiver type parameters.
+			recvtypeargs:   fn.recvtypeargs,   // share the parent's receiver type arguments.
+			typeparams:     fn.typeparams,     // share the parent's type parameters.
+			typeargs:       fn.typeargs,       // share the parent's type arguments.
+			subst:          fn.subst,          // share the parent's type substitutions.
+		}
+		fn2.uniq = fn.uniq // start from parent's unique values
+		fn.AnonFuncs = append(fn.AnonFuncs, fn2)
+		// Build anon immediately, as it may cause fn's locals to escape.
+		// (It is not marked 'built' until the end of the enclosing FuncDecl.)
+		fn2.build(b, fn2)
+		fn.uniq = fn2.uniq // resume after anon's unique values
+		if fn2.FreeVars == nil {
+			return fn2
+		}
+		v := &MakeClosure{Fn: fn2}
+		v.setType(fn.typ(tv.Type))
+		for _, fv := range fn2.FreeVars {
+			v.Bindings = append(v.Bindings, fv.outer)
+			fv.outer = nil
+		}
+		return fn.emit(v, e)
+
+	case *ast.TypeAssertExpr: // single-result form only
+		return emitTypeAssert(fn, b.expr(fn, e.X), fn.typ(tv.Type), e)
+
+	case *ast.CallExpr:
+		if fn.info.Types[e.Fun].IsType() {
+			// Explicit type conversion, e.g. string(x) or big.Int(x)
+			x := b.expr(fn, e.Args[0])
+			y := emitConv(fn, x, fn.typ(tv.Type), e)
+			return y
+		}
+		// Call to "intrinsic" built-ins, e.g. new, make, panic.
+		if id, ok := ast.Unparen(e.Fun).(*ast.Ident); ok {
+			if obj, ok := fn.info.Uses[id].(*types.Builtin); ok {
+				if v := b.builtin(fn, obj, e.Args, fn.typ(tv.Type), e); v != nil {
+					return v
+				}
+			}
+		}
+		// Regular function call.
+		var v Call
+		b.setCall(fn, e, &v.Call)
+		v.setType(fn.typ(tv.Type))
+		return emitCall(fn, &v, e)
+
+	case *ast.UnaryExpr:
+		switch e.Op {
+		case token.AND: // &X --- potentially escaping.
+			addr := b.addr(fn, e.X, true)
+			if _, ok := ast.Unparen(e.X).(*ast.StarExpr); ok {
+				// &*p must panic if p is nil (https://golang.org/s/go12nil).
+				// For simplicity, we'll just (suboptimally) rely
+				// on the side effects of a load.
+				// TODO(adonovan): emit dedicated nilcheck.
+				addr.load(fn, e)
+			}
+			return addr.address(fn)
+		case token.ADD:
+			return b.expr(fn, e.X)
+		case token.NOT, token.SUB, token.XOR: // ! <- - ^
+			v := &UnOp{
+				Op: e.Op,
+				X:  b.expr(fn, e.X),
+			}
+			v.setType(fn.typ(tv.Type))
+			return fn.emit(v, e)
+		case token.ARROW:
+			return emitRecv(fn, b.expr(fn, e.X), false, fn.typ(tv.Type), e)
+		default:
+			panic(e.Op)
+		}
+
+	case *ast.BinaryExpr:
+		switch e.Op {
+		case token.LAND, token.LOR:
+			return b.logicalBinop(fn, e)
+		case token.SHL, token.SHR:
+			fallthrough
+		case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT:
+			return emitArith(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), fn.typ(tv.Type), e)
+
+		case token.EQL, token.NEQ, token.GTR, token.LSS, token.LEQ, token.GEQ:
+			cmp := emitCompare(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), e)
+			// The type of x==y may be UntypedBool.
+			return emitConv(fn, cmp, types.Default(fn.typ(tv.Type)), e)
+		default:
+			panic("illegal op in BinaryExpr: " + e.Op.String())
+		}
+
+	case *ast.SliceExpr:
+		var low, high, max Value
+		var x Value
+		xtyp := fn.typeOf(e.X)
+		switch typeutil.CoreType(xtyp).(type) {
+		case *types.Array:
+			// Potentially escaping.
+			x = b.addr(fn, e.X, true).address(fn)
+		case *types.Basic, *types.Slice, *types.Pointer: // *array
+			x = b.expr(fn, e.X)
+		default:
+			// core type exception?
+			if isBytestring(xtyp) {
+				x = b.expr(fn, e.X) // bytestring is handled as string and []byte.
+			} else {
+				panic("unexpected sequence type in SliceExpr")
+			}
+		}
+		if e.Low != nil {
+			low = b.expr(fn, e.Low)
+		}
+		if e.High != nil {
+			high = b.expr(fn, e.High)
+		}
+		if e.Slice3 {
+			max = b.expr(fn, e.Max)
+		}
+		v := &Slice{
+			X:    x,
+			Low:  low,
+			High: high,
+			Max:  max,
+		}
+		v.setType(fn.typ(tv.Type))
+		return fn.emit(v, e)
+
+	case *ast.Ident:
+		obj := fn.info.Uses[e]
+		// Universal built-in or nil?
+		switch obj := obj.(type) {
+		case *types.Builtin:
+			return &Builtin{name: obj.Name(), sig: fn.instanceType(e).(*types.Signature)}
+		case *types.Nil:
+			return zeroConst(fn.instanceType(e), e)
+		}
+
+		// Package-level func or var?
+		// (obj must belong to same package or a direct import.)
+		if v := fn.Prog.packageLevelMember(obj); v != nil {
+			if g, ok := v.(*Global); ok {
+				return emitLoad(fn, g, e) // var (address)
+			}
+			callee := v.(*Function) // (func)
+			if callee.typeparams.Len() > 0 {
+				targs := fn.subtargs(e)
+				callee = callee.instance(nil, targs, b)
+			}
+			return callee
+		}
+		// Local var.
+		return emitLoad(fn, fn.lookup(obj.(*types.Var), false), e) // var (address)
+
+	case *ast.SelectorExpr:
+		sel := fn.selection(e)
+		if sel == nil {
+			// builtin unsafe.{Add,Slice}
+			if obj, ok := fn.info.Uses[e.Sel].(*types.Builtin); ok {
+				return &Builtin{name: "Unsafe" + obj.Name(), sig: fn.typ(tv.Type).(*types.Signature)}
+			}
+			// qualified identifier
+			return b.expr(fn, e.Sel)
+		}
+		switch sel.kind {
+		case types.MethodExpr:
+			// (*T).f or T.f, the method f from the method-set of type T.
+			// The result is a "thunk".
+			targs := fn.subtargs(e.Sel)
+			thunk := createThunk(fn.Prog, sel, targs)
+			b.enqueue(thunk)
+			return thunk
+
+		case types.MethodVal:
+			// e.f where e is an expression and f is a method.
+			// The result is a "bound".
+			m := sel.obj.(*types.Func)
+			rt := fn.typ(recvType(m))
+			wantAddr := isPointer(rt)
+			escaping := true
+			v := b.receiver(fn, e.X, wantAddr, escaping, sel, e)
+
+			if types.IsInterface(rt) {
+				// If v may be an interface type I (after instantiating),
+				// we must emit a check that v is non-nil.
+				if recv, ok := types.Unalias(sel.recv).(*types.TypeParam); ok {
+					// Emit a nil check if any possible instantiation of the
+					// type parameter is an interface type.
+					if !typeSetIsEmpty(recv) {
+						// recv has a concrete term its typeset.
+						// So it cannot be instantiated as an interface.
+						//
+						// Example:
+						// func _[T interface{~int; Foo()}] () {
+						//    var v T
+						//    _ = v.Foo // <-- MethodVal
+						// }
+					} else {
+						// rt may be instantiated as an interface.
+						// Emit nil check: typeassert (any(v)).(any).
+						emitTypeAssert(fn, emitConv(fn, v, tEface, nil), tEface, nil)
+					}
+				} else {
+					// non-type param interface
+					// Emit nil check: typeassert v.(I).
+					emitTypeAssert(fn, v, rt, e.Sel)
+				}
+			}
+
+			if rtargs := fn.subrtargs(m); len(rtargs) > 0 {
+				m = fn.Prog.canon.instantiateMethod(m, rtargs, fn.Prog.ctxt)
+			}
+
+			targs := fn.subtargs(e.Sel)
+			bound := createBound(fn.Prog, m, targs)
+			b.enqueue(bound)
+
+			// The assignment may widen a type parameter to its
+			// interface bound (case #3 of go.dev/issue.78110).
+			v = emitConv(fn, v, bound.FreeVars[0].Type(), nil)
+
+			c := &MakeClosure{
+				Fn:       bound,
+				Bindings: []Value{v},
+			}
+			c.source = e.Sel
+			c.setType(bound.Signature)
+			return fn.emit(c, e.Sel)
+
+		case types.FieldVal:
+			indices := sel.index
+			last := len(indices) - 1
+			v := b.expr(fn, e.X)
+			v = emitImplicitSelections(fn, v, indices[:last], e)
+			v = emitFieldSelection(fn, v, indices[last], false, e.Sel)
+			return v
+		}
+
+		panic("unexpected expression-relative selector")
+
+	case *ast.IndexListExpr:
+		// f[X, Y] must be a generic function
+		if !instance(fn.info, e.X) {
+			panic("unexpected expression-could not match index list to instantiation")
+		}
+		return b.expr(fn, e.X) // Handle instantiation within the *Ident or *SelectorExpr cases.
+
+	case *ast.IndexExpr:
+		if instance(fn.info, e.X) {
+			return b.expr(fn, e.X) // Handle instantiation within the *Ident or *SelectorExpr cases.
+		}
+		// not a generic instantiation.
+		xt := fn.typeOf(e.X)
+		switch et, mode := indexType(xt); mode {
+		case ixVar:
+			// Addressable slice/array; use IndexAddr and Load.
+			return b.addr(fn, e, false).load(fn, e)
+
+		case ixArrVar, ixValue:
+			// An array in a register, a string or a combined type that contains
+			// either an [_]array (ixArrVar) or string (ixValue).
+
+			// Note: for ixArrVar and CoreType(xt)==nil can be IndexAddr and Load.
+			index := b.expr(fn, e.Index)
+			if isUntyped(index.Type()) {
+				index = emitConv(fn, index, tInt, e.Index)
+			}
+			v := &Index{
+				X:     b.expr(fn, e.X),
+				Index: index,
+			}
+			v.setType(et)
+			return fn.emit(v, e)
+
+		case ixMap:
+			ct := typeutil.CoreType(xt).(*types.Map)
+			v := &MapLookup{
+				X:     b.expr(fn, e.X),
+				Index: emitConv(fn, b.expr(fn, e.Index), ct.Key(), e.Index),
+			}
+			v.setType(ct.Elem())
+			return fn.emit(v, e)
+		default:
+			panic("unexpected container type in IndexExpr: " + xt.String())
+		}
+
+	case *ast.CompositeLit, *ast.StarExpr:
+		// Addressable types (lvalues)
+		return b.addr(fn, e, false).load(fn, e)
+	}
+
+	panic(fmt.Sprintf("unexpected expr: %T", e))
+}
+
+// stmtList emits to fn code for all statements in list.
+func (b *builder) stmtList(fn *Function, list []ast.Stmt) {
+	for _, s := range list {
+		b.stmt(fn, s)
+	}
+}
+
+// receiver emits to fn code for expression e in the "receiver"
+// position of selection e.f (where f may be a field or a method) and
+// returns the effective receiver after applying the implicit field
+// selections of sel.
+//
+// wantAddr requests that the result is an address.  If
+// !sel.indirect, this may require that e be built in addr() mode; it
+// must thus be addressable.
+//
+// escaping is defined as per builder.addr().
+func (b *builder) receiver(fn *Function, e ast.Expr, wantAddr, escaping bool, sel *selection, source ast.Node) Value {
+	var v Value
+	if wantAddr && !sel.indirect && !isPointerCore(fn.typeOf(e)) {
+		v = b.addr(fn, e, escaping).address(fn)
+	} else {
+		v = b.expr(fn, e)
+	}
+
+	last := len(sel.index) - 1
+	v = emitImplicitSelections(fn, v, sel.index[:last], source)
+	if types.IsInterface(v.Type()) {
+		// When v is an interface, sel.Kind()==MethodValue and v.f is invoked.
+		// So v is not loaded, even if v has a pointer core type.
+	} else if !wantAddr && isPointerCore(v.Type()) {
+		v = emitLoad(fn, v, e)
+	}
+	return v
+}
+
+// setCallFunc populates the function parts of a CallCommon structure
+// (Func, Method, Recv, Args[0]) based on the kind of invocation
+// occurring in e.
+func (b *builder) setCallFunc(fn *Function, e *ast.CallExpr, c *CallCommon) {
+	// Is this a (possibly generic) method call?
+	m := ast.Unparen(e.Fun)
+	switch e := m.(type) {
+	case *ast.IndexExpr:
+		m = e.X
+	case *ast.IndexListExpr:
+		m = e.X
+	}
+	if selector, ok := m.(*ast.SelectorExpr); ok {
+		sel := fn.selection(selector)
+		if sel != nil && sel.kind == types.MethodVal {
+			obj := sel.obj.(*types.Func)
+			recv := recvType(obj)
+
+			wantAddr := isPointer(recv)
+			escaping := true
+			v := b.receiver(fn, selector.X, wantAddr, escaping, sel, selector)
+			if types.IsInterface(recv) {
+				// Invoke-mode call.
+				c.Value = v // possibly type param
+				c.Method = obj
+			} else {
+				// "Call"-mode call.
+				targs := fn.subtargs(selector.Sel)
+				c.Value = fn.Prog.objectMethod(obj, targs, b)
+				c.Args = append(c.Args, v)
+			}
+			return
+		}
+
+		// sel.kind==MethodExpr indicates T.f() or (*T).f():
+		// a statically dispatched call to the method f in the
+		// method-set of T or *T.  T may be an interface.
+		//
+		// e.Fun would evaluate to a concrete method, interface
+		// wrapper function, or promotion wrapper.
+		//
+		// For now, we evaluate it in the usual way.
+		//
+		// TODO(adonovan): opt: inline expr() here, to make the
+		// call static and to avoid generation of wrappers.
+		// It's somewhat tricky as it may consume the first
+		// actual parameter if the call is "invoke" mode.
+		//
+		// Examples:
+		//  type T struct{}; func (T) f() {}   // "call" mode
+		//  type T interface { f() }           // "invoke" mode
+		//
+		//  type S struct{ T }
+		//
+		//  var s S
+		//  S.f(s)
+		//  (*S).f(&s)
+		//
+		// Suggested approach:
+		// - consume the first actual parameter expression
+		//   and build it with b.expr().
+		// - apply implicit field selections.
+		// - use MethodVal logic to populate fields of c.
+	}
+
+	// Evaluate the function operand in the usual way.
+	c.Value = b.expr(fn, e.Fun)
+}
+
+// emitCallArgs emits to f code for the actual parameters of call e to
+// a (possibly built-in) function of effective type sig.
+// The argument values are appended to args, which is then returned.
+func (b *builder) emitCallArgs(fn *Function, sig *types.Signature, e *ast.CallExpr, args []Value) []Value {
+	// f(x, y, z...): pass slice z straight through.
+	if e.Ellipsis != 0 {
+		for i, arg := range e.Args {
+			v := emitConv(fn, b.expr(fn, arg), sig.Params().At(i).Type(), arg)
+			args = append(args, v)
+		}
+		return args
+	}
+
+	offset := len(args) // 1 if call has receiver, 0 otherwise
+
+	// Evaluate actual parameter expressions.
+	//
+	// If this is a chained call of the form f(g()) where g has
+	// multiple return values (MRV), they are flattened out into
+	// args; a suffix of them may end up in a varargs slice.
+	for _, arg := range e.Args {
+		v := b.expr(fn, arg)
+		if ttuple, ok := v.Type().(*types.Tuple); ok { // MRV chain
+			for i, n := 0, ttuple.Len(); i < n; i++ {
+				args = append(args, emitExtract(fn, v, i, arg))
+			}
+		} else {
+			args = append(args, v)
+		}
+	}
+
+	// Actual->formal assignability conversions for normal parameters.
+	np := sig.Params().Len() // number of normal parameters
+	if sig.Variadic() {
+		np--
+	}
+	for i := 0; i < np; i++ {
+		args[offset+i] = emitConv(fn, args[offset+i], sig.Params().At(i).Type(), args[offset+i].Source())
+	}
+
+	// Actual->formal assignability conversions for variadic parameter,
+	// and construction of slice.
+	if sig.Variadic() {
+		varargs := args[offset+np:]
+		st := sig.Params().At(np).Type().(*types.Slice)
+		vt := st.Elem()
+		if len(varargs) == 0 {
+			args = append(args, zeroConst(st, nil))
+		} else {
+			// Replace a suffix of args with a slice containing it.
+			at := types.NewArray(vt, int64(len(varargs)))
+			a := emitNew(fn, at, e, "varargs")
+			for i, arg := range varargs {
+				iaddr := &IndexAddr{
+					X:     a,
+					Index: intConst(int64(i), nil),
+				}
+				iaddr.setType(types.NewPointer(vt))
+				fn.emit(iaddr, e)
+				emitStore(fn, iaddr, arg, arg.Source())
+			}
+			s := &Slice{X: a}
+			s.setType(st)
+			args[offset+np] = fn.emit(s, args[offset+np].Source())
+			args = args[:offset+np+1]
+		}
+	}
+	return args
+}
+
+// setCall emits to fn code to evaluate all the parameters of a function
+// call e, and populates *c with those values.
+func (b *builder) setCall(fn *Function, e *ast.CallExpr, c *CallCommon) {
+	// First deal with the f(...) part and optional receiver.
+	b.setCallFunc(fn, e, c)
+
+	// Then append the other actual parameters.
+	sig, _ := typeutil.CoreType(fn.typeOf(e.Fun)).(*types.Signature)
+	if sig == nil {
+		panic(fmt.Sprintf("no signature for call of %s", e.Fun))
+	}
+	c.Args = b.emitCallArgs(fn, sig, e, c.Args)
+}
+
+// assignOp emits to fn code to perform loc = val.
+func (b *builder) assignOp(fn *Function, loc lvalue, val Value, op token.Token, source ast.Node) {
+	loc.store(fn, emitArith(fn, op, loc.load(fn, source), val, loc.typ(), source), source)
+}
+
+// localValueSpec emits to fn code to define all of the vars in the
+// function-local ValueSpec, spec.
+func (b *builder) localValueSpec(fn *Function, spec *ast.ValueSpec) {
+	switch {
+	case len(spec.Values) == len(spec.Names):
+		// e.g. var x, y = 0, 1
+		// 1:1 assignment
+		for i, id := range spec.Names {
+			if !isBlankIdent(id) {
+				emitLocalVar(fn, identVar(fn, id), id)
+			}
+			lval := b.addr(fn, id, false) // non-escaping
+			b.assign(fn, lval, spec.Values[i], true, nil, spec)
+		}
+
+	case len(spec.Values) == 0:
+		// e.g. var x, y int
+		// Locals are implicitly zero-initialized.
+		for _, id := range spec.Names {
+			if !isBlankIdent(id) {
+				lhs := emitLocalVar(fn, identVar(fn, id), id)
+				if fn.debugInfo() {
+					emitDebugRef(fn, id, lhs, true)
+				}
+			}
+		}
+
+	default:
+		// e.g. var x, y = pos()
+		tuple := b.exprN(fn, spec.Values[0])
+		for i, id := range spec.Names {
+			if !isBlankIdent(id) {
+				emitLocalVar(fn, identVar(fn, id), id)
+				lhs := b.addr(fn, id, false) // non-escaping
+				lhs.store(fn, emitExtract(fn, tuple, i, id), id)
+			}
+		}
+	}
+}
+
+// assignStmt emits code to fn for a parallel assignment of rhss to lhss.
+// isDef is true if this is a short variable declaration (:=).
+//
+// Note the similarity with localValueSpec.
+func (b *builder) assignStmt(fn *Function, lhss, rhss []ast.Expr, isDef bool, source ast.Node) {
+	// Side effects of all LHSs and RHSs must occur in left-to-right order.
+	lvals, isZero := b.assignLHS(fn, lhss, isDef, source)
+	if len(lhss) == len(rhss) {
+		// Simple assignment:   x     = f()        (!isDef)
+		// Parallel assignment: x, y  = f(), g()   (!isDef)
+		// or short var decl:   x, y := f(), g()   (isDef)
+		//
+		// In all cases, the RHSs may refer to the LHSs,
+		// so we need a storebuf.
+		var sb storebuf
+		for i := range rhss {
+			b.assign(fn, lvals[i], rhss[i], isZero[i], &sb, source)
+		}
+		sb.emit(fn)
+	} else {
+		// e.g. x, y = pos()
+		tuple := b.exprN(fn, rhss[0])
+		emitDebugRef(fn, rhss[0], tuple, false)
+		for i, lval := range lvals {
+			lval.store(fn, emitExtract(fn, tuple, i, source), source)
+		}
+	}
+}
+
+func (b *builder) assignLHS(fn *Function, lhss []ast.Expr, isDef bool, source ast.Node) ([]lvalue, []bool) {
+	lvals := make([]lvalue, len(lhss))
+	isZero := make([]bool, len(lhss))
+	for i, lhs := range lhss {
+		var lval lvalue = blank{}
+		if !isBlankIdent(lhs) {
+			if isDef {
+				if obj, ok := fn.info.Defs[lhs.(*ast.Ident)].(*types.Var); ok {
+					emitLocalVar(fn, obj, source)
+					isZero[i] = true
+				}
+			}
+			lval = b.addr(fn, lhs, false) // non-escaping
+		}
+		lvals[i] = lval
+	}
+	return lvals, isZero
+}
+
+// assignSelectRecvStmt emits a receive assignment from a single-case select.
+// Unlike an ordinary assignment, its (single expression) right-hand side is
+// evaluated and the receive is performed before its left-hand side is evaluated.
+func (b *builder) assignSelectRecvStmt(fn *Function, assign *ast.AssignStmt, source ast.Node) {
+	var values []Value
+	if len(assign.Lhs) == 1 {
+		values = append(values, b.expr(fn, assign.Rhs[0]))
+	} else {
+		tuple := b.exprN(fn, assign.Rhs[0])
+		emitDebugRef(fn, assign.Rhs[0], tuple, false)
+		for i := range assign.Lhs {
+			values = append(values, emitExtract(fn, tuple, i, source))
+		}
+	}
+	lvals, _ := b.assignLHS(fn, assign.Lhs, assign.Tok == token.DEFINE, source)
+	for i, lval := range lvals {
+		lval.store(fn, values[i], source)
+	}
+}
+
+// arrayLen returns the length of the array whose composite literal elements are elts.
+func (b *builder) arrayLen(fn *Function, elts []ast.Expr) int64 {
+	var max int64 = -1
+	var i int64 = -1
+	for _, e := range elts {
+		if kv, ok := e.(*ast.KeyValueExpr); ok {
+			i = b.expr(fn, kv.Key).(*Const).Int64()
+		} else {
+			i++
+		}
+		if i > max {
+			max = i
+		}
+	}
+	return max + 1
+}
+
+// compLit emits to fn code to initialize a composite literal e at
+// address addr with type typ.
+//
+// Nested composite literals are recursively initialized in place
+// where possible. If isZero is true, compLit assumes that addr
+// holds the zero value for typ.
+//
+// Because the elements of a composite literal may refer to the
+// variables being updated, as in the second line below,
+//
+//	x := T{a: 1}
+//	x = T{a: x.a}
+//
+// all the reads must occur before all the writes. Thus all stores to
+// loc are emitted to the storebuf sb for later execution.
+//
+// A CompositeLit may have pointer type only in the recursive (nested)
+// case when the type name is implicit.  e.g. in []*T{{}}, the inner
+// literal has type *T behaves like &T{}.
+// In that case, addr must hold a T, not a *T.
+func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero bool, sb *storebuf) {
+	typ := deref(fn.typeOf(e)) // retain the named/alias/param type, if any
+	switch t := typeutil.CoreType(typ).(type) {
+	case *types.Struct:
+		lvalue := &address{addr: addr, expr: e}
+		if len(e.Elts) == 0 {
+			if !isZero {
+				sb.store(lvalue, zeroConst(deref(addr.Type()), e), e)
+			}
+		} else {
+			v := &CompositeValue{
+				Values: make([]Value, t.NumFields()),
+			}
+			for i := range t.NumFields() {
+				v.Values[i] = zeroConst(t.Field(i).Type(), e)
+			}
+			v.setType(typ)
+
+			type chainElement struct {
+				children []chainElement
+				cv       *CompositeValue
+			}
+
+			chain := chainElement{
+				cv: v,
+			}
+
+			for i, e := range e.Elts {
+				if kv, ok := e.(*ast.KeyValueExpr); ok {
+					fname := kv.Key.(*ast.Ident).Name
+					_, index, _ := types.LookupFieldOrMethod(t, true, fn.declaredPackage().Pkg, fname)
+
+					var parent *chainElement
+					chain := &chain
+					chainCoreType := t
+
+					// Ensure that the entire chain of embedded fields has
+					// corresponding CompositeValues
+					for _, idx := range index[:len(index)-1] {
+						if idx >= len(chain.children) {
+							n := make([]chainElement, idx+1)
+							copy(n, chain.children)
+							chain.children = n
+						}
+
+						parent = chain
+						chain = &chain.children[idx]
+						treeType := chainCoreType.Field(idx).Type()
+						chainCoreType = typeutil.CoreType(treeType).(*types.Struct)
+						if chain.cv == nil {
+							ncv := &CompositeValue{
+								Values: make([]Value, chainCoreType.NumFields()),
+							}
+							for i := range chainCoreType.NumFields() {
+								ncv.Values[i] = zeroConst(chainCoreType.Field(i).Type(), kv)
+							}
+							ncv.setType(treeType)
+							chain.cv = ncv
+							ce := &compositeElement{
+								cv:  parent.cv,
+								idx: idx,
+								t:   ncv.Type(),
+							}
+							parent.cv.Bitmap.SetBit(&parent.cv.Bitmap, idx, 1)
+							parent.cv.NumSet++
+							sb.store(ce, chain.cv, kv)
+						}
+					}
+
+					ce := &compositeElement{
+						cv:   chain.cv,
+						idx:  index[len(index)-1],
+						t:    chainCoreType.Field(index[len(index)-1]).Type(),
+						expr: kv.Value,
+					}
+					// We use b.assign for its handling of implicit & (which,
+					// albeit not needed for structs now, may be needed in the
+					// future), but no store buffer because 1) it's not needed 2)
+					// implicit conversions have to be emitted before we emit the
+					// CompositeValue.
+					b.assign(fn, ce, kv.Value, isZero, nil, kv)
+					chain.cv.Bitmap.SetBit(&chain.cv.Bitmap, index[len(index)-1], 1)
+					chain.cv.NumSet++
+				} else {
+					ce := &compositeElement{
+						cv:   v,
+						idx:  i,
+						t:    t.Field(i).Type(),
+						expr: e,
+					}
+					b.assign(fn, ce, e, isZero, nil, e)
+					v.Bitmap.SetBit(&v.Bitmap, i, 1)
+					v.NumSet++
+				}
+			}
+
+			var dfs func(t chainElement)
+			dfs = func(t chainElement) {
+				for _, tt := range t.children {
+					dfs(tt)
+				}
+
+				// XXX better e
+				if t.cv != nil {
+					fn.emit(t.cv, e)
+				}
+			}
+			dfs(chain)
+			sb.store(lvalue, v, e)
+		}
+
+	case *types.Array, *types.Slice:
+		var at *types.Array
+		var array Value
+		switch t := t.(type) {
+		case *types.Slice:
+			at = types.NewArray(t.Elem(), b.arrayLen(fn, e.Elts))
+			array = emitNew(fn, at, e, "slicelit")
+		case *types.Array:
+			at = t
+			array = addr
+		}
+
+		var final Value
+		if len(e.Elts) == 0 {
+			if !isZero {
+				zc := zeroConst(at, e)
+				final = zc
+			}
+		} else {
+			if at.Len() == int64(len(e.Elts)) {
+				// The literal specifies all elements, so we can use a composite value
+				v := &CompositeValue{
+					Values: make([]Value, at.Len()),
+				}
+				zc := zeroConst(at.Elem(), e)
+				for i := range v.Values {
+					v.Values[i] = zc
+				}
+				v.setType(at)
+
+				var idx *Const
+				for _, e := range e.Elts {
+					if kv, ok := e.(*ast.KeyValueExpr); ok {
+						idx = b.expr(fn, kv.Key).(*Const)
+						e = kv.Value
+					} else {
+						var idxval int64
+						if idx != nil {
+							idxval = idx.Int64() + 1
+						}
+						idx = intConst(idxval, e)
+					}
+
+					iaddr := &compositeElement{
+						cv:   v,
+						idx:  int(idx.Int64()),
+						t:    at.Elem(),
+						expr: e,
+					}
+
+					// We use b.assign for its handling of implicit &, but no
+					// store buffer because 1) it's not needed 2) implicit
+					// conversions have to be emitted before we emit the
+					// CompositeValue.
+					b.assign(fn, iaddr, e, true, nil, e)
+					v.Bitmap.SetBit(&v.Bitmap, int(idx.Int64()), 1)
+					v.NumSet++
+				}
+				final = v
+				fn.emit(v, e)
+			} else {
+				// Not all elements are specified. Populate the array with a series of stores, to guard against literals
+				// like []int{1<<62: 1}.
+				if !isZero {
+					// memclear
+					sb.store(&address{array, nil}, zeroConst(deref(array.Type()), e), e)
+				}
+
+				var idx *Const
+				for _, e := range e.Elts {
+					if kv, ok := e.(*ast.KeyValueExpr); ok {
+						idx = b.expr(fn, kv.Key).(*Const)
+						e = kv.Value
+					} else {
+						var idxval int64
+						if idx != nil {
+							idxval = idx.Int64() + 1
+						}
+						idx = intConst(idxval, e)
+					}
+					iaddr := &IndexAddr{
+						X:     array,
+						Index: idx,
+					}
+					iaddr.setType(types.NewPointer(at.Elem()))
+					fn.emit(iaddr, e)
+					if t != at { // slice
+						// backing array is unaliased => storebuf not needed.
+						b.assign(fn, &address{addr: iaddr, expr: e}, e, true, nil, e)
+					} else {
+						b.assign(fn, &address{addr: iaddr, expr: e}, e, true, sb, e)
+					}
+				}
+			}
+		}
+		if t != at { // slice
+			if final != nil {
+				sb.store(&address{addr: array}, final, e)
+			}
+			s := &Slice{X: array}
+			s.setType(typ)
+			sb.store(&address{addr: addr, expr: e}, fn.emit(s, e), e)
+		} else if final != nil {
+			sb.store(&address{addr: array, expr: e}, final, e)
+		}
+
+	case *types.Map:
+		m := &MakeMap{Reserve: intConst(int64(len(e.Elts)), e)}
+		m.setType(typ)
+		fn.emit(m, e)
+		for _, e := range e.Elts {
+			e := e.(*ast.KeyValueExpr)
+
+			// If a key expression in a map literal is  itself a
+			// composite literal, the type may be omitted.
+			// For example:
+			//	map[*struct{}]bool{{}: true}
+			// An &-operation may be implied:
+			//	map[*struct{}]bool{&struct{}{}: true}
+			wantAddr := false
+			if _, ok := ast.Unparen(e.Key).(*ast.CompositeLit); ok {
+				wantAddr = isPointerCore(t.Key())
+			}
+
+			var key Value
+			if wantAddr {
+				// A CompositeLit never evaluates to a pointer,
+				// so if the type of the location is a pointer,
+				// an &-operation is implied.
+				key = b.addr(fn, e.Key, true).address(fn)
+			} else {
+				key = b.expr(fn, e.Key)
+			}
+
+			loc := element{
+				m: m,
+				k: emitConv(fn, key, t.Key(), e),
+				t: t.Elem(),
+			}
+
+			// We call assign() only because it takes care
+			// of any &-operation required in the recursive
+			// case, e.g.,
+			// map[int]*struct{}{0: {}} implies &struct{}{}.
+			// In-place update is of course impossible,
+			// and no storebuf is needed.
+			b.assign(fn, &loc, e.Value, true, nil, e)
+		}
+		sb.store(&address{addr: addr, expr: e}, m, e)
+
+	default:
+		panic("unexpected CompositeLit type: " + typ.String())
+	}
+}
+
+func (b *builder) switchStmt(fn *Function, s *ast.SwitchStmt, label *lblock) {
+	if s.Tag == nil {
+		b.switchStmtDynamic(fn, s, label)
+		return
+	}
+	dynamic := false
+	for _, iclause := range s.Body.List {
+		clause := iclause.(*ast.CaseClause)
+		for _, cond := range clause.List {
+			if fn.info.Types[ast.Unparen(cond)].Value == nil {
+				dynamic = true
+				break
+			}
+		}
+	}
+
+	if dynamic {
+		b.switchStmtDynamic(fn, s, label)
+		return
+	}
+
+	if s.Init != nil {
+		b.stmt(fn, s.Init)
+	}
+
+	entry := fn.currentBlock
+	tag := b.expr(fn, s.Tag)
+
+	heads := make([]*BasicBlock, 0, len(s.Body.List))
+	bodies := make([]*BasicBlock, len(s.Body.List))
+	conds := make([]Value, 0, len(s.Body.List))
+
+	hasDefault := false
+	done := fn.newBasicBlock("switch.done")
+	if label != nil {
+		label._break = done
+	}
+	for i, stmt := range s.Body.List {
+		body := fn.newBasicBlock(fmt.Sprintf("switch.body.%d", i))
+		bodies[i] = body
+		cas := stmt.(*ast.CaseClause)
+		if cas.List == nil {
+			// default branch
+			hasDefault = true
+			head := fn.newBasicBlock(fmt.Sprintf("switch.head.%d", i))
+			conds = append(conds, nil)
+			heads = append(heads, head)
+			fn.currentBlock = head
+			emitJump(fn, body, cas)
+		}
+		for j, cond := range stmt.(*ast.CaseClause).List {
+			fn.currentBlock = entry
+			head := fn.newBasicBlock(fmt.Sprintf("switch.head.%d.%d", i, j))
+			conds = append(conds, b.expr(fn, cond))
+			heads = append(heads, head)
+			fn.currentBlock = head
+			emitJump(fn, body, cond)
+		}
+	}
+
+	for i, stmt := range s.Body.List {
+		clause := stmt.(*ast.CaseClause)
+		body := bodies[i]
+		fn.currentBlock = body
+		fallthru := done
+		if i+1 < len(bodies) {
+			fallthru = bodies[i+1]
+		}
+		fn.targets = &targets{
+			tail:         fn.targets,
+			_break:       done,
+			_fallthrough: fallthru,
+		}
+		b.stmtList(fn, clause.Body)
+		fn.targets = fn.targets.tail
+		emitJump(fn, done, stmt)
+	}
+
+	if !hasDefault {
+		head := fn.newBasicBlock("switch.head.implicit-default")
+		body := fn.newBasicBlock("switch.body.implicit-default")
+		fn.currentBlock = head
+		emitJump(fn, body, s)
+		fn.currentBlock = body
+		emitJump(fn, done, s)
+		heads = append(heads, head)
+		conds = append(conds, nil)
+	}
+
+	if len(heads) != len(conds) {
+		panic(fmt.Sprintf("internal error: %d heads for %d conds", len(heads), len(conds)))
+	}
+	for _, head := range heads {
+		addEdge(entry, head)
+	}
+	fn.currentBlock = entry
+	entry.emit(&ConstantSwitch{
+		Tag:   tag,
+		Conds: conds,
+	}, s)
+	fn.currentBlock = done
+}
+
+// switchStmt emits to fn code for the switch statement s, optionally
+// labelled by label.
+func (b *builder) switchStmtDynamic(fn *Function, s *ast.SwitchStmt, label *lblock) {
+	// We treat SwitchStmt like a sequential if-else chain.
+	// Multiway dispatch can be recovered later by irutil.Switches()
+	// to those cases that are free of side effects.
+	if s.Init != nil {
+		b.stmt(fn, s.Init)
+	}
+	var tag Value = vTrue
+
+	if s.Tag != nil {
+		tag = b.expr(fn, s.Tag)
+	}
+
+	done := fn.newBasicBlock("switch.done")
+	if label != nil {
+		label._break = done
+	}
+	// We pull the default case (if present) down to the end.
+	// But each fallthrough label must point to the next
+	// body block in source order, so we preallocate a
+	// body block (fallthru) for the next case.
+	// Unfortunately this makes for a confusing block order.
+	var dfltBody *[]ast.Stmt
+	var dfltFallthrough *BasicBlock
+	var fallthru, dfltBlock *BasicBlock
+	ncases := len(s.Body.List)
+	for i, clause := range s.Body.List {
+		body := fallthru
+		if body == nil {
+			body = fn.newBasicBlock("switch.body") // first case only
+		}
+
+		// Preallocate body block for the next case.
+		fallthru = done
+		if i+1 < ncases {
+			fallthru = fn.newBasicBlock("switch.body")
+		}
+
+		cc := clause.(*ast.CaseClause)
+		if cc.List == nil {
+			// Default case.
+			dfltBody = &cc.Body
+			dfltFallthrough = fallthru
+			dfltBlock = body
+			continue
+		}
+
+		var nextCond *BasicBlock
+		for _, cond := range cc.List {
+			nextCond = fn.newBasicBlock("switch.next")
+			// For boolean switches, emit short-circuit control flow,
+			// just like an if/else-chain.
+			if tag == vTrue && !isNonTypeParamInterface(fn.info.Types[cond].Type) {
+				b.cond(fn, cond, body, nextCond)
+			} else {
+				cond := emitCompare(fn, token.EQL, tag, b.expr(fn, cond), cond)
+				emitIf(fn, cond, body, nextCond, cond.Source())
+			}
+
+			fn.currentBlock = nextCond
+		}
+		fn.currentBlock = body
+		fn.targets = &targets{
+			tail:         fn.targets,
+			_break:       done,
+			_fallthrough: fallthru,
+		}
+		b.stmtList(fn, cc.Body)
+		fn.targets = fn.targets.tail
+		emitJump(fn, done, s)
+		fn.currentBlock = nextCond
+	}
+	if dfltBlock != nil {
+		// The lack of a Source for the jump doesn't matter, block
+		// fusing will get rid of the jump later.
+
+		emitJump(fn, dfltBlock, s)
+		fn.currentBlock = dfltBlock
+		fn.targets = &targets{
+			tail:         fn.targets,
+			_break:       done,
+			_fallthrough: dfltFallthrough,
+		}
+		b.stmtList(fn, *dfltBody)
+		fn.targets = fn.targets.tail
+	}
+	emitJump(fn, done, s)
+	fn.currentBlock = done
+}
+
+// typeSwitchStmt emits to fn code for the type switch statement s, optionally
+// labelled by label.
+func (b *builder) typeSwitchStmt(fn *Function, s *ast.TypeSwitchStmt, label *lblock) {
+	if s.Init != nil {
+		b.stmt(fn, s.Init)
+	}
+
+	var tag Value
+	switch e := s.Assign.(type) {
+	case *ast.ExprStmt: // x.(type)
+		tag = b.expr(fn, ast.Unparen(e.X).(*ast.TypeAssertExpr).X)
+	case *ast.AssignStmt: // y := x.(type)
+		tag = b.expr(fn, ast.Unparen(e.Rhs[0]).(*ast.TypeAssertExpr).X)
+	default:
+		panic("unreachable")
+	}
+
+	// +1 in case there's no explicit default case
+	heads := make([]*BasicBlock, 0, len(s.Body.List)+1)
+
+	entry := fn.currentBlock
+	done := fn.newBasicBlock("typeswitch.done")
+	if label != nil {
+		label._break = done
+	}
+
+	// set up type switch and constant switch, populate their conditions
+	tswtch := &TypeSwitch{
+		Tag:   tag,
+		Conds: make([]types.Type, 0, len(s.Body.List)+1),
+	}
+	cswtch := &ConstantSwitch{
+		Conds: make([]Value, 0, len(s.Body.List)+1),
+	}
+
+	rets := make([]types.Type, 0, len(s.Body.List)+1)
+	index := 0
+	var default_ *ast.CaseClause
+	for _, clause := range s.Body.List {
+		cc := clause.(*ast.CaseClause)
+		if obj, ok := fn.info.Implicits[cc].(*types.Var); ok {
+			emitLocalVar(fn, obj, cc)
+		}
+		if cc.List == nil {
+			// default case
+			default_ = cc
+		} else {
+			for _, expr := range cc.List {
+				tswtch.Conds = append(tswtch.Conds, fn.typeOf(expr))
+				cswtch.Conds = append(cswtch.Conds, intConst(int64(index), expr))
+				index++
+			}
+			if len(cc.List) == 1 {
+				rets = append(rets, fn.typeOf(cc.List[0]))
+			} else {
+				for range cc.List {
+					rets = append(rets, tag.Type())
+				}
+			}
+		}
+	}
+
+	// default branch
+	rets = append(rets, tag.Type())
+
+	var vars []*types.Var
+	vars = append(vars, varIndex)
+	for _, typ := range rets {
+		vars = append(vars, anonVar(typ))
+	}
+	tswtch.setType(types.NewTuple(vars...))
+	// default branch
+	fn.currentBlock = entry
+	fn.emit(tswtch, s)
+	cswtch.Conds = append(cswtch.Conds, intConst(int64(-1), nil))
+	cswtch.Tag = emitExtract(fn, tswtch, 0, s)
+	fn.emit(cswtch, s)
+
+	// build heads and bodies
+	index = 0
+	for _, clause := range s.Body.List {
+		cc := clause.(*ast.CaseClause)
+		if cc.List == nil {
+			continue
+		}
+
+		body := fn.newBasicBlock("typeswitch.body")
+		for _, expr := range cc.List {
+			head := fn.newBasicBlock("typeswitch.head")
+			heads = append(heads, head)
+			fn.currentBlock = head
+
+			if obj, ok := fn.info.Implicits[cc].(*types.Var); ok {
+				// In a switch y := x.(type), each case clause
+				// implicitly declares a distinct object y.
+				// In a single-type case, y has that type.
+				// In multi-type cases, 'case nil' and default,
+				// y has the same type as the interface operand.
+
+				l := fn.vars[obj]
+				if rets[index] == tUntypedNil {
+					emitStore(fn, l, nilConst(tswtch.Tag.Type(), nil), s.Assign)
+				} else {
+					x := emitExtract(fn, tswtch, index+1, s.Assign)
+					emitStore(fn, l, x, nil)
+				}
+			}
+
+			emitJump(fn, body, expr)
+			index++
+		}
+		fn.currentBlock = body
+		fn.targets = &targets{
+			tail:   fn.targets,
+			_break: done,
+		}
+		b.stmtList(fn, cc.Body)
+		fn.targets = fn.targets.tail
+		emitJump(fn, done, clause)
+	}
+
+	if default_ == nil {
+		// implicit default
+		heads = append(heads, done)
+	} else {
+		body := fn.newBasicBlock("typeswitch.default")
+		heads = append(heads, body)
+		fn.currentBlock = body
+		fn.targets = &targets{
+			tail:   fn.targets,
+			_break: done,
+		}
+		if obj, ok := fn.info.Implicits[default_].(*types.Var); ok {
+			l := fn.vars[obj]
+			x := emitExtract(fn, tswtch, index+1, s.Assign)
+			emitStore(fn, l, x, s)
+		}
+		b.stmtList(fn, default_.Body)
+		fn.targets = fn.targets.tail
+		emitJump(fn, done, s)
+	}
+
+	fn.currentBlock = entry
+	for _, head := range heads {
+		addEdge(entry, head)
+	}
+	fn.currentBlock = done
+}
+
+// selectStmt emits to fn code for the select statement s, optionally
+// labelled by label.
+func (b *builder) selectStmt(fn *Function, s *ast.SelectStmt, label *lblock) (noreturn bool) {
+	if len(s.Body.List) == 0 {
+		instr := &Select{Blocking: true}
+		instr.setType(types.NewTuple(varIndex, varOk))
+		fn.emit(instr, s)
+		fn.emit(new(Unreachable), s)
+		return true
+	}
+
+	// A blocking select of a single case degenerates to a
+	// simple send or receive.
+	// TODO(adonovan): opt: is this optimization worth its weight?
+	if len(s.Body.List) == 1 {
+		clause := s.Body.List[0].(*ast.CommClause)
+		if clause.Comm != nil {
+			if recvAssign, ok := clause.Comm.(*ast.AssignStmt); ok {
+				b.assignSelectRecvStmt(fn, recvAssign, clause.Comm)
+			} else {
+				b.stmt(fn, clause.Comm)
+			}
+			done := fn.newBasicBlock("select.done")
+			if label != nil {
+				label._break = done
+			}
+			fn.targets = &targets{
+				tail:   fn.targets,
+				_break: done,
+			}
+			b.stmtList(fn, clause.Body)
+			fn.targets = fn.targets.tail
+			emitJump(fn, done, clause)
+			fn.currentBlock = done
+			return false
+		}
+	}
+
+	// First evaluate all channels in all cases, and find
+	// the directions of each state.
+	var states []*SelectState
+	blocking := true
+	debugInfo := fn.debugInfo()
+	for _, clause := range s.Body.List {
+		var st *SelectState
+		switch comm := clause.(*ast.CommClause).Comm.(type) {
+		case nil: // default case
+			blocking = false
+			continue
+
+		case *ast.SendStmt: // ch<- i
+			ch := b.expr(fn, comm.Chan)
+			st = &SelectState{
+				Dir:  types.SendOnly,
+				Chan: ch,
+				Send: emitConv(fn, b.expr(fn, comm.Value),
+					typeutil.CoreType(fn.typ(ch.Type())).(*types.Chan).Elem(), comm),
+				Pos: comm.Arrow,
+			}
+			if debugInfo {
+				st.DebugNode = comm
+			}
+
+		case *ast.AssignStmt: // x := <-ch
+			recv := ast.Unparen(comm.Rhs[0]).(*ast.UnaryExpr)
+			st = &SelectState{
+				Dir:  types.RecvOnly,
+				Chan: b.expr(fn, recv.X),
+				Pos:  recv.OpPos,
+			}
+			if debugInfo {
+				st.DebugNode = recv
+			}
+
+		case *ast.ExprStmt: // <-ch
+			recv := ast.Unparen(comm.X).(*ast.UnaryExpr)
+			st = &SelectState{
+				Dir:  types.RecvOnly,
+				Chan: b.expr(fn, recv.X),
+				Pos:  recv.OpPos,
+			}
+			if debugInfo {
+				st.DebugNode = recv
+			}
+		}
+		states = append(states, st)
+	}
+
+	// We dispatch on the (fair) result of Select using a
+	// switch on the returned index.
+	sel := &Select{
+		States:   states,
+		Blocking: blocking,
+	}
+	sel.source = s
+	var vars []*types.Var
+	vars = append(vars, varIndex, varOk)
+	for _, st := range states {
+		if st.Dir == types.RecvOnly {
+			tElem := typeutil.CoreType(fn.typ(st.Chan.Type())).(*types.Chan).Elem()
+			vars = append(vars, anonVar(tElem))
+		}
+	}
+	sel.setType(types.NewTuple(vars...))
+	fn.emit(sel, s)
+	idx := emitExtract(fn, sel, 0, s)
+
+	done := fn.newBasicBlock("select.done")
+	if label != nil {
+		label._break = done
+	}
+
+	entry := fn.currentBlock
+	swtch := &ConstantSwitch{
+		Tag: idx,
+		// one condition per case
+		Conds: make([]Value, 0, len(s.Body.List)+1),
+	}
+	// note that we don't need heads; a select case can only have a single condition
+	var bodies []*BasicBlock
+
+	state := 0
+	r := 2 // index in 'sel' tuple of value; increments if st.Dir==RECV
+	for _, cc := range s.Body.List {
+		clause := cc.(*ast.CommClause)
+		if clause.Comm == nil {
+			body := fn.newBasicBlock("select.default")
+			fn.currentBlock = body
+			bodies = append(bodies, body)
+			fn.targets = &targets{
+				tail:   fn.targets,
+				_break: done,
+			}
+			b.stmtList(fn, clause.Body)
+			emitJump(fn, done, s)
+			fn.targets = fn.targets.tail
+			swtch.Conds = append(swtch.Conds, intConst(-1, nil))
+			continue
+		}
+		swtch.Conds = append(swtch.Conds, intConst(int64(state), nil))
+		body := fn.newBasicBlock("select.body")
+		fn.currentBlock = body
+		bodies = append(bodies, body)
+		fn.targets = &targets{
+			tail:   fn.targets,
+			_break: done,
+		}
+		switch comm := clause.Comm.(type) {
+		case *ast.ExprStmt: // <-ch
+			if debugInfo {
+				v := emitExtract(fn, sel, r, comm)
+				emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false)
+			}
+			r++
+
+		case *ast.AssignStmt: // x := <-states[state].Chan
+			if comm.Tok == token.DEFINE {
+				id := comm.Lhs[0].(*ast.Ident)
+				emitLocalVar(fn, identVar(fn, id), id)
+			}
+			x := b.addr(fn, comm.Lhs[0], false) // non-escaping
+			v := emitExtract(fn, sel, r, comm)
+			if debugInfo {
+				emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false)
+			}
+			x.store(fn, v, comm)
+
+			if len(comm.Lhs) == 2 { // x, ok := ...
+				if comm.Tok == token.DEFINE {
+					id := comm.Lhs[1].(*ast.Ident)
+					emitLocalVar(fn, identVar(fn, id), id)
+				}
+				ok := b.addr(fn, comm.Lhs[1], false) // non-escaping
+				ok.store(fn, emitExtract(fn, sel, 1, comm), comm)
+			}
+			r++
+		}
+		b.stmtList(fn, clause.Body)
+		fn.targets = fn.targets.tail
+		emitJump(fn, done, s)
+		state++
+	}
+	fn.currentBlock = entry
+	fn.emit(swtch, s)
+	for _, body := range bodies {
+		addEdge(entry, body)
+	}
+	fn.currentBlock = done
+	return false
+}
+
+// forStmt emits to fn code for the for statement s, optionally
+// labelled by label.
+func (b *builder) forStmt(fn *Function, s *ast.ForStmt, label *lblock) {
+	// Use forStmtGo122 instead if it applies.
+	if s.Init != nil {
+		if assign, ok := s.Init.(*ast.AssignStmt); ok && assign.Tok == token.DEFINE {
+			if versions.AtLeast(fn.goversion, versions.Go1_22) {
+				b.forStmtGo122(fn, s, label)
+				return
+			}
+		}
+	}
+
+	//     ...init...
+	//     jump loop
+	// loop:
+	//     if cond goto body else done
+	// body:
+	//     ...body...
+	//     jump post
+	// post:                                 (target of continue)
+	//     ...post...
+	//     jump loop
+	// done:                                 (target of break)
+	if s.Init != nil {
+		b.stmt(fn, s.Init)
+	}
+	body := fn.newBasicBlock("for.body")
+	done := fn.newBasicBlock("for.done") // target of 'break'
+	loop := body                         // target of back-edge
+	if s.Cond != nil {
+		loop = fn.newBasicBlock("for.loop")
+	}
+	cont := loop // target of 'continue'
+	if s.Post != nil {
+		cont = fn.newBasicBlock("for.post")
+	}
+	if label != nil {
+		label._break = done
+		label._continue = cont
+	}
+	emitJump(fn, loop, s)
+	fn.currentBlock = loop
+	if loop != body {
+		b.cond(fn, s.Cond, body, done)
+		fn.currentBlock = body
+	}
+	fn.targets = &targets{
+		tail:      fn.targets,
+		_break:    done,
+		_continue: cont,
+	}
+	b.stmt(fn, s.Body)
+	fn.targets = fn.targets.tail
+	emitJump(fn, cont, s)
+
+	if s.Post != nil {
+		fn.currentBlock = cont
+		b.stmt(fn, s.Post)
+		emitJump(fn, loop, s) // back-edge
+	}
+	fn.currentBlock = done
+}
+
+// forStmtGo122 emits to fn code for the for statement s, optionally
+// labelled by label. s must define its variables.
+//
+// This allocates once per loop iteration. This is only correct in
+// GoVersions >= go1.22.
+func (b *builder) forStmtGo122(fn *Function, s *ast.ForStmt, label *lblock) {
+	//     i_outer = alloc[T]
+	//     *i_outer = ...init...        // under objects[i] = i_outer
+	//     jump loop
+	// loop:
+	//     i = phi [head: i_outer, loop: i_next]
+	//     ...cond...                   // under objects[i] = i
+	//     if cond goto body else done
+	// body:
+	//     ...body...                   // under objects[i] = i (same as loop)
+	//     jump post
+	// post:
+	//     tmp = *i
+	//     i_next = alloc[T]
+	//     *i_next = tmp
+	//     ...post...                   // under objects[i] = i_next
+	//     goto loop
+	// done:
+
+	init := s.Init.(*ast.AssignStmt)
+	startingBlocks := len(fn.Blocks)
+
+	pre := fn.currentBlock               // current block before starting
+	loop := fn.newBasicBlock("for.loop") // target of back-edge
+	body := fn.newBasicBlock("for.body")
+	post := fn.newBasicBlock("for.post") // target of 'continue'
+	done := fn.newBasicBlock("for.done") // target of 'break'
+
+	// For each of the n loop variables, we create five SSA values,
+	// outer, phi, next, load, and store in pre, loop, and post.
+	// There is no limit on n.
+	type loopVar struct {
+		obj   *types.Var
+		outer *Alloc
+		phi   *Phi
+		load  *Load
+		next  *Alloc
+		store *Store
+	}
+	vars := make([]loopVar, len(init.Lhs))
+	for i, lhs := range init.Lhs {
+		v := identVar(fn, lhs.(*ast.Ident))
+		typ := fn.typ(v.Type())
+
+		fn.currentBlock = pre
+		outer := emitLocal(fn, typ, lhs, v.Name())
+
+		fn.currentBlock = loop
+		phi := &Phi{}
+		phi.comment = v.Name()
+		phi.typ = outer.Type()
+		fn.emit(phi, lhs)
+
+		fn.currentBlock = post
+		// If next is local, it reuses the address and zeroes the old value so
+		// load before allocating next.
+		load := emitLoad(fn, phi, init)
+		next := emitLocal(fn, typ, lhs, v.Name())
+		store := emitStore(fn, next, load, s)
+
+		phi.Edges = []Value{outer, next} // pre edge is emitted before post edge.
+		vars[i] = loopVar{v, outer, phi, load, next, store}
+	}
+
+	// ...init... under fn.objects[v] = i_outer
+	fn.currentBlock = pre
+	for _, v := range vars {
+		fn.vars[v.obj] = v.outer
+	}
+	const isDef = false // assign to already-allocated outers
+	b.assignStmt(fn, init.Lhs, init.Rhs, isDef, init)
+	if label != nil {
+		label._break = done
+		label._continue = post
+	}
+	emitJump(fn, loop, s)
+
+	// ...cond... under fn.objects[v] = i
+	fn.currentBlock = loop
+	for _, v := range vars {
+		fn.vars[v.obj] = v.phi
+	}
+	if s.Cond != nil {
+		b.cond(fn, s.Cond, body, done)
+	} else {
+		emitJump(fn, body, s)
+	}
+
+	// ...body... under fn.objects[v] = i
+	fn.currentBlock = body
+	fn.targets = &targets{
+		tail:      fn.targets,
+		_break:    done,
+		_continue: post,
+	}
+	b.stmt(fn, s.Body)
+	fn.targets = fn.targets.tail
+	emitJump(fn, post, s)
+
+	// ...post... under fn.objects[v] = i_next
+	for _, v := range vars {
+		fn.vars[v.obj] = v.next
+	}
+	fn.currentBlock = post
+	if s.Post != nil {
+		b.stmt(fn, s.Post)
+	}
+	emitJump(fn, loop, s) // back-edge
+	fn.currentBlock = done
+
+	// For each loop variable that does not escape,
+	// (the common case), fuse its next cells into its
+	// (local) outer cell as they have disjoint live ranges.
+	//
+	// It is sufficient to test whether i_next escapes,
+	// because its Heap flag will be marked true if either
+	// the cond or post expression causes i to escape
+	// (because escape distributes over phi).
+	var nlocals int
+	for _, v := range vars {
+		if !v.next.Heap {
+			nlocals++
+		}
+	}
+	if nlocals > 0 {
+		replace := make(map[Value]Value, 2*nlocals)
+		dead := make(map[Instruction]bool, 4*nlocals)
+		for _, v := range vars {
+			if !v.next.Heap {
+				replace[v.next] = v.outer
+				replace[v.phi] = v.outer
+				dead[v.phi], dead[v.next], dead[v.load], dead[v.store] = true, true, true, true
+			}
+		}
+
+		// Replace all uses of i_next and phi with i_outer.
+		// Referrers have not been built for fn yet so only update Instruction operands.
+		// We need only look within the blocks added by the loop.
+		var operands []*Value // recycle storage
+		for _, b := range fn.Blocks[startingBlocks:] {
+			for _, instr := range b.Instrs {
+				operands = instr.Operands(operands[:0])
+				for _, ptr := range operands {
+					k := *ptr
+					if v := replace[k]; v != nil {
+						*ptr = v
+					}
+				}
+			}
+		}
+
+		// Remove instructions for phi, load, and store.
+		// lift() will remove the unused i_next *Alloc.
+		isDead := func(i Instruction) bool { return dead[i] }
+		loop.Instrs = slices.DeleteFunc(loop.Instrs, isDead)
+		post.Instrs = slices.DeleteFunc(post.Instrs, isDead)
+	}
+}
+
+// rangeIndexed emits to fn the header for an integer-indexed loop
+// over array, *array or slice value x.
+// The v result is defined only if tv is non-nil.
+// forPos is the position of the "for" token.
+func (b *builder) rangeIndexed(fn *Function, x Value, tv types.Type, source ast.Node) (k, v Value, loop, done *BasicBlock) {
+	//
+	//     length = len(x)
+	//     index = -1
+	// loop:                                     (target of continue)
+	//     index++
+	//     if index < length goto body else done
+	// body:
+	//     k = index
+	//     v = x[index]
+	//     ...body...
+	//     jump loop
+	// done:                                     (target of break)
+
+	// Determine number of iterations.
+	var length Value
+	dt := deref(x.Type())
+	if arr, ok := typeutil.CoreType(dt).(*types.Array); ok {
+		// For array or *array, the number of iterations is
+		// known statically thanks to the type.  We avoid a
+		// data dependence upon x, permitting later dead-code
+		// elimination if x is pure, static unrolling, etc.
+		// Ranging over a nil *array may have >0 iterations.
+		// We still generate code for x, in case it has effects.
+		length = intConst(arr.Len(), nil)
+	} else {
+		// length = len(x).
+		var c Call
+		c.Call.Value = makeLen(x.Type())
+		c.Call.Args = []Value{x}
+		c.setType(tInt)
+		length = fn.emit(&c, source)
+	}
+
+	index := emitLocal(fn, tInt, source, "rangeindex")
+	emitStore(fn, index, intConst(-1, nil), source)
+
+	loop = fn.newBasicBlock("rangeindex.loop")
+	emitJump(fn, loop, source)
+	fn.currentBlock = loop
+
+	incr := &BinOp{
+		Op: token.ADD,
+		X:  emitLoad(fn, index, source),
+		Y:  vOne,
+	}
+	incr.setType(tInt)
+	emitStore(fn, index, fn.emit(incr, source), source)
+
+	body := fn.newBasicBlock("rangeindex.body")
+	done = fn.newBasicBlock("rangeindex.done")
+	emitIf(fn, emitCompare(fn, token.LSS, incr, length, source), body, done, source)
+	fn.currentBlock = body
+
+	k = emitLoad(fn, index, source)
+	if tv != nil {
+		switch t := typeutil.CoreType(x.Type()).(type) {
+		case *types.Array:
+			instr := &Index{
+				X:     x,
+				Index: k,
+			}
+			instr.setType(t.Elem())
+			v = fn.emit(instr, source)
+
+		case *types.Pointer: // *array
+			instr := &IndexAddr{
+				X:     x,
+				Index: k,
+			}
+			instr.setType(types.NewPointer(t.Elem().Underlying().(*types.Array).Elem()))
+			v = emitLoad(fn, fn.emit(instr, source), source)
+
+		case *types.Slice:
+			instr := &IndexAddr{
+				X:     x,
+				Index: k,
+			}
+			instr.setType(types.NewPointer(t.Elem()))
+			v = emitLoad(fn, fn.emit(instr, source), source)
+
+		default:
+			panic("rangeIndexed x:" + t.String())
+		}
+	}
+	return
+}
+
+// rangeIter emits to fn the header for a loop using
+// Range/Next/Extract to iterate over map or string value x.
+// tk and tv are the types of the key/value results k and v, or nil
+// if the respective component is not wanted.
+func (b *builder) rangeIter(fn *Function, x Value, tk, tv types.Type, source ast.Node) (k, v Value, loop, done *BasicBlock) {
+	//
+	//	it = range x
+	// loop:                                   (target of continue)
+	//	okv = next it                      (ok, key, value)
+	//  	ok = extract okv #0
+	// 	if ok goto body else done
+	// body:
+	// 	k = extract okv #1
+	// 	v = extract okv #2
+	//      ...body...
+	// 	jump loop
+	// done:                                   (target of break)
+	//
+
+	var ak, av types.Type
+	isString := false
+	if m, ok := typeutil.CoreType(x.Type()).(*types.Map); ok {
+		ak, av = m.Key(), m.Elem()
+	} else {
+		isString = true
+		ak, av = tInt, tRune
+	}
+	if tk == nil {
+		ak = tInvalid
+	}
+	if tv == nil {
+		av = tInvalid
+	}
+
+	rng := &Range{X: x}
+	rng.setType(typeutil.NewIterator(types.NewTuple(
+		varOk,
+		newVar("k", ak),
+		newVar("v", av),
+	)))
+	it := fn.emit(rng, source)
+
+	loop = fn.newBasicBlock("rangeiter.loop")
+	emitJump(fn, loop, source)
+	fn.currentBlock = loop
+
+	okv := &Next{
+		Iter:     it,
+		IsString: isString,
+	}
+	okv.setType(rng.typ.(*typeutil.Iterator).Elem())
+	fn.emit(okv, source)
+
+	body := fn.newBasicBlock("rangeiter.body")
+	done = fn.newBasicBlock("rangeiter.done")
+	emitIf(fn, emitExtract(fn, okv, 0, source), body, done, source)
+	fn.currentBlock = body
+
+	// The assignment may widen a map or string
+	// key/value to a variable's interface type
+	// (cases #1 and #2 of go.dev/issue/78110).
+	if tk != nil {
+		k = emitConv(fn, emitExtract(fn, okv, 1, source), tk, source)
+	}
+	if tv != nil {
+		v = emitConv(fn, emitExtract(fn, okv, 2, source), tv, source)
+	}
+	return
+}
+
+// rangeChan emits to fn the header for a loop that receives from
+// channel x until it fails.
+// tk is the channel's element type, or nil if the k result is
+// not wanted
+// pos is the position of the '=' or ':=' token.
+func (b *builder) rangeChan(fn *Function, x Value, tk types.Type, source ast.Node) (k Value, loop, done *BasicBlock) {
+	//
+	// loop:                                   (target of continue)
+	//      ko = <-x                           (key, ok)
+	//      ok = extract ko #1
+	//      if ok goto body else done
+	// body:
+	//      k = extract ko #0
+	//      ...
+	//      goto loop
+	// done:                                   (target of break)
+
+	loop = fn.newBasicBlock("rangechan.loop")
+	emitJump(fn, loop, source)
+	fn.currentBlock = loop
+
+	retv := emitRecv(fn, x, true, types.NewTuple(newVar("k", typeutil.CoreType(x.Type()).(*types.Chan).Elem()), varOk), source)
+
+	body := fn.newBasicBlock("rangechan.body")
+	done = fn.newBasicBlock("rangechan.done")
+	emitIf(fn, emitExtract(fn, retv, 1, source), body, done, source)
+	fn.currentBlock = body
+	if tk != nil {
+		k = emitExtract(fn, retv, 0, source)
+	}
+	return
+}
+
+// rangeInt emits to fn the header for a range loop with an integer operand.
+// tk is the key value's type, or nil if the k result is not wanted.
+// pos is the position of the "for" token.
+func (b *builder) rangeInt(fn *Function, x Value, tk types.Type, source ast.Node) (k Value, loop, done *BasicBlock) {
+	//
+	//     iter = 0
+	//     if 0 < x goto body else done
+	// loop:                                   (target of continue)
+	//     iter++
+	//     if iter < x goto body else done
+	// body:
+	//     k = x
+	//     ...body...
+	//     jump loop
+	// done:                                   (target of break)
+
+	if b, ok := x.Type().(*types.Basic); ok && b.Info()&types.IsUntyped != 0 {
+		x = emitConv(fn, x, tInt, source)
+	}
+
+	T := x.Type()
+	iter := emitLocal(fn, T, source, "rangeint.iter")
+	// x may be unsigned. Avoid initializing x to -1.
+
+	body := fn.newBasicBlock("rangeint.body")
+	done = fn.newBasicBlock("rangeint.done")
+	emitIf(fn, emitCompare(fn, token.LSS, zeroConst(T, source), x, source), body, done, source)
+
+	loop = fn.newBasicBlock("rangeint.loop")
+	fn.currentBlock = loop
+
+	incr := &BinOp{
+		Op: token.ADD,
+		X:  emitLoad(fn, iter, source),
+		Y:  emitConv(fn, intConst(1, source), T, source),
+	}
+	incr.setType(T)
+	emitStore(fn, iter, fn.emit(incr, source), source)
+	emitIf(fn, emitCompare(fn, token.LSS, incr, x, source), body, done, source)
+	fn.currentBlock = body
+
+	if tk != nil {
+		// Integer types (int, uint8, etc.) are named and
+		// we know that k is assignable to x when tk != nil.
+		// This implies tk and T are identical so no conversion is needed.
+		k = emitLoad(fn, iter, source)
+	}
+
+	return
+}
+
+// rangeStmt emits to fn code for the range statement s, optionally
+// labelled by label.
+func (b *builder) rangeStmt(fn *Function, s *ast.RangeStmt, label *lblock, source ast.Node) {
+	var tk, tv types.Type
+	if s.Key != nil && !isBlankIdent(s.Key) {
+		tk = fn.typeOf(s.Key)
+	}
+	if s.Value != nil && !isBlankIdent(s.Value) {
+		tv = fn.typeOf(s.Value)
+	}
+
+	// create locals for s.Key and s.Value
+	createVars := func() {
+		// Unlike a short variable declaration, a RangeStmt
+		// using := never redeclares an existing variable; it
+		// always creates a new one.
+		if tk != nil {
+			id := s.Key.(*ast.Ident)
+			emitLocalVar(fn, identVar(fn, id), id)
+		}
+		if tv != nil {
+			id := s.Value.(*ast.Ident)
+			emitLocalVar(fn, identVar(fn, id), id)
+		}
+	}
+
+	afterGo122 := versions.AtLeast(fn.goversion, versions.Go1_22)
+	if s.Tok == token.DEFINE && !afterGo122 {
+		// pre-go1.22: If iteration variables are defined (:=), this
+		// occurs once outside the loop.
+		createVars()
+	}
+
+	x := b.expr(fn, s.X)
+
+	var k, v Value
+	var loop, done *BasicBlock
+	switch rt := typeutil.CoreType(x.Type()).(type) {
+	case *types.Slice, *types.Array, *types.Pointer: // *array
+		k, v, loop, done = b.rangeIndexed(fn, x, tv, source)
+
+	case *types.Chan:
+		k, loop, done = b.rangeChan(fn, x, tk, source)
+
+	case *types.Map:
+		k, v, loop, done = b.rangeIter(fn, x, tk, tv, source)
+
+	case *types.Basic:
+		switch {
+		case rt.Info()&types.IsString != 0:
+			k, v, loop, done = b.rangeIter(fn, x, tk, tv, source)
+
+		case rt.Info()&types.IsInteger != 0:
+			k, loop, done = b.rangeInt(fn, x, tk, source)
+
+		default:
+			panic("Cannot range over basic type: " + rt.String())
+		}
+
+	case *types.Signature:
+		// Special case rewrite (fn.goversion >= go1.23):
+		//      for x := range f { ... }
+		// into
+		//      f(func(x T) bool { ... })
+		b.rangeFunc(fn, x, s, label)
+		return
+
+	default:
+		panic("Cannot range over: " + rt.String())
+	}
+
+	if s.Tok == token.DEFINE && afterGo122 {
+		// go1.22: If iteration variables are defined (:=), this occurs inside the loop.
+		createVars()
+	}
+
+	// Evaluate both LHS expressions before we update either.
+	var kl, vl lvalue
+	if tk != nil {
+		kl = b.addr(fn, s.Key, false) // non-escaping
+	}
+	if tv != nil {
+		vl = b.addr(fn, s.Value, false) // non-escaping
+	}
+	if tk != nil {
+		kl.store(fn, k, s)
+	}
+	if tv != nil {
+		vl.store(fn, v, s)
+	}
+
+	if label != nil {
+		label._break = done
+		label._continue = loop
+	}
+
+	fn.targets = &targets{
+		tail:      fn.targets,
+		_break:    done,
+		_continue: loop,
+	}
+	b.stmt(fn, s.Body)
+	fn.targets = fn.targets.tail
+	emitJump(fn, loop, source) // back-edge
+	fn.currentBlock = done
+}
+
+// rangeFunc emits to fn code for the range-over-func rng.Body of the iterator
+// function x, optionally labelled by label. It creates a new anonymous function
+// yield for rng and builds the function.
+func (b *builder) rangeFunc(fn *Function, x Value, rng *ast.RangeStmt, label *lblock) {
+	// Consider the SSA code for the outermost range-over-func in fn:
+	//
+	//   func fn(...) (ret R) {
+	//     ...
+	//     for k, v = range x {
+	//           ...
+	//     }
+	//     ...
+	//   }
+	//
+	// The code emitted into fn will look something like this.
+	//
+	// loop:
+	//     jump := READY
+	//     y := make closure yield [ret, deferstack, jump, k, v]
+	//     x(y)
+	//     switch jump {
+	//        [see resuming execution]
+	//     }
+	//     goto done
+	// done:
+	//     ...
+	//
+	// where yield is a new synthetic yield function:
+	//
+	// func yield(_k tk, _v tv) bool
+	//   free variables: [ret, stack, jump, k, v]
+	// {
+	//    entry:
+	//      if jump != READY then goto invalid else valid
+	//    invalid:
+	//      panic("iterator called when it is not in a ready state")
+	//    valid:
+	//      jump = BUSY
+	//      k = _k
+	//      v = _v
+	//    ...
+	//    cont:
+	//      jump = READY
+	//      return true
+	// }
+	//
+	// Yield state:
+	//
+	// Each range loop has an associated jump variable that records
+	// the state of the iterator. A yield function is initially
+	// in a READY (0) and callable state.  If the yield function is called
+	// and is not in READY state, it panics. When it is called in a callable
+	// state, it becomes BUSY. When execution reaches the end of the body
+	// of the loop (or a continue statement targeting the loop is executed),
+	// the yield function returns true and resumes being in a READY state.
+	// After the iterator function x(y) returns, then if the yield function
+	// is in a READY state, the yield enters the DONE state.
+	//
+	// Each lowered control statement (break X, continue X, goto Z, or return)
+	// that exits the loop sets the variable to a unique positive EXIT value,
+	// before returning false from the yield function.
+	//
+	// If the yield function returns abruptly due to a panic or GoExit,
+	// it remains in a BUSY state. The generated code asserts that, after
+	// the iterator call x(y) returns normally, the jump variable state
+	// is DONE.
+	//
+	// Resuming execution:
+	//
+	// The code generated for the range statement checks the jump
+	// variable to determine how to resume execution.
+	//
+	//    switch jump {
+	//    case BUSY:  panic("...")
+	//    case DONE:  goto done
+	//    case READY: state = DONE; goto done
+	//    case 123:   ... // action for exit 123.
+	//    case 456:   ... // action for exit 456.
+	//    ...
+	//    }
+	//
+	// Forward goto statements within a yield are jumps to labels that
+	// have not yet been traversed in fn. They may be in the Body of the
+	// function. What we emit for these is:
+	//
+	//    goto target
+	//  target:
+	//    ...
+	//
+	// We leave an unresolved exit in yield.exits to check at the end
+	// of building yield if it encountered target in the body. If it
+	// encountered target, no additional work is required. Otherwise,
+	// the yield emits a new early exit in the basic block for target.
+	// We expect that blockopt will fuse the early exit into the case
+	// block later. The unresolved exit is then added to yield.parent.exits.
+
+	loop := fn.newBasicBlock("rangefunc.loop")
+	done := fn.newBasicBlock("rangefunc.done")
+
+	// These are targets within y.
+	fn.targets = &targets{
+		tail:   fn.targets,
+		_break: done,
+		// _continue is within y.
+	}
+	if label != nil {
+		label._break = done
+		// _continue is within y
+	}
+
+	emitJump(fn, loop, nil)
+	fn.currentBlock = loop
+
+	// loop:
+	//     jump := READY
+
+	anonIdx := len(fn.AnonFuncs)
+
+	jump := newVar(fmt.Sprintf("jump$%d", anonIdx+1), tInt)
+	emitLocalVar(fn, jump, nil) // zero value is READY
+
+	xsig := typeutil.CoreType(x.Type()).(*types.Signature)
+	ysig := typeutil.CoreType(xsig.Params().At(0).Type()).(*types.Signature)
+
+	/* synthetic yield function for body of range-over-func loop */
+	y := &Function{
+		name:           fmt.Sprintf("%s$%d", fn.Name(), anonIdx+1),
+		Signature:      ysig,
+		Synthetic:      "range-over-func yield",
+		pos:            rng.Range,
+		parent:         fn,
+		anonIdx:        int32(len(fn.AnonFuncs)),
+		Pkg:            fn.Pkg,
+		Prog:           fn.Prog,
+		syntax:         rng,
+		info:           fn.info,
+		build:          (*builder).buildYieldFunc,
+		topLevelOrigin: nil,
+		recvtypeparams: fn.recvtypeparams,
+		recvtypeargs:   fn.recvtypeargs,
+		typeparams:     fn.typeparams,
+		typeargs:       fn.typeargs,
+		subst:          fn.subst,
+	}
+	y.goversion = fn.goversion
+	y.jump = jump
+	y.deferstack = fn.deferstack
+	y.returnVars = fn.returnVars // use the parent's return variables
+	y.uniq = fn.uniq             // start from parent's unique values
+
+	// If the RangeStmt has a label, this is how it is passed to buildYieldFunc.
+	if label != nil {
+		y.lblocks = map[*types.Label]*lblock{label.label: nil}
+	}
+	fn.AnonFuncs = append(fn.AnonFuncs, y)
+
+	// Build y immediately. It may:
+	// * cause fn's locals to escape, and
+	// * create new exit nodes in exits.
+	// (y is not marked 'built' until the end of the enclosing FuncDecl.)
+	unresolved := len(fn.exits)
+	y.build(b, y)
+	fn.uniq = y.uniq // resume after y's unique values
+
+	// Emit the call of y.
+	//   c := MakeClosure y
+	//   x(c)
+	c := &MakeClosure{Fn: y}
+	c.setType(ysig)
+	c.comment = "yield"
+	for _, fv := range y.FreeVars {
+		c.Bindings = append(c.Bindings, fv.outer)
+		fv.outer = nil
+	}
+	fn.emit(c, nil)
+	call := Call{
+		Call: CallCommon{
+			Value: x,
+			Args:  []Value{c},
+		},
+	}
+	call.setType(xsig.Results())
+	fn.emit(&call, nil)
+
+	exits := fn.exits[unresolved:]
+	b.buildYieldResume(fn, jump, exits, done)
+
+	fn.currentBlock = done
+	// pop the stack for the range-over-func
+	fn.targets = fn.targets.tail
+}
+
+// buildYieldResume emits to fn code for how to resume execution once a call to
+// the iterator function over the yield function returns x(y). It does this by building
+// a switch over the value of jump for when it is READY, BUSY, or EXIT(id).
+func (b *builder) buildYieldResume(fn *Function, jump *types.Var, exits []*exit, done *BasicBlock) {
+	//    v := *jump
+	//    switch v {
+	//    case BUSY:    panic("...")
+	//    case READY:   jump = DONE; goto done
+	//    case EXIT(a): ...
+	//    case EXIT(b): ...
+	//    ...
+	//    }
+	v := emitLoad(fn, fn.lookup(jump, false), nil)
+
+	entry := fn.currentBlock
+	bodies := make([]*BasicBlock, 2, 2+len(exits))
+	bodies[0] = fn.newBasicBlock("rangefunc.resume.busy")
+	bodies[1] = fn.newBasicBlock("rangefunc.resume.ready")
+
+	conds := make([]Value, 2, 2+len(exits))
+	conds[0] = jBusy
+	conds[1] = jReady
+
+	fn.currentBlock = bodies[0]
+	fn.emit(
+		&Panic{
+			X: emitConv(fn, jDroppedPanic, tEface, nil),
+		},
+		nil,
+	)
+
+	fn.currentBlock = bodies[1]
+	storeVar(fn, jump, jDone, nil)
+	emitJump(fn, done, nil)
+
+	for _, e := range exits {
+		body := fn.newBasicBlock(fmt.Sprintf("rangefunc.resume.exit.%d", e.id))
+		bodies = append(bodies, body)
+		id := intConst(e.id, nil)
+		conds = append(conds, id)
+
+		fn.currentBlock = body
+		switch {
+		case e.label != nil: // forward goto?
+			// case EXIT(id): goto lb // label
+			lb := fn.lblockOf(e.label)
+			// Do not mark lb as resolved.
+			// If fn does not contain label, lb remains unresolved and
+			// fn must itself be a range-over-func function. lb will be:
+			//   lb:
+			//     fn.jump = id
+			//     return false
+			emitJump(fn, lb._goto, e.source)
+
+		case e.to != fn: // e jumps to an ancestor of fn?
+			// case EXIT(id): { fn.jump = id; return false }
+			// fn is a range-over-func function.
+
+			storeVar(fn, fn.jump, id, e.source)
+			vFalse := NewConst(constant.MakeBool(false), tBool, e.source)
+			fn.emit(&Return{Results: []Value{vFalse}}, e.source)
+
+		case e.block == nil && e.label == nil: // return from fn?
+			// case EXIT(id): { return ... }
+			fn.emit(new(RunDefers), e.source)
+			results := make([]Value, len(fn.results))
+			for i, r := range fn.results {
+				results[i] = emitLoad(fn, r, e.source)
+			}
+			fn.emit(&Return{Results: results}, e.source)
+
+		case e.block != nil:
+			// case EXIT(id): goto block
+			emitJump(fn, e.block, e.source)
+
+		default:
+			panic("unreachable")
+		}
+
+	}
+
+	fn.currentBlock = entry
+	// Note that this switch does not have an implicit default case. This wouldn't be
+	// valid for a user-provided switch statement, but for range-over-func we know all
+	// possible values and we can avoid the impossible branch.
+	swtch := &ConstantSwitch{
+		Tag:   v,
+		Conds: conds,
+	}
+	fn.emit(swtch, nil)
+	for _, body := range bodies {
+		addEdge(entry, body)
+	}
+}
+
+// stmt lowers statement s to IR form, emitting code to fn.
+func (b *builder) stmt(fn *Function, _s ast.Stmt) {
+	// The label of the current statement.  If non-nil, its _goto
+	// target is always set; its _break and _continue are set only
+	// within the body of switch/typeswitch/select/for/range.
+	// It is effectively an additional default-nil parameter of stmt().
+	var label *lblock
+start:
+	switch s := _s.(type) {
+	case *ast.EmptyStmt:
+		// ignore.  (Usually removed by gofmt.)
+
+	case *ast.DeclStmt: // Con, Var or Typ
+		d := s.Decl.(*ast.GenDecl)
+		if d.Tok == token.VAR {
+			for _, spec := range d.Specs {
+				if vs, ok := spec.(*ast.ValueSpec); ok {
+					b.localValueSpec(fn, vs)
+				}
+			}
+		}
+
+	case *ast.LabeledStmt:
+		if s.Label.Name == "_" {
+			// Blank labels can't be the target of a goto, break,
+			// or continue statement, so we don't need a new block.
+			_s = s.Stmt
+			goto start
+		}
+		label = fn.lblockOf(fn.label(s.Label))
+		label.resolved = true
+		emitJump(fn, label._goto, s)
+		fn.currentBlock = label._goto
+		_s = s.Stmt
+		goto start // effectively: tailcall stmt(fn, s.Stmt, label)
+
+	case *ast.ExprStmt:
+		b.expr(fn, s.X)
+
+	case *ast.SendStmt:
+		instr := &Send{
+			Chan: b.expr(fn, s.Chan),
+			X: emitConv(fn, b.expr(fn, s.Value),
+				typeutil.CoreType(fn.typeOf(s.Chan)).(*types.Chan).Elem(), s),
+		}
+		fn.emit(instr, s)
+
+	case *ast.IncDecStmt:
+		op := token.ADD
+		if s.Tok == token.DEC {
+			op = token.SUB
+		}
+		loc := b.addr(fn, s.X, false)
+		b.assignOp(fn, loc, NewConst(constant.MakeInt64(1), loc.typ(), s), op, s)
+
+	case *ast.AssignStmt:
+		switch s.Tok {
+		case token.ASSIGN, token.DEFINE:
+			b.assignStmt(fn, s.Lhs, s.Rhs, s.Tok == token.DEFINE, _s)
+
+		default: // +=, etc.
+			op := s.Tok + token.ADD - token.ADD_ASSIGN
+			b.assignOp(fn, b.addr(fn, s.Lhs[0], false), b.expr(fn, s.Rhs[0]), op, s)
+		}
+
+	case *ast.GoStmt:
+		// The "intrinsics" new/make/len/cap are forbidden here.
+		// panic is treated like an ordinary function call.
+		v := Go{}
+		b.setCall(fn, s.Call, &v.Call)
+		fn.emit(&v, s)
+
+	case *ast.DeferStmt:
+		// The "intrinsics" new/make/len/cap are forbidden here.
+		// panic is treated like an ordinary function call.
+		deferstack := emitLoad(fn, fn.lookup(fn.deferstack, false), s)
+		v := Defer{DeferStack: deferstack}
+		b.setCall(fn, s.Call, &v.Call)
+		fn.emit(&v, s)
+
+		// A deferred call can cause recovery from panic,
+		// and control resumes at the Recover block.
+		createRecoverBlock(fn.source)
+
+	case *ast.ReturnStmt:
+		b.returnStmt(fn, s)
+
+	case *ast.BranchStmt:
+		b.branchStmt(fn, s)
+
+	case *ast.BlockStmt:
+		b.stmtList(fn, s.List)
+
+	case *ast.IfStmt:
+		if s.Init != nil {
+			b.stmt(fn, s.Init)
+		}
+		then := fn.newBasicBlock("if.then")
+		done := fn.newBasicBlock("if.done")
+		els := done
+		if s.Else != nil {
+			els = fn.newBasicBlock("if.else")
+		}
+		instr := b.cond(fn, s.Cond, then, els)
+		instr.source = s
+		fn.currentBlock = then
+		b.stmt(fn, s.Body)
+		emitJump(fn, done, s)
+
+		if s.Else != nil {
+			fn.currentBlock = els
+			b.stmt(fn, s.Else)
+			emitJump(fn, done, s)
+		}
+
+		fn.currentBlock = done
+
+	case *ast.SwitchStmt:
+		b.switchStmt(fn, s, label)
+
+	case *ast.TypeSwitchStmt:
+		b.typeSwitchStmt(fn, s, label)
+
+	case *ast.SelectStmt:
+		if b.selectStmt(fn, s, label) {
+			// the select has no cases, it blocks forever
+			fn.currentBlock = fn.newBasicBlock("unreachable")
+		}
+
+	case *ast.ForStmt:
+		b.forStmt(fn, s, label)
+
+	case *ast.RangeStmt:
+		b.rangeStmt(fn, s, label, s)
+
+	default:
+		panic(fmt.Sprintf("unexpected statement kind: %T", s))
+	}
+}
+
+func (b *builder) branchStmt(fn *Function, s *ast.BranchStmt) {
+	var block *BasicBlock
+	if s.Label == nil {
+		block = targetedBlock(fn, s.Tok)
+	} else {
+		target := fn.label(s.Label)
+		block = labelledBlock(fn, target, s.Tok)
+		if block == nil { // forward goto
+			lb := fn.lblockOf(target)
+			block = lb._goto // jump to lb._goto
+			if fn.jump != nil {
+				// fn is a range-over-func and the goto may exit fn.
+				// Create an exit and resolve it at the end of
+				// builder.buildYieldFunc.
+				labelExit(fn, target, s)
+			}
+		}
+	}
+	to := block.parent
+
+	if to == fn {
+		emitJump(fn, block, s)
+	} else { // break outside of fn.
+		// fn must be a range-over-func
+		e := blockExit(fn, block, s)
+		id := intConst(e.id, s)
+		storeVar(fn, fn.jump, id, s)
+		vFalse := NewConst(constant.MakeBool(false), tBool, s)
+		fn.emit(&Return{Results: []Value{vFalse}}, e.source)
+	}
+	fn.currentBlock = fn.newBasicBlock("unreachable")
+}
+
+func (b *builder) returnStmt(fn *Function, s *ast.ReturnStmt) {
+	// TODO(dh): we could emit tighter position information by
+	// using the ith returned expression
+
+	var results []Value
+
+	sig := fn.source.Signature // signature of the enclosing source function
+
+	// Convert return operands to result type.
+	if len(s.Results) == 1 && sig.Results().Len() > 1 {
+		// Return of one expression in a multi-valued function.
+		tuple := b.exprN(fn, s.Results[0])
+		ttuple := tuple.Type().(*types.Tuple)
+		for i, n := 0, ttuple.Len(); i < n; i++ {
+			results = append(results,
+				emitConv(fn, emitExtract(fn, tuple, i, s),
+					sig.Results().At(i).Type(), s))
+		}
+	} else {
+		// 1:1 return, or no-arg return in non-void function.
+		for i, r := range s.Results {
+			v := emitConv(fn, b.expr(fn, r), sig.Results().At(i).Type(), s)
+			results = append(results, v)
+		}
+	}
+
+	// Store the results.
+	for i, r := range results {
+		var result Value // fn.sourceFn.result[i] conceptually
+		if fn == fn.source {
+			result = fn.results[i]
+		} else { // lookup needed?
+			result = fn.lookup(fn.returnVars[i], false)
+		}
+		emitStore(fn, result, r, s)
+	}
+
+	if fn.jump != nil {
+		// Return from body of a range-over-func.
+		// The return statement is syntactically within the loop,
+		// but the generated code is in the 'switch jump {...}' after it.
+		e := returnExit(fn, s)
+		id := intConst(e.id, e.source)
+		storeVar(fn, fn.jump, id, e.source)
+		vFalse := NewConst(constant.MakeBool(false), tBool, e.source)
+		fn.emit(&Return{Results: []Value{vFalse}}, e.source)
+		fn.currentBlock = fn.newBasicBlock("unreachable")
+		return
+	}
+
+	// Run function calls deferred in this
+	// function when explicitly returning from it.
+	fn.emit(new(RunDefers), s)
+	// Reload (potentially) named result variables to form the result tuple.
+	results = results[:0]
+	for _, nr := range fn.results {
+		results = append(results, emitLoad(fn, nr, s))
+	}
+
+	fn.emit(&Return{Results: results}, s)
+	fn.currentBlock = fn.newBasicBlock("unreachable")
+}
+
+// A buildFunc is a strategy for building the SSA body for a function.
+type buildFunc = func(*builder, *Function)
+
+// iterate causes all created but unbuilt functions to be built. As
+// this may create new methods, the process is iterated until it
+// converges.
+//
+// Waits for any dependencies to finish building.
+func (b *builder) iterate() {
+	for ; b.finished < len(b.fns); b.finished++ {
+		fn := b.fns[b.finished]
+		b.buildFunction(fn)
+	}
+
+	b.buildshared.markDone()
+	b.buildshared.wait()
+}
+
+// buildFunction builds IR code for the body of function fn.  Idempotent.
+func (b *builder) buildFunction(fn *Function) {
+	if fn.build != nil {
+		assert(fn.parent == nil, "anonymous functions should not be built by buildFunction()")
+
+		if fn.Prog.mode&LogSource != 0 {
+			defer logStack("build %s @ %s", fn, fn.Prog.Fset.Position(fn.pos))()
+		}
+		fn.build(b, fn)
+		fn.done()
+	}
+}
+
+// buildParamsOnly builds fn.Params from fn.Signature, but does not build fn.Body.
+func (b *builder) buildParamsOnly(fn *Function) {
+	// For external (C, asm) functions or functions loaded from
+	// export data, we must set fn.Params even though there is no
+	// body code to reference them.
+	if recv := fn.Signature.Recv(); recv != nil {
+		// TODO(dh): should we synthesize a node so we have position info?
+		fn.addParamVar(recv, nil)
+	}
+	params := fn.Signature.Params()
+	for i, n := 0, params.Len(); i < n; i++ {
+		// TODO(dh): should we synthesize a node so we have position info?
+		fn.addParamVar(params.At(i), nil)
+	}
+
+	// clear out other function state (keep consistent with finishBody)
+	fn.subst = nil
+	if !fn.isGenericOrigin() {
+		fn.info = nil
+	}
+}
+
+// buildFromSyntax builds fn.Body from fn.syntax, which must be non-nil.
+func (b *builder) buildFromSyntax(fn *Function) {
+	var (
+		recvField *ast.FieldList
+		body      *ast.BlockStmt
+		functype  *ast.FuncType
+	)
+	switch syntax := fn.syntax.(type) {
+	case *ast.FuncDecl:
+		functype = syntax.Type
+		recvField = syntax.Recv
+		body = syntax.Body
+		if body == nil {
+			b.buildParamsOnly(fn) // no body (non-Go function)
+			return
+		}
+	case *ast.FuncLit:
+		functype = syntax.Type
+		body = syntax.Body
+	case nil:
+		panic("no syntax")
+	default:
+		panic(syntax) // unexpected syntax
+	}
+	fn.source = fn
+	fn.startBody()
+	fn.createSyntacticParams(recvField, functype)
+	fn.createDeferStack()
+	b.stmt(fn, body)
+	if cb := fn.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb == fn.Recover || cb.Preds != nil) {
+		// Control fell off the end of the function's body block.
+		//
+		// Block optimizations eliminate the current block, if
+		// unreachable.  It is a builder invariant that
+		// if this no-arg return is ill-typed for
+		// fn.Signature.Results, this block must be
+		// unreachable.  The sanity checker checks this.
+		fn.emit(new(RunDefers), nil)
+		fn.emit(new(Return), nil)
+	}
+	fn.finishBody()
+}
+
+// buildYieldFunc builds the body of the yield function created
+// from a range-over-func *ast.RangeStmt.
+func (b *builder) buildYieldFunc(fn *Function) {
+	// See builder.rangeFunc for detailed documentation on how fn is set up.
+	//
+	// In pseudo-Go this roughly builds:
+	// func yield(_k tk, _v tv) bool {
+	// 	   if jump != READY { panic("yield function called after range loop exit") }
+	//     jump = BUSY
+	//     k, v = _k, _v // assign the iterator variable (if needed)
+	//     ... // rng.Body
+	//   continue:
+	//     jump = READY
+	//     return true
+	// }
+	s := fn.syntax.(*ast.RangeStmt)
+	fn.source = fn.parent.source
+	fn.startBody()
+	params := fn.Signature.Params()
+	for v := range params.Variables() {
+		fn.addParamVar(v, nil)
+	}
+
+	// Initial targets
+	ycont := fn.newBasicBlock("yield-continue")
+	// lblocks is either {} or is {label: nil} where label is the label of syntax.
+	for label := range fn.lblocks {
+		fn.lblocks[label] = &lblock{
+			label:     label,
+			resolved:  true,
+			_continue: ycont,
+			// `goto label` searches the parent lblock, and
+			// `break label` targets fn.parent.targets._break.
+		}
+	}
+	fn.targets = &targets{
+		tail:      fn.targets,
+		_continue: ycont,
+		// `break` statement targets fn.parent.targets._break.
+	}
+
+	// continue:
+	//   jump = READY
+	//   return true
+	saved := fn.currentBlock
+	fn.currentBlock = ycont
+	storeVar(fn, fn.jump, jReady, s.Body)
+	// A yield function's own deferstack is always empty, so rundefers is not needed.
+	fn.emit(&Return{Results: []Value{vTrue}}, nil)
+
+	// Emit header:
+	//
+	//   if jump != READY { panic("yield iterator accessed after exit") }
+	//   jump = BUSY
+	//   k, v = _k, _v
+	fn.currentBlock = saved
+	yloop := fn.newBasicBlock("yield-loop")
+	invalid := fn.newBasicBlock("yield-invalid")
+
+	jumpVal := emitLoad(fn, fn.lookup(fn.jump, true), nil)
+	emitIf(fn, emitCompare(fn, token.EQL, jumpVal, jReady, nil), yloop, invalid, nil)
+	fn.currentBlock = invalid
+	fn.emit(
+		&Panic{
+			X: emitConv(fn, jLateYield, tEface, nil),
+		},
+		nil,
+	)
+
+	fn.currentBlock = yloop
+	storeVar(fn, fn.jump, jBusy, s.Body)
+
+	// Initialize k and v from params.
+	var tk, tv types.Type
+	if s.Key != nil && !isBlankIdent(s.Key) {
+		tk = fn.typeOf(s.Key) // fn.parent.typeOf is identical
+	}
+	if s.Value != nil && !isBlankIdent(s.Value) {
+		tv = fn.typeOf(s.Value)
+	}
+	if s.Tok == token.DEFINE {
+		if tk != nil {
+			emitLocalVar(fn, identVar(fn, s.Key.(*ast.Ident)), s.Key)
+		}
+		if tv != nil {
+			emitLocalVar(fn, identVar(fn, s.Value.(*ast.Ident)), s.Value)
+		}
+	}
+	var k, v Value
+	if len(fn.Params) > 0 {
+		k = fn.Params[0]
+	}
+	if len(fn.Params) > 1 {
+		v = fn.Params[1]
+	}
+	var kl, vl lvalue
+	if tk != nil {
+		kl = b.addr(fn, s.Key, false) // non-escaping
+	}
+	if tv != nil {
+		vl = b.addr(fn, s.Value, false) // non-escaping
+	}
+	if tk != nil {
+		kl.store(fn, k, s.Key)
+	}
+	if tv != nil {
+		vl.store(fn, v, s.Value)
+	}
+
+	// Build the body of the range loop.
+	b.stmt(fn, s.Body)
+	if cb := fn.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb == fn.Recover || cb.Preds != nil) {
+		// Control fell off the end of the function's body block.
+		// Block optimizations eliminate the current block, if
+		// unreachable.
+		emitJump(fn, ycont, nil)
+	}
+	// pop the stack for the yield function
+	fn.targets = fn.targets.tail
+
+	// Clean up exits and promote any unresolved exits to fn.parent.
+	for _, e := range fn.exits {
+		if e.label != nil {
+			lb := fn.lblocks[e.label]
+			if lb.resolved {
+				// label was resolved. Do not turn lb into an exit.
+				// e does not need to be handled by the parent.
+				continue
+			}
+
+			// _goto becomes an exit.
+			//   _goto:
+			//     jump = id
+			//     return false
+			fn.currentBlock = lb._goto
+			id := intConst(e.id, e.source)
+			storeVar(fn, fn.jump, id, e.source)
+			vFalse := NewConst(constant.MakeBool(false), tBool, e.source)
+			fn.emit(&Return{Results: []Value{vFalse}}, e.source)
+		}
+
+		if e.to != fn { // e needs to be handled by the parent too.
+			fn.parent.exits = append(fn.parent.exits, e)
+		}
+	}
+
+	fn.finishBody()
+}
+
+// addMakeInterfaceType records non-interface type t as the type of
+// the operand a MakeInterface operation, for [Program.RuntimeTypes].
+//
+// Acquires prog.makeInterfaceTypesMu.
+func addMakeInterfaceType(prog *Program, t types.Type) {
+	prog.makeInterfaceTypesMu.Lock()
+	defer prog.makeInterfaceTypesMu.Unlock()
+	if prog.makeInterfaceTypes == nil {
+		prog.makeInterfaceTypes = make(map[types.Type]unit)
+	}
+	prog.makeInterfaceTypes[t] = unit{}
+}
+
+// Build calls Package.Build for each package in prog.
+// Building occurs in parallel unless the BuildSerially mode flag was set.
+//
+// Build is intended for whole-program analysis; a typical compiler
+// need only build a single package.
+//
+// Build is idempotent and thread-safe.
+func (prog *Program) Build() {
+	var wg sync.WaitGroup
+	for _, p := range prog.packages {
+		if prog.mode&BuildSerially != 0 {
+			p.Build()
+		} else {
+			wg.Add(1)
+			cpuLimit <- unit{} // acquire a token
+			go func(p *Package) {
+				p.Build()
+				wg.Done()
+				<-cpuLimit // release a token
+			}(p)
+		}
+	}
+	wg.Wait()
+}
+
+// cpuLimit is a counting semaphore to limit CPU parallelism.
+var cpuLimit = make(chan unit, runtime.GOMAXPROCS(0))
+
+// Build builds IR code for all functions and vars in package p.
+//
+// CreatePackage must have been called for all of p's direct imports
+// (and hence its direct imports must have been error-free). It is not
+// necessary to call CreatePackage for indirect dependencies.
+// Functions will be created for all necessary methods in those
+// packages on demand.
+//
+// Build is idempotent and thread-safe.
+func (p *Package) Build() { p.buildOnce.Do(p.build) }
+
+func (p *Package) build() {
+	if p.info == nil {
+		return // synthetic package, e.g. "testmain"
+	}
+	if p.Prog.mode&LogSource != 0 {
+		defer logStack("build %s", p)()
+	}
+
+	b := builder{fns: p.created}
+	b.iterate()
+
+	// We no longer need transient information: ASTs or go/types deductions.
+	p.info = nil
+	p.created = nil
+	p.files = nil
+	p.initVersion = nil
+
+	if p.Prog.mode&SanityCheckFunctions != 0 {
+		sanityCheckPackage(p)
+	}
+}
+
+// buildPackageInit builds fn.Body for the synthetic package initializer.
+func (b *builder) buildPackageInit(init *Function) {
+	p := init.Pkg
+	init.startBody()
+
+	var done *BasicBlock
+
+	if p.Prog.mode&BareInits == 0 {
+		// Make init() skip if package is already initialized.
+		initguard := p.Var("init$guard")
+		doinit := init.newBasicBlock("init.start")
+		done = init.newBasicBlock("init.done")
+		emitIf(init, emitLoad(init, initguard, nil), done, doinit, nil)
+		init.currentBlock = doinit
+		emitStore(init, initguard, vTrue, nil)
+
+		// Call the init() function of each package we import.
+		for _, pkg := range p.Pkg.Imports() {
+			prereq := p.Prog.packages[pkg]
+			if prereq == nil {
+				panic(fmt.Sprintf("Package(%q).Build(): unsatisfied import: Program.CreatePackage(%q) was not called", p.Pkg.Path(), pkg.Path()))
+			}
+			var v Call
+			v.Call.Value = prereq.init
+			v.setType(types.NewTuple())
+			init.emit(&v, nil)
+		}
+	}
+
+	// Initialize package-level vars in correct order.
+	if len(p.info.InitOrder) > 0 && len(p.files) == 0 {
+		panic("no source files provided for package. cannot initialize globals")
+	}
+
+	for _, varinit := range p.info.InitOrder {
+		if init.Prog.mode&LogSource != 0 {
+			fmt.Fprintf(os.Stderr, "build global initializer %v @ %s\n",
+				varinit.Lhs, p.Prog.Fset.Position(varinit.Rhs.Pos()))
+		}
+		// Initializers for global vars are evaluated in dependency
+		// order, but may come from arbitrary files of the package
+		// with different versions, so we transiently update
+		// init.goversion for each one. (Since init is a synthetic
+		// function it has no syntax of its own that needs a version.)
+		init.goversion = p.initVersion[varinit.Rhs]
+		if len(varinit.Lhs) == 1 {
+			// 1:1 initialization: var x, y = a(), b()
+			var lval lvalue
+			if v := varinit.Lhs[0]; v.Name() != "_" {
+				lval = &address{addr: p.values[v].(*Global)}
+			} else {
+				lval = blank{}
+			}
+			// TODO(dh): do emit position information
+			b.assign(init, lval, varinit.Rhs, true, nil, nil)
+		} else {
+			// n:1 initialization: var x, y :=  f()
+			tuple := b.exprN(init, varinit.Rhs)
+			for i, v := range varinit.Lhs {
+				if v.Name() == "_" {
+					continue
+				}
+				emitStore(init, p.values[v].(*Global), emitExtract(init, tuple, i, nil), nil)
+			}
+		}
+	}
+
+	// The rest of the init function is synthetic:
+	// no syntax, info, goversion.
+	init.info = nil
+	init.goversion = ""
+
+	// Call all of the declared init() functions in source order.
+	for _, file := range p.files {
+		for _, decl := range file.Decls {
+			if decl, ok := decl.(*ast.FuncDecl); ok {
+				id := decl.Name
+				if !isBlankIdent(id) && id.Name == "init" && decl.Recv == nil {
+					declaredInit := p.values[p.info.Defs[id]].(*Function)
+					var v Call
+					v.Call.Value = declaredInit
+					v.setType(types.NewTuple())
+					p.init.emit(&v, nil)
+				}
+			}
+		}
+	}
+
+	// Finish up init().
+	if p.Prog.mode&BareInits == 0 {
+		emitJump(init, done, nil)
+		init.currentBlock = done
+	}
+	init.emit(new(Return), nil)
+	init.finishBody()
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/const.go b/vendor/honnef.co/go/tools/go/ir/const.go
new file mode 100644
index 0000000..ebe134e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/const.go
@@ -0,0 +1,243 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file defines the Const SSA value type.
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/types"
+	"strconv"
+
+	"golang.org/x/exp/typeparams"
+	"honnef.co/go/tools/internal/xtools-internal/typesinternal"
+)
+
+// soleTypeKind returns a BasicInfo for which constant.Value can
+// represent all zero values for the types in the type set.
+//
+//	types.IsBoolean for false is a representative.
+//	types.IsInteger for 0
+//	types.IsString for ""
+//	0 otherwise.
+func soleTypeKind(typ types.Type) types.BasicInfo {
+	// State records the set of possible zero values (false, 0, "").
+	// Candidates (perhaps all) are eliminated during the type-set
+	// iteration, which executes at least once.
+	state := types.IsBoolean | types.IsInteger | types.IsString
+	underIs(typ, func(ut types.Type) bool {
+		var c types.BasicInfo
+		if t, ok := ut.(*types.Basic); ok {
+			c = t.Info()
+		}
+		if c&types.IsNumeric != 0 { // int/float/complex
+			c = types.IsInteger
+		}
+		state = state & c
+		return state != 0
+	})
+	return state
+}
+
+// NewConst returns a new constant of the specified value and type.
+// val must be valid according to the specification of Const.Value.
+func NewConst(val constant.Value, typ types.Type, source ast.Node) *Const {
+	if val == nil {
+		switch soleTypeKind(typ) {
+		case types.IsBoolean:
+			val = constant.MakeBool(false)
+		case types.IsInteger:
+			val = constant.MakeInt64(0)
+		case types.IsString:
+			val = constant.MakeString("")
+		}
+	}
+	c := &Const{
+		typ:   typ,
+		Value: val,
+	}
+	c.setSource(source)
+	return c
+}
+
+// intConst returns an 'int' constant that evaluates to i.
+// (i is an int64 in case the host is narrower than the target.)
+func intConst(i int64, source ast.Node) *Const {
+	return NewConst(constant.MakeInt64(i), tInt, source)
+}
+
+// nilConst returns a nil constant of the specified type, which may
+// be any reference type, including interfaces.
+func nilConst(typ types.Type, source ast.Node) *Const {
+	return NewConst(nil, typ, source)
+}
+
+// stringConst returns a 'string' constant that evaluates to s.
+func stringConst(s string, source ast.Node) *Const {
+	return NewConst(constant.MakeString(s), tString, source)
+}
+
+// zeroConst returns a new "zero" constant of the specified type.
+func zeroConst(t types.Type, source ast.Node) Constant {
+	return NewConst(nil, t, source)
+}
+
+func (c *Const) RelString(from *types.Package) string {
+	var p string
+	if c.Value == nil {
+		switch c.typ.(type) {
+		case *types.Array, *types.Struct:
+			p = "{}"
+		case *types.Alias:
+			switch c.typ.Underlying().(type) {
+			case *types.Array, *types.Struct:
+				p = "{}"
+			default:
+				p, _ = typesinternal.ZeroString(types.Unalias(c.typ), types.RelativeTo(from))
+			}
+		default:
+			p, _ = typesinternal.ZeroString(c.typ, types.RelativeTo(from))
+		}
+	} else if c.Value.Kind() == constant.String {
+		v := constant.StringVal(c.Value)
+		const max = 20
+		// TODO(adonovan): don't cut a rune in half.
+		if len(v) > max {
+			v = v[:max-3] + "..." // abbreviate
+		}
+		p = strconv.Quote(v)
+	} else {
+		p = c.Value.String()
+	}
+	return p + ":" + relType(c.Type(), from)
+}
+
+func (c *Const) Name() string {
+	return c.RelString(nil)
+}
+
+func (c *Const) String() string {
+	return c.RelString(nil)
+}
+
+func (c *Const) Type() types.Type {
+	return c.typ
+}
+
+func (c *Const) Referrers() *[]Instruction {
+	return nil
+}
+
+func (c *Const) Parent() *Function { return nil }
+
+func (v *AggregateConst) RelString(pkg *types.Package) string {
+	var b bytes.Buffer
+	fmt.Fprint(&b, "const {")
+	for i, vv := range v.Values {
+		if i > 0 {
+			fmt.Fprint(&b, ", ")
+		}
+		fmt.Fprint(&b, relName(vv, v))
+	}
+	fmt.Fprint(&b, "}")
+	return b.String()
+}
+
+func (v *AggregateConst) Name() string {
+	return v.RelString(nil)
+}
+
+func (v *AggregateConst) String() string {
+	return v.RelString(nil)
+}
+
+func (v *AggregateConst) Type() types.Type {
+	return v.typ
+}
+
+func (v *AggregateConst) Referrers() *[]Instruction {
+	return nil
+}
+
+func (v *AggregateConst) Parent() *Function { return nil }
+
+// IsNil returns true if this constant represents a typed or untyped nil value.
+func (c *Const) IsNil() bool {
+	return c.Value == nil && nillable(c.typ)
+}
+
+// nillable reports whether *new(T) == nil is legal for type T.
+func nillable(t types.Type) bool {
+	if typeparams.IsTypeParam(t) {
+		return underIs(t, func(u types.Type) bool {
+			// empty type set (u==nil) => any underlying types => not nillable
+			return u != nil && nillable(u)
+		})
+	}
+	switch t := t.Underlying().(type) {
+	case *types.Basic:
+		return t.Kind() == types.UnsafePointer
+	case *types.Pointer, *types.Slice, *types.Chan, *types.Map, *types.Signature:
+		return true
+	case *types.Interface:
+		return true // basic interface.
+	default:
+		return false
+	}
+}
+
+// TODO(adonovan): move everything below into honnef.co/go/tools/go/ir/interp.
+
+// Int64 returns the numeric value of this constant truncated to fit
+// a signed 64-bit integer.
+func (c *Const) Int64() int64 {
+	switch x := constant.ToInt(c.Value); x.Kind() {
+	case constant.Int:
+		if i, ok := constant.Int64Val(x); ok {
+			return i
+		}
+		return 0
+	case constant.Float:
+		f, _ := constant.Float64Val(x)
+		return int64(f)
+	}
+	panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
+}
+
+// Uint64 returns the numeric value of this constant truncated to fit
+// an unsigned 64-bit integer.
+func (c *Const) Uint64() uint64 {
+	switch x := constant.ToInt(c.Value); x.Kind() {
+	case constant.Int:
+		if u, ok := constant.Uint64Val(x); ok {
+			return u
+		}
+		return 0
+	case constant.Float:
+		f, _ := constant.Float64Val(x)
+		return uint64(f)
+	}
+	panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
+}
+
+// Float64 returns the numeric value of this constant truncated to fit
+// a float64.
+func (c *Const) Float64() float64 {
+	x := constant.ToFloat(c.Value) // (c.Value == nil) => x.Kind() == Unknown
+	f, _ := constant.Float64Val(x)
+	return f
+}
+
+// Complex128 returns the complex value of this constant truncated to
+// fit a complex128.
+func (c *Const) Complex128() complex128 {
+	x := constant.ToComplex(c.Value) // (c.Value == nil) => x.Kind() == Unknown
+	re, _ := constant.Float64Val(constant.Real(x))
+	im, _ := constant.Float64Val(constant.Imag(x))
+	return complex(re, im)
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/create.go b/vendor/honnef.co/go/tools/go/ir/create.go
new file mode 100644
index 0000000..f5656e2
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/create.go
@@ -0,0 +1,319 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file implements the CREATE phase of IR construction.
+// See builder.go for explanation.
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"os"
+	"sync"
+
+	"honnef.co/go/tools/internal/xtools-internal/versions"
+)
+
+// NewProgram returns a new IR Program.
+//
+// mode controls diagnostics and checking during IR construction.
+//
+// To construct an SSA program:
+//
+//   - Call NewProgram to create an empty Program.
+//   - Call CreatePackage providing typed syntax for each package
+//     you want to build, and call it with types but not
+//     syntax for each of those package's direct dependencies.
+//   - Call [Package.Build] on each syntax package you wish to build,
+//     or [Program.Build] to build all of them.
+//
+// See the Example tests for simple examples.
+func NewProgram(fset *token.FileSet, mode BuilderMode) *Program {
+	return &Program{
+		Fset:     fset,
+		imported: make(map[string]*Package),
+		packages: make(map[*types.Package]*Package),
+		mode:     mode,
+		canon:    newCanonizer(),
+		ctxt:     types.NewContext(),
+	}
+}
+
+// memberFromObject populates package pkg with a member for the
+// typechecker object obj.
+//
+// For objects from Go source code, syntax is the associated syntax tree
+// (for funcs and vars only) and goversion defines the appropriate
+// interpretation; they will be used during the build phase.
+func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node, goversion string) {
+	name := obj.Name()
+	switch obj := obj.(type) {
+	case *types.Builtin:
+		if pkg.Pkg != types.Unsafe {
+			panic("unexpected builtin object: " + obj.String())
+		}
+
+	case *types.TypeName:
+		if name != "_" {
+			pkg.Members[name] = &Type{
+				object: obj,
+				pkg:    pkg,
+			}
+		}
+
+	case *types.Const:
+		c := &NamedConst{
+			object: obj,
+			Value:  NewConst(obj.Val(), obj.Type(), syntax),
+			pkg:    pkg,
+		}
+		pkg.values[obj] = c
+		if name != "_" {
+			pkg.Members[name] = c
+		}
+
+	case *types.Var:
+		g := &Global{
+			Pkg:    pkg,
+			name:   name,
+			object: obj,
+			typ:    types.NewPointer(obj.Type()), // address
+		}
+		g.source = syntax
+		pkg.values[obj] = g
+		if name != "_" {
+			pkg.Members[name] = g
+		}
+
+	case *types.Func:
+		sig := obj.Type().(*types.Signature)
+		if sig.Recv() == nil && name == "init" {
+			pkg.ninit++
+			name = fmt.Sprintf("init#%d", pkg.ninit)
+		}
+		fn := createFunction(pkg.Prog, obj, name, syntax, pkg.info, goversion)
+		fn.Pkg = pkg
+		pkg.created = append(pkg.created, fn)
+		pkg.values[obj] = fn
+		pkg.Functions = append(pkg.Functions, fn)
+		if name != "_" && sig.Recv() == nil {
+			pkg.Members[name] = fn // package-level function
+		}
+
+	default: // (incl. *types.Package)
+		panic("unexpected Object type: " + obj.String())
+	}
+}
+
+// createFunction creates a function or method. It supports both
+// CreatePackage (with or without syntax) and the on-demand creation
+// of methods in non-created packages based on their types.Func.
+func createFunction(prog *Program, obj *types.Func, name string, syntax ast.Node, info *types.Info, goversion string) *Function {
+	sig := obj.Type().(*types.Signature)
+
+	/* declared function/method (from syntax or export data) */
+	fn := &Function{
+		name:           name,
+		object:         obj,
+		Signature:      sig,
+		build:          (*builder).buildFromSyntax,
+		info:           info,
+		goversion:      goversion,
+		pos:            obj.Pos(),
+		syntax:         syntax,
+		Pkg:            nil, // may be set by caller
+		Prog:           prog,
+		recvtypeparams: sig.RecvTypeParams(),
+		typeparams:     sig.TypeParams(),
+	}
+	if syntax == nil {
+		fn.Synthetic = "from type information"
+		fn.build = (*builder).buildParamsOnly
+	}
+	if fn.hasTypeParams() {
+		fn.generic = new(generic)
+	}
+	return fn
+}
+
+// membersFromDecl populates package pkg with members for each
+// typechecker object (var, func, const or type) associated with the
+// specified decl.
+func membersFromDecl(pkg *Package, decl ast.Decl, goversion string) {
+	switch decl := decl.(type) {
+	case *ast.GenDecl: // import, const, type or var
+		switch decl.Tok {
+		case token.CONST:
+			for _, spec := range decl.Specs {
+				for _, id := range spec.(*ast.ValueSpec).Names {
+					memberFromObject(pkg, pkg.info.Defs[id], nil, "")
+				}
+			}
+
+		case token.VAR:
+			for _, spec := range decl.Specs {
+				for _, rhs := range spec.(*ast.ValueSpec).Values {
+					pkg.initVersion[rhs] = goversion
+				}
+				for _, id := range spec.(*ast.ValueSpec).Names {
+					memberFromObject(pkg, pkg.info.Defs[id], spec, goversion)
+				}
+			}
+
+		case token.TYPE:
+			for _, spec := range decl.Specs {
+				id := spec.(*ast.TypeSpec).Name
+				memberFromObject(pkg, pkg.info.Defs[id], nil, "")
+			}
+		}
+
+	case *ast.FuncDecl:
+		id := decl.Name
+		memberFromObject(pkg, pkg.info.Defs[id], decl, goversion)
+	}
+}
+
+// CreatePackage creates and returns an IR Package from the
+// specified type-checked, error-free file ASTs, and populates its
+// Members mapping.
+//
+// importable determines whether this package should be returned by a
+// subsequent call to ImportedPackage(pkg.Path()).
+//
+// The real work of building IR form for each function is not done
+// until a subsequent call to Package.Build.
+func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *types.Info, importable bool) *Package {
+	if pkg == nil {
+		panic("nil pkg") // otherwise pkg.Scope below returns types.Universe!
+	}
+	p := &Package{
+		Prog:    prog,
+		Members: make(map[string]Member),
+		values:  make(map[types.Object]Member),
+		Pkg:     pkg,
+		syntax:  info != nil,
+		// transient values (cleared after Package.Build)
+		info:        info,
+		files:       files,
+		initVersion: make(map[ast.Expr]string),
+	}
+
+	/* synthesized package initializer */
+	p.init = &Function{
+		name:      "init",
+		Signature: new(types.Signature),
+		Synthetic: "package initializer",
+		Pkg:       p,
+		Prog:      prog,
+		build:     (*builder).buildPackageInit,
+		info:      p.info,
+		goversion: "", // See Package.build for details.
+	}
+	p.Members[p.init.name] = p.init
+	p.Functions = append(p.Functions, p.init)
+	p.created = append(p.created, p.init)
+
+	// Allocate all package members: vars, funcs, consts and types.
+	if len(files) > 0 {
+		// Go source package.
+		for _, file := range files {
+			goversion := versions.Lang(versions.FileVersion(p.info, file))
+			for _, decl := range file.Decls {
+				membersFromDecl(p, decl, goversion)
+			}
+		}
+	} else {
+		// GC-compiled binary package (or "unsafe")
+		// No code.
+		// No position information.
+		scope := p.Pkg.Scope()
+		for _, name := range scope.Names() {
+			obj := scope.Lookup(name)
+			memberFromObject(p, obj, nil, "")
+			if obj, ok := obj.(*types.TypeName); ok {
+				// No Unalias: aliases should not duplicate methods.
+				if named, ok := obj.Type().(*types.Named); ok {
+					for i, n := 0, named.NumMethods(); i < n; i++ {
+						memberFromObject(p, named.Method(i), nil, "")
+					}
+				}
+			}
+		}
+	}
+
+	if prog.mode&BareInits == 0 {
+		// Add initializer guard variable.
+		initguard := &Global{
+			Pkg:  p,
+			name: "init$guard",
+			typ:  types.NewPointer(tBool),
+		}
+		p.Members[initguard.Name()] = initguard
+	}
+
+	if prog.mode&GlobalDebug != 0 {
+		p.SetDebugMode(true)
+	}
+
+	if prog.mode&PrintPackages != 0 {
+		printMu.Lock()
+		p.WriteTo(os.Stdout)
+		printMu.Unlock()
+	}
+
+	if importable {
+		prog.imported[p.Pkg.Path()] = p
+	}
+	prog.packages[p.Pkg] = p
+
+	return p
+}
+
+// printMu serializes printing of Packages/Functions to stdout.
+var printMu sync.Mutex
+
+// AllPackages returns a new slice containing all packages created by
+// prog.CreatePackage in unspecified order.
+func (prog *Program) AllPackages() []*Package {
+	pkgs := make([]*Package, 0, len(prog.packages))
+	for _, pkg := range prog.packages {
+		pkgs = append(pkgs, pkg)
+	}
+	return pkgs
+}
+
+// ImportedPackage returns the importable Package whose PkgPath
+// is path, or nil if no such Package has been created.
+//
+// A parameter to CreatePackage determines whether a package should be
+// considered importable. For example, no import declaration can resolve
+// to the ad-hoc main package created by 'go build foo.go'.
+//
+// TODO(adonovan): rethink this function and the "importable" concept;
+// most packages are importable. This function assumes that all
+// types.Package.Path values are unique within the ir.Program, which is
+// false---yet this function remains very convenient.
+// Clients should use (*Program).Package instead where possible.
+// IR doesn't really need a string-keyed map of packages.
+//
+// Furthermore, the graph of packages may contain multiple variants
+// (e.g. "p" vs "p as compiled for q.test"), and each has a different
+// view of its dependencies.
+func (prog *Program) ImportedPackage(path string) *Package {
+	return prog.imported[path]
+}
+
+// SetNoReturn sets the predicate used when building the ir.Program
+// prog that reports whether a given function cannot return.
+// This may be used to prune spurious control flow edges
+// after (e.g.) log.Fatal, improving the precision of analyses.
+//
+// A typical implementation is the [ctrlflow.CFGs.NoReturn] method from
+// [golang.org/x/tools/go/analysis/passes/ctrlflow].
+func (prog *Program) SetNoReturn(fn func(*types.Func) bool) {
+	prog.noReturn = fn
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/doc.go b/vendor/honnef.co/go/tools/go/ir/doc.go
new file mode 100644
index 0000000..13e4749
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/doc.go
@@ -0,0 +1,123 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ir defines a representation of the elements of Go programs
+// (packages, types, functions, variables and constants) using a
+// static single-assignment (SSA) form intermediate representation
+// (IR) for the bodies of functions.
+//
+// For an introduction to SSA form, see
+// http://en.wikipedia.org/wiki/Static_single_assignment_form.
+// This page provides a broader reading list:
+// http://www.dcs.gla.ac.uk/~jsinger/ssa.html.
+//
+// The level of abstraction of the IR form is intentionally close to
+// the source language to facilitate construction of source analysis
+// tools.  It is not intended for machine code generation.
+//
+// The simplest way to create the IR of a package is
+// to load typed syntax trees using [golang.org/x/tools/go/packages], then
+// invoke the [honnef.co/go/tools/go/ir/irutil.Packages] helper function.
+// (See the package-level Examples named LoadPackages and LoadWholeProgram.)
+// The resulting [ir.Program] contains all the packages and their
+// members, but IR code is not created for function bodies until a
+// subsequent call to [Package.Build] or [Program.Build].
+//
+// The builder initially builds a naive IR form in which all local
+// variables are addresses of stack locations with explicit loads and
+// stores.  Registerisation of eligible locals and φ-node insertion
+// using dominance and dataflow are then performed as a second pass
+// called "lifting" to improve the accuracy and performance of
+// subsequent analyses; this pass can be skipped by setting the
+// NaiveForm builder flag.
+//
+// The primary interfaces of this package are:
+//
+//   - [Member]: a named member of a Go package.
+//   - [Value]: an expression that yields a value.
+//   - [Instruction]: a statement that consumes values and performs computation.
+//   - [Node]: a [Value] or [Instruction] (emphasizing its membership in the IR value graph)
+//
+// A computation that yields a result implements both the [Value] and
+// [Instruction] interfaces.  The following table shows for each
+// concrete type which of these interfaces it implements.
+//
+//	                   Value?          Instruction?      Member?
+//	*Alloc                ✔               ✔
+//	*BinOp                ✔               ✔
+//	*BlankStore                           ✔
+//	*Builtin              ✔
+//	*Call                 ✔               ✔
+//	*ChangeInterface      ✔               ✔
+//	*ChangeType           ✔               ✔
+//	*Const                ✔               ✔
+//	*Convert              ✔               ✔
+//	*DebugRef                             ✔
+//	*Defer                                ✔
+//	*Extract              ✔               ✔
+//	*Field                ✔               ✔
+//	*FieldAddr            ✔               ✔
+//	*FreeVar              ✔
+//	*Function             ✔                               ✔ (func)
+//	*Global               ✔                               ✔ (var)
+//	*Go                                   ✔
+//	*If                                   ✔
+//	*Index                ✔               ✔
+//	*IndexAddr            ✔               ✔
+//	*Jump                                 ✔
+//	*Load                 ✔               ✔
+//	*MakeChan             ✔               ✔
+//	*MakeClosure          ✔               ✔
+//	*MakeInterface        ✔               ✔
+//	*MakeMap              ✔               ✔
+//	*MakeSlice            ✔               ✔
+//	*MapLookup            ✔               ✔
+//	*MapUpdate                            ✔
+//	*MultiConvert         ✔               ✔
+//	*NamedConst                                           ✔ (const)
+//	*Next                 ✔               ✔
+//	*Panic                                ✔
+//	*Parameter            ✔               ✔
+//	*Phi                  ✔               ✔
+//	*Range                ✔               ✔
+//	*Recv                 ✔               ✔
+//	*Return                               ✔
+//	*RunDefers                            ✔
+//	*Select               ✔               ✔
+//	*Send                                 ✔
+//	*Slice                ✔               ✔
+//	*SliceToArrayPointer  ✔               ✔
+//	*SliceToArray         ✔               ✔
+//	*Store                                ✔
+//	*StringLookup         ✔               ✔
+//	*Type                                                 ✔ (type)
+//	*TypeAssert           ✔               ✔
+//	*UnOp                 ✔               ✔
+//	*Unreachable                          ✔
+//
+// Other key types in this package include: [Program], [Package], [Function]
+// and [BasicBlock].
+//
+// The program representation constructed by this package is fully
+// resolved internally, i.e. it does not rely on the names of Values,
+// Packages, Functions, Types or BasicBlocks for the correct
+// interpretation of the program.  Only the identities of objects and
+// the topology of the IR and type graphs are semantically
+// significant.  (There is one exception: [types.Id] values, which identify field
+// and method names, contain strings.)  Avoidance of name-based
+// operations simplifies the implementation of subsequent passes and
+// can make them very efficient.  Many objects are nonetheless named
+// to aid in debugging, but it is not essential that the names be
+// either accurate or unambiguous.  The public API exposes a number of
+// name-based maps for client convenience.
+//
+// The [honnef.co/go/tools/go/ir/irutil] package provides various
+// helper functions, for example to simplify loading a Go program into
+// SSA form.
+//
+// TODO(adonovan): write a how-to document for all the various cases
+// of trying to determine corresponding elements across the four
+// domains of source locations, ast.Nodes, types.Objects,
+// ssa.Values/Instructions.
+package ir // import "honnef.co/go/tools/go/ir"
diff --git a/vendor/honnef.co/go/tools/go/ir/dom.go b/vendor/honnef.co/go/tools/go/ir/dom.go
new file mode 100644
index 0000000..d733c95
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/dom.go
@@ -0,0 +1,345 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file defines algorithms related to dominance.
+
+// Dominator tree construction ----------------------------------------
+//
+// We use the algorithm described in Lengauer & Tarjan. 1979.  A fast
+// algorithm for finding dominators in a flowgraph.
+// https://doi.acm.org/10.1145/357062.357071
+//
+// We also apply the optimizations to SLT described in Georgiadis et
+// al, Finding Dominators in Practice, JGAA 2006,
+// https://jgaa.info/accepted/2006/GeorgiadisTarjanWerneck2006.10.1.pdf
+// to avoid the need for buckets of size > 1.
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"math/big"
+	"os"
+	"slices"
+	"sort"
+)
+
+// Idom returns the block that immediately dominates b:
+// its parent in the dominator tree, if any.
+// Neither the entry node (b.Index==0) nor recover node
+// (b==b.Parent().Recover()) have a parent.
+func (b *BasicBlock) Idom() *BasicBlock { return b.dom.idom }
+
+// Dominees returns the list of blocks that b immediately dominates:
+// its children in the dominator tree.
+func (b *BasicBlock) Dominees() []*BasicBlock { return b.dom.children }
+
+// Dominates reports whether b dominates c.
+func (b *BasicBlock) Dominates(c *BasicBlock) bool {
+	return b.dom.pre <= c.dom.pre && c.dom.post <= b.dom.post
+}
+
+// DomPreorder returns a new slice containing the blocks of f
+// in a preorder traversal of the dominator tree.
+func (f *Function) DomPreorder() []*BasicBlock {
+	slice := slices.Clone(f.Blocks)
+	sort.Slice(slice, func(i, j int) bool {
+		return slice[i].dom.pre < slice[j].dom.pre
+	})
+	return slice
+}
+
+// DomPostorder returns a new slice containing the blocks of f
+// in a postorder traversal of the dominator tree.
+// (This is not the same as a postdominance order.)
+func (f *Function) DomPostorder() []*BasicBlock {
+	slice := slices.Clone(f.Blocks)
+	sort.Slice(slice, func(i, j int) bool {
+		return slice[i].dom.post < slice[j].dom.post
+	})
+	return slice
+}
+
+// domInfo contains a BasicBlock's dominance information.
+type domInfo struct {
+	idom      *BasicBlock   // immediate dominator (parent in domtree)
+	children  []*BasicBlock // nodes immediately dominated by this one
+	pre, post int32         // pre- and post-order numbering within domtree
+}
+
+// ltState holds the working state for Lengauer-Tarjan algorithm
+// (during which domInfo.pre is repurposed for CFG DFS preorder number).
+type ltState struct {
+	// Each slice is indexed by b.Index.
+	sdom     []*BasicBlock // b's semidominator
+	parent   []*BasicBlock // b's parent in DFS traversal of CFG
+	ancestor []*BasicBlock // b's ancestor with least sdom
+}
+
+// dfs implements the depth-first search part of the LT algorithm.
+func (lt *ltState) dfs(v *BasicBlock, i int32, preorder []*BasicBlock) int32 {
+	preorder[i] = v
+	v.dom.pre = i // For now: DFS preorder of spanning tree of CFG
+	i++
+	lt.sdom[v.Index] = v
+	lt.link(nil, v)
+	for _, w := range v.Succs {
+		if lt.sdom[w.Index] == nil {
+			lt.parent[w.Index] = v
+			i = lt.dfs(w, i, preorder)
+		}
+	}
+	return i
+}
+
+// eval implements the EVAL part of the LT algorithm.
+func (lt *ltState) eval(v *BasicBlock) *BasicBlock {
+	// TODO(adonovan): opt: do path compression per simple LT.
+	u := v
+	for ; lt.ancestor[v.Index] != nil; v = lt.ancestor[v.Index] {
+		if lt.sdom[v.Index].dom.pre < lt.sdom[u.Index].dom.pre {
+			u = v
+		}
+	}
+	return u
+}
+
+// link implements the LINK part of the LT algorithm.
+func (lt *ltState) link(v, w *BasicBlock) {
+	lt.ancestor[w.Index] = v
+}
+
+// buildDomTree computes the dominator tree of f using the LT algorithm.
+// Precondition: all blocks are reachable (e.g. optimizeBlocks has been run).
+func buildDomTree(fn *Function) {
+	// The step numbers refer to the original LT paper; the
+	// reordering is due to Georgiadis.
+
+	// Clear any previous domInfo.
+	for _, b := range fn.Blocks {
+		b.dom = domInfo{}
+	}
+
+	n := len(fn.Blocks)
+	// Allocate space for 5 contiguous [n]*BasicBlock arrays:
+	// sdom, parent, ancestor, preorder, buckets.
+	space := make([]*BasicBlock, 5*n)
+	lt := ltState{
+		sdom:     space[0:n],
+		parent:   space[n : 2*n],
+		ancestor: space[2*n : 3*n],
+	}
+
+	// Step 1.  Number vertices by depth-first preorder.
+	preorder := space[3*n : 4*n]
+	root := fn.Blocks[0]
+	prenum := lt.dfs(root, 0, preorder)
+	recover := fn.Recover
+	if recover != nil {
+		lt.dfs(recover, prenum, preorder)
+	}
+
+	buckets := space[4*n : 5*n]
+	copy(buckets, preorder)
+
+	// In reverse preorder...
+	for i := int32(n) - 1; i > 0; i-- {
+		w := preorder[i]
+
+		// Step 3. Implicitly define the immediate dominator of each node.
+		for v := buckets[i]; v != w; v = buckets[v.dom.pre] {
+			u := lt.eval(v)
+			if lt.sdom[u.Index].dom.pre < i {
+				v.dom.idom = u
+			} else {
+				v.dom.idom = w
+			}
+		}
+
+		// Step 2. Compute the semidominators of all nodes.
+		lt.sdom[w.Index] = lt.parent[w.Index]
+		for _, v := range w.Preds {
+			u := lt.eval(v)
+			if lt.sdom[u.Index].dom.pre < lt.sdom[w.Index].dom.pre {
+				lt.sdom[w.Index] = lt.sdom[u.Index]
+			}
+		}
+
+		lt.link(lt.parent[w.Index], w)
+
+		if lt.parent[w.Index] == lt.sdom[w.Index] {
+			w.dom.idom = lt.parent[w.Index]
+		} else {
+			buckets[i] = buckets[lt.sdom[w.Index].dom.pre]
+			buckets[lt.sdom[w.Index].dom.pre] = w
+		}
+	}
+
+	// The final 'Step 3' is now outside the loop.
+	for v := buckets[0]; v != root; v = buckets[v.dom.pre] {
+		v.dom.idom = root
+	}
+
+	// Step 4. Explicitly define the immediate dominator of each
+	// node, in preorder.
+	for _, w := range preorder[1:] {
+		if w == root || w == recover {
+			w.dom.idom = nil
+		} else {
+			if w.dom.idom != lt.sdom[w.Index] {
+				w.dom.idom = w.dom.idom.dom.idom
+			}
+			// Calculate Children relation as inverse of Idom.
+			w.dom.idom.dom.children = append(w.dom.idom.dom.children, w)
+		}
+	}
+
+	pre, post := numberDomTree(root, 0, 0)
+	if recover != nil {
+		numberDomTree(recover, pre, post)
+	}
+
+	// printDomTreeDot(os.Stderr, f)        // debugging
+	// printDomTreeText(os.Stderr, root, 0) // debugging
+
+	if fn.Prog.mode&SanityCheckFunctions != 0 {
+		sanityCheckDomTree(fn)
+	}
+}
+
+// numberDomTree sets the pre- and post-order numbers of a depth-first
+// traversal of the dominator tree rooted at v.  These are used to
+// answer dominance queries in constant time.
+func numberDomTree(v *BasicBlock, pre, post int32) (int32, int32) {
+	v.dom.pre = pre
+	pre++
+	for _, child := range v.dom.children {
+		pre, post = numberDomTree(child, pre, post)
+	}
+	v.dom.post = post
+	post++
+	return pre, post
+}
+
+// Testing utilities ----------------------------------------
+
+// sanityCheckDomTree checks the correctness of the dominator tree
+// computed by the LT algorithm by comparing against the dominance
+// relation computed by a naive Kildall-style forward dataflow
+// analysis (Algorithm 10.16 from the "Dragon" book).
+func sanityCheckDomTree(f *Function) {
+	n := len(f.Blocks)
+
+	// D[i] is the set of blocks that dominate f.Blocks[i],
+	// represented as a bit-set of block indices.
+	D := make([]big.Int, n)
+
+	one := big.NewInt(1)
+
+	// all is the set of all blocks; constant.
+	var all big.Int
+	all.Set(one).Lsh(&all, uint(n)).Sub(&all, one)
+
+	// Initialization.
+	for i, b := range f.Blocks {
+		if i == 0 || b == f.Recover {
+			// A root is dominated only by itself.
+			D[i].SetBit(&D[0], 0, 1)
+		} else {
+			// All other blocks are (initially) dominated
+			// by every block.
+			D[i].Set(&all)
+		}
+	}
+
+	// Iteration until fixed point.
+	for changed := true; changed; {
+		changed = false
+		for i, b := range f.Blocks {
+			if i == 0 || b == f.Recover {
+				continue
+			}
+			// Compute intersection across predecessors.
+			var x big.Int
+			x.Set(&all)
+			for _, pred := range b.Preds {
+				x.And(&x, &D[pred.Index])
+			}
+			x.SetBit(&x, i, 1) // a block always dominates itself.
+			if D[i].Cmp(&x) != 0 {
+				D[i].Set(&x)
+				changed = true
+			}
+		}
+	}
+
+	// Check the entire relation.  O(n^2).
+	// The Recover block (if any) must be treated specially so we skip it.
+	ok := true
+	for i := range n {
+		for j := range n {
+			b, c := f.Blocks[i], f.Blocks[j]
+			if c == f.Recover {
+				continue
+			}
+			actual := b.Dominates(c)
+			expected := D[j].Bit(i) == 1
+			if actual != expected {
+				fmt.Fprintf(os.Stderr, "dominates(%s, %s)==%t, want %t\n", b, c, actual, expected)
+				ok = false
+			}
+		}
+	}
+
+	preorder := f.DomPreorder()
+	for _, b := range f.Blocks {
+		if got := preorder[b.dom.pre]; got != b {
+			fmt.Fprintf(os.Stderr, "preorder[%d]==%s, want %s\n", b.dom.pre, got, b)
+			ok = false
+		}
+	}
+
+	if !ok {
+		panic("sanityCheckDomTree failed for " + f.String())
+	}
+}
+
+// Printing functions ----------------------------------------
+
+// printDomTreeText prints the dominator tree as text, using indentation.
+//
+//lint:ignore U1000 used during debugging
+func printDomTreeText(buf *bytes.Buffer, v *BasicBlock, indent int) {
+	fmt.Fprintf(buf, "%*s%s\n", 4*indent, "", v)
+	for _, child := range v.dom.children {
+		printDomTreeText(buf, child, indent+1)
+	}
+}
+
+// printDomTreeDot prints the dominator tree of f in AT&T GraphViz
+// (.dot) format.
+//
+//lint:ignore U1000 used during debugging
+func printDomTreeDot(buf io.Writer, f *Function) {
+	fmt.Fprintln(buf, "//", f)
+	fmt.Fprintln(buf, "digraph domtree {")
+	for i, b := range f.Blocks {
+		v := b.dom
+		fmt.Fprintf(buf, "\tn%d [label=\"%s (%d, %d)\",shape=\"rectangle\"];\n", v.pre, b, v.pre, v.post)
+		// TODO(adonovan): improve appearance of edges
+		// belonging to both dominator tree and CFG.
+
+		// Dominator tree edge.
+		if i != 0 {
+			fmt.Fprintf(buf, "\tn%d -> n%d [style=\"solid\",weight=100];\n", v.idom.dom.pre, v.pre)
+		}
+		// CFG edges.
+		for _, pred := range b.Preds {
+			fmt.Fprintf(buf, "\tn%d -> n%d [style=\"dotted\",weight=0];\n", pred.dom.pre, v.pre)
+		}
+	}
+	fmt.Fprintln(buf, "}")
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/emit.go b/vendor/honnef.co/go/tools/go/ir/emit.go
new file mode 100644
index 0000000..bd9a5bc
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/emit.go
@@ -0,0 +1,645 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// Helpers for emitting IR instructions.
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"go/types"
+
+	"golang.org/x/exp/typeparams"
+)
+
+// emitAlloc emits to f a new Alloc instruction allocating a variable
+// of type typ.
+//
+// The caller must set Alloc.Heap=true (for a heap-allocated variable)
+// or add the Alloc to f.Locals (for a frame-allocated variable).
+//
+// During building, a variable in f.Locals may have its Heap flag
+// set when it is discovered that its address is taken.
+// These Allocs are removed from f.Locals at the end.
+//
+// The builder should generally call one of the emit{New,Local,LocalVar} wrappers instead.
+func emitAlloc(f *Function, typ types.Type, source ast.Node, comment string) *Alloc {
+	v := &Alloc{}
+	v.comment = comment
+	v.setType(types.NewPointer(typ))
+	f.emit(v, source)
+	return v
+}
+
+// emitNew emits to f a new Alloc instruction heap-allocating a
+// variable of type typ.
+func emitNew(f *Function, typ types.Type, source ast.Node, comment string) *Alloc {
+	alloc := emitAlloc(f, typ, source, comment)
+	alloc.Heap = true
+	return alloc
+}
+
+// emitLocal creates a local var for (t, source, comment) and
+// emits an Alloc instruction for it.
+//
+// (Use this function or emitNew for synthetic variables;
+// for source-level variables in the same function, use emitLocalVar.)
+func emitLocal(f *Function, t types.Type, source ast.Node, comment string) *Alloc {
+	local := emitAlloc(f, t, source, comment)
+	f.Locals = append(f.Locals, local)
+	return local
+}
+
+// emitLocalVar creates a local var for v and emits an Alloc instruction for it.
+// Subsequent calls to f.lookup(v) return it.
+// It applies the appropriate generic instantiation to the type.
+func emitLocalVar(f *Function, v *types.Var, source ast.Node) *Alloc {
+	alloc := emitLocal(f, f.typ(v.Type()), source, v.Name())
+	f.vars[v] = alloc
+	return alloc
+}
+
+// emitLoad emits to f an instruction to load the address addr into a
+// new temporary, and returns the value so defined.
+func emitLoad(f *Function, addr Value, source ast.Node) *Load {
+	v := &Load{X: addr}
+	v.setType(deref(addr.Type()))
+	f.emit(v, source)
+	return v
+}
+
+func emitRecv(f *Function, ch Value, commaOk bool, typ types.Type, source ast.Node) Value {
+	recv := &Recv{
+		Chan:    ch,
+		CommaOk: commaOk,
+	}
+	recv.setType(typ)
+	return f.emit(recv, source)
+}
+
+// emitDebugRef emits to f a DebugRef pseudo-instruction associating
+// expression e with value v.
+func emitDebugRef(f *Function, e ast.Expr, v Value, isAddr bool) {
+	ref := makeDebugRef(f, e, v, isAddr)
+	if ref == nil {
+		return
+	}
+	f.emit(ref, nil)
+}
+
+func makeDebugRef(f *Function, e ast.Expr, v Value, isAddr bool) *debugRef {
+	if !f.debugInfo() {
+		return nil // debugging not enabled
+	}
+	if v == nil || e == nil {
+		panic("nil")
+	}
+	var obj types.Object
+	e = ast.Unparen(e)
+	if id, ok := e.(*ast.Ident); ok {
+		if isBlankIdent(id) {
+			return nil
+		}
+		obj = f.objectOf(id)
+		switch obj.(type) {
+		case *types.Nil, *types.Const, *types.Builtin:
+			return nil
+		}
+	}
+	return &debugRef{
+		X:      v,
+		Expr:   e,
+		IsAddr: isAddr,
+		object: obj,
+	}
+}
+
+// emitArith emits to f code to compute the binary operation op(x, y)
+// where op is an eager shift, logical or arithmetic operation.
+// (Use emitCompare() for comparisons and Builder.logicalBinop() for
+// non-eager operations.)
+func emitArith(f *Function, op token.Token, x, y Value, t types.Type, source ast.Node) Value {
+	switch op {
+	case token.SHL, token.SHR:
+		x = emitConv(f, x, t, source)
+		// y may be signed or an 'untyped' constant.
+		// There is a runtime panic if y is signed and <0. Instead of inserting a check for y<0
+		// and converting to an unsigned value (like the compiler) leave y as is.
+		if b, ok := y.Type().Underlying().(*types.Basic); ok && b.Info()&types.IsUntyped != 0 {
+			// Untyped conversion:
+			// Spec https://go.dev/ref/spec#Operators:
+			// The right operand in a shift expression must have integer type or be an untyped constant
+			// representable by a value of type uint.
+			y = emitConv(f, y, types.Typ[types.Uint], source)
+		}
+
+	case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT:
+		x = emitConv(f, x, t, source)
+		y = emitConv(f, y, t, source)
+
+	default:
+		panic("illegal op in emitArith: " + op.String())
+
+	}
+	v := &BinOp{
+		Op: op,
+		X:  x,
+		Y:  y,
+	}
+	v.setType(t)
+	return f.emit(v, source)
+}
+
+// emitCompare emits to f code compute the boolean result of
+// comparison 'x op y'.
+func emitCompare(f *Function, op token.Token, x, y Value, source ast.Node) Value {
+	xt := x.Type().Underlying()
+	yt := y.Type().Underlying()
+
+	// Special case to optimise a tagless SwitchStmt so that
+	// these are equivalent
+	//   switch { case e: ...}
+	//   switch true { case e: ... }
+	//   if e==true { ... }
+	// even in the case when e's type is an interface.
+	// TODO(adonovan): opt: generalise to x==true, false!=y, etc.
+	if x, ok := x.(*Const); ok && op == token.EQL && x.Value != nil && x.Value.Kind() == constant.Bool && constant.BoolVal(x.Value) {
+		if yt, ok := yt.(*types.Basic); ok && yt.Info()&types.IsBoolean != 0 {
+			return y
+		}
+	}
+
+	if types.Identical(xt, yt) {
+		// no conversion necessary
+	} else if _, ok := xt.(*types.Interface); ok && !typeparams.IsTypeParam(x.Type()) {
+		y = emitConv(f, y, x.Type(), source)
+	} else if _, ok := yt.(*types.Interface); ok && !typeparams.IsTypeParam(y.Type()) {
+		x = emitConv(f, x, y.Type(), source)
+	} else if _, ok := x.(*Const); ok {
+		x = emitConv(f, x, y.Type(), source)
+	} else if _, ok := y.(*Const); ok {
+		y = emitConv(f, y, x.Type(), source)
+		//lint:ignore SA9003 no-op
+	} else {
+		// other cases, e.g. channels.  No-op.
+	}
+
+	v := &BinOp{
+		Op: op,
+		X:  x,
+		Y:  y,
+	}
+	v.setType(tBool)
+	return f.emit(v, source)
+}
+
+// isValuePreserving returns true if a conversion from ut_src to
+// ut_dst is value-preserving, i.e. just a change of type.
+// Precondition: neither argument is a named or alias type.
+func isValuePreserving(ut_src, ut_dst types.Type) bool {
+	// Identical underlying types?
+	if types.IdenticalIgnoreTags(ut_dst, ut_src) {
+		return true
+	}
+
+	switch ut_dst.(type) {
+	case *types.Chan:
+		// Conversion between channel types?
+		_, ok := ut_src.(*types.Chan)
+		return ok
+
+	case *types.Pointer:
+		// Conversion between pointers with identical base types?
+		_, ok := ut_src.(*types.Pointer)
+		return ok
+	}
+	return false
+}
+
+// emitConv emits to f code to convert Value val to exactly type typ,
+// and returns the converted value.  Implicit conversions are required
+// by language assignability rules in assignments, parameter passing,
+// etc.
+func emitConv(f *Function, val Value, t_dst types.Type, source ast.Node) Value {
+	t_src := val.Type()
+
+	// Identical types?  Conversion is a no-op.
+	if types.Identical(t_src, t_dst) {
+		return val
+	}
+
+	ut_dst := t_dst.Underlying()
+	ut_src := t_src.Underlying()
+
+	// Conversion to, or construction of a value of, an interface type?
+	if isNonTypeParamInterface(t_dst) {
+		// Interface name change?
+		if isValuePreserving(ut_src, ut_dst) {
+			c := &ChangeType{X: val}
+			c.setType(t_dst)
+			return f.emit(c, source)
+		}
+
+		// Assignment from one interface type to another?
+		if isNonTypeParamInterface(t_src) {
+			c := &ChangeInterface{X: val}
+			c.setType(t_dst)
+			return f.emit(c, source)
+		}
+
+		// Untyped nil constant?  Return interface-typed nil constant.
+		if ut_src == tUntypedNil {
+			return zeroConst(t_dst, source)
+		}
+
+		// Convert (non-nil) "untyped" literals to their default type.
+		if t, ok := ut_src.(*types.Basic); ok && t.Info()&types.IsUntyped != 0 {
+			val = emitConv(f, val, types.Default(ut_src), source)
+		}
+
+		// Record the types of operands to MakeInterface, if
+		// non-parameterized, as they are the set of runtime types.
+		t := val.Type()
+		if !f.Prog.isParameterized(t) {
+			addMakeInterfaceType(f.Prog, t)
+		}
+
+		mi := &MakeInterface{X: val}
+		mi.setType(t_dst)
+		return f.emit(mi, source)
+	}
+
+	// conversionCase describes an instruction pattern that maybe emitted to
+	// model d <- s for d in dst_terms and s in src_terms.
+	// Multiple conversions can match the same pattern.
+	type conversionCase uint8
+	const (
+		changeType conversionCase = 1 << iota
+		sliceToArray
+		sliceToArrayPtr
+		sliceTo0Array
+		sliceTo0ArrayPtr
+		convert
+	)
+	// classify the conversion case of a source type us to a destination type ud.
+	// us and ud are underlying types (not *Named or *Alias)
+	classify := func(s, d types.Type) conversionCase {
+		// Just a change of type, but not value or representation?
+		if isValuePreserving(s, d) {
+			return changeType
+		}
+
+		// Conversion from slice to array or slice to array pointer?
+		if slice, ok := s.(*types.Slice); ok {
+			var arr *types.Array
+			var ptr bool
+			// Conversion from slice to array pointer?
+			switch d := d.(type) {
+			case *types.Array:
+				arr = d
+			case *types.Pointer:
+				arr, _ = d.Elem().Underlying().(*types.Array)
+				ptr = true
+			}
+			if arr != nil && types.Identical(slice.Elem(), arr.Elem()) {
+				if arr.Len() == 0 {
+					if ptr {
+						return sliceTo0ArrayPtr
+					} else {
+						return sliceTo0Array
+					}
+				}
+				if ptr {
+					return sliceToArrayPtr
+				} else {
+					return sliceToArray
+				}
+			}
+		}
+
+		// The only remaining case in well-typed code is a representation-
+		// changing conversion of basic types (possibly with []byte/[]rune).
+		if !isBasic(s) && !isBasic(d) {
+			panic(fmt.Sprintf("in %s: cannot convert term %s (%s [within %s]) to type %s [within %s]", f, val, val.Type(), s, t_dst, d))
+		}
+		return convert
+	}
+
+	var classifications conversionCase
+	underIs(ut_src, func(us types.Type) bool {
+		return underIs(ut_dst, func(ud types.Type) bool {
+			if us != nil && ud != nil {
+				classifications |= classify(us, ud)
+			}
+			return classifications != 0
+		})
+	})
+	if classifications == 0 {
+		panic(fmt.Sprintf("in %s: cannot convert %s (%s) to %s", f, val, val.Type(), t_dst))
+	}
+
+	// Conversion of a compile-time constant value?
+	if c, ok := val.(*Const); ok {
+		// Conversion to a basic type?
+		if isBasic(ut_dst) {
+			// Conversion of a compile-time constant to
+			// another constant type results in a new
+			// constant of the destination type and
+			// (initially) the same abstract value.
+			// We don't truncate the value yet.
+			return NewConst(c.Value, t_dst, source)
+		}
+		// Can we always convert from zero value without panicking?
+		const mayPanic = sliceToArray | sliceToArrayPtr
+		if c.Value == nil && classifications&mayPanic == 0 {
+			return NewConst(nil, t_dst, source)
+		}
+
+		// We're converting from constant to non-constant type,
+		// e.g. string -> []byte/[]rune.
+	}
+
+	switch classifications {
+	case changeType: // representation-preserving change
+		c := &ChangeType{X: val}
+		c.setType(t_dst)
+		return f.emit(c, source)
+
+	case sliceToArrayPtr, sliceTo0ArrayPtr: // slice to array pointer
+		c := &SliceToArrayPointer{X: val}
+		c.setType(t_dst)
+		return f.emit(c, source)
+
+	case sliceToArray: // slice to arrays (not zero-length)
+		p := &SliceToArray{X: val}
+		p.setType(t_dst)
+		return f.emit(p, source)
+
+	case sliceTo0Array: // slice to zero-length arrays (constant)
+		return zeroConst(t_dst, source)
+
+	case convert: // representation-changing conversion
+		c := &Convert{X: val}
+		c.setType(t_dst)
+		return f.emit(c, source)
+
+	default: // The conversion represents a cross product.
+		c := &MultiConvert{X: val, from: t_src, to: t_dst}
+		c.setType(t_dst)
+		return f.emit(c, source)
+	}
+}
+
+// emitTypeCoercion emits to f code to coerce the type of a
+// Value v to exactly type typ, and returns the coerced value.
+//
+// Requires that coercing v.Typ() to typ is a value preserving change.
+//
+// Currently used only when v.Type() is a type instance of typ or vice versa.
+// A type v is a type instance of a type t if there exists a
+// type parameter substitution σ s.t. σ(v) == t. Example:
+//
+//	σ(func(T) T) == func(int) int for σ == [T ↦ int]
+//
+// This happens in instantiation wrappers for conversion
+// from an instantiation to a parameterized type (and vice versa)
+// with σ substituting f.typeparams by f.typeargs.
+func emitTypeCoercion(f *Function, v Value, typ types.Type, source ast.Node) Value {
+	if types.Identical(v.Type(), typ) {
+		return v // no coercion needed
+	}
+	// TODO(taking): for instances should we record which side is the instance?
+	c := &ChangeType{
+		X: v,
+	}
+	c.setType(typ)
+	f.emit(c, source)
+	return c
+}
+
+// emitStore emits to f an instruction to store value val at location
+// addr, applying implicit conversions as required by assignability rules.
+func emitStore(f *Function, addr, val Value, source ast.Node) *Store {
+	typ := deref(addr.Type())
+	s := &Store{
+		Addr: addr,
+		Val:  emitConv(f, val, typ, source),
+	}
+	f.emit(s, source)
+	return s
+}
+
+// emitJump emits to f a jump to target, and updates the control-flow graph.
+// Postcondition: f.currentBlock is nil.
+func emitJump(f *Function, target *BasicBlock, source ast.Node) *Jump {
+	b := f.currentBlock
+	j := new(Jump)
+	b.emit(j, source)
+	addEdge(b, target)
+	f.currentBlock = nil
+	return j
+}
+
+// emitIf emits to f a conditional jump to tblock or fblock based on
+// cond, and updates the control-flow graph.
+// Postcondition: f.currentBlock is nil.
+func emitIf(f *Function, cond Value, tblock, fblock *BasicBlock, source ast.Node) *If {
+	b := f.currentBlock
+	stmt := &If{Cond: cond}
+	b.emit(stmt, source)
+	addEdge(b, tblock)
+	addEdge(b, fblock)
+	f.currentBlock = nil
+	return stmt
+}
+
+// emitExtract emits to f an instruction to extract the index'th
+// component of tuple.  It returns the extracted value.
+func emitExtract(f *Function, tuple Value, index int, source ast.Node) Value {
+	e := &Extract{Tuple: tuple, Index: index}
+	e.setType(tuple.Type().(*types.Tuple).At(index).Type())
+	return f.emit(e, source)
+}
+
+// emitTypeAssert emits to f a type assertion value := x.(t) and
+// returns the value.  x.Type() must be an interface.
+func emitTypeAssert(f *Function, x Value, t types.Type, source ast.Node) Value {
+	a := &TypeAssert{X: x, AssertedType: t}
+	a.setType(t)
+	return f.emit(a, source)
+}
+
+// emitTypeTest emits to f a type test value,ok := x.(t) and returns
+// a (value, ok) tuple.  x.Type() must be an interface.
+func emitTypeTest(f *Function, x Value, t types.Type, source ast.Node) Value {
+	a := &TypeAssert{
+		X:            x,
+		AssertedType: t,
+		CommaOk:      true,
+	}
+	a.setType(types.NewTuple(
+		newVar("value", t),
+		varOk,
+	))
+	return f.emit(a, source)
+}
+
+// emitTailCall emits to f a function call in tail position.  The
+// caller is responsible for all fields of 'call' except its type.
+// Intended for wrapper methods.
+// Precondition: f does/will not use deferred procedure calls.
+// Postcondition: f.currentBlock is nil.
+func emitTailCall(f *Function, call *Call, source ast.Node) {
+	tresults := f.Signature.Results()
+	nr := tresults.Len()
+	if nr == 1 {
+		call.typ = tresults.At(0).Type()
+	} else {
+		call.typ = tresults
+	}
+	tuple := emitCall(f, call, source)
+	var ret Return
+	switch nr {
+	case 0:
+		// no-op
+	case 1:
+		ret.Results = []Value{tuple}
+	default:
+		for i := range nr {
+			v := emitExtract(f, tuple, i, source)
+			// TODO(adonovan): in principle, this is required:
+			//   v = emitConv(f, o.Type, f.Signature.Results[i].Type)
+			// but in practice emitTailCall is only used when
+			// the types exactly match.
+			ret.Results = append(ret.Results, v)
+		}
+	}
+
+	f.emit(&ret, source)
+	f.currentBlock = nil
+}
+
+// emitCall emits a call instruction. If the callee is "no return",
+// it also emits a panic to eliminate infeasible CFG edges.
+func emitCall(fn *Function, call *Call, source ast.Node) Value {
+	res := fn.emit(call, source)
+
+	callee := call.Call.StaticCallee()
+	if callee != nil &&
+		callee.object != nil &&
+		fn.Prog.noReturn != nil &&
+		fn.Prog.noReturn(callee.object) {
+		// Call doesn't return normally. Either it doesn't return at all
+		// (infinitely blocked or exitting the process), or it unwinds the stack
+		// (panic, runtime.Goexit). Model this as a panic.
+		fn.emit(&Panic{
+			X: emitConv(fn, vNoReturn, tEface, source),
+		}, source)
+		fn.currentBlock = fn.newBasicBlock("unreachable")
+	}
+
+	return res
+}
+
+// emitImplicitSelections emits to f code to apply the sequence of
+// implicit field selections specified by indices to base value v, and
+// returns the selected value.
+//
+// If v is the address of a struct, the result will be the address of
+// a field; if it is the value of a struct, the result will be the
+// value of a field.
+func emitImplicitSelections(f *Function, v Value, indices []int, source ast.Node) Value {
+	for _, index := range indices {
+		// We may have a generic type containing a pointer, or a pointer to a generic type containing a struct. A
+		// pointer to a generic containing a pointer to a struct shouldn't be possible because the outer pointer gets
+		// dereferenced implicitly before we get here.
+		if isPointerCore(v.Type()) {
+			fld := fieldOf(deref(v.Type()), index)
+			instr := &FieldAddr{
+				X:     v,
+				Field: index,
+			}
+			instr.setType(types.NewPointer(fld.Type()))
+			v = f.emit(instr, source)
+			// Load the field's value iff indirectly embedded.
+			if isPointerCore(fld.Type()) {
+				v = emitLoad(f, v, source)
+			}
+		} else {
+			fld := fieldOf(v.Type(), index)
+			instr := &Field{
+				X:     v,
+				Field: index,
+			}
+			instr.setType(fld.Type())
+			v = f.emit(instr, source)
+		}
+	}
+	return v
+}
+
+// emitFieldSelection emits to f code to select the index'th field of v.
+//
+// If wantAddr, the input must be a pointer-to-struct and the result
+// will be the field's address; otherwise the result will be the
+// field's value.
+// Ident id is used for position and debug info.
+func emitFieldSelection(f *Function, v Value, index int, wantAddr bool, id *ast.Ident) Value {
+	if isPointerCore(v.Type()) {
+		fld := fieldOf(deref(v.Type()), index)
+		instr := &FieldAddr{
+			X:     v,
+			Field: index,
+		}
+		instr.setSource(id)
+		instr.setType(types.NewPointer(fld.Type()))
+		v = f.emit(instr, id)
+		// Load the field's value iff we don't want its address.
+		if !wantAddr {
+			v = emitLoad(f, v, id)
+		}
+	} else {
+		fld := fieldOf(v.Type(), index)
+		instr := &Field{
+			X:     v,
+			Field: index,
+		}
+		instr.setSource(id)
+		instr.setType(fld.Type())
+		v = f.emit(instr, id)
+	}
+	emitDebugRef(f, id, v, wantAddr)
+	return v
+}
+
+// createRecoverBlock emits to f a block of code to return after a
+// recovered panic, and sets f.Recover to it.
+//
+// If f's result parameters are named, the code loads and returns
+// their current values, otherwise it returns the zero values of their
+// type.
+//
+// Idempotent.
+func createRecoverBlock(f *Function) {
+	if f.Recover != nil {
+		return // already created
+	}
+	saved := f.currentBlock
+
+	f.Recover = f.newBasicBlock("recover")
+	f.currentBlock = f.Recover
+
+	var results []Value
+	// Reload NRPs to form value tuple.
+	for _, nr := range f.results {
+		results = append(results, emitLoad(f, nr, nr.source))
+	}
+
+	f.emit(&Return{Results: results}, nil)
+
+	f.currentBlock = saved
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/func.go b/vendor/honnef.co/go/tools/go/ir/func.go
new file mode 100644
index 0000000..c31f3e2
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/func.go
@@ -0,0 +1,949 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file implements the Function type.
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"io"
+	"iter"
+	"os"
+	"strings"
+)
+
+// Like ObjectOf, but panics instead of returning nil.
+// Only valid during f's create and build phases.
+func (f *Function) objectOf(id *ast.Ident) types.Object {
+	if o := f.info.ObjectOf(id); o != nil {
+		return o
+	}
+	panic(fmt.Sprintf("no types.Object for ast.Ident %s @ %s",
+		id.Name, f.Prog.Fset.Position(id.Pos())))
+}
+
+// instrs returns an iterator that returns each reachable instruction of the SSA function.
+func (f *Function) instrs() iter.Seq[Instruction] {
+	return func(yield func(i Instruction) bool) {
+		for _, block := range f.Blocks {
+			for _, instr := range block.Instrs {
+				if !yield(instr) {
+					return
+				}
+			}
+		}
+	}
+}
+
+// Like TypeOf, but panics instead of returning nil.
+// Only valid during f's create and build phases.
+func (f *Function) typeOf(e ast.Expr) types.Type {
+	if T := f.info.TypeOf(e); T != nil {
+		return f.typ(T)
+	}
+	panic(fmt.Sprintf("no type for %T @ %s", e, f.Prog.Fset.Position(e.Pos())))
+}
+
+// typ is the locally instantiated type of T.
+// If f is not an instantiation, then f.typ(T)==T.
+func (f *Function) typ(T types.Type) types.Type {
+	return f.subst.typ(T)
+}
+
+// If id is an Instance, returns info.Instances[id].Type.
+// Otherwise returns f.typeOf(id).
+func (f *Function) instanceType(id *ast.Ident) types.Type {
+	if t, ok := f.info.Instances[id]; ok {
+		return t.Type
+	}
+	return f.typeOf(id)
+}
+
+// selection returns a *selection corresponding to f.info.Selections[selector]
+// with potential updates for type substitution.
+func (f *Function) selection(selector *ast.SelectorExpr) *selection {
+	sel := f.info.Selections[selector]
+	if sel == nil {
+		return nil
+	}
+
+	switch sel.Kind() {
+	case types.MethodExpr, types.MethodVal:
+		if recv := f.typ(sel.Recv()); recv != sel.Recv() {
+			// recv changed during type substitution.
+			pkg := f.declaredPackage().Pkg
+			obj, index, indirect := types.LookupFieldOrMethod(recv, true, pkg, sel.Obj().Name())
+
+			// sig replaces sel.Type(). See (types.Selection).Typ() for details.
+			sig := obj.Type().(*types.Signature)
+			sig = changeRecv(sig, newVar(sig.Recv().Name(), recv))
+			if sel.Kind() == types.MethodExpr {
+				sig = recvAsFirstArg(sig)
+			}
+			return &selection{
+				kind:     sel.Kind(),
+				recv:     recv,
+				typ:      sig,
+				obj:      obj,
+				index:    index,
+				indirect: indirect,
+			}
+		}
+	}
+	return toSelection(sel)
+}
+
+// Destinations associated with unlabelled for/switch/select stmts.
+// We push/pop one of these as we enter/leave each construct and for
+// each BranchStmt we scan for the innermost target of the right type.
+type targets struct {
+	tail         *targets // rest of stack
+	_break       *BasicBlock
+	_continue    *BasicBlock
+	_fallthrough *BasicBlock
+}
+
+// Destinations associated with a labelled block.
+// We populate these as labels are encountered in forward gotos or
+// labelled statements.
+// Forward gotos are resolved once it is known which statement they
+// are associated with inside the Function.
+type lblock struct {
+	label     *types.Label // Label targeted by the blocks.
+	resolved  bool         // _goto block encountered (back jump or resolved fwd jump)
+	_goto     *BasicBlock
+	_break    *BasicBlock
+	_continue *BasicBlock
+}
+
+// label returns the symbol denoted by a label identifier.
+//
+// label should be a non-blank identifier (label.Name != "_").
+func (f *Function) label(label *ast.Ident) *types.Label {
+	return f.objectOf(label).(*types.Label)
+}
+
+// lblockOf returns the branch target associated with the
+// specified label, creating it if needed.
+func (f *Function) lblockOf(label *types.Label) *lblock {
+	lb := f.lblocks[label]
+	if lb == nil {
+		lb = &lblock{
+			label: label,
+			_goto: f.newBasicBlock(label.Name()),
+		}
+		if f.lblocks == nil {
+			f.lblocks = make(map[*types.Label]*lblock)
+		}
+		f.lblocks[label] = lb
+	}
+	return lb
+}
+
+// labelledBlock searches f for the block of the specified label.
+//
+// If f is a yield function, it additionally searches ancestor Functions
+// corresponding to enclosing range-over-func statements within the
+// same source function, so the returned block may belong to a different Function.
+func labelledBlock(f *Function, label *types.Label, tok token.Token) *BasicBlock {
+	if lb := f.lblocks[label]; lb != nil {
+		var block *BasicBlock
+		switch tok {
+		case token.BREAK:
+			block = lb._break
+		case token.CONTINUE:
+			block = lb._continue
+		case token.GOTO:
+			block = lb._goto
+		}
+		if block != nil {
+			return block
+		}
+	}
+	// Search ancestors if this is a yield function.
+	if f.jump != nil {
+		return labelledBlock(f.parent, label, tok)
+	}
+	return nil
+}
+
+// targetedBlock looks for the nearest block in f.targets
+// (and f's ancestors) that matches tok's type, and returns
+// the block and function it was found in.
+func targetedBlock(f *Function, tok token.Token) *BasicBlock {
+	if f == nil {
+		return nil
+	}
+	for t := f.targets; t != nil; t = t.tail {
+		var block *BasicBlock
+		switch tok {
+		case token.BREAK:
+			block = t._break
+		case token.CONTINUE:
+			block = t._continue
+		case token.FALLTHROUGH:
+			block = t._fallthrough
+		}
+		if block != nil {
+			return block
+		}
+	}
+	// Search f's ancestors (in case f is a yield function).
+	return targetedBlock(f.parent, tok)
+}
+
+// addResultVar adds a result for a variable v to f.results and v to f.returnVars.
+func (f *Function) addResultVar(v *types.Var, source ast.Node) {
+	name := v.Name()
+	if name == "" {
+		name = fmt.Sprintf("res.%d", len(f.results))
+	}
+	result := emitLocalVar(f, v, source)
+	result.comment = name
+	f.results = append(f.results, result)
+	f.returnVars = append(f.returnVars, v)
+}
+
+// addParamVar adds a parameter to f.Params.
+func (f *Function) addParamVar(v *types.Var, source ast.Node) *Parameter {
+	name := v.Name()
+	if name == "" {
+		name = fmt.Sprintf("arg%d", len(f.Params))
+	}
+	param := &Parameter{name: name, typ: f.typ(v.Type()), parent: f}
+	param.setSource(source)
+	param.object = v
+	f.Params = append(f.Params, param)
+	return param
+}
+
+// addSpilledParam declares a parameter that is pre-spilled to the
+// stack; the function body will load/store the spilled location.
+// Subsequent lifting will eliminate spills where possible.
+func (f *Function) addSpilledParam(obj *types.Var, source ast.Node) {
+	param := f.addParamVar(obj, source)
+	spill := emitLocalVar(f, obj, source)
+	emitStore(f, spill, param, source)
+}
+
+// startBody initializes the function prior to generating IR code for its body.
+// Precondition: f.Type() already set.
+func (f *Function) startBody() {
+	entry := f.newBasicBlock("entry")
+	f.currentBlock = entry
+	f.vars = make(map[*types.Var]Value) // needed for some synthetics, e.g. init
+}
+
+func (f *Function) blockset(i int) *BlockSet {
+	bs := &f.blocksets[i]
+	if len(bs.values) != len(f.Blocks) {
+		if cap(bs.values) >= len(f.Blocks) {
+			bs.values = bs.values[:len(f.Blocks)]
+			bs.Clear()
+		} else {
+			bs.values = make([]bool, len(f.Blocks))
+		}
+	} else {
+		bs.Clear()
+	}
+	return bs
+}
+
+// createSyntacticParams populates f.Params and generates code (spills
+// and named result locals) for all the parameters declared in the
+// syntax.  In addition it populates the f.objects mapping.
+//
+// Preconditions:
+// f.startBody() was called. f.info != nil.
+// Postcondition:
+// len(f.Params) == len(f.Signature.Params) + (f.Signature.Recv() ? 1 : 0)
+func (f *Function) createSyntacticParams(recv *ast.FieldList, functype *ast.FuncType) {
+	// Receiver (at most one inner iteration).
+	if recv != nil {
+		for _, field := range recv.List {
+			for _, n := range field.Names {
+				f.addSpilledParam(identVar(f, n), n)
+			}
+			// Anonymous receiver?  No need to spill.
+			if field.Names == nil {
+				f.addParamVar(f.Signature.Recv(), field)
+			}
+		}
+	}
+
+	// Parameters.
+	if functype.Params != nil {
+		n := len(f.Params) // 1 if has recv, 0 otherwise
+		for _, field := range functype.Params.List {
+			for _, n := range field.Names {
+				f.addSpilledParam(identVar(f, n), n)
+			}
+			// Anonymous parameter?  No need to spill.
+			if field.Names == nil {
+				f.addParamVar(f.Signature.Params().At(len(f.Params)-n), field)
+			}
+		}
+	}
+
+	// Results.
+	if functype.Results != nil {
+		for _, field := range functype.Results.List {
+			// Implicit "var" decl of locals for named results.
+			for _, n := range field.Names {
+				v := identVar(f, n)
+				f.addResultVar(v, n)
+			}
+			// Implicit "var" decl of local for an unnamed result.
+			if field.Names == nil {
+				v := f.Signature.Results().At(len(f.results))
+				f.addResultVar(v, field.Type)
+			}
+		}
+	}
+}
+
+// createDeferStack initializes fn.deferstack to a local variable
+// initialized to a ssa:deferstack() call.
+func (fn *Function) createDeferStack() {
+	// Each syntactic function makes a call to ssa:deferstack,
+	// which is spilled to a local. Unused ones are later removed.
+	fn.deferstack = newVar("defer$stack", tDeferStack)
+	call := &Call{Call: CallCommon{Value: vDeferStack}}
+	call.setType(tDeferStack)
+	deferstack := fn.emit(call, nil)
+	spill := emitLocalVar(fn, fn.deferstack, nil)
+	emitStore(fn, spill, deferstack, nil)
+}
+
+func numberNodes(f *Function) {
+	var base ID
+	for _, b := range f.Blocks {
+		for _, instr := range b.Instrs {
+			if instr == nil {
+				continue
+			}
+			base++
+			instr.setID(base)
+		}
+	}
+}
+
+func updateOperandsReferrers(instr Instruction, ops []*Value) {
+	for _, op := range ops {
+		if r := *op; r != nil {
+			if refs := (*op).Referrers(); refs != nil {
+				if len(*refs) == 0 {
+					// per median, each value has two referrers, so we can avoid one call into growslice
+					//
+					// Note: we experimented with allocating
+					// sequential scratch space, but we
+					// couldn't find a value that gave better
+					// performance than making many individual
+					// allocations
+					*refs = make([]Instruction, 1, 2)
+					(*refs)[0] = instr
+				} else {
+					*refs = append(*refs, instr)
+				}
+			}
+		}
+	}
+}
+
+// buildReferrers populates the def/use information in all non-nil
+// Value.Referrers slice.
+// Precondition: all such slices are initially empty.
+func buildReferrers(f *Function) {
+	var rands []*Value
+
+	for _, b := range f.Blocks {
+		for _, instr := range b.Instrs {
+			rands = instr.Operands(rands[:0]) // recycle storage
+			updateOperandsReferrers(instr, rands)
+		}
+	}
+}
+
+// finishBody() finalizes the contents of the function after IR code generation of its body.
+//
+// The function is not done being built until done() is called.
+func (f *Function) finishBody() {
+	f.currentBlock = nil
+	f.lblocks = nil
+	f.returnVars = nil
+	f.jump = nil
+	f.source = nil
+	f.exits = nil
+
+	// Remove from f.Locals any Allocs that escape to the heap.
+	j := 0
+	for _, l := range f.Locals {
+		if !l.Heap {
+			f.Locals[j] = l
+			j++
+		}
+	}
+	// Nil out f.Locals[j:] to aid GC.
+	for i := j; i < len(f.Locals); i++ {
+		f.Locals[i] = nil
+	}
+	f.Locals = f.Locals[:j]
+
+	optimizeBlocks(f)
+	buildReferrers(f)
+	buildDomTree(f)
+	buildSCCs(f)
+
+	if f.Prog.mode&NaiveForm == 0 {
+		for lift(f) {
+		}
+		if doSimplifyConstantCompositeValues {
+			for simplifyConstantCompositeValues(f) {
+			}
+		}
+	}
+
+	if f.debugInfo() {
+		// Turn debug references into a map
+		f.exprToValue = map[ast.Expr]struct {
+			v      Value
+			isAddr bool
+		}{}
+		for _, b := range f.Blocks {
+			newInstrs := b.Instrs[:0]
+			for _, instr := range b.Instrs {
+				if instr, ok := instr.(*debugRef); ok {
+					if refs := instr.X.Referrers(); refs != nil {
+						*refs = removeInstr(*refs, instr)
+					}
+					if _, ok := f.exprToValue[instr.Expr]; !ok {
+						f.exprToValue[instr.Expr] = struct {
+							v      Value
+							isAddr bool
+						}{instr.X, instr.IsAddr}
+					}
+					continue
+				}
+				newInstrs = append(newInstrs, instr)
+			}
+			b.Instrs = newInstrs
+		}
+	}
+
+	// clear remaining builder state
+	f.results = nil    // (used by lifting)
+	f.deferstack = nil // (used by lifting)
+	f.vars = nil       // (used by lifting)
+
+	numberNodes(f)
+
+	// clear out other function state (keep consistent with buildParamsOnly)
+	f.subst = nil
+
+	// Release the package's type information, unless
+	// instances of f will later be built from it.
+	if !f.isGenericOrigin() {
+		f.info = nil
+	}
+
+	numberNodes(f)
+}
+
+// done marks the building of f's SSA body complete,
+// along with any nested functions, and optionally prints them.
+func (f *Function) done() {
+	assert(f.parent == nil, "done called on an anonymous function")
+
+	var visit func(*Function)
+	visit = func(f *Function) {
+		for _, anon := range f.AnonFuncs {
+			visit(anon) // anon is done building before f.
+		}
+
+		f.uniq = 0    // done with uniq
+		f.build = nil // function is built
+
+		if f.Prog.mode&PrintFunctions != 0 {
+			printMu.Lock()
+			f.WriteTo(os.Stdout)
+			printMu.Unlock()
+		}
+
+		if f.Prog.mode&SanityCheckFunctions != 0 {
+			mustSanityCheck(f, nil)
+		}
+	}
+	visit(f)
+}
+
+func isUselessPhi(phi *Phi) (Value, bool) {
+	var v0 Value
+	if len(phi.Edges) == 0 {
+		panic("φ with no edges")
+	}
+	for _, e := range phi.Edges {
+		if e == nil {
+			panic(fmt.Sprintf("φ has nil edge: %v", phi))
+		}
+		if e == phi {
+			continue
+		}
+		if v0 == nil {
+			v0 = e
+		}
+		if v0 != e {
+			if v0, ok := v0.(*Const); ok {
+				if e, ok := e.(*Const); ok {
+					if v0.typ == e.typ && v0.Value == e.Value {
+						continue
+					}
+				}
+			}
+			return nil, false
+		}
+	}
+	if v0 == nil {
+		panic("trying to replace φ with nil")
+	}
+	return v0, true
+}
+
+// removeNilBlocks eliminates nils from f.Blocks and updates each
+// BasicBlock.Index.  Use this after any pass that may delete blocks.
+func (f *Function) removeNilBlocks() {
+	j := 0
+	for _, b := range f.Blocks {
+		if b != nil {
+			b.Index = j
+			f.Blocks[j] = b
+			j++
+		}
+	}
+	// Nil out f.Blocks[j:] to aid GC.
+	for i := j; i < len(f.Blocks); i++ {
+		f.Blocks[i] = nil
+	}
+	f.Blocks = f.Blocks[:j]
+}
+
+// SetDebugMode sets the debug mode for package pkg.  If true, all its
+// functions will include full debug info.  This greatly increases the
+// size of the instruction stream, and causes Functions to depend upon
+// the ASTs, potentially keeping them live in memory for longer.
+func (pkg *Package) SetDebugMode(debug bool) {
+	pkg.debug = debug
+}
+
+// debugInfo reports whether debug info is wanted for this function.
+func (f *Function) debugInfo() bool {
+	// debug info for instantiations follows the debug info of their origin.
+	p := f.declaredPackage()
+	return p != nil && p.debug
+}
+
+// lookup returns the address of the named variable identified by obj
+// that is local to function f or one of its enclosing functions.
+// If escaping, the reference comes from a potentially escaping pointer
+// expression and the referent must be heap-allocated.
+// We assume the referent is a *Alloc or *Phi.
+// (The only Phis at this stage are those created directly by go1.22 "for" loops.)
+func (f *Function) lookup(obj *types.Var, escaping bool) Value {
+	if v, ok := f.vars[obj]; ok {
+		if escaping {
+			switch v := v.(type) {
+			case *Alloc:
+				v.Heap = true
+			case *Phi:
+				for _, edge := range v.Edges {
+					if alloc, ok := edge.(*Alloc); ok {
+						alloc.Heap = true
+					}
+				}
+			}
+		}
+		return v // function-local var (address)
+	}
+
+	// Definition must be in an enclosing function;
+	// plumb it through intervening closures.
+	if f.parent == nil {
+		panic("no ir.Value for " + obj.String())
+	}
+	outer := f.parent.lookup(obj, true) // escaping
+	v := &FreeVar{
+		name:   obj.Name(),
+		typ:    outer.Type(),
+		outer:  outer,
+		parent: f,
+	}
+	f.vars[obj] = v
+	f.FreeVars = append(f.FreeVars, v)
+	return v
+}
+
+// emit emits the specified instruction to function f.
+func (f *Function) emit(instr Instruction, source ast.Node) Value {
+	return f.currentBlock.emit(instr, source)
+}
+
+// RelString returns the full name of this function, qualified by
+// package name, receiver type, etc.
+//
+// The specific formatting rules are not guaranteed and may change.
+//
+// Examples:
+//
+//	"math.IsNaN"                  // a package-level function
+//	"(*bytes.Buffer).Bytes"       // a declared method or a wrapper
+//	"(*bytes.Buffer).Bytes$thunk" // thunk (func wrapping method; receiver is param 0)
+//	"(*bytes.Buffer).Bytes$bound" // bound (func wrapping method; receiver supplied by closure)
+//	"main.main$1"                 // an anonymous function in main
+//	"main.init#1"                 // a declared init function
+//	"main.init"                   // the synthesized package initializer
+//
+// When these functions are referred to from within the same package
+// (i.e. from == f.Pkg.Object), they are rendered without the package path.
+// For example: "IsNaN", "(*Buffer).Bytes", etc.
+//
+// All non-synthetic functions have distinct package-qualified names.
+// (But two methods may have the same name "(T).f" if one is a synthetic
+// wrapper promoting a non-exported method "f" from another package; in
+// that case, the strings are equal but the identifiers "f" are distinct.)
+func (f *Function) RelString(from *types.Package) string {
+	// Anonymous?
+	if f.parent != nil {
+		// An anonymous function's Name() looks like "parentName$1",
+		// but its String() should include the type/package/etc.
+		parent := f.parent.RelString(from)
+		for i, anon := range f.parent.AnonFuncs {
+			if anon == f {
+				return fmt.Sprintf("%s$%d", parent, 1+i)
+			}
+		}
+
+		return f.name // should never happen
+	}
+
+	// Method (declared or wrapper)?
+	if recv := f.Signature.Recv(); recv != nil {
+		return f.relMethod(from, recv.Type())
+	}
+
+	// Thunk?
+	if f.method != nil {
+		return f.relMethod(from, f.method.recv)
+	}
+
+	// Bound?
+	if len(f.FreeVars) == 1 && strings.HasSuffix(f.name, "$bound") {
+		return f.relMethod(from, f.FreeVars[0].Type())
+	}
+
+	// Package-level function?
+	// Prefix with package name for cross-package references only.
+	if p := f.relPkg(); p != nil && p != from {
+		return fmt.Sprintf("%s.%s", p.Path(), f.name)
+	}
+
+	// Unknown.
+	return f.name
+}
+
+func (f *Function) relMethod(from *types.Package, recv types.Type) string {
+	return fmt.Sprintf("(%s).%s", relType(recv, from), f.name)
+}
+
+// writeSignature writes to buf the signature sig in declaration syntax.
+func writeSignature(buf *bytes.Buffer, from *types.Package, name string, sig *types.Signature) {
+	buf.WriteString("func ")
+	if recv := sig.Recv(); recv != nil {
+		buf.WriteString("(")
+		if name := recv.Name(); name != "" {
+			buf.WriteString(name)
+			buf.WriteString(" ")
+		}
+		types.WriteType(buf, recv.Type(), types.RelativeTo(from))
+		buf.WriteString(") ")
+	}
+	buf.WriteString(name)
+	types.WriteSignature(buf, sig, types.RelativeTo(from))
+}
+
+// declaredPackage returns the package fn is declared in or nil if the
+// function is not declared in a package.
+func (fn *Function) declaredPackage() *Package {
+	switch {
+	case fn.Pkg != nil:
+		return fn.Pkg // non-generic function  (does that follow??)
+	case fn.topLevelOrigin != nil:
+		return fn.topLevelOrigin.Pkg // instance of a named generic function
+	case fn.parent != nil:
+		return fn.parent.declaredPackage() // instance of an anonymous [generic] function
+	default:
+		return nil // function is not declared in a package, e.g. a wrapper.
+	}
+}
+
+// relPkg returns types.Package fn is printed in relationship to.
+func (fn *Function) relPkg() *types.Package {
+	if p := fn.declaredPackage(); p != nil {
+		return p.Pkg
+	}
+	return nil
+}
+
+var _ io.WriterTo = (*Function)(nil) // *Function implements io.Writer
+
+func (f *Function) WriteTo(w io.Writer) (int64, error) {
+	var buf bytes.Buffer
+	WriteFunction(&buf, f)
+	n, err := w.Write(buf.Bytes())
+	return int64(n), err
+}
+
+// WriteFunction writes to buf a human-readable "disassembly" of f.
+func WriteFunction(buf *bytes.Buffer, f *Function) {
+	fmt.Fprintf(buf, "# Name: %s\n", f.String())
+	if f.Pkg != nil {
+		fmt.Fprintf(buf, "# Package: %s\n", f.Pkg.Pkg.Path())
+	}
+	if syn := f.Synthetic; syn != "" {
+		fmt.Fprintln(buf, "# Synthetic:", syn)
+	}
+	if pos := f.Pos(); pos.IsValid() {
+		fmt.Fprintf(buf, "# Location: %s\n", f.Prog.Fset.Position(pos))
+	}
+
+	if f.parent != nil {
+		fmt.Fprintf(buf, "# Parent: %s\n", f.parent.Name())
+	}
+
+	from := f.relPkg()
+
+	// NB. column calculations are confused by non-ASCII
+	// characters
+	const punchcard = 80 // for old time's sake.
+	const padding = "        "
+
+	if f.FreeVars != nil {
+		buf.WriteString("# Free variables:\n")
+		for i, fv := range f.FreeVars {
+			fmt.Fprintf(buf, "# % 3d:%s%s %s\n", i, padding, fv.Name(), relType(fv.Type(), from))
+		}
+	}
+
+	if len(f.Locals) > 0 {
+		buf.WriteString("# Locals:\n")
+		for i, l := range f.Locals {
+			fmt.Fprintf(buf, "# % 3d:%s%s %s\n", i, padding, l.Name(), relType(deref(l.Type()), from))
+		}
+	}
+	writeSignature(buf, from, f.Name(), f.Signature)
+	buf.WriteString(":\n")
+
+	if f.Blocks == nil {
+		buf.WriteString(padding)
+		buf.WriteString("(external)\n")
+	}
+
+	for _, b := range f.Blocks {
+		if b == nil {
+			// Corrupt CFG.
+			fmt.Fprintf(buf, ".nil:\n")
+			continue
+		}
+		n, _ := fmt.Fprintf(buf, "%d:", b.Index)
+		// (|predecessors|, |successors|, immediate dominator)
+		bmsg := fmt.Sprintf("%s P:%d S:%d", b.Comment, len(b.Preds), len(b.Succs))
+		if b.Idom() != nil {
+			bmsg = fmt.Sprintf("%s idom:%d", bmsg, b.Idom().Index)
+		}
+		fmt.Fprintf(buf, "%*s%s\n", punchcard-1-n-len(bmsg), "", bmsg)
+
+		if false { // CFG debugging
+			fmt.Fprintf(buf, "%s# CFG: %s --> %s --> %s\n", padding, b.Preds, b, b.Succs)
+		}
+		for _, instr := range b.Instrs {
+			buf.WriteString(padding)
+			switch v := instr.(type) {
+			case Value:
+				l := punchcard - len(padding)
+				// Left-align the instruction.
+				if name := v.Name(); name != "" {
+					n, _ := fmt.Fprintf(buf, "%s = ", name)
+					l -= n
+				}
+				n, _ := buf.WriteString(instr.String())
+				l -= n
+				// Right-align the type if there's space.
+				if t := v.Type(); t != nil {
+					buf.WriteByte(' ')
+					ts := relType(t, from)
+					l -= len(ts) + len("  ") // (spaces before and after type)
+					if l > 0 {
+						fmt.Fprintf(buf, "%*s", l, "")
+					}
+					buf.WriteString(ts)
+				}
+			case nil:
+				// Be robust against bad transforms.
+				buf.WriteString("")
+			default:
+				buf.WriteString(instr.String())
+			}
+			// -mode=S: show line numbers
+			if f.Prog.mode&LogSource != 0 {
+				if pos := instr.Pos(); pos.IsValid() {
+					fmt.Fprintf(buf, " L%d", f.Prog.Fset.Position(pos).Line)
+				}
+			}
+			buf.WriteString("\n")
+		}
+	}
+	buf.WriteString("\n")
+}
+
+// newBasicBlock adds to f a new basic block and returns it.  It does
+// not automatically become the current block for subsequent calls to emit.
+// comment is an optional string for more readable debugging output.
+func (f *Function) newBasicBlock(comment string) *BasicBlock {
+	b := &BasicBlock{
+		Index:   len(f.Blocks),
+		Comment: comment,
+		parent:  f,
+	}
+	b.Succs = b.succs2[:0]
+	f.Blocks = append(f.Blocks, b)
+	return b
+}
+
+// NewFunction returns a new synthetic Function instance belonging to
+// prog, with its name and signature fields set as specified.
+//
+// The caller is responsible for initializing the remaining fields of
+// the function object, e.g. Pkg, Params, Blocks.
+//
+// It is practically impossible for clients to construct well-formed
+// IR functions/packages/programs directly, so we assume this is the
+// job of the Builder alone.  NewFunction exists to provide clients a
+// little flexibility.  For example, analysis tools may wish to
+// construct fake Functions for the root of the callgraph, a fake
+// "reflect" package, etc.
+//
+// TODO(adonovan): think harder about the API here.
+func (prog *Program) NewFunction(name string, sig *types.Signature, provenance string) *Function {
+	return &Function{Prog: prog, name: name, Signature: sig, Synthetic: provenance}
+}
+
+//lint:ignore U1000 we may make use of this for functions loaded from export data
+type extentNode [2]token.Pos
+
+func (n extentNode) Pos() token.Pos { return n[0] }
+func (n extentNode) End() token.Pos { return n[1] }
+
+func killInstruction(instr Instruction) {
+	ops := instr.Operands(nil)
+	for _, op := range ops {
+		if refs := (*op).Referrers(); refs != nil {
+			*refs = removeInstr(*refs, instr)
+		}
+	}
+}
+
+// Syntax returns the function's syntax (*ast.Func{Decl,Lit})
+// if it was produced from syntax or an *ast.RangeStmt if
+// it is a range-over-func yield function.
+func (f *Function) Syntax() ast.Node { return f.syntax }
+
+// identVar returns the variable defined by id.
+func identVar(fn *Function, id *ast.Ident) *types.Var {
+	return fn.info.Defs[id].(*types.Var)
+}
+
+// unique returns a unique positive int within the source tree of f.
+// The source tree of f includes all of f's ancestors by parent and all
+// of the AnonFuncs contained within these.
+func unique(f *Function) int64 {
+	f.uniq++
+	return f.uniq
+}
+
+// exit is a change of control flow going from a range-over-func
+// yield function to an ancestor function caused by a break, continue,
+// goto, or return statement.
+//
+// There are 3 types of exits:
+// * return from the source function (from ReturnStmt),
+// * jump to a block (from break and continue statements [labelled/unlabelled]),
+// * go to a label (from goto statements).
+//
+// As the builder does one pass over the ast, it is unclear whether
+// a forward goto statement will leave a range-over-func body.
+// The function being exited to is unresolved until the end
+// of building the range-over-func body.
+type exit struct {
+	id     int64     // unique value for exit within from and to
+	from   *Function // the function the exit starts from
+	to     *Function // the function being exited to (nil if unresolved)
+	source ast.Node
+
+	block *BasicBlock  // basic block within to being jumped to.
+	label *types.Label // forward label being jumped to via goto.
+	// block == nil && label == nil => return
+}
+
+// storeVar emits to function f code to store a value v to a *types.Var x.
+func storeVar(f *Function, x *types.Var, v Value, source ast.Node) {
+	emitStore(f, f.lookup(x, true), v, source)
+}
+
+// labelExit creates a new exit to a yield fn to exit the function using a label.
+func labelExit(fn *Function, label *types.Label, source ast.Node) *exit {
+	e := &exit{
+		id:     unique(fn),
+		from:   fn,
+		to:     nil,
+		source: source,
+		label:  label,
+	}
+	fn.exits = append(fn.exits, e)
+	return e
+}
+
+// blockExit creates a new exit to a yield fn that jumps to a basic block.
+func blockExit(fn *Function, block *BasicBlock, source ast.Node) *exit {
+	e := &exit{
+		id:     unique(fn),
+		from:   fn,
+		to:     block.parent,
+		source: source,
+		block:  block,
+	}
+	fn.exits = append(fn.exits, e)
+	return e
+}
+
+// returnExit creates a new exit to a yield fn that returns to the source function.
+func returnExit(fn *Function, source ast.Node) *exit {
+	e := &exit{
+		id:     unique(fn),
+		from:   fn,
+		to:     fn.source,
+		source: source,
+	}
+	fn.exits = append(fn.exits, e)
+	return e
+}
+
+// isGenericOrigin reports whether f is an uninstantiated generic
+// function or a method of an uninstantiated generic type.
+func (f *Function) isGenericOrigin() bool {
+	return (f.typeparams.Len() > 0 && len(f.typeargs) == 0) ||
+		(f.recvtypeparams.Len() > 0 && len(f.recvtypeargs) == 0)
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/instantiate.go b/vendor/honnef.co/go/tools/go/ir/instantiate.go
new file mode 100644
index 0000000..bcb6d9a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/instantiate.go
@@ -0,0 +1,161 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"fmt"
+	"go/types"
+	"slices"
+	"sync"
+)
+
+// A generic records information about a generic origin function,
+// including a cache of existing instantiations.
+type generic struct {
+	instancesMu sync.Mutex
+	instances   map[*typeList]*Function // canonical type arguments to an instance.
+}
+
+// instance returns a Function that is the instantiation of generic
+// origin function fn with the type arguments rtargs and targs.
+//
+// Any created instance is added to cr.
+//
+// Acquires fn.generic.instancesMu.
+func (fn *Function) instance(rtargs, targs []types.Type, b *builder) *Function {
+	key := fn.Prog.canon.List(slices.Concat(rtargs, targs))
+
+	gen := fn.generic
+
+	gen.instancesMu.Lock()
+	defer gen.instancesMu.Unlock()
+	inst, ok := gen.instances[key]
+	if !ok {
+		inst = createInstance(fn, rtargs, targs)
+		inst.buildshared = b.shared()
+		b.enqueue(inst)
+
+		if gen.instances == nil {
+			gen.instances = make(map[*typeList]*Function)
+		}
+		gen.instances[key] = inst
+	} else {
+		b.waitForSharedFunction(inst)
+	}
+	return inst
+}
+
+// createInstance returns the instantiation of generic function fn using targs.
+// If fn is a method on a generic type, fn's receiver type will be instantiated
+// using rtargs.
+//
+// Requires fn.generic.instancesMu.
+func createInstance(fn *Function, rtargs, targs []types.Type) *Function {
+	prog := fn.Prog
+
+	// Compute signature.
+	var sig *types.Signature
+	var obj *types.Func
+	if recv := fn.Signature.Recv(); recv != nil {
+		// method, len(rtargs) > 0 || len(targs) > 0
+		if len(rtargs) > 0 {
+			// possibly generic method on generic type
+			obj = prog.canon.instantiateMethod(fn.object, rtargs, prog.ctxt)
+		} else {
+			// generic method on non-generic type
+			obj = fn.object // instantiation does not exist yet
+		}
+		if len(targs) > 0 {
+			// generic method
+			instSig, err := types.Instantiate(prog.ctxt, obj.Signature(), targs, false)
+			if err != nil {
+				panic(err)
+			}
+			instance, ok := instSig.(*types.Signature)
+			if !ok {
+				panic("Instantiate of a Signature returned a non-signature")
+			}
+			// Do not canonicalize generic methods, because the receiver is not
+			// part of a Signature's type identity. For example,
+			// (*G[int]).m[int] and (G[int]).n[int] may be identical types even
+			// though their receiver types differ.
+			sig = instance
+		} else {
+			// non-generic method on generic type
+			sig = obj.Signature()
+		}
+	} else {
+		// function, len(rtargs) == 0 && len(targs) > 0
+		instSig, err := types.Instantiate(prog.ctxt, fn.Signature, targs, false)
+		if err != nil {
+			panic(err)
+		}
+		instance, ok := instSig.(*types.Signature)
+		if !ok {
+			panic("Instantiate of a Signature returned a non-signature")
+		}
+		obj = fn.object // instantiation does not exist yet
+		sig = prog.canon.Type(instance).(*types.Signature)
+	}
+
+	// Choose strategy (instance or wrapper).
+	var (
+		synthetic string
+		subst     *subster
+		build     buildFunc
+	)
+	if prog.mode&InstantiateGenerics != 0 && !prog.isParameterized(slices.Concat(rtargs, targs)...) {
+		synthetic = fmt.Sprintf("instance of %s", fn.Name())
+		if fn.syntax != nil {
+			subst = makeSubster(prog.ctxt, obj, fn.recvtypeparams, rtargs, fn.typeparams, targs)
+			build = (*builder).buildFromSyntax
+		} else {
+			build = (*builder).buildParamsOnly
+		}
+	} else {
+		synthetic = fmt.Sprintf("instantiation wrapper of %s", fn.Name())
+		build = (*builder).buildInstantiationWrapper
+	}
+
+	name := fn.Name()
+	if len(targs) > 0 {
+		name = fmt.Sprintf("%s%s", name, targstr(targs)) // may not be unique
+	}
+
+	/* generic instance or instantiation wrapper */
+	ret := &Function{
+		name:           name,
+		object:         obj,
+		Signature:      sig,
+		Synthetic:      synthetic,
+		syntax:         fn.syntax,    // \
+		info:           fn.info,      //  } empty for non-created packages
+		goversion:      fn.goversion, // /
+		build:          build,
+		topLevelOrigin: fn,
+		pos:            obj.Pos(),
+		Pkg:            nil,
+		Prog:           fn.Prog,
+		recvtypeparams: fn.recvtypeparams, // share with origin
+		recvtypeargs:   rtargs,
+		typeparams:     fn.typeparams, // share with origin
+		typeargs:       targs,
+		subst:          subst,
+	}
+	return ret
+}
+
+// isParameterized reports whether any of the specified types contains
+// a free type parameter. It is safe to call concurrently.
+func (prog *Program) isParameterized(ts ...types.Type) bool {
+	prog.hasParamsMu.Lock()
+	defer prog.hasParamsMu.Unlock()
+
+	// TODO(adonovan): profile. If this operation is expensive,
+	// handle the most common but shallow cases such as T, pkg.T,
+	// *T without consulting the cache under the lock.
+
+	return slices.ContainsFunc(ts, prog.hasParams.Has)
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/load.go b/vendor/honnef.co/go/tools/go/ir/irutil/load.go
new file mode 100644
index 0000000..49eaa72
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/irutil/load.go
@@ -0,0 +1,189 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package irutil
+
+// This file defines utility functions for constructing programs in IR form.
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/go/ir"
+
+	"golang.org/x/tools/go/packages"
+)
+
+// Packages creates an IR program for a set of packages.
+//
+// The packages must have been loaded from source syntax using the
+// golang.org/x/tools/go/packages.Load function in LoadSyntax or
+// LoadAllSyntax mode.
+//
+// Packages creates an IR package for each well-typed package in the
+// initial list, plus all their dependencies. The resulting list of
+// packages corresponds to the list of initial packages, and may contain
+// a nil if IR code could not be constructed for the corresponding initial
+// package due to type errors.
+//
+// Code for bodies of functions is not built until Build is called on
+// the resulting Program. IR code is constructed only for the initial
+// packages with well-typed syntax trees.
+//
+// The mode parameter controls diagnostics and checking during IR construction.
+func Packages(initial []*packages.Package, mode ir.BuilderMode) (*ir.Program, []*ir.Package) {
+	// TODO(adonovan): opt: this calls CreatePackage far more than
+	// necessary: for all dependencies, not just the (non-initial)
+	// direct dependencies of the initial packages.
+	//
+	// But can it reasonably be changed without breaking the
+	// spirit and/or letter of the law above? Clients may notice
+	// if we call CreatePackage less, as methods like
+	// Program.FuncValue will return nil. Or must we provide a new
+	// function (and perhaps deprecate this one)? Is it worth it?
+	//
+	// Tim King makes the interesting point that it would be
+	// possible to entirely alleviate the client from the burden
+	// of calling CreatePackage for non-syntax packages, if we
+	// were to treat vars and funcs lazily in the same way we now
+	// treat methods. (In essence, try to move away from the
+	// notion of ir.Packages, and make the Program answer
+	// all reasonable questions about any types.Object.)
+
+	return doPackages(initial, mode, false)
+}
+
+// AllPackages creates an IR program for a set of packages plus all
+// their dependencies.
+//
+// The packages must have been loaded from source syntax using the
+// golang.org/x/tools/go/packages.Load function in LoadAllSyntax mode.
+//
+// AllPackages creates an IR package for each well-typed package in the
+// initial list, plus all their dependencies. The resulting list of
+// packages corresponds to the list of initial packages, and may contain
+// a nil if IR code could not be constructed for the corresponding
+// initial package due to type errors.
+//
+// Code for bodies of functions is not built until Build is called on
+// the resulting Program. IR code is constructed for all packages with
+// well-typed syntax trees.
+//
+// The mode parameter controls diagnostics and checking during IR construction.
+func AllPackages(initial []*packages.Package, mode ir.BuilderMode) (*ir.Program, []*ir.Package) {
+	return doPackages(initial, mode, true)
+}
+
+func doPackages(initial []*packages.Package, mode ir.BuilderMode, deps bool) (*ir.Program, []*ir.Package) {
+	var fset *token.FileSet
+	if len(initial) > 0 {
+		fset = initial[0].Fset
+	}
+
+	prog := ir.NewProgram(fset, mode)
+
+	isInitial := make(map[*packages.Package]bool, len(initial))
+	for _, p := range initial {
+		isInitial[p] = true
+	}
+
+	irmap := make(map[*packages.Package]*ir.Package)
+	packages.Visit(initial, nil, func(p *packages.Package) {
+		if p.Types != nil && !p.IllTyped {
+			var files []*ast.File
+			var info *types.Info
+			if deps || isInitial[p] {
+				files = p.Syntax
+				info = p.TypesInfo
+			}
+			irmap[p] = prog.CreatePackage(p.Types, files, info, true)
+		}
+	})
+
+	var irpkgs []*ir.Package
+	for _, p := range initial {
+		irpkgs = append(irpkgs, irmap[p]) // may be nil
+	}
+	return prog, irpkgs
+}
+
+// BuildPackage builds an IR program with IR intermediate
+// representation (IR) for all functions of a single package.
+//
+// It populates pkg by type-checking the specified file ASTs.  All
+// dependencies are loaded using the importer specified by tc, which
+// typically loads compiler export data; IR code cannot be built for
+// those packages.  BuildPackage then constructs an ir.Program with all
+// dependency packages created, and builds and returns the IR package
+// corresponding to pkg.
+//
+// The caller must have set pkg.Path() to the import path.
+//
+// The operation fails if there were any type-checking or import errors.
+//
+// See ../ir/example_test.go for an example.
+func BuildPackage(tc *types.Config, fset *token.FileSet, pkg *types.Package, files []*ast.File, mode ir.BuilderMode) (*ir.Package, *types.Info, error) {
+	if fset == nil {
+		panic("no token.FileSet")
+	}
+	if pkg.Path() == "" {
+		panic("package has no import path")
+	}
+
+	info := &types.Info{
+		Types:        make(map[ast.Expr]types.TypeAndValue),
+		Defs:         make(map[*ast.Ident]types.Object),
+		Uses:         make(map[*ast.Ident]types.Object),
+		Implicits:    make(map[ast.Node]types.Object),
+		Scopes:       make(map[ast.Node]*types.Scope),
+		Selections:   make(map[*ast.SelectorExpr]*types.Selection),
+		Instances:    make(map[*ast.Ident]types.Instance),
+		FileVersions: make(map[*ast.File]string),
+	}
+	if err := types.NewChecker(tc, fset, pkg, info).Files(files); err != nil {
+		return nil, nil, err
+	}
+
+	prog := ir.NewProgram(fset, mode)
+
+	// Create IR packages for all imports.
+	// Order is not significant.
+	created := make(map[*types.Package]bool)
+	var createAll func(pkgs []*types.Package)
+	createAll = func(pkgs []*types.Package) {
+		for _, p := range pkgs {
+			if !created[p] {
+				created[p] = true
+				prog.CreatePackage(p, nil, nil, true)
+				createAll(p.Imports())
+			}
+		}
+	}
+	createAll(pkg.Imports())
+
+	// TODO(adonovan): we could replace createAll with just:
+	//
+	// // Create IR packages for all imports.
+	// for _, p := range pkg.Imports() {
+	// 	prog.CreatePackage(p, nil, nil, true)
+	// }
+	//
+	// (with minor changes to changes to ../builder_test.go as
+	// shown in CL 511715 PS 10.) But this would strictly violate
+	// the letter of the doc comment above, which says "all
+	// dependencies created".
+	//
+	// Tim makes the good point with some extra work we could
+	// remove the need for any CreatePackage calls except the
+	// ones with syntax (i.e. primary packages). Of course
+	// You wouldn't have ir.Packages and Members for as
+	// many things but no-one really uses that anyway.
+	// I wish I had done this from the outset.
+
+	// Create and build the primary package.
+	irpkg := prog.CreatePackage(pkg, files, info, false)
+	irpkg.Build()
+	return irpkg, info, nil
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/loops.go b/vendor/honnef.co/go/tools/go/ir/irutil/loops.go
new file mode 100644
index 0000000..751cc68
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/irutil/loops.go
@@ -0,0 +1,54 @@
+package irutil
+
+import "honnef.co/go/tools/go/ir"
+
+type Loop struct{ *ir.BlockSet }
+
+func FindLoops(fn *ir.Function) []Loop {
+	if fn.Blocks == nil {
+		return nil
+	}
+	tree := fn.DomPreorder()
+	var sets []Loop
+	for _, h := range tree {
+		for _, n := range h.Preds {
+			if !h.Dominates(n) {
+				continue
+			}
+			// n is a back-edge to h
+			// h is the loop header
+			if n == h {
+				set := Loop{ir.NewBlockSet(len(fn.Blocks))}
+				set.Add(n)
+				sets = append(sets, set)
+				continue
+			}
+			set := Loop{ir.NewBlockSet(len(fn.Blocks))}
+			set.Add(h)
+			set.Add(n)
+			for _, b := range allPredsBut(n, h, nil) {
+				set.Add(b)
+			}
+			sets = append(sets, set)
+		}
+	}
+	return sets
+}
+
+func allPredsBut(b, but *ir.BasicBlock, list []*ir.BasicBlock) []*ir.BasicBlock {
+outer:
+	for _, pred := range b.Preds {
+		if pred == but {
+			continue
+		}
+		for _, p := range list {
+			// TODO improve big-o complexity of this function
+			if pred == p {
+				continue outer
+			}
+		}
+		list = append(list, pred)
+		list = allPredsBut(pred, but, list)
+	}
+	return list
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/stub.go b/vendor/honnef.co/go/tools/go/ir/irutil/stub.go
new file mode 100644
index 0000000..6863481
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/irutil/stub.go
@@ -0,0 +1,97 @@
+package irutil
+
+import (
+	"honnef.co/go/tools/go/ir"
+)
+
+// IsStub reports whether a function is a stub. A function is
+// considered a stub if it has no instructions or if all it does is
+// return a fixed value (either an actual constant or a new allocation).
+func IsStub(fn *ir.Function) bool {
+	if fn.Source() == nil {
+		// External functions have to be assumed to not be stubs.
+		return false
+	}
+
+	for _, b := range fn.Blocks {
+		for _, instr := range b.Instrs {
+			switch instr.(type) {
+			case *ir.Panic:
+				// panic is a stub if it only uses constants
+			case *ir.Return:
+				// return is a stub if it only uses constants
+			case *ir.Jump:
+				// if there are no disallowed instructions, then we're
+				// only jumping to the exit block (or possibly
+				// somewhere else that's stubby?)
+			case *ir.MakeInterface:
+				// this can only be wrapping Const and HeapAlloc, which is fine.
+			case *ir.Alloc:
+				// allocating is fine as long as all we do with the allocation
+				// is return it (possibly in an interface value)
+			default:
+				// all other instructions are assumed to do actual work
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// IsTrivial reports whether a function is trivial. A function is
+// considered trivial if it is a stub, only returns a global variable, or calls
+// another trivial function.
+func IsTrivial(fn *ir.Function) bool {
+	return isTrivial(fn, nil)
+}
+
+func isTrivial(fn *ir.Function, seen map[*ir.Function]struct{}) bool {
+	if fn == nil || fn.Source() == nil {
+		// External functions have to be assumed to be nontrivial.
+		return false
+	}
+
+	if _, ok := seen[fn]; ok {
+		// Mutual recursion is not trivial
+		return false
+	}
+
+	// We delay adding to seen until a call, to avoid creating garbage in the
+	// common case.
+	for _, b := range fn.Blocks {
+		for _, instr := range b.Instrs {
+			switch instr := instr.(type) {
+			case *ir.Panic:
+				// panic is a stub if it only uses constants
+			case *ir.Return:
+				// return is a stub if it only uses constants
+			case *ir.Jump:
+				// if there are no disallowed instructions, then we're
+				// only jumping to the exit block (or possibly
+				// somewhere else that's stubby?)
+			case *ir.MakeInterface:
+				// this can only be wrapping allowed instructions
+			case *ir.Alloc:
+				// allocating is fine as long as all we do with the allocation
+				// is return it (possibly in an interface value)
+			case *ir.Load:
+				if _, ok := instr.X.(*ir.Global); !ok {
+					return false
+				}
+			case *ir.Call:
+				if seen == nil {
+					seen = make(map[*ir.Function]struct{})
+				}
+				seen[fn] = struct{}{}
+				callee := instr.Call.StaticCallee()
+				if callee == nil || !isTrivial(callee, seen) {
+					return false
+				}
+			default:
+				// all other instructions are assumed to do actual work
+				return false
+			}
+		}
+	}
+	return true
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/switch.go b/vendor/honnef.co/go/tools/go/ir/irutil/switch.go
new file mode 100644
index 0000000..cf7c54e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/irutil/switch.go
@@ -0,0 +1,250 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package irutil
+
+// This file implements discovery of switch and type-switch constructs
+// from low-level control flow.
+//
+// Many techniques exist for compiling a high-level switch with
+// constant cases to efficient machine code.  The optimal choice will
+// depend on the data type, the specific case values, the code in the
+// body of each case, and the hardware.
+// Some examples:
+// - a lookup table (for a switch that maps constants to constants)
+// - a computed goto
+// - a binary tree
+// - a perfect hash
+// - a two-level switch (to partition constant strings by their first byte).
+
+import (
+	"bytes"
+	"fmt"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/go/ir"
+)
+
+// A ConstCase represents a single constant comparison.
+// It is part of a Switch.
+type ConstCase struct {
+	Block *ir.BasicBlock // block performing the comparison
+	Body  *ir.BasicBlock // body of the case
+	Value *ir.Const      // case comparand
+}
+
+// A TypeCase represents a single type assertion.
+// It is part of a Switch.
+type TypeCase struct {
+	Block   *ir.BasicBlock // block performing the type assert
+	Body    *ir.BasicBlock // body of the case
+	Type    types.Type     // case type
+	Binding ir.Value       // value bound by this case
+}
+
+// A Switch is a logical high-level control flow operation
+// (a multiway branch) discovered by analysis of a CFG containing
+// only if/else chains.  It is not part of the ir.Instruction set.
+//
+// One of ConstCases and TypeCases has length >= 2;
+// the other is nil.
+//
+// In a value switch, the list of cases may contain duplicate constants.
+// A type switch may contain duplicate types, or types assignable
+// to an interface type also in the list.
+// TODO(adonovan): eliminate such duplicates.
+type Switch struct {
+	Start      *ir.BasicBlock // block containing start of if/else chain
+	X          ir.Value       // the switch operand
+	ConstCases []ConstCase    // ordered list of constant comparisons
+	TypeCases  []TypeCase     // ordered list of type assertions
+	Default    *ir.BasicBlock // successor if all comparisons fail
+}
+
+func (sw *Switch) String() string {
+	// We represent each block by the String() of its
+	// first Instruction, e.g. "print(42:int)".
+	var buf bytes.Buffer
+	if sw.ConstCases != nil {
+		fmt.Fprintf(&buf, "switch %s {\n", sw.X.Name())
+		for _, c := range sw.ConstCases {
+			fmt.Fprintf(&buf, "case %s: %s\n", c.Value.Name(), c.Body.Instrs[0])
+		}
+	} else {
+		fmt.Fprintf(&buf, "switch %s.(type) {\n", sw.X.Name())
+		for _, c := range sw.TypeCases {
+			fmt.Fprintf(&buf, "case %s %s: %s\n",
+				c.Binding.Name(), c.Type, c.Body.Instrs[0])
+		}
+	}
+	if sw.Default != nil {
+		fmt.Fprintf(&buf, "default: %s\n", sw.Default.Instrs[0])
+	}
+	fmt.Fprintf(&buf, "}")
+	return buf.String()
+}
+
+// Switches examines the control-flow graph of fn and returns the
+// set of inferred value and type switches.  A value switch tests an
+// ir.Value for equality against two or more compile-time constant
+// values.  Switches involving link-time constants (addresses) are
+// ignored.  A type switch type-asserts an ir.Value against two or
+// more types.
+//
+// The switches are returned in dominance order.
+//
+// The resulting switches do not necessarily correspond to uses of the
+// 'switch' keyword in the source: for example, a single source-level
+// switch statement with non-constant cases may result in zero, one or
+// many Switches, one per plural sequence of constant cases.
+// Switches may even be inferred from if/else- or goto-based control flow.
+// (In general, the control flow constructs of the source program
+// cannot be faithfully reproduced from the IR.)
+func Switches(fn *ir.Function) []Switch {
+	// Traverse the CFG in dominance order, so we don't
+	// enter an if/else-chain in the middle.
+	var switches []Switch
+	seen := make(map[*ir.BasicBlock]bool) // TODO(adonovan): opt: use ir.blockSet
+	for _, b := range fn.DomPreorder() {
+		if x, k := isComparisonBlock(b); x != nil {
+			// Block b starts a switch.
+			sw := Switch{Start: b, X: x}
+			valueSwitch(&sw, k, seen)
+			if len(sw.ConstCases) > 1 {
+				switches = append(switches, sw)
+			}
+		}
+
+		if y, x, T := isTypeAssertBlock(b); y != nil {
+			// Block b starts a type switch.
+			sw := Switch{Start: b, X: x}
+			typeSwitch(&sw, y, T, seen)
+			if len(sw.TypeCases) > 1 {
+				switches = append(switches, sw)
+			}
+		}
+	}
+	return switches
+}
+
+func valueSwitch(sw *Switch, k *ir.Const, seen map[*ir.BasicBlock]bool) {
+	b := sw.Start
+	x := sw.X
+	for sw.X == x {
+		if seen[b] {
+			break
+		}
+		seen[b] = true
+
+		sw.ConstCases = append(sw.ConstCases, ConstCase{
+			Block: b,
+			Body:  b.Succs[0],
+			Value: k,
+		})
+		b = b.Succs[1]
+		n := 0
+		for _, instr := range b.Instrs {
+			switch instr.(type) {
+			case *ir.If, *ir.BinOp:
+				n++
+			case *ir.Phi:
+			default:
+				n += 1000
+			}
+		}
+		if n != 2 {
+			// Block b contains not just 'if x == k' and ϕ nodes,
+			// so it may have side effects that
+			// make it unsafe to elide.
+			break
+		}
+		if len(b.Preds) != 1 {
+			// Block b has multiple predecessors,
+			// so it cannot be treated as a case.
+			break
+		}
+		x, k = isComparisonBlock(b)
+	}
+	sw.Default = b
+}
+
+func typeSwitch(sw *Switch, y ir.Value, T types.Type, seen map[*ir.BasicBlock]bool) {
+	b := sw.Start
+	x := sw.X
+	for sw.X == x {
+		if seen[b] {
+			break
+		}
+		seen[b] = true
+
+		sw.TypeCases = append(sw.TypeCases, TypeCase{
+			Block:   b,
+			Body:    b.Succs[0],
+			Type:    T,
+			Binding: y,
+		})
+		b = b.Succs[1]
+		n := 0
+		for _, instr := range b.Instrs {
+			switch instr.(type) {
+			case *ir.TypeAssert, *ir.Extract, *ir.If:
+				n++
+			case *ir.Phi:
+			default:
+				n += 1000
+			}
+		}
+		if n != 4 {
+			// Block b contains not just
+			//  {TypeAssert; Extract #0; Extract #1; If}
+			// so it may have side effects that
+			// make it unsafe to elide.
+			break
+		}
+		if len(b.Preds) != 1 {
+			// Block b has multiple predecessors,
+			// so it cannot be treated as a case.
+			break
+		}
+		y, x, T = isTypeAssertBlock(b)
+	}
+	sw.Default = b
+}
+
+// isComparisonBlock returns the operands (v, k) if a block ends with
+// a comparison v==k, where k is a compile-time constant.
+func isComparisonBlock(b *ir.BasicBlock) (v ir.Value, k *ir.Const) {
+	if n := len(b.Instrs); n >= 2 {
+		if i, ok := b.Instrs[n-1].(*ir.If); ok {
+			if binop, ok := i.Cond.(*ir.BinOp); ok && binop.Block() == b && binop.Op == token.EQL {
+				if k, ok := binop.Y.(*ir.Const); ok {
+					return binop.X, k
+				}
+				if k, ok := binop.X.(*ir.Const); ok {
+					return binop.Y, k
+				}
+			}
+		}
+	}
+	return
+}
+
+// isTypeAssertBlock returns the operands (y, x, T) if a block ends with
+// a type assertion "if y, ok := x.(T); ok {".
+func isTypeAssertBlock(b *ir.BasicBlock) (y, x ir.Value, T types.Type) {
+	if n := len(b.Instrs); n >= 4 {
+		if i, ok := b.Instrs[n-1].(*ir.If); ok {
+			if ext1, ok := i.Cond.(*ir.Extract); ok && ext1.Block() == b && ext1.Index == 1 {
+				if ta, ok := ext1.Tuple.(*ir.TypeAssert); ok && ta.Block() == b {
+					// hack: relies upon instruction ordering.
+					if ext0, ok := b.Instrs[n-3].(*ir.Extract); ok {
+						return ext0, ta.X, ta.AssertedType
+					}
+				}
+			}
+		}
+	}
+	return
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/terminates.go b/vendor/honnef.co/go/tools/go/ir/irutil/terminates.go
new file mode 100644
index 0000000..84e7503
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/irutil/terminates.go
@@ -0,0 +1,70 @@
+package irutil
+
+import (
+	"go/types"
+
+	"honnef.co/go/tools/go/ir"
+)
+
+// Terminates reports whether fn is supposed to return, that is if it
+// has at least one theoretic path that returns from the function.
+// Explicit panics do not count as terminating.
+func Terminates(fn *ir.Function) bool {
+	if fn.Blocks == nil {
+		// assuming that a function terminates is the conservative
+		// choice
+		return true
+	}
+
+	for _, block := range fn.Blocks {
+		if _, ok := block.Control().(*ir.Return); ok {
+			if len(block.Preds) == 0 {
+				return true
+			}
+			for _, pred := range block.Preds {
+				switch ctrl := pred.Control().(type) {
+				case *ir.Panic:
+					// explicit panics do not count as terminating
+				case *ir.If:
+					// Check if we got here by receiving from a closed
+					// time.Tick channel – this cannot happen at
+					// runtime and thus doesn't constitute termination
+					iff := ctrl
+					if !ok {
+						return true
+					}
+					ex, ok := iff.Cond.(*ir.Extract)
+					if !ok {
+						return true
+					}
+					if ex.Index != 1 {
+						return true
+					}
+					recv, ok := ex.Tuple.(*ir.Recv)
+					if !ok {
+						return true
+					}
+					call, ok := recv.Chan.(*ir.Call)
+					if !ok {
+						return true
+					}
+					fn, ok := call.Common().Value.(*ir.Function)
+					if !ok {
+						return true
+					}
+					fn2, ok := fn.Object().(*types.Func)
+					if !ok {
+						return true
+					}
+					if fn2.FullName() != "time.Tick" {
+						return true
+					}
+				default:
+					// we've reached the exit block
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/util.go b/vendor/honnef.co/go/tools/go/ir/irutil/util.go
new file mode 100644
index 0000000..c8b980b
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/irutil/util.go
@@ -0,0 +1,151 @@
+package irutil
+
+import (
+	"go/types"
+	"slices"
+	"strings"
+
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/types/typeutil"
+)
+
+func Reachable(from, to *ir.BasicBlock) bool {
+	if from == to {
+		return true
+	}
+	if from.Dominates(to) {
+		return true
+	}
+
+	found := false
+	Walk(from, func(b *ir.BasicBlock) bool {
+		if b == to {
+			found = true
+			return false
+		}
+		return true
+	})
+	return found
+}
+
+func Walk(b *ir.BasicBlock, fn func(*ir.BasicBlock) bool) {
+	seen := map[*ir.BasicBlock]bool{}
+	wl := []*ir.BasicBlock{b}
+	for len(wl) > 0 {
+		b := wl[len(wl)-1]
+		wl = wl[:len(wl)-1]
+		if seen[b] {
+			continue
+		}
+		seen[b] = true
+		if !fn(b) {
+			continue
+		}
+		wl = append(wl, b.Succs...)
+	}
+}
+
+func Vararg(x *ir.Slice) ([]ir.Value, bool) {
+	var out []ir.Value
+	alloc, ok := x.X.(*ir.Alloc)
+	if !ok {
+		return nil, false
+	}
+	for _, ref := range *alloc.Referrers() {
+		if ref == x {
+			continue
+		}
+		if ref.Block() != x.Block() {
+			return nil, false
+		}
+		switch ref := ref.(type) {
+		case *ir.IndexAddr:
+			idx := ref
+			if len(*idx.Referrers()) != 1 {
+				return nil, false
+			}
+			store, ok := (*idx.Referrers())[0].(*ir.Store)
+			if !ok {
+				return nil, false
+			}
+			out = append(out, store.Val)
+		default:
+			return nil, false
+		}
+	}
+	return out, true
+}
+
+func CallName(call *ir.CallCommon) string {
+	if call.IsInvoke() {
+		return ""
+	}
+	switch v := call.Value.(type) {
+	case *ir.Function:
+		fn, ok := v.Object().(*types.Func)
+		if !ok {
+			return ""
+		}
+		return typeutil.FuncName(fn)
+	case *ir.Builtin:
+		return v.Name()
+	}
+	return ""
+}
+
+func IsCallTo(call *ir.CallCommon, name string) bool { return CallName(call) == name }
+
+func IsCallToAny(call *ir.CallCommon, names ...string) bool {
+	q := CallName(call)
+	return slices.Contains(names, q)
+}
+
+func IsExample(fn *ir.Function) bool {
+	if !strings.HasPrefix(fn.Name(), "Example") {
+		return false
+	}
+	f := fn.Prog.Fset.File(fn.Pos())
+	if f == nil {
+		return false
+	}
+	return strings.HasSuffix(f.Name(), "_test.go")
+}
+
+// Flatten recursively returns the underlying value of an
+// ir.Phi node. If all edges in an ir.Phi node are the same (after
+// flattening), the flattened edge will get returned. If flattening is
+// not possible, nil is returned.
+func Flatten(v ir.Value) ir.Value {
+	failed := false
+	seen := map[ir.Value]struct{}{}
+	var out ir.Value
+	var dfs func(v ir.Value)
+	dfs = func(v ir.Value) {
+		if failed {
+			return
+		}
+		if _, ok := seen[v]; ok {
+			return
+		}
+		seen[v] = struct{}{}
+
+		switch v := v.(type) {
+		case *ir.Phi:
+			for _, e := range v.Edges {
+				dfs(e)
+			}
+		default:
+			if out == nil {
+				out = v
+			} else if out != v {
+				failed = true
+			}
+		}
+	}
+	dfs(v)
+
+	if failed {
+		return nil
+	}
+	return out
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/visit.go b/vendor/honnef.co/go/tools/go/ir/irutil/visit.go
new file mode 100644
index 0000000..ef438a9
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/irutil/visit.go
@@ -0,0 +1,166 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package irutil // import "honnef.co/go/tools/go/ir/irutil"
+
+import (
+	"go/ast"
+	"go/types"
+
+	_ "unsafe" // for linkname hack
+
+	"honnef.co/go/tools/go/ir"
+)
+
+// This file defines utilities for visiting the IR of
+// a Program.
+//
+// TODO(adonovan): test coverage.
+
+// AllFunctions finds and returns the set of functions potentially
+// needed by program prog, as determined by a simple linker-style
+// reachability algorithm starting from the members and method-sets of
+// each package.  The result may include anonymous functions and
+// synthetic wrappers.
+//
+// Precondition: all packages are built.
+//
+// TODO(adonovan): this function is underspecified. It doesn't
+// actually work like a linker, which computes reachability from main
+// using something like go/callgraph/cha (without materializing the
+// call graph). In fact, it treats all public functions and all
+// methods of public non-parameterized types as roots, even though
+// they may be unreachable--but only in packages created from syntax.
+//
+// I think we should deprecate AllFunctions function in favor of two
+// clearly defined ones:
+//
+//  1. The first would efficiently compute CHA reachability from a set
+//     of main packages, making it suitable for a whole-program
+//     analysis context with InstantiateGenerics, in conjunction with
+//     Program.Build.
+//
+//  2. The second would return only the set of functions corresponding
+//     to source Func{Decl,Lit} syntax, like SrcFunctions in
+//     go/analysis/passes/buildssa; this is suitable for
+//     package-at-a-time (or handful of packages) context.
+//     ir.Package could easily expose it as a field.
+//
+// We could add them unexported for now and use them via the linkname hack.
+func AllFunctions(prog *ir.Program) map[*ir.Function]bool {
+	seen := make(map[*ir.Function]bool)
+
+	var function func(fn *ir.Function)
+	function = func(fn *ir.Function) {
+		if !seen[fn] {
+			seen[fn] = true
+			var buf [10]*ir.Value // avoid alloc in common case
+			for _, b := range fn.Blocks {
+				for _, instr := range b.Instrs {
+					for _, op := range instr.Operands(buf[:0]) {
+						if fn, ok := (*op).(*ir.Function); ok {
+							function(fn)
+						}
+					}
+				}
+			}
+		}
+	}
+
+	// TODO(adonovan): opt: provide a way to share a builder
+	// across a sequence of MethodValue calls.
+
+	methodsOf := func(T types.Type) {
+		if !types.IsInterface(T) {
+			mset := prog.MethodSets.MethodSet(T)
+			for sel := range mset.Methods() {
+				// Skip generic methods.
+				if sel.Obj().(*types.Func).Signature().TypeParams() == nil {
+					function(prog.MethodValue(sel))
+				}
+			}
+		}
+	}
+
+	// Historically, Program.RuntimeTypes used to include the type
+	// of any exported member of a package loaded from syntax that
+	// has a non-parameterized type, plus all types
+	// reachable from that type using reflection, even though
+	// these runtime types may not be required for them.
+	//
+	// Rather than break existing programs that rely on
+	// AllFunctions visiting extra methods that are unreferenced
+	// by IR and unreachable via reflection, we moved the logic
+	// here, unprincipled though it is.
+	// (See doc comment for better ideas.)
+	//
+	// Nonetheless, after the move, we no longer visit every
+	// method of any type recursively reachable from T, only the
+	// methods of T and *T themselves, and we only apply this to
+	// named types T, and not to the type of every exported
+	// package member.
+	exportedTypeHack := func(t *ir.Type) {
+		if isSyntactic(t.Package()) &&
+			ast.IsExported(t.Name()) &&
+			!types.IsInterface(t.Type()) {
+			// Consider only named types.
+			// (Ignore aliases and unsafe.Pointer.)
+			if named, ok := t.Type().(*types.Named); ok {
+				// Skip generic types.
+				if named.TypeParams() == nil {
+					methodsOf(named)                   //  T
+					methodsOf(types.NewPointer(named)) // *T
+				}
+			}
+		}
+	}
+
+	for _, pkg := range prog.AllPackages() {
+		for _, mem := range pkg.Members {
+			switch mem := mem.(type) {
+			case *ir.Function:
+				// Visit all package-level declared functions.
+				//
+				// (This may include generic functions, which is
+				// inconsistent with the treatment of methods:
+				// we skip both generic methods,
+				// and methods of generic types.)
+				function(mem)
+
+			case *ir.Type:
+				exportedTypeHack(mem)
+			}
+		}
+	}
+
+	// Visit all methods of types for which runtime types were
+	// materialized, as they are reachable through reflection.
+	for _, T := range prog.RuntimeTypes() {
+		methodsOf(T)
+	}
+
+	return seen
+}
+
+// MainPackages returns the subset of the specified packages
+// named "main" that define a main function.
+// The result may include synthetic "testmain" packages.
+func MainPackages(pkgs []*ir.Package) []*ir.Package {
+	var mains []*ir.Package
+	for _, pkg := range pkgs {
+		if pkg.Pkg.Name() == "main" && pkg.Func("main") != nil {
+			mains = append(mains, pkg)
+		}
+	}
+	return mains
+}
+
+// TODO(adonovan): propose a principled API for this. One possibility
+// is a new field, Package.SrcFunctions []*Function, which would
+// contain the list of SrcFunctions described in point 2 of the
+// AllFunctions doc comment, or nil if the package is not from syntax.
+// But perhaps overloading nil vs empty slice is too subtle.
+//
+//go:linkname isSyntactic honnef.co/go/tools/go/ir.isSyntactic
+func isSyntactic(pkg *ir.Package) bool
diff --git a/vendor/honnef.co/go/tools/go/ir/lift.go b/vendor/honnef.co/go/tools/go/ir/lift.go
new file mode 100644
index 0000000..61324b0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/lift.go
@@ -0,0 +1,1261 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file defines the lifting pass which tries to "lift" Alloc
+// cells (new/local variables) into SSA registers, replacing loads
+// with the dominating stored value, eliminating loads and stores, and
+// inserting φ-nodes as needed.
+
+// Cited papers and resources:
+//
+// Ron Cytron et al. 1991. Efficiently computing SSA form...
+// https://doi.acm.org/10.1145/115372.115320
+//
+// Cooper, Harvey, Kennedy.  2001.  A Simple, Fast Dominance Algorithm.
+// Software Practice and Experience 2001, 4:1-10.
+// https://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+//
+// Daniel Berlin, llvmdev mailing list, 2012.
+// https://lists.cs.uiuc.edu/pipermail/llvmdev/2012-January/046638.html
+// (Be sure to expand the whole thread.)
+//
+// C. Scott Ananian. 1997. The static single information form.
+//
+// Jeremy Singer. 2006. Static program analysis based on virtual register renaming.
+
+// TODO(adonovan): opt: there are many optimizations worth evaluating, and
+// the conventional wisdom for SSA construction is that a simple
+// algorithm well engineered often beats those of better asymptotic
+// complexity on all but the most egregious inputs.
+//
+// Danny Berlin suggests that the Cooper et al. algorithm for
+// computing the dominance frontier is superior to Cytron et al.
+// Furthermore he recommends that rather than computing the DF for the
+// whole function then renaming all alloc cells, it may be cheaper to
+// compute the DF for each alloc cell separately and throw it away.
+//
+// Consider exploiting liveness information to avoid creating dead
+// φ-nodes which we then immediately remove.
+//
+// Also see many other "TODO: opt" suggestions in the code.
+
+import (
+	"fmt"
+	"os"
+	"slices"
+)
+
+// If true, show diagnostic information at each step of lifting.
+// Very verbose.
+const debugLifting = false
+
+// domFrontier maps each block to the set of blocks in its dominance
+// frontier.  The outer slice is conceptually a map keyed by
+// Block.Index.  The inner slice is conceptually a set, possibly
+// containing duplicates.
+//
+// TODO(adonovan): opt: measure impact of dups; consider a packed bit
+// representation, e.g. big.Int, and bitwise parallel operations for
+// the union step in the Children loop.
+//
+// domFrontier's methods mutate the slice's elements but not its
+// length, so their receivers needn't be pointers.
+type domFrontier BlockMap[[]*BasicBlock]
+
+func (df domFrontier) add(u, v *BasicBlock) {
+	df[u.Index] = append(df[u.Index], v)
+}
+
+// build builds the dominance frontier df for the dominator tree of
+// fn, using the algorithm found in A Simple, Fast Dominance
+// Algorithm, Figure 5.
+//
+// TODO(adonovan): opt: consider Berlin approach, computing pruned SSA
+// by pruning the entire IDF computation, rather than merely pruning
+// the DF -> IDF step.
+func (df domFrontier) build(fn *Function) {
+	for _, b := range fn.Blocks {
+		if len(b.Preds) >= 2 {
+			for _, p := range b.Preds {
+				runner := p
+				for runner != b.dom.idom {
+					df.add(runner, b)
+					runner = runner.dom.idom
+				}
+			}
+		}
+	}
+}
+
+func buildDomFrontier(fn *Function) domFrontier {
+	df := make(domFrontier, len(fn.Blocks))
+	df.build(fn)
+	return df
+}
+
+func removeInstr(refs []Instruction, instr Instruction) []Instruction {
+	s := refs
+	i := -1
+	for j := range s {
+		if instr == s[j] {
+			i = j
+			break
+		}
+	}
+	if i == -1 {
+		return s
+	}
+	// Don't start copying elements until we find one to delete.
+	for j := i + 1; j < len(s); j++ {
+		if v := s[j]; v != instr {
+			s[i] = v
+			i++
+		}
+	}
+	clear(s[i:]) // zero/nil out the obsolete elements, for GC
+	return s[:i]
+}
+
+func clearInstrs(instrs []Instruction) {
+	for i := range instrs {
+		instrs[i] = nil
+	}
+}
+
+func numberNodesPerBlock(f *Function) {
+	for _, b := range f.Blocks {
+		var base ID
+		for _, instr := range b.Instrs {
+			if instr == nil {
+				continue
+			}
+			instr.setID(base)
+			base++
+		}
+	}
+}
+
+// lift replaces local and new Allocs accessed only with
+// load/store by IR registers, inserting φ-nodes where necessary.
+// The result is a program in pruned SSA form.
+//
+// Preconditions:
+// - fn has no dead blocks (blockopt has run).
+// - Def/use info (Operands and Referrers) is up-to-date.
+// - The dominator tree is up-to-date.
+func lift(fn *Function) bool {
+	// TODO(adonovan): opt: lots of little optimizations may be
+	// worthwhile here, especially if they cause us to avoid
+	// buildDomFrontier.  For example:
+	//
+	// - Alloc never loaded?  Eliminate.
+	// - Alloc never stored?  Replace all loads with a zero constant.
+	// - Alloc stored once?  Replace loads with dominating store;
+	//   don't forget that an Alloc is itself an effective store
+	//   of zero.
+	// - Alloc used only within a single block?
+	//   Use degenerate algorithm avoiding φ-nodes.
+	// - Consider synergy with scalar replacement of aggregates (SRA).
+	//   e.g. *(&x.f) where x is an Alloc.
+	//   Perhaps we'd get better results if we generated this as x.f
+	//   i.e. Field(x, .f) instead of Load(FieldIndex(x, .f)).
+	//   Unclear.
+	//
+	// But we will start with the simplest correct code.
+	var df domFrontier
+	var newPhis BlockMap[[]newPhi]
+
+	// During this pass we will replace some BasicBlock.Instrs
+	// (allocs, loads and stores) with nil, keeping a count in
+	// BasicBlock.gaps.  At the end we will reset Instrs to the
+	// concatenation of all non-dead newPhis and non-nil Instrs
+	// for the block, reusing the original array if space permits.
+
+	// While we're here, we also eliminate 'rundefers'
+	// instructions and ssa:deferstack() in functions that contain no
+	// 'defer' instructions. Eliminate ssa:deferstack() if it does not
+	// escape.
+	usesDefer := false
+	deferstackAlloc, deferstackCall := deferstackPreamble(fn)
+	eliminateDeferStack := deferstackAlloc != nil && !deferstackAlloc.Heap
+
+	// Determine which allocs we can lift and number them densely.
+	// The renaming phase uses this numbering for compact maps.
+	numAllocs := 0
+
+	instructions := make(BlockMap[liftInstructions], len(fn.Blocks))
+	for i := range instructions {
+		instructions[i].insertInstructions = map[Instruction][]Instruction{}
+	}
+
+	// Number nodes, for liftable
+	numberNodesPerBlock(fn)
+
+	heads := make(BlockMap[int], len(fn.Blocks))
+	for i := range heads {
+		heads[i] = -1
+	}
+	for _, b := range fn.Blocks {
+		for i, instr := range b.Instrs {
+			if _, ok := instr.(*Phi); !ok {
+				heads[b.Index] = i
+				break
+			}
+		}
+	}
+
+	for _, b := range fn.Blocks {
+		b.gaps = 0
+		b.rundefers = 0
+
+		for _, instr := range b.Instrs {
+			switch instr := instr.(type) {
+			case *Alloc:
+				if !liftable(instr, instructions, heads) {
+					instr.index = -1
+					continue
+				}
+
+				if numAllocs == 0 {
+					df = buildDomFrontier(fn)
+					newPhis = make(BlockMap[[]newPhi], len(fn.Blocks))
+
+					if debugLifting {
+						title := false
+						for i, blocks := range df {
+							if blocks != nil {
+								if !title {
+									fmt.Fprintf(os.Stderr, "Dominance frontier of %s:\n", fn)
+									title = true
+								}
+								fmt.Fprintf(os.Stderr, "\t%s: %s\n", fn.Blocks[i], blocks)
+							}
+						}
+					}
+				}
+				instr.index = numAllocs
+				numAllocs++
+			case *Defer:
+				usesDefer = true
+				if eliminateDeferStack {
+					// Clear _DeferStack and remove references to loads
+					if instr.DeferStack != nil {
+						if refs := instr.DeferStack.Referrers(); refs != nil {
+							*refs = removeInstr(*refs, instr)
+						}
+						instr.DeferStack = nil
+					}
+				}
+			case *RunDefers:
+				b.rundefers++
+			}
+		}
+	}
+
+	if numAllocs > 0 {
+		for _, b := range fn.Blocks {
+			work := instructions[b.Index]
+			for _, rename := range work.renameAllocs {
+				for _, instr_ := range b.Instrs[rename.startingAt:] {
+					replace(instr_, rename.from, rename.to)
+				}
+			}
+		}
+
+		for _, b := range fn.Blocks {
+			work := instructions[b.Index]
+			if len(work.insertInstructions) != 0 {
+				newInstrs := make([]Instruction, 0, len(fn.Blocks)+len(work.insertInstructions)*3)
+				for _, instr := range b.Instrs {
+					if add, ok := work.insertInstructions[instr]; ok {
+						newInstrs = append(newInstrs, add...)
+					}
+					newInstrs = append(newInstrs, instr)
+				}
+				b.Instrs = newInstrs
+			}
+		}
+
+		// TODO(dh): remove inserted allocs that end up unused after lifting.
+
+		for _, b := range fn.Blocks {
+			for _, instr := range b.Instrs {
+				if instr, ok := instr.(*Alloc); ok && instr.index >= 0 {
+					liftAlloc(df, instr, newPhis)
+				}
+			}
+		}
+
+		// renaming maps an alloc (keyed by index) to its replacement
+		// value.  Initially the renaming contains nil, signifying the
+		// zero constant of the appropriate type; we construct the
+		// Const lazily at most once on each path through the domtree.
+		// TODO(adonovan): opt: cache per-function not per subtree.
+		renaming := make([]Value, numAllocs)
+
+		// Renaming.
+		rename(fn.Blocks[0], renaming, newPhis)
+
+		simplifyPhis(newPhis)
+
+		// Eliminate dead φ-nodes.
+		markLiveNodes(fn.Blocks, newPhis)
+
+		// Eliminate ssa:deferstack() call.
+		if eliminateDeferStack {
+			b := deferstackCall.block
+			for i, instr := range b.Instrs {
+				if instr == deferstackCall {
+					b.Instrs[i] = nil
+					b.gaps++
+					break
+				}
+			}
+		}
+	}
+
+	// Prepend remaining live φ-nodes to each block and possibly kill rundefers.
+	for _, b := range fn.Blocks {
+		var head []Instruction
+		if numAllocs > 0 {
+			nps := newPhis[b.Index]
+			head = make([]Instruction, 0, len(nps))
+			for _, np := range nps {
+				if np.phi.live {
+					head = append(head, np.phi)
+				} else {
+					for _, edge := range np.phi.Edges {
+						if refs := edge.Referrers(); refs != nil {
+							*refs = removeInstr(*refs, np.phi)
+						}
+					}
+					np.phi.block = nil
+				}
+			}
+		}
+
+		rundefersToKill := b.rundefers
+		if usesDefer {
+			rundefersToKill = 0
+		}
+
+		j := len(head)
+		if j+b.gaps+rundefersToKill == 0 {
+			continue // fast path: no new phis or gaps
+		}
+
+		// We could do straight copies instead of element-wise copies
+		// when both b.gaps and rundefersToKill are zero. However,
+		// that seems to only be the case ~1% of the time, which
+		// doesn't seem worth the extra branch.
+
+		// Remove dead instructions, add phis
+		ns := len(b.Instrs) + j - b.gaps - rundefersToKill
+		if ns <= cap(b.Instrs) {
+			// b.Instrs has enough capacity to store all instructions
+
+			// OPT(dh): check cap vs the actually required space; if
+			// there is a big enough difference, it may be worth
+			// allocating a new slice, to avoid pinning memory.
+			dst := b.Instrs[:cap(b.Instrs)]
+			i := len(dst) - 1
+			for n := len(b.Instrs) - 1; n >= 0; n-- {
+				instr := dst[n]
+				if instr == nil {
+					continue
+				}
+				if !usesDefer {
+					if _, ok := instr.(*RunDefers); ok {
+						continue
+					}
+				}
+				dst[i] = instr
+				i--
+			}
+			off := i + 1 - len(head)
+			// aid GC
+			clearInstrs(dst[:off])
+			dst = dst[off:]
+			copy(dst, head)
+			b.Instrs = dst
+		} else {
+			// not enough space, so allocate a new slice and copy
+			// over.
+			dst := make([]Instruction, ns)
+			copy(dst, head)
+
+			for _, instr := range b.Instrs {
+				if instr == nil {
+					continue
+				}
+				if !usesDefer {
+					if _, ok := instr.(*RunDefers); ok {
+						continue
+					}
+				}
+				dst[j] = instr
+				j++
+			}
+			b.Instrs = dst
+		}
+	}
+
+	// Remove any fn.Locals that were lifted.
+	j := 0
+	for _, l := range fn.Locals {
+		if l.index < 0 {
+			fn.Locals[j] = l
+			j++
+		}
+	}
+	// Nil out fn.Locals[j:] to aid GC.
+	for i := j; i < len(fn.Locals); i++ {
+		fn.Locals[i] = nil
+	}
+	fn.Locals = fn.Locals[:j]
+
+	return numAllocs > 0
+}
+
+func hasDirectReferrer(instr Instruction) bool {
+	for _, instr := range *instr.Referrers() {
+		if _, ok := instr.(*Phi); !ok {
+			return true
+		}
+	}
+	return false
+}
+
+func markLiveNodes(blocks []*BasicBlock, newPhis BlockMap[[]newPhi]) {
+	// Phis may become dead due to optimization passes.
+
+	// Phi nodes are considered live if a non-phi
+	// node uses them. Once we find a node that is live, we mark all
+	// of its operands as used, too.
+	for _, npList := range newPhis {
+		for _, np := range npList {
+			phi := np.phi
+			if !phi.live && hasDirectReferrer(phi) {
+				markLivePhi(phi)
+			}
+		}
+	}
+	// Existing φ-nodes due to && and || operators
+	// are all considered live (see Go issue 19622).
+	for _, b := range blocks {
+		for _, phi := range b.phis() {
+			markLivePhi(phi.(*Phi))
+		}
+	}
+}
+
+func markLivePhi(phi *Phi) {
+	phi.live = true
+	for _, rand := range phi.Edges {
+		if rand, ok := rand.(*Phi); ok {
+			if !rand.live {
+				markLivePhi(rand)
+			}
+		}
+	}
+}
+
+// simplifyPhis replaces trivial phis with non-phi alternatives. Phi
+// nodes where all edges are identical, or consist of only the phi
+// itself and one other value, may be replaced with the value.
+func simplifyPhis(newPhis BlockMap[[]newPhi]) {
+	// find all phis that are trivial and can be replaced with a
+	// non-phi value. run until we reach a fixpoint, because replacing
+	// a phi may make other phis trivial.
+	for changed := true; changed; {
+		changed = false
+		for _, npList := range newPhis {
+			for _, np := range npList {
+				if np.phi.live {
+					// we're reusing 'live' to mean 'dead' in the context of simplifyPhis
+					continue
+				}
+				if r, ok := isUselessPhi(np.phi); ok {
+					// useless phi, replace its uses with the
+					// replacement value. the dead phi pass will clean
+					// up the phi afterwards.
+					replaceAll(np.phi, r)
+					np.phi.live = true
+					changed = true
+				}
+			}
+		}
+	}
+}
+
+type BlockSet struct {
+	idx    int
+	values []bool
+	count  int
+}
+
+func NewBlockSet(size int) *BlockSet {
+	return &BlockSet{values: make([]bool, size)}
+}
+
+func (s *BlockSet) Set(s2 *BlockSet) {
+	copy(s.values, s2.values)
+	s.count = 0
+	for _, v := range s.values {
+		if v {
+			s.count++
+		}
+	}
+}
+
+func (s *BlockSet) Num() int {
+	return s.count
+}
+
+func (s *BlockSet) Has(b *BasicBlock) bool {
+	if b.Index >= len(s.values) {
+		return false
+	}
+	return s.values[b.Index]
+}
+
+// add adds b to the set and returns true if the set changed.
+func (s *BlockSet) Add(b *BasicBlock) bool {
+	if s.values[b.Index] {
+		return false
+	}
+	s.count++
+	s.values[b.Index] = true
+	s.idx = b.Index
+
+	return true
+}
+
+func (s *BlockSet) Clear() {
+	for j := range s.values {
+		s.values[j] = false
+	}
+	s.count = 0
+}
+
+// take removes an arbitrary element from a set s and
+// returns its index, or returns -1 if empty.
+func (s *BlockSet) Take() int {
+	// [i, end]
+	for i := s.idx; i < len(s.values); i++ {
+		if s.values[i] {
+			s.values[i] = false
+			s.idx = i
+			s.count--
+			return i
+		}
+	}
+
+	// [start, i)
+	for i := 0; i < s.idx; i++ {
+		if s.values[i] {
+			s.values[i] = false
+			s.idx = i
+			s.count--
+			return i
+		}
+	}
+
+	return -1
+}
+
+// newPhi is a pair of a newly introduced φ-node and the lifted Alloc
+// it replaces.
+type newPhi struct {
+	phi   *Phi
+	alloc *Alloc
+}
+
+type liftInstructions struct {
+	insertInstructions map[Instruction][]Instruction
+	renameAllocs       []struct {
+		from       *Alloc
+		to         *Alloc
+		startingAt int
+	}
+}
+
+type liftableBlockDesc struct {
+	// is the block (partially) unliftable, because it contains unliftable
+	// instructions or is reachable by an unliftable block
+	isUnliftable     bool
+	hasLiftableLoad  bool
+	hasLiftableOther bool
+	// we need to emit stores in predecessors because the unliftable use is in
+	// a phi
+	storeInPreds bool
+
+	lastLiftable    int
+	firstUnliftable int
+}
+
+// liftable determines if alloc can be lifted, and records instructions to split partially liftable allocs.
+//
+// In the trivial case, all uses of the alloc can be lifted. This is the case when it is only used for storing into and
+// loading from. In that case, no instructions are recorded.
+//
+// In the more complex case, the alloc is used for storing into and loading from, but it is also used as a value, for
+// example because it gets passed to a function, e.g. fn(&x). In this case, uses of the alloc fall into one of two
+// categories: those that can be lifted and those that can't. A boundary forms between these two categories in the
+// function's control flow: Once an unliftable use is encountered, the alloc is no longer liftable for the remainder of
+// the basic block the use is in, nor in any blocks reachable from it.
+//
+// We record instructions that split the alloc into two allocs: one that is used in liftable uses, and one that is used
+// in unliftable uses. Whenever we encounter a boundary between liftable and unliftable uses or blocks, we emit a pair
+// of Load and Store that copy the value from the liftable alloc into the unliftable alloc. Taking these instructions
+// into account, the normal lifting machinery will completely lift the liftable alloc, store the correct lifted values
+// into the unliftable alloc, and will not at all lift the unliftable alloc.
+//
+// In Go syntax, the transformation looks somewhat like this:
+//
+//	func foo() {
+//		x := 32
+//		if cond {
+//			println(x)
+//			escape(&x)
+//			println(x)
+//		} else {
+//			println(x)
+//		}
+//		println(x)
+//	}
+//
+// transforms into
+//
+//	func fooSplitAlloc() {
+//		x := 32
+//		var x_ int
+//		if cond {
+//			println(x)
+//			x_ = x
+//			escape(&x_)
+//			println(x_)
+//		} else {
+//			println(x)
+//			x_ = x
+//		}
+//		println(x_)
+//	}
+func liftable(alloc *Alloc, instructions BlockMap[liftInstructions], heads BlockMap[int]) bool {
+	fn := alloc.block.parent
+
+	// Don't lift result values in functions that defer
+	// calls that may recover from panic.
+	if fn.Recover != nil {
+		if slices.Contains(fn.results, alloc) {
+			return false
+		}
+	}
+
+	blocks := fn.liftableBlockMap
+	if len(blocks) != len(fn.Blocks) {
+		blocks = make(BlockMap[liftableBlockDesc], len(fn.Blocks))
+		fn.liftableBlockMap = blocks
+	} else {
+		clear(blocks)
+	}
+	for _, b := range fn.Blocks {
+		blocks[b.Index].lastLiftable = -1
+		blocks[b.Index].firstUnliftable = len(b.Instrs) + 1
+	}
+
+	// Look at all uses of the alloc and deduce which blocks have liftable or unliftable instructions.
+	for _, instr := range alloc.referrers {
+		// Find the first unliftable use
+
+		desc := &blocks[instr.Block().Index]
+		hasUnliftable := false
+		inHead := false
+		switch instr := instr.(type) {
+		case *Store:
+			if instr.Val == alloc {
+				hasUnliftable = true
+			}
+		case *Load:
+		case *debugRef:
+		case *Phi:
+			inHead = true
+			hasUnliftable = true
+		default:
+			hasUnliftable = true
+		}
+
+		if hasUnliftable {
+			desc.isUnliftable = true
+			if int(instr.ID()) < desc.firstUnliftable {
+				desc.firstUnliftable = int(instr.ID())
+			}
+			if inHead {
+				desc.storeInPreds = true
+				desc.firstUnliftable = 0
+			}
+		}
+	}
+
+	for _, instr := range alloc.referrers {
+		// Find the last liftable use, taking the previously calculated firstUnliftable into consideration
+
+		desc := &blocks[instr.Block().Index]
+		if int(instr.ID()) >= desc.firstUnliftable {
+			continue
+		}
+		hasLiftable := false
+		switch instr := instr.(type) {
+		case *Store:
+			if instr.Val != alloc {
+				desc.hasLiftableOther = true
+				hasLiftable = true
+			}
+		case *Load:
+			desc.hasLiftableLoad = true
+			hasLiftable = true
+		case *debugRef:
+			desc.hasLiftableOther = true
+		}
+		if hasLiftable {
+			if int(instr.ID()) > desc.lastLiftable {
+				desc.lastLiftable = int(instr.ID())
+			}
+		}
+	}
+
+	for i := range blocks {
+		// Update firstUnliftable to be one after lastLiftable. We do this to include the unliftable's preceding
+		// DebugRefs in the renaming.
+		if blocks[i].lastLiftable == -1 && !blocks[i].storeInPreds {
+			// There are no liftable instructions (for this alloc) in this block. Set firstUnliftable to the
+			// first non-head instruction to avoid inserting the store before phi instructions, which would
+			// fail validation.
+			first := heads[i]
+			blocks[i].firstUnliftable = first
+		} else {
+			blocks[i].firstUnliftable = blocks[i].lastLiftable + 1
+		}
+	}
+
+	// If a block is reachable by a (partially) unliftable block, then the entirety of the block is unliftable. In that
+	// case, stores have to be inserted in the predecessors.
+	//
+	// TODO(dh): this isn't always necessary. If the block is reachable by itself, i.e. part of a loop, then if the
+	// Alloc instruction is itself part of that loop, then there is a subset of instructions in the loop that can be
+	// lifted. For example:
+	//
+	// 	for {
+	// 		x := 42
+	// 		println(x)
+	// 		escape(&x)
+	// 	}
+	//
+	// The x that escapes in one iteration of the loop isn't the same x that we read from on the next iteration.
+	seen := make(BlockMap[bool], len(fn.Blocks))
+	var dfs func(b *BasicBlock)
+	dfs = func(b *BasicBlock) {
+		if seen[b.Index] {
+			return
+		}
+		seen[b.Index] = true
+		desc := &blocks[b.Index]
+		desc.hasLiftableLoad = false
+		desc.hasLiftableOther = false
+		desc.isUnliftable = true
+		desc.firstUnliftable = 0
+		desc.storeInPreds = true
+		for _, succ := range b.Succs {
+			dfs(succ)
+		}
+	}
+	for _, b := range fn.Blocks {
+		if blocks[b.Index].isUnliftable {
+			for _, succ := range b.Succs {
+				dfs(succ)
+			}
+		}
+	}
+
+	hasLiftableLoad := false
+	hasLiftableOther := false
+	hasUnliftable := false
+	for _, b := range fn.Blocks {
+		desc := &blocks[b.Index]
+		hasLiftableLoad = hasLiftableLoad || desc.hasLiftableLoad
+		hasLiftableOther = hasLiftableOther || desc.hasLiftableOther
+		if desc.isUnliftable {
+			hasUnliftable = true
+		}
+	}
+	if !hasLiftableLoad && !hasLiftableOther {
+		// There are no liftable uses
+		return false
+	} else if !hasUnliftable {
+		// The alloc is entirely liftable without splitting
+		return true
+	} else if !hasLiftableLoad {
+		// The alloc is not entirely liftable, and the only liftable uses are stores. While some of those stores could
+		// get lifted away, it would also lead to an infinite loop when lifting to a fixpoint, because the newly created
+		// allocs also get stored into repeatable and that's their only liftable uses.
+		return false
+	}
+
+	// We need to insert stores for the new alloc. If a (partially) unliftable block has no unliftable
+	// predecessors and the use isn't in a phi node, then the store can be inserted right before the unliftable use.
+	// Otherwise, stores have to be inserted at the end of all liftable predecessors.
+
+	newAlloc := &Alloc{Heap: true}
+	newAlloc.setBlock(alloc.block)
+	newAlloc.setType(alloc.typ)
+	newAlloc.setSource(alloc.source)
+	newAlloc.index = -1
+	newAlloc.comment = "split alloc"
+
+	{
+		work := instructions[alloc.block.Index]
+		work.insertInstructions[alloc] = append(work.insertInstructions[alloc], newAlloc)
+	}
+
+	predHasStore := make(BlockMap[bool], len(fn.Blocks))
+	for _, b := range fn.Blocks {
+		desc := &blocks[b.Index]
+		bWork := &instructions[b.Index]
+
+		if desc.isUnliftable {
+			bWork.renameAllocs = append(bWork.renameAllocs, struct {
+				from       *Alloc
+				to         *Alloc
+				startingAt int
+			}{
+				alloc, newAlloc, int(desc.firstUnliftable),
+			})
+		}
+
+		if !desc.isUnliftable {
+			continue
+		}
+
+		propagate := func(in *BasicBlock, before Instruction) {
+			load := &Load{
+				X: alloc,
+			}
+			store := &Store{
+				Addr: newAlloc,
+				Val:  load,
+			}
+			load.setType(deref(alloc.typ))
+			load.setBlock(in)
+			load.comment = "split alloc"
+			store.setBlock(in)
+			updateOperandReferrers(load)
+			updateOperandReferrers(store)
+			store.comment = "split alloc"
+
+			entry := &instructions[in.Index]
+			entry.insertInstructions[before] = append(entry.insertInstructions[before], load, store)
+		}
+
+		if desc.storeInPreds {
+			// emit stores at the end of liftable preds
+			for _, pred := range b.Preds {
+				if blocks[pred.Index].isUnliftable {
+					continue
+				}
+
+				if !alloc.block.Dominates(pred) {
+					// Consider this cfg:
+					//
+					//      1
+					//     /|
+					//    / |
+					//   ↙  ↓
+					//  2--→3
+					//
+					// with an Alloc in block 2. It doesn't make sense to insert a store in block 1 for the jump to
+					// block 3, because 1 can never see the Alloc in the first place.
+					//
+					// Ignoring phi nodes, an Alloc always dominates all of its uses, and phi nodes don't matter here,
+					// because for the incoming edges that do matter, we do emit the stores.
+
+					continue
+				}
+
+				if predHasStore[pred.Index] {
+					// Don't generate redundant propagations. Not only is it unnecessary, it can lead to infinite loops
+					// when trying to lift to a fix point, because redundant stores are liftable.
+					continue
+				}
+
+				predHasStore[pred.Index] = true
+
+				before := pred.Instrs[len(pred.Instrs)-1]
+				propagate(pred, before)
+			}
+		} else {
+			// emit store before the first unliftable use
+			before := b.Instrs[desc.firstUnliftable]
+			propagate(b, before)
+		}
+	}
+
+	return true
+}
+
+// liftAlloc lifts alloc into registers and populates newPhis with all the φ-nodes it may require.
+func liftAlloc(df domFrontier, alloc *Alloc, newPhis BlockMap[[]newPhi]) {
+	fn := alloc.Parent()
+
+	defblocks := fn.blockset(0)
+	Aphi := fn.blockset(2)
+	W := fn.blockset(3)
+
+	// Compute defblocks, the set of blocks containing a
+	// definition of the alloc cell.
+	for _, instr := range *alloc.Referrers() {
+		switch instr := instr.(type) {
+		case *Store:
+			defblocks.Add(instr.Block())
+		}
+	}
+	// The Alloc itself counts as a (zero) definition of the cell.
+	defblocks.Add(alloc.Block())
+
+	if debugLifting {
+		fmt.Fprintln(os.Stderr, "\tlifting ", alloc, alloc.Name())
+	}
+
+	// Φ-insertion.
+	//
+	// What follows is the body of the main loop of the insert-φ
+	// function described by Cytron et al, but instead of using
+	// counter tricks, we just reset the 'hasAlready' and 'work'
+	// sets each iteration.  These are bitmaps so it's pretty cheap.
+
+	// Initialize W and work to defblocks.
+
+	for change := true; change; {
+		change = false
+		{
+			// Traverse iterated dominance frontier, inserting φ-nodes.
+			W.Set(defblocks)
+
+			for i := W.Take(); i != -1; i = W.Take() {
+				n := fn.Blocks[i]
+				for _, y := range df[n.Index] {
+					if Aphi.Add(y) {
+						if len(*alloc.Referrers()) == 0 {
+							continue
+						}
+						live := false
+						for _, ref := range *alloc.Referrers() {
+							if _, ok := ref.(*Load); ok {
+								if y.Reaches(ref.Block()) {
+									live = true
+									break
+								}
+							}
+						}
+						if !live {
+							continue
+						}
+
+						// Create φ-node.
+						// It will be prepended to v.Instrs later, if needed.
+						phi := &Phi{
+							Edges: make([]Value, len(y.Preds)),
+						}
+						phi.comment = alloc.comment
+						phi.source = alloc.source
+						phi.setType(deref(alloc.Type()))
+						phi.block = y
+						if debugLifting {
+							fmt.Fprintf(os.Stderr, "\tplace %s = %s at block %s\n", phi.Name(), phi, y)
+						}
+						newPhis[y.Index] = append(newPhis[y.Index], newPhi{phi, alloc})
+
+						change = true
+						if defblocks.Add(y) {
+							W.Add(y)
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+// replaceAll replaces all intraprocedural uses of x with y,
+// updating x.Referrers and y.Referrers.
+// Precondition: x.Referrers() != nil, i.e. x must be local to some function.
+func replaceAll(x, y Value) {
+	var rands []*Value
+	pxrefs := x.Referrers()
+	pyrefs := y.Referrers()
+	for _, instr := range *pxrefs {
+		switch instr := instr.(type) {
+		case *CompositeValue:
+			// Special case CompositeValue because it might have very large lists of operands
+			//
+			// OPT(dh): this loop is still expensive for large composite values
+			for i, rand := range instr.Values {
+				if rand == x {
+					instr.Values[i] = y
+				}
+			}
+		default:
+			rands = instr.Operands(rands[:0]) // recycle storage
+			for _, rand := range rands {
+				if *rand != nil {
+					if *rand == x {
+						*rand = y
+					}
+				}
+			}
+		}
+		if pyrefs != nil {
+			*pyrefs = append(*pyrefs, instr) // dups ok
+		}
+	}
+	*pxrefs = nil // x is now unreferenced
+}
+
+func replace(instr Instruction, x, y Value) {
+	args := instr.Operands(nil)
+	matched := false
+	for _, arg := range args {
+		if *arg == x {
+			*arg = y
+			matched = true
+		}
+	}
+	if matched {
+		yrefs := y.Referrers()
+		if yrefs != nil {
+			*yrefs = append(*yrefs, instr)
+		}
+
+		xrefs := x.Referrers()
+		if xrefs != nil {
+			*xrefs = removeInstr(*xrefs, instr)
+		}
+	}
+}
+
+// renamed returns the value to which alloc is being renamed,
+// constructing it lazily if it's the implicit zero initialization.
+func renamed(fn *Function, renaming []Value, alloc *Alloc) Value {
+	v := renaming[alloc.index]
+	if v == nil {
+		v = zeroConst(deref(alloc.Type()), alloc.source)
+		renaming[alloc.index] = v
+	}
+	return v
+}
+
+// rename implements the Cytron et al-based SSA renaming algorithm, a
+// preorder traversal of the dominator tree replacing all loads of
+// Alloc cells with the value stored to that cell by the dominating
+// store instruction.
+//
+// renaming is a map from *Alloc (keyed by index number) to its
+// dominating stored value; newPhis[x] is the set of new φ-nodes to be
+// prepended to block x.
+func rename(u_ *BasicBlock, renaming_ []Value, newPhis BlockMap[[]newPhi]) {
+	type worklistEntry struct {
+		u        *BasicBlock
+		renaming []Value
+	}
+
+	worklist := []worklistEntry{{u_, renaming_}}
+	var freelist [][]Value
+
+	for len(worklist) > 0 {
+		entry := worklist[len(worklist)-1]
+		worklist = worklist[:len(worklist)-1]
+		u, renaming := entry.u, entry.renaming
+
+		// Each φ-node becomes the new name for its associated Alloc.
+		for _, np := range newPhis[u.Index] {
+			phi := np.phi
+			alloc := np.alloc
+			renaming[alloc.index] = phi
+		}
+
+		// Rename loads and stores of allocs.
+		for i, instr := range u.Instrs {
+			switch instr := instr.(type) {
+			case *Alloc:
+				if instr.index >= 0 { // store of zero to Alloc cell
+					// Replace dominated loads by the zero value.
+					renaming[instr.index] = nil
+					if debugLifting {
+						fmt.Fprintf(os.Stderr, "\tkill alloc %s\n", instr)
+					}
+					// Delete the Alloc.
+					u.Instrs[i] = nil
+					u.gaps++
+				}
+
+			case *Store:
+				if alloc, ok := instr.Addr.(*Alloc); ok && alloc.index >= 0 { // store to Alloc cell
+					// Replace dominated loads by the stored value.
+					renaming[alloc.index] = instr.Val
+					if debugLifting {
+						fmt.Fprintf(os.Stderr, "\tkill store %s; new value: %s\n",
+							instr, instr.Val.Name())
+					}
+					if refs := instr.Addr.Referrers(); refs != nil {
+						*refs = removeInstr(*refs, instr)
+					}
+					if refs := instr.Val.Referrers(); refs != nil {
+						*refs = removeInstr(*refs, instr)
+					}
+					// Delete the Store.
+					u.Instrs[i] = nil
+					u.gaps++
+				}
+
+			case *Load:
+				if alloc, ok := instr.X.(*Alloc); ok && alloc.index >= 0 { // load of Alloc cell
+					newval := renamed(u.Parent(), renaming, alloc)
+					if debugLifting {
+						fmt.Fprintf(os.Stderr, "\tupdate load %s = %s with %s\n",
+							instr.Name(), instr, newval)
+					}
+					// Replace all references to the loaded value by the dominating
+					// stored value.
+					replaceAll(instr, newval)
+					u.Instrs[i] = nil
+					u.gaps++
+				}
+
+			case *debugRef:
+				if x, ok := instr.X.(*Alloc); ok && x.index >= 0 {
+					if instr.IsAddr {
+						instr.X = renamed(u.Parent(), renaming, x)
+						instr.IsAddr = false
+
+						// Add DebugRef to instr.X's referrers.
+						if refs := instr.X.Referrers(); refs != nil {
+							*refs = append(*refs, instr)
+						}
+					} else {
+						// A source expression denotes the address
+						// of an Alloc that was optimized away.
+						instr.X = nil
+
+						// Delete the DebugRef.
+						u.Instrs[i] = nil
+						u.gaps++
+					}
+				}
+			}
+		}
+
+		// For each φ-node in a CFG successor, rename the edge.
+		for _, v := range u.Succs {
+			phis := newPhis[v.Index]
+			if len(phis) == 0 {
+				continue
+			}
+			i := v.predIndex(u)
+			for _, np := range phis {
+				phi := np.phi
+				alloc := np.alloc
+				newval := renamed(u.Parent(), renaming, alloc)
+				if debugLifting {
+					fmt.Fprintf(os.Stderr, "\tsetphi %s edge %s -> %s (#%d) (alloc=%s) := %s\n",
+						phi.Name(), u, v, i, alloc.Name(), newval.Name())
+				}
+				phi.Edges[i] = newval
+				if prefs := newval.Referrers(); prefs != nil {
+					*prefs = append(*prefs, phi)
+				}
+			}
+		}
+
+		// Continue depth-first recursion over domtree, pushing a
+		// fresh copy of the renaming map for each subtree.
+		for _, v := range slices.Backward(u.dom.children) {
+			var r []Value
+			if len(freelist) == 0 {
+				r = make([]Value, len(renaming))
+			} else {
+				r = freelist[len(freelist)-1]
+				freelist = freelist[:len(freelist)-1]
+			}
+			copy(r, renaming)
+			worklist = append(worklist, worklistEntry{v, r})
+		}
+		freelist = append(freelist, renaming)
+	}
+}
+
+func simplifyConstantCompositeValues(fn *Function) bool {
+	changed := false
+
+	for _, b := range fn.Blocks {
+		n := 0
+		for _, instr := range b.Instrs {
+			replaced := false
+
+			if cv, ok := instr.(*CompositeValue); ok {
+				ac := &AggregateConst{}
+				ac.typ = cv.typ
+				replaced = true
+				for _, v := range cv.Values {
+					if c, ok := v.(Constant); ok {
+						ac.Values = append(ac.Values, c)
+					} else {
+						replaced = false
+						break
+					}
+				}
+				if replaced {
+					replaceAll(cv, ac)
+					killInstruction(cv)
+				}
+
+			}
+
+			if replaced {
+				changed = true
+			} else {
+				b.Instrs[n] = instr
+				n++
+			}
+		}
+
+		clearInstrs(b.Instrs[n:])
+		b.Instrs = b.Instrs[:n]
+	}
+
+	return changed
+}
+
+func updateOperandReferrers(instr Instruction) {
+	for _, op := range instr.Operands(nil) {
+		refs := (*op).Referrers()
+		if refs != nil {
+			*refs = append(*refs, instr)
+		}
+	}
+}
+
+// deferstackPreamble returns the *Alloc and ssa:deferstack() call for fn.deferstack.
+func deferstackPreamble(fn *Function) (*Alloc, *Call) {
+	if alloc, _ := fn.vars[fn.deferstack].(*Alloc); alloc != nil {
+		for _, ref := range *alloc.Referrers() {
+			if ref, _ := ref.(*Store); ref != nil && ref.Addr == alloc {
+				if call, _ := ref.Val.(*Call); call != nil {
+					return alloc, call
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/lvalue.go b/vendor/honnef.co/go/tools/go/ir/lvalue.go
new file mode 100644
index 0000000..502293c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/lvalue.go
@@ -0,0 +1,175 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// lvalues are the union of addressable expressions and map-index
+// expressions.
+
+import (
+	"go/ast"
+	"go/types"
+)
+
+// An lvalue represents an assignable location that may appear on the
+// left-hand side of an assignment.  This is a generalization of a
+// pointer to permit updates to elements of maps.
+type lvalue interface {
+	store(fn *Function, v Value, source ast.Node) // stores v into the location
+	load(fn *Function, source ast.Node) Value     // loads the contents of the location
+	address(fn *Function) Value                   // address of the location
+	typ() types.Type                              // returns the type of the location
+}
+
+// An address is an lvalue represented by a true pointer.
+type address struct {
+	addr Value    // must have a pointer core type.
+	expr ast.Expr // source syntax of the value (not address) [debug mode]
+}
+
+func (a *address) load(fn *Function, source ast.Node) Value {
+	return emitLoad(fn, a.addr, source)
+}
+
+func (a *address) store(fn *Function, v Value, source ast.Node) {
+	store := emitStore(fn, a.addr, v, source)
+	if a.expr != nil {
+		// store.Val is v, converted for assignability.
+		emitDebugRef(fn, a.expr, store.Val, false)
+	}
+}
+
+func (a *address) address(fn *Function) Value {
+	if a.expr != nil {
+		emitDebugRef(fn, a.expr, a.addr, true)
+	}
+	return a.addr
+}
+
+func (a *address) typ() types.Type {
+	return deref(a.addr.Type())
+}
+
+type compositeElement struct {
+	cv   *CompositeValue
+	idx  int
+	t    types.Type
+	expr ast.Expr
+}
+
+func (ce *compositeElement) load(fn *Function, source ast.Node) Value {
+	panic("not implemented")
+}
+
+func (ce *compositeElement) store(fn *Function, v Value, source ast.Node) {
+	v = emitConv(fn, v, ce.t, source)
+	ce.cv.Values[ce.idx] = v
+	if ce.expr != nil {
+		// store.Val is v, converted for assignability.
+		emitDebugRef(fn, ce.expr, v, false)
+	}
+}
+
+func (ce *compositeElement) address(fn *Function) Value {
+	panic("not implemented")
+}
+
+func (ce *compositeElement) typ() types.Type {
+	return ce.t
+}
+
+// An element is an lvalue represented by m[k], the location of an
+// element of a map.  These locations are not addressable
+// since pointers cannot be formed from them, but they do support
+// load() and store().
+type element struct {
+	m, k Value      // map
+	t    types.Type // map element type
+}
+
+func (e *element) load(fn *Function, source ast.Node) Value {
+	l := &MapLookup{
+		X:     e.m,
+		Index: e.k,
+	}
+	l.setType(e.t)
+	return fn.emit(l, source)
+}
+
+func (e *element) store(fn *Function, v Value, source ast.Node) {
+	up := &MapUpdate{
+		Map:   e.m,
+		Key:   e.k,
+		Value: emitConv(fn, v, e.t, source),
+	}
+	fn.emit(up, source)
+}
+
+func (e *element) address(fn *Function) Value {
+	panic("map elements are not addressable")
+}
+
+func (e *element) typ() types.Type {
+	return e.t
+}
+
+// A lazyAddress is an lvalue whose address is the result of an instruction.
+// These work like an *address except a new address.address() Value
+// is created on each load, store and address call.
+// A lazyAddress can be used to control when a side effect (nil pointer
+// dereference, index out of bounds) of using a location happens.
+type lazyAddress struct {
+	addr func(fn *Function) Value // emit to fn the computation of the address
+	t    types.Type               // type of the location
+	expr ast.Expr                 // source syntax of the value (not address) [debug mode]
+}
+
+func (l *lazyAddress) load(fn *Function, source ast.Node) Value {
+	load := emitLoad(fn, l.addr(fn), source)
+	return load
+}
+
+func (l *lazyAddress) store(fn *Function, v Value, source ast.Node) {
+	store := emitStore(fn, l.addr(fn), v, source)
+	if l.expr != nil {
+		// store.Val is v, converted for assignability.
+		emitDebugRef(fn, l.expr, store.Val, false)
+	}
+}
+
+func (l *lazyAddress) address(fn *Function) Value {
+	addr := l.addr(fn)
+	if l.expr != nil {
+		emitDebugRef(fn, l.expr, addr, true)
+	}
+	return addr
+}
+
+func (l *lazyAddress) typ() types.Type { return l.t }
+
+// A blank is a dummy variable whose name is "_".
+// It is not reified: loads are illegal and stores are ignored.
+type blank struct{}
+
+func (bl blank) load(fn *Function, source ast.Node) Value {
+	panic("blank.load is illegal")
+}
+
+func (bl blank) store(fn *Function, v Value, source ast.Node) {
+	s := &BlankStore{
+		Val: v,
+	}
+	fn.emit(s, source)
+}
+
+func (bl blank) address(fn *Function) Value {
+	panic("blank var is not addressable")
+}
+
+func (bl blank) typ() types.Type {
+	// This should be the type of the blank Ident; the typechecker
+	// doesn't provide this yet, but fortunately, we don't need it
+	// yet either.
+	panic("blank.typ is unimplemented")
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/methods.go b/vendor/honnef.co/go/tools/go/ir/methods.go
new file mode 100644
index 0000000..0cdce8f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/methods.go
@@ -0,0 +1,245 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file defines utilities for population of method sets.
+
+import (
+	"fmt"
+	"go/token"
+	"go/types"
+
+	"golang.org/x/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/xtools-internal/typesinternal"
+)
+
+// MethodValue returns the Function implementing method sel, building
+// wrapper methods on demand. It returns nil if sel denotes an
+// interface or generic method, or a method of a generic type.
+//
+// Precondition: sel.Kind() == MethodVal.
+//
+// Thread-safe.
+//
+// Acquires prog.methodsMu.
+func (prog *Program) MethodValue(sel *types.Selection) *Function {
+	if sel.Kind() != types.MethodVal {
+		panic(fmt.Sprintf("MethodValue(%s) kind != MethodVal", sel))
+	}
+
+	method := sel.Obj().(*types.Func)
+	if method.Signature().TypeParams().Len() > 0 {
+		return nil // generic method
+	}
+
+	T := sel.Recv()
+	if types.IsInterface(T) {
+		return nil // interface method or type parameter
+	}
+
+	// We can avoid materializing sel.Type(): it will be parameterized iff
+	// the receiver type T is too (see go.dev/issue/81308).
+	if prog.isParameterized(T) {
+		return nil // method on generic type
+	}
+
+	if prog.mode&LogSource != 0 {
+		defer logStack("MethodValue %s %v", T, sel)()
+	}
+
+	key := methodKeyOf(method.Pkg(), method.Name())
+
+	// The critical section returns a builder only if it created a
+	// new Function. In the common case, a method created by an
+	// earlier call, it allocates nothing: a builder declared out
+	// here would escape to the heap on every call.
+	fn, b := func() (*Function, *builder) {
+		prog.methodsMu.Lock()
+		defer prog.methodsMu.Unlock()
+
+		// Get or create SSA method set.
+		mset, ok := prog.methodSets.At(T)
+		if !ok {
+			mset = &methodSet{mapping: make(map[methodKey]*Function)}
+			prog.methodSets.Set(T, mset)
+		}
+
+		// Get or create SSA method.
+		if fn, ok := mset.mapping[key]; ok {
+			return fn, nil
+		}
+		b := new(builder)
+		var fn *Function
+		needsPromotion := len(sel.Index()) > 1
+		needsIndirection := !isPointer(recvType(method)) && isPointer(T)
+		if needsPromotion || needsIndirection {
+			fn = createWrapper(prog, toSelection(sel), nil)
+			fn.buildshared = b.shared()
+			b.enqueue(fn)
+		} else {
+			fn = prog.objectMethod(method, nil, b)
+		}
+		if fn.Signature.Recv() == nil {
+			panic(fn)
+		}
+		mset.mapping[key] = fn
+		return fn, b
+	}()
+
+	if b != nil {
+		b.iterate()
+	} else if !fn.buildshared.isTransitivelyDone() {
+		// fn was created by an earlier call and another builder
+		// is still building it: wait for that to finish.
+		var b builder
+		b.waitForSharedFunction(fn)
+		b.iterate()
+	}
+	return fn
+}
+
+// objectMethod returns the Function for a given method symbol.
+// The symbol may be an instance of a generic function. It need not
+// belong to an existing SSA package created by a call to
+// prog.CreatePackage.
+//
+// objectMethod panics if the function is not a method.
+//
+// Acquires prog.objectMethodsMu.
+func (prog *Program) objectMethod(obj *types.Func, targs []types.Type, b *builder) *Function {
+	sig := obj.Type().(*types.Signature)
+	if sig.Recv() == nil {
+		panic("not a method: " + obj.String())
+	}
+
+	// Instantiation of generic?
+	if orig := obj.Origin(); orig != obj || len(targs) > 0 {
+		return prog.objectMethod(orig, nil, b).instance(receiverTypeArgs(obj), targs, b)
+	}
+
+	// Belongs to a created package?
+	if fn := prog.FuncValue(obj); fn != nil {
+		return fn
+	}
+
+	// Consult/update cache of methods created from types.Func.
+	prog.objectMethodsMu.Lock()
+	defer prog.objectMethodsMu.Unlock()
+	fn, ok := prog.objectMethods[obj]
+	if !ok {
+		fn = createFunction(prog, obj, obj.Name(), nil, nil, "")
+		fn.Synthetic = "from type information (on demand)"
+		fn.buildshared = b.shared()
+		b.enqueue(fn)
+
+		if prog.objectMethods == nil {
+			prog.objectMethods = make(map[*types.Func]*Function)
+		}
+		prog.objectMethods[obj] = fn
+	} else {
+		b.waitForSharedFunction(fn)
+	}
+	return fn
+}
+
+// LookupMethod returns the implementation of the method of type T
+// identified by (pkg, name).  It returns nil if the method exists but
+// is an interface method or generic method, and panics if T has no such method.
+func (prog *Program) LookupMethod(T types.Type, pkg *types.Package, name string) *Function {
+	// Fast path: the method was created and built by an earlier
+	// call. RTA calls LookupMethod once per (call site, concrete
+	// type) pair, so this is the common case; it avoids computing
+	// the method set of T and searching it, which dominates the
+	// cost of the slow path below.
+	if fn := prog.existingMethod(T, methodKeyOf(pkg, name)); fn != nil {
+		return fn
+	}
+
+	sel := prog.MethodSets.MethodSet(T).Lookup(pkg, name)
+	if sel == nil {
+		panic(fmt.Sprintf("%s has no method %s", T, types.Id(pkg, name)))
+	}
+	return prog.MethodValue(sel)
+}
+
+// existingMethod returns the Function implementing the method of
+// the concrete type T identified by key, if it has already been
+// created and built, or nil. A recorded method implies that T was
+// found to be concrete and non-parameterized and the method
+// non-generic when it was created.
+//
+// Acquires prog.methodsMu.
+func (prog *Program) existingMethod(T types.Type, key methodKey) *Function {
+	prog.methodsMu.Lock()
+	defer prog.methodsMu.Unlock()
+	if mset, ok := prog.methodSets.At(T); ok {
+		if fn := mset.mapping[key]; fn != nil && fn.buildshared.isTransitivelyDone() {
+			return fn
+		}
+	}
+	return nil
+}
+
+// methodSet contains the (concrete) methods of a concrete type (non-interface, non-parameterized).
+type methodSet struct {
+	mapping map[methodKey]*Function // populated lazily
+}
+
+// methodKey identifies a method within a method set the same way
+// types.Id does, by name for exported methods and by package path
+// and name for unexported ones, without building a string.
+type methodKey struct {
+	path string // package path, or "" if name is exported
+	name string
+}
+
+func methodKeyOf(pkg *types.Package, name string) methodKey {
+	if token.IsExported(name) {
+		return methodKey{"", name}
+	}
+	path := "_" // as types.Id does when pkg is nil
+	if pkg != nil {
+		path = pkg.Path()
+	}
+	return methodKey{path, name}
+}
+
+// RuntimeTypes returns a new unordered slice containing all types in
+// the program for which a runtime type is required.
+//
+// A runtime type is required for any non-parameterized, non-interface
+// type that is converted to an interface, or for any type (including
+// interface types) derivable from one through reflection.
+//
+// The methods of such types may be reachable through reflection or
+// interface calls even if they are never called directly.
+//
+// Thread-safe.
+//
+// Acquires prog.makeInterfaceTypesMu.
+func (prog *Program) RuntimeTypes() []types.Type {
+	prog.makeInterfaceTypesMu.Lock()
+	defer prog.makeInterfaceTypesMu.Unlock()
+
+	// Compute the derived types on demand, since many SSA clients
+	// never call RuntimeTypes, and those that do typically call
+	// it once (often within irutil.AllFunctions, which will
+	// eventually not use it; see Go issue #69291.) This
+	// eliminates the need to eagerly compute all the element
+	// types during SSA building.
+	var runtimeTypes []types.Type
+	var set typeutil.Map // for de-duping identical types
+	for t := range prog.makeInterfaceTypes {
+		typesinternal.ForEachElement(prog.MethodSets.MethodSet, t, func(t types.Type) bool {
+			seen, _ := set.Set(t, true).(bool)
+			if !seen {
+				runtimeTypes = append(runtimeTypes, t)
+			}
+			return seen
+		})
+	}
+
+	return runtimeTypes
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/mode.go b/vendor/honnef.co/go/tools/go/ir/mode.go
new file mode 100644
index 0000000..8f55bce
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/mode.go
@@ -0,0 +1,118 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file defines the BuilderMode type and its command-line flag.
+
+import (
+	"bytes"
+	"fmt"
+)
+
+// BuilderMode is a bitmask of options for diagnostics and checking.
+//
+// *BuilderMode satisfies the flag.Value interface.  Example:
+//
+//	var mode = ir.BuilderMode(0)
+//	func init() { flag.Var(&mode, "build", ir.BuilderModeDoc) }
+type BuilderMode uint
+
+const (
+	PrintPackages        BuilderMode = 1 << iota // Print package inventory to stdout
+	PrintFunctions                               // Print function IR code to stdout
+	PrintSource                                  // Print source code when printing function IR
+	LogSource                                    // Log source locations as IR builder progresses
+	SanityCheckFunctions                         // Perform sanity checking of function bodies
+	NaiveForm                                    // Build naïve IR form: don't replace local loads/stores with registers
+	BuildSerially                                // Build packages serially, not in parallel.
+	GlobalDebug                                  // Enable debug info for all packages
+	BareInits                                    // Build init functions without guards or calls to dependent inits
+	InstantiateGenerics                          // Instantiate generics functions (monomorphize) while building
+)
+
+const BuilderModeDoc = `Options controlling the IR builder.
+The value is a sequence of zero or more of these letters:
+C	perform sanity [C]hecking of the IR form.
+D	include [D]ebug info for every function.
+P	print [P]ackage inventory.
+F	print [F]unction IR code.
+A	print [A]ST nodes responsible for IR instructions
+S	log [S]ource locations as IR builder progresses.
+L	build distinct packages seria[L]ly instead of in parallel.
+N	build [N]aive IR form: don't replace local loads/stores with registers.
+I	build bare [I]nit functions: no init guards or calls to dependent inits.
+G   instantiate [G]eneric function bodies via monomorphization
+`
+
+func (m BuilderMode) String() string {
+	var buf bytes.Buffer
+	if m&GlobalDebug != 0 {
+		buf.WriteByte('D')
+	}
+	if m&PrintPackages != 0 {
+		buf.WriteByte('P')
+	}
+	if m&PrintFunctions != 0 {
+		buf.WriteByte('F')
+	}
+	if m&PrintSource != 0 {
+		buf.WriteByte('A')
+	}
+	if m&LogSource != 0 {
+		buf.WriteByte('S')
+	}
+	if m&SanityCheckFunctions != 0 {
+		buf.WriteByte('C')
+	}
+	if m&NaiveForm != 0 {
+		buf.WriteByte('N')
+	}
+	if m&BuildSerially != 0 {
+		buf.WriteByte('L')
+	}
+	if m&BareInits != 0 {
+		buf.WriteByte('I')
+	}
+	if m&InstantiateGenerics != 0 {
+		buf.WriteByte('G')
+	}
+	return buf.String()
+}
+
+// Set parses the flag characters in s and updates *m.
+func (m *BuilderMode) Set(s string) error {
+	var mode BuilderMode
+	for _, c := range s {
+		switch c {
+		case 'D':
+			mode |= GlobalDebug
+		case 'P':
+			mode |= PrintPackages
+		case 'F':
+			mode |= PrintFunctions
+		case 'A':
+			mode |= PrintSource
+		case 'S':
+			mode |= LogSource | BuildSerially
+		case 'C':
+			mode |= SanityCheckFunctions
+		case 'N':
+			mode |= NaiveForm
+		case 'L':
+			mode |= BuildSerially
+		case 'I':
+			mode |= BareInits
+		case 'G':
+			mode |= InstantiateGenerics
+		default:
+			return fmt.Errorf("unknown BuilderMode option: %q", c)
+		}
+	}
+	*m = mode
+	return nil
+}
+
+// Get returns m.
+func (m BuilderMode) Get() any { return m }
diff --git a/vendor/honnef.co/go/tools/go/ir/print.go b/vendor/honnef.co/go/tools/go/ir/print.go
new file mode 100644
index 0000000..c71518a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/print.go
@@ -0,0 +1,554 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file implements the String() methods for all Value and
+// Instruction types.
+
+import (
+	"bytes"
+	"fmt"
+	"go/types"
+	"io"
+	"reflect"
+	"sort"
+	"strings"
+
+	"honnef.co/go/tools/go/types/typeutil"
+)
+
+// relName returns the name of v relative to i.
+// In most cases, this is identical to v.Name(), but references to
+// Functions (including methods) and Globals use RelString and
+// all types are displayed with relType, so that only cross-package
+// references are package-qualified.
+func relName(v Value, i Node) string {
+	if v == nil {
+		return ""
+	}
+	var from *types.Package
+	if i != nil {
+		from = i.Parent().relPkg()
+	}
+	switch v := v.(type) {
+	case Member: // *Function or *Global
+		return v.RelString(from)
+	case *Const:
+		return v.RelString(from)
+	}
+	return v.Name()
+}
+
+func relType(t types.Type, from *types.Package) string {
+	return types.TypeString(t, types.RelativeTo(from))
+}
+
+func relTerm(term *types.Term, from *types.Package) string {
+	s := relType(term.Type(), from)
+	if term.Tilde() {
+		return "~" + s
+	}
+	return s
+}
+
+func relString(m Member, from *types.Package) string {
+	// NB: not all globals have an Object (e.g. init$guard),
+	// so use Package().Object not Object.Package().
+	if pkg := m.Package().Pkg; pkg != nil && pkg != from {
+		return fmt.Sprintf("%s.%s", pkg.Path(), m.Name())
+	}
+	return m.Name()
+}
+
+// Value.String()
+//
+// This method is provided only for debugging.
+// It never appears in disassembly, which uses Value.Name().
+
+func (v *Parameter) String() string {
+	from := v.Parent().relPkg()
+	return fmt.Sprintf("parameter %s : %s", v.Object().Name(), relType(v.Type(), from))
+}
+
+func (v *FreeVar) String() string {
+	from := v.Parent().relPkg()
+	return fmt.Sprintf("freevar %s : %s", v.Name(), relType(v.Type(), from))
+}
+
+func (v *Builtin) String() string {
+	return fmt.Sprintf("builtin %s", v.Name())
+}
+
+// Instruction.String()
+
+func (v *Alloc) String() string {
+	op := "local"
+	if v.Heap {
+		op = "new"
+	}
+	from := v.Parent().relPkg()
+	return fmt.Sprintf("%s %s (%s)", op, relType(deref(v.Type()), from), v.Comment())
+}
+
+func (v *Phi) String() string {
+	var b bytes.Buffer
+	b.WriteString("phi [")
+	for i, edge := range v.Edges {
+		if i > 0 {
+			b.WriteString(", ")
+		}
+		// Be robust against malformed CFG.
+		if v.block == nil {
+			b.WriteString("??")
+			continue
+		}
+		block := -1
+		if i < len(v.block.Preds) {
+			block = v.block.Preds[i].Index
+		}
+		fmt.Fprintf(&b, "%d: ", block)
+		edgeVal := "" // be robust
+		if edge != nil {
+			edgeVal = relName(edge, v)
+		}
+		b.WriteString(edgeVal)
+	}
+	b.WriteString("]")
+	if v.Comment() != "" {
+		b.WriteString(" #")
+		b.WriteString(v.Comment())
+	}
+	return b.String()
+}
+
+func printCall(v *CallCommon, prefix string, instr Instruction) string {
+	var b bytes.Buffer
+	b.WriteString(prefix)
+	if !v.IsInvoke() {
+		b.WriteString(relName(v.Value, instr))
+	} else {
+		fmt.Fprintf(&b, "invoke %s.%s", relName(v.Value, instr), v.Method.Name())
+	}
+	b.WriteString("(")
+	for i, arg := range v.Args {
+		if i > 0 {
+			b.WriteString(", ")
+		}
+		b.WriteString(relName(arg, instr))
+	}
+	if v.Signature().Variadic() {
+		b.WriteString("...")
+	}
+	b.WriteString(")")
+	return b.String()
+}
+
+func (c *CallCommon) String() string {
+	return printCall(c, "", nil)
+}
+
+func (v *Call) String() string {
+	return printCall(&v.Call, "", v)
+}
+
+func (v *BinOp) String() string {
+	return fmt.Sprintf("%s %s %s", relName(v.X, v), v.Op.String(), relName(v.Y, v))
+}
+
+func (v *UnOp) String() string {
+	return fmt.Sprintf("%s%s", v.Op, relName(v.X, v))
+}
+
+func (v *Load) String() string {
+	return fmt.Sprintf("*%s", relName(v.X, v))
+}
+
+func printConv(prefix string, v, x Value) string {
+	from := v.Parent().relPkg()
+	return fmt.Sprintf("%s %s <- %s (%s)",
+		prefix,
+		relType(v.Type(), from),
+		relType(x.Type(), from),
+		relName(x, v.(Instruction)))
+}
+
+func (v *ChangeType) String() string          { return printConv("changetype", v, v.X) }
+func (v *Convert) String() string             { return printConv("convert", v, v.X) }
+func (v *ChangeInterface) String() string     { return printConv("change interface", v, v.X) }
+func (v *SliceToArrayPointer) String() string { return printConv("slice to array pointer", v, v.X) }
+func (v *SliceToArray) String() string        { return printConv("SliceToArray", v, v.X) }
+func (v *MakeInterface) String() string       { return printConv("make", v, v.X) }
+
+func (v *MultiConvert) String() string {
+	from := v.Parent().relPkg()
+
+	var b strings.Builder
+	b.WriteString(printConv("multiconvert", v, v.X))
+	b.WriteString(" [")
+	for i, s := range termListOf(v.from) {
+		for j, d := range termListOf(v.to) {
+			if i != 0 || j != 0 {
+				b.WriteString(" | ")
+			}
+			fmt.Fprintf(&b, "%s <- %s", relTerm(d, from), relTerm(s, from))
+		}
+	}
+	b.WriteString("]")
+	return b.String()
+}
+
+func (v *MakeClosure) String() string {
+	var b bytes.Buffer
+	fmt.Fprintf(&b, "make closure %s", relName(v.Fn, v))
+	if v.Bindings != nil {
+		b.WriteString(" [")
+		for i, c := range v.Bindings {
+			if i > 0 {
+				b.WriteString(", ")
+			}
+			b.WriteString(relName(c, v))
+		}
+		b.WriteString("]")
+	}
+	return b.String()
+}
+
+func (v *MakeSlice) String() string {
+	from := v.Parent().relPkg()
+	return fmt.Sprintf("make %s %s %s",
+		relType(v.Type(), from),
+		relName(v.Len, v),
+		relName(v.Cap, v))
+}
+
+func (v *Slice) String() string {
+	var b bytes.Buffer
+	b.WriteString("slice ")
+	b.WriteString(relName(v.X, v))
+	b.WriteString("[")
+	if v.Low != nil {
+		b.WriteString(relName(v.Low, v))
+	}
+	b.WriteString(":")
+	if v.High != nil {
+		b.WriteString(relName(v.High, v))
+	}
+	if v.Max != nil {
+		b.WriteString(":")
+		b.WriteString(relName(v.Max, v))
+	}
+	b.WriteString("]")
+	return b.String()
+}
+
+func (v *MakeMap) String() string {
+	res := ""
+	if v.Reserve != nil {
+		res = relName(v.Reserve, v)
+	}
+	from := v.Parent().relPkg()
+	return fmt.Sprintf("make %s %s", relType(v.Type(), from), res)
+}
+
+func (v *MakeChan) String() string {
+	from := v.Parent().relPkg()
+	return fmt.Sprintf("make %s %s", relType(v.Type(), from), relName(v.Size, v))
+}
+
+func (v *FieldAddr) String() string {
+	// Be robust against a bad index.
+	name := "?"
+	if fld := fieldOf(deref(v.X.Type()), v.Field); fld != nil {
+		name = fld.Name()
+	}
+	return fmt.Sprintf("&%s.%s [#%d]", relName(v.X, v), name, v.Field)
+}
+
+func (v *Field) String() string {
+	// Be robust against a bad index.
+	name := "?"
+	if fld := fieldOf(v.X.Type(), v.Field); fld != nil {
+		name = fld.Name()
+	}
+	return fmt.Sprintf("%s.%s [#%d]", relName(v.X, v), name, v.Field)
+}
+
+func (v *IndexAddr) String() string {
+	return fmt.Sprintf("&%s[%s]", relName(v.X, v), relName(v.Index, v))
+}
+
+func (v *Index) String() string {
+	return fmt.Sprintf("%s[%s]", relName(v.X, v), relName(v.Index, v))
+}
+
+func (v *MapLookup) String() string {
+	return fmt.Sprintf("%s[%s]%s", relName(v.X, v), relName(v.Index, v), commaOk(v.CommaOk))
+}
+
+func (v *StringLookup) String() string {
+	return fmt.Sprintf("%s[%s]", relName(v.X, v), relName(v.Index, v))
+}
+
+func (v *Range) String() string {
+	return "range " + relName(v.X, v)
+}
+
+func (v *Next) String() string {
+	return "next " + relName(v.Iter, v)
+}
+
+func (v *TypeAssert) String() string {
+	from := v.Parent().relPkg()
+	return fmt.Sprintf("typeassert%s %s.(%s)", commaOk(v.CommaOk), relName(v.X, v), relType(v.AssertedType, from))
+}
+
+func (v *Extract) String() string {
+	name := v.Tuple.Type().(*types.Tuple).At(v.Index).Name()
+	if name == "" {
+		return fmt.Sprintf("extract %s #%d", relName(v.Tuple, v), v.Index)
+	} else {
+		return fmt.Sprintf("extract %s #%d (%s)", relName(v.Tuple, v), v.Index, name)
+	}
+}
+
+func (s *Jump) String() string {
+	// Be robust against malformed CFG.
+	block := -1
+	if s.block != nil && len(s.block.Succs) == 1 {
+		block = s.block.Succs[0].Index
+	}
+	str := fmt.Sprintf("jump %d", block)
+	if s.Comment() != "" {
+		str = fmt.Sprintf("%s # %s", str, s.Comment())
+	}
+	return str
+}
+
+func (s *Unreachable) String() string {
+	return "Unreachable"
+}
+
+func (s *If) String() string {
+	// Be robust against malformed CFG.
+	tblock, fblock := -1, -1
+	if s.block != nil && len(s.block.Succs) == 2 {
+		tblock = s.block.Succs[0].Index
+		fblock = s.block.Succs[1].Index
+	}
+	return fmt.Sprintf("if %s goto %d else %d", relName(s.Cond, s), tblock, fblock)
+}
+
+func (s *ConstantSwitch) String() string {
+	var b bytes.Buffer
+	fmt.Fprintf(&b, "ConstantSwitch %s", relName(s.Tag, s))
+	for _, cond := range s.Conds {
+		fmt.Fprintf(&b, " %s", relName(cond, s))
+	}
+	fmt.Fprint(&b, " →")
+	for _, succ := range s.block.Succs {
+		fmt.Fprintf(&b, " b%d", succ.Index)
+	}
+	return b.String()
+}
+
+func (v *CompositeValue) String() string {
+	var b bytes.Buffer
+	fmt.Fprint(&b, "{")
+	first := true
+
+	var printValue func(idx int, vv Value)
+	switch typ := typeutil.CoreType(v.typ).(type) {
+	case *types.Struct:
+		printValue = func(idx int, vv Value) {
+			fieldName := typ.Field(idx).Name()
+			fmt.Fprintf(&b, "%s: %s", fieldName, relName(vv, v))
+		}
+	case *types.Array:
+		if v.NumSet >= len(v.Values) {
+			printValue = func(idx int, vv Value) {
+				fmt.Fprint(&b, relName(vv, v))
+			}
+		} else {
+			// This is currently unreachable as we don't use CompositeValue for
+			// incomplete arrays.
+			printValue = func(idx int, vv Value) {
+				fmt.Fprintf(&b, "%d: %s", idx, relName(vv, v))
+			}
+		}
+	default:
+		panic(fmt.Sprintf("internal error: unexpected type %T (%v)", typ, typ))
+	}
+	for i, vv := range v.Values {
+		if !first {
+			fmt.Fprint(&b, ", ")
+		}
+		first = false
+		printValue(i, vv)
+	}
+	fmt.Fprint(&b, "}")
+	return b.String()
+}
+
+func (s *TypeSwitch) String() string {
+	var b bytes.Buffer
+	fmt.Fprintf(&b, "switch %s.(type)", relName(s.Tag, s))
+	for _, cond := range s.Conds {
+		fmt.Fprintf(&b, " %s", relType(cond, s.block.parent.relPkg()))
+	}
+	return b.String()
+}
+
+func (s *Go) String() string {
+	return printCall(&s.Call, "go ", s)
+}
+
+func (s *Panic) String() string {
+	return "panic " + relName(s.X, s)
+}
+
+func (s *Return) String() string {
+	var b bytes.Buffer
+	b.WriteString("return")
+	for i, r := range s.Results {
+		if i == 0 {
+			b.WriteString(" ")
+		} else {
+			b.WriteString(", ")
+		}
+		b.WriteString(relName(r, s))
+	}
+	return b.String()
+}
+
+func (*RunDefers) String() string {
+	return "rundefers"
+}
+
+func (s *Send) String() string {
+	return fmt.Sprintf("send %s <- %s", relName(s.Chan, s), relName(s.X, s))
+}
+
+func (recv *Recv) String() string {
+	return fmt.Sprintf("<-%s", relName(recv.Chan, recv))
+}
+
+func (s *Defer) String() string {
+	prefix := "defer "
+	if s.DeferStack != nil {
+		prefix += "[" + relName(s.DeferStack, s) + "] "
+	}
+	c := printCall(&s.Call, prefix, s)
+	return c
+}
+
+func (s *Select) String() string {
+	var b bytes.Buffer
+	for i, st := range s.States {
+		if i > 0 {
+			b.WriteString(", ")
+		}
+		if st.Dir == types.RecvOnly {
+			b.WriteString("<-")
+			b.WriteString(relName(st.Chan, s))
+		} else {
+			b.WriteString(relName(st.Chan, s))
+			b.WriteString("<-")
+			b.WriteString(relName(st.Send, s))
+		}
+	}
+	non := ""
+	if !s.Blocking {
+		non = "non"
+	}
+	return fmt.Sprintf("select %sblocking [%s]", non, b.String())
+}
+
+func (s *Store) String() string {
+	return fmt.Sprintf("*%s = %s", relName(s.Addr, s), relName(s.Val, s))
+}
+
+func (s *BlankStore) String() string {
+	return fmt.Sprintf("_ = %s", relName(s.Val, s))
+}
+
+func (s *MapUpdate) String() string {
+	return fmt.Sprintf("%s[%s] = %s", relName(s.Map, s), relName(s.Key, s), relName(s.Value, s))
+}
+
+func (s *debugRef) String() string {
+	p := s.Parent().Prog.Fset.Position(s.Pos())
+	var descr any
+	if s.object != nil {
+		descr = s.object // e.g. "var x int"
+	} else {
+		descr = reflect.TypeOf(s.Expr) // e.g. "*ast.CallExpr"
+	}
+	var addr string
+	if s.IsAddr {
+		addr = "address of "
+	}
+	return fmt.Sprintf("; %s%s @ %d:%d is %s", addr, descr, p.Line, p.Column, s.X.Name())
+}
+
+func (p *Package) String() string {
+	return "package " + p.Pkg.Path()
+}
+
+var _ io.WriterTo = (*Package)(nil) // *Package implements io.Writer
+
+func (p *Package) WriteTo(w io.Writer) (int64, error) {
+	var buf bytes.Buffer
+	WritePackage(&buf, p)
+	n, err := w.Write(buf.Bytes())
+	return int64(n), err
+}
+
+// WritePackage writes to buf a human-readable summary of p.
+func WritePackage(buf *bytes.Buffer, p *Package) {
+	fmt.Fprintf(buf, "%s:\n", p)
+
+	var names []string
+	maxname := 0
+	for name := range p.Members {
+		if l := len(name); l > maxname {
+			maxname = l
+		}
+		names = append(names, name)
+	}
+
+	from := p.Pkg
+	sort.Strings(names)
+	for _, name := range names {
+		switch mem := p.Members[name].(type) {
+		case *NamedConst:
+			fmt.Fprintf(buf, "  const %-*s %s = %s\n",
+				maxname, name, mem.Name(), mem.Value.RelString(from))
+
+		case *Function:
+			fmt.Fprintf(buf, "  func  %-*s %s\n",
+				maxname, name, relType(mem.Type(), from))
+
+		case *Type:
+			fmt.Fprintf(buf, "  type  %-*s %s\n",
+				maxname, name, relType(mem.Type().Underlying(), from))
+			for _, meth := range typeutil.IntuitiveMethodSet(mem.Type(), &p.Prog.MethodSets) {
+				fmt.Fprintf(buf, "    %s\n", types.SelectionString(meth, types.RelativeTo(from)))
+			}
+
+		case *Global:
+			fmt.Fprintf(buf, "  var   %-*s %s\n",
+				maxname, name, relType(deref(mem.Type()), from))
+		}
+	}
+
+	fmt.Fprintf(buf, "\n")
+}
+
+func commaOk(x bool) string {
+	if x {
+		return ",ok"
+	}
+	return ""
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/sanity.go b/vendor/honnef.co/go/tools/go/ir/sanity.go
new file mode 100644
index 0000000..ab379ed
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/sanity.go
@@ -0,0 +1,689 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// An optional pass for sanity-checking invariants of the IR representation.
+// Currently it checks CFG invariants but little at the instruction level.
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/types"
+	"io"
+	"os"
+	"slices"
+	"strings"
+
+	"honnef.co/go/tools/go/types/typeutil"
+)
+
+type sanity struct {
+	reporter io.Writer
+	fn       *Function
+	block    *BasicBlock
+	instrs   map[Instruction]struct{}
+	insane   bool
+}
+
+// sanityCheck performs integrity checking of the IR representation
+// of the function fn and returns true if it was valid.  Diagnostics
+// are written to reporter if non-nil, os.Stderr otherwise.  Some
+// diagnostics are only warnings and do not imply a negative result.
+//
+// Sanity-checking is intended to facilitate the debugging of code
+// transformation passes.
+func sanityCheck(fn *Function, reporter io.Writer) bool {
+	if reporter == nil {
+		reporter = os.Stderr
+	}
+	return (&sanity{reporter: reporter}).checkFunction(fn)
+}
+
+// mustSanityCheck is like sanityCheck but panics instead of returning
+// a negative result.
+func mustSanityCheck(fn *Function, reporter io.Writer) {
+	if !sanityCheck(fn, reporter) {
+		fn.WriteTo(os.Stderr)
+		panic("SanityCheck failed")
+	}
+}
+
+func (s *sanity) diagnostic(prefix, format string, args ...any) {
+	fmt.Fprintf(s.reporter, "%s: function %s", prefix, s.fn)
+	if s.block != nil {
+		fmt.Fprintf(s.reporter, ", block %s", s.block)
+	}
+	io.WriteString(s.reporter, ": ")
+	fmt.Fprintf(s.reporter, format, args...)
+	io.WriteString(s.reporter, "\n")
+}
+
+func (s *sanity) errorf(format string, args ...any) {
+	s.insane = true
+	s.diagnostic("Error", format, args...)
+}
+
+func (s *sanity) warnf(format string, args ...any) {
+	s.diagnostic("Warning", format, args...)
+}
+
+// findDuplicate returns an arbitrary basic block that appeared more
+// than once in blocks, or nil if all were unique.
+func findDuplicate(blocks []*BasicBlock) *BasicBlock {
+	if len(blocks) < 2 {
+		return nil
+	}
+	if blocks[0] == blocks[1] {
+		return blocks[0]
+	}
+	// Slow path:
+	m := make(map[*BasicBlock]bool)
+	for _, b := range blocks {
+		if m[b] {
+			return b
+		}
+		m[b] = true
+	}
+	return nil
+}
+
+func (s *sanity) checkInstr(idx int, instr Instruction) {
+	switch instr := instr.(type) {
+	case *If, *Jump, *Return, *Panic, *Unreachable, *ConstantSwitch:
+		s.errorf("control flow instruction not at end of block")
+	case *Phi:
+		if idx == 0 {
+			// It suffices to apply this check to just the first phi node.
+			if dup := findDuplicate(s.block.Preds); dup != nil {
+				s.errorf("phi node in block with duplicate predecessor %s", dup)
+			}
+		} else {
+			prev := s.block.Instrs[idx-1]
+			switch prev.(type) {
+			case *Phi:
+			default:
+				s.errorf("Phi instruction follows a non-Phi: %T", prev)
+			}
+		}
+		if ne, np := len(instr.Edges), len(s.block.Preds); ne != np {
+			s.errorf("phi node has %d edges but %d predecessors", ne, np)
+		} else {
+			for i, e := range instr.Edges {
+				if e == nil {
+					s.errorf("phi node '%s' has no value for edge #%d from %s", instr.Comment(), i, s.block.Preds[i])
+				} else if !types.Identical(instr.typ, e.Type()) {
+					s.errorf("phi node '%s' has a different type (%s) for edge #%d from %s (%s)",
+						instr.Comment(), instr.Type(), i, s.block.Preds[i], e.Type())
+				}
+			}
+		}
+
+	case *Alloc:
+		if !instr.Heap && !slices.Contains(s.fn.Locals, instr) {
+			s.errorf("local alloc %s = %s does not appear in Function.Locals", instr.Name(), instr)
+		}
+
+	case *BinOp:
+	case *Call:
+		if common := instr.Call; common.IsInvoke() {
+			if !types.IsInterface(common.Value.Type()) {
+				s.errorf("invoke on %s (%s) which is not an interface type (or type param)", common.Value, common.Value.Type())
+			}
+		}
+	case *ChangeInterface:
+	case *ChangeType:
+	case *SliceToArrayPointer:
+	case *SliceToArray:
+	case *Convert:
+		if from := instr.X.Type(); !isBasicConvTypes(from) {
+			if to := instr.Type(); !isBasicConvTypes(to) {
+				s.errorf("convert %s -> %s: at least one type must be basic (or all basic, []byte, or []rune)", from, to)
+			}
+		}
+	case *MultiConvert:
+	case *Defer:
+	case *Extract:
+	case *Field:
+	case *FieldAddr:
+	case *Go:
+	case *Index:
+	case *IndexAddr:
+	case *MapLookup:
+	case *StringLookup:
+	case *MakeChan:
+	case *MakeClosure:
+		numFree := len(instr.Fn.(*Function).FreeVars)
+		numBind := len(instr.Bindings)
+		if numFree != numBind {
+			s.errorf("MakeClosure has %d Bindings for function %s with %d free vars",
+				numBind, instr.Fn, numFree)
+		} else {
+			for i, fv := range instr.Fn.(*Function).FreeVars {
+				if !types.Identical(instr.Bindings[i].Type(), fv.Type()) {
+					s.errorf("MakeClosure binding %d for %s has type %s, expected %s",
+						i, fv.Name(), instr.Bindings[i].Type(), fv.Type())
+				}
+			}
+		}
+		if recv := instr.Type().(*types.Signature).Recv(); recv != nil {
+			s.errorf("MakeClosure's type includes receiver %s", recv.Type())
+		}
+
+	case *MakeInterface:
+	case *MakeMap:
+	case *MakeSlice:
+	case *MapUpdate:
+	case *Next:
+		rng, ok := instr.Iter.(*Range)
+		if !ok {
+			s.errorf("Next: Iter is %T, not *Range", instr.Iter)
+		}
+		var ek, ev types.Type
+		switch xt := typeutil.CoreType(rng.X.Type()).(type) {
+		case *types.Basic:
+			if types.Default(xt) != tString {
+				s.errorf("Next: basic operand of Next.Iter (Range) is %s, want string or untyped string", xt)
+			}
+			ek, ev = tInt, tRune
+		case *types.Map:
+			ek, ev = xt.Key(), xt.Elem()
+		}
+
+		res := instr.Type().(*types.Tuple) // (ok bool, k K, v V), but K or V may be invalid if unused
+		if !types.Identical(res.At(1).Type(), ek) && res.At(1).Type() != tInvalid {
+			s.errorf("Next: key type %s does not match map key type %s", res.At(1).Type(), ek)
+		}
+		if !types.Identical(res.At(2).Type(), ev) && res.At(2).Type() != tInvalid {
+			s.errorf("Next: value type %s does not match map value type %s", res.At(2).Type(), ev)
+		}
+
+	case *Range:
+	case *RunDefers:
+	case *Select:
+	case *Send:
+	case *Slice:
+	case *Store:
+		if !types.Identical(instr.Val.Type(), typeutil.CoreType(instr.Addr.Type()).(*types.Pointer).Elem()) {
+			s.errorf("Store: value type %s does not match address type %s",
+				instr.Val.Type(), instr.Addr.Type())
+		}
+	case *TypeAssert:
+	case *UnOp:
+	case *debugRef:
+	case *BlankStore:
+	case *Load:
+	case *Recv:
+	case *TypeSwitch:
+	case *CompositeValue:
+	default:
+		panic(fmt.Sprintf("Unknown instruction type: %T", instr))
+	}
+
+	if call, ok := instr.(CallInstruction); ok {
+		if call.Common().Signature() == nil {
+			s.errorf("nil signature: %s", call)
+		}
+	}
+
+	// Check that value-defining instructions have valid types
+	// and a valid referrer list.
+	if v, ok := instr.(Value); ok {
+		t := v.Type()
+		if t == nil {
+			s.errorf("no type: %s = %s", v.Name(), v)
+		} else if t == tDeferStack {
+			// not a proper type; ignore.
+		} else if b, ok := t.Underlying().(*types.Basic); ok && b.Info()&types.IsUntyped != 0 {
+			if _, ok := v.(*Const); !ok {
+				s.errorf("instruction has 'untyped' result: %s = %s : %s", v.Name(), v, t)
+			}
+		}
+		s.checkReferrerList(v)
+	}
+
+	// Untyped constants are legal as instruction Operands(),
+	// for example:
+	//   _ = "foo"[0]
+	// or:
+	//   if wordsize==64 {...}
+
+	// All other non-Instruction Values can be found via their
+	// enclosing Function or Package.
+}
+
+func (s *sanity) checkFinalInstr(instr Instruction) {
+	switch instr := instr.(type) {
+	case *If:
+		if nsuccs := len(s.block.Succs); nsuccs != 2 {
+			s.errorf("If-terminated block has %d successors; expected 2", nsuccs)
+			return
+		}
+		if s.block.Succs[0] == s.block.Succs[1] {
+			s.errorf("If-instruction has same True, False target blocks: %s", s.block.Succs[0])
+			return
+		}
+
+	case *Jump:
+		if nsuccs := len(s.block.Succs); nsuccs != 1 {
+			s.errorf("Jump-terminated block has %d successors; expected 1", nsuccs)
+			return
+		}
+
+	case *Return:
+		if nsuccs := len(s.block.Succs); nsuccs != 0 {
+			s.errorf("Return-terminated block has %d successors; expected none", nsuccs)
+			return
+		}
+		if na, nf := len(instr.Results), s.fn.Signature.Results().Len(); nf != na {
+			s.errorf("%d-ary return in %d-ary function", na, nf)
+		}
+
+	case *Panic:
+		if nsuccs := len(s.block.Succs); nsuccs != 0 {
+			s.errorf("Panic-terminated block has %d successors; expected none", nsuccs)
+			return
+		}
+
+	case *Unreachable:
+		if nsuccs := len(s.block.Succs); nsuccs != 0 {
+			s.errorf("Unreachable-terminated block has %d successors; expected none", nsuccs)
+			return
+		}
+
+	case *ConstantSwitch:
+		if nsuccs := len(s.block.Succs); nsuccs != len(instr.Conds) {
+			s.errorf("ConstantSwitch-terminated block has %d successors for %d constants",
+				nsuccs, len(instr.Conds))
+			return
+		}
+
+	default:
+		s.errorf("non-control flow instruction at end of block")
+	}
+}
+
+func (s *sanity) checkBlock(b *BasicBlock, index int) {
+	s.block = b
+
+	if b.Index != index {
+		s.errorf("block has incorrect Index %d", b.Index)
+	}
+	if b.parent != s.fn {
+		s.errorf("block has incorrect parent %s", b.parent)
+	}
+
+	// Check all blocks are reachable.
+	// (The entry block is always implicitly reachable,
+	// as is the Recover block, if any.)
+	if (index > 0 && b != b.parent.Recover) && len(b.Preds) == 0 {
+		s.warnf("unreachable block")
+		if b.Instrs == nil {
+			// Since this block is about to be pruned,
+			// tolerating transient problems in it
+			// simplifies other optimizations.
+			return
+		}
+	}
+
+	// Check predecessor and successor relations are dual,
+	// and that all blocks in CFG belong to same function.
+	for _, a := range b.Preds {
+		if !slices.Contains(a.Succs, b) {
+			s.errorf("expected successor edge in predecessor %s; found only: %s", a, a.Succs)
+		}
+		if a.parent != s.fn {
+			s.errorf("predecessor %s belongs to different function %s", a, a.parent)
+		}
+	}
+	for _, c := range b.Succs {
+		if !slices.Contains(c.Preds, b) {
+			s.errorf("expected predecessor edge in successor %s; found only: %s", c, c.Preds)
+		}
+		if c.parent != s.fn {
+			s.errorf("successor %s belongs to different function %s", c, c.parent)
+		}
+	}
+
+	// Check each instruction is sane.
+	n := len(b.Instrs)
+	if n == 0 {
+		s.errorf("basic block contains no instructions")
+	}
+	var rands [10]*Value // reuse storage
+	for j, instr := range b.Instrs {
+		if instr == nil {
+			s.errorf("nil instruction at index %d", j)
+			continue
+		}
+		if b2 := instr.Block(); b2 == nil {
+			s.errorf("nil Block() for instruction at index %d", j)
+			continue
+		} else if b2 != b {
+			s.errorf("wrong Block() (%s) for instruction at index %d ", b2, j)
+			continue
+		}
+		if j < n-1 {
+			s.checkInstr(j, instr)
+		} else {
+			s.checkFinalInstr(instr)
+		}
+
+		// Check Instruction.Operands.
+	operands:
+		for i, op := range instr.Operands(rands[:0]) {
+			if op == nil {
+				s.errorf("nil operand pointer %d of %s", i, instr)
+				continue
+			}
+			val := *op
+			if val == nil {
+				continue // a nil operand is ok
+			}
+
+			// Check that "untyped" types only appear on constant operands.
+			if _, ok := (*op).(*Const); !ok {
+				if basic, ok := (*op).Type().Underlying().(*types.Basic); ok {
+					if basic.Info()&types.IsUntyped != 0 {
+						s.errorf("operand #%d of %s is untyped: %s", i, instr, basic)
+					}
+				}
+			}
+
+			// Check that Operands that are also Instructions belong to same function.
+			// TODO(adonovan): also check their block dominates block b.
+			if val, ok := val.(Instruction); ok {
+				if val.Block() == nil {
+					s.errorf("operand %d of %s is an instruction (%s) that belongs to no block", i, instr, val)
+				} else if val.Parent() != s.fn {
+					s.errorf("operand %d of %s is an instruction (%s) from function %s", i, instr, val, val.Parent())
+				}
+			}
+
+			// Check that each function-local operand of
+			// instr refers back to instr.  (NB: quadratic)
+			switch val := val.(type) {
+			case *Const, *Global, *Builtin:
+				continue // not local
+			case *Function:
+				if val.parent == nil {
+					continue // only anon functions are local
+				}
+			}
+
+			// TODO(adonovan): check val.Parent() != nil <=> val.Referrers() is defined.
+
+			if refs := val.Referrers(); refs != nil {
+				for _, ref := range *refs {
+					if ref == instr {
+						continue operands
+					}
+				}
+				s.errorf("operand %d of %s (%s) does not refer to us", i, instr, val)
+			} else {
+				s.errorf("operand %d of %s (%s) has no referrers", i, instr, val)
+			}
+		}
+	}
+}
+
+func (s *sanity) checkReferrerList(v Value) {
+	refs := v.Referrers()
+	if refs == nil {
+		s.errorf("%s has missing referrer list", v.Name())
+		return
+	}
+	for i, ref := range *refs {
+		if _, ok := s.instrs[ref]; !ok {
+			if val, ok := ref.(Value); ok {
+				s.errorf("%s.Referrers()[%d] = %s = %s is not an instruction belonging to this function", v.Name(), i, val.Name(), val)
+			} else {
+				s.errorf("%s.Referrers()[%d] = %s is not an instruction belonging to this function", v.Name(), i, ref)
+			}
+		}
+	}
+}
+
+func (s *sanity) checkFunctionParams() {
+	signature := s.fn.Signature
+	params := s.fn.Params
+
+	// startSigParams is the start of signature.Params() within params.
+	startSigParams := 0
+	if signature.Recv() != nil {
+		startSigParams = 1
+	}
+
+	if startSigParams+signature.Params().Len() != len(params) {
+		s.errorf("function has %d parameters in signature but has %d after building",
+			startSigParams+signature.Params().Len(), len(params))
+		return
+	}
+
+	for i, param := range params {
+		var sigType types.Type
+		si := i - startSigParams
+		if si < 0 {
+			sigType = signature.Recv().Type()
+		} else {
+			sigType = signature.Params().At(si).Type()
+		}
+
+		if !types.Identical(sigType, param.Type()) {
+			s.errorf("expect type %s in signature but got type %s in param %d", sigType, param.Type(), i)
+		}
+	}
+}
+
+// checkTransientFields checks whether all transient fields of Function are cleared.
+func (s *sanity) checkTransientFields() {
+	fn := s.fn
+	if fn.build != nil {
+		s.errorf("function transient field 'build' is not nil")
+	}
+	if fn.currentBlock != nil {
+		s.errorf("function transient field 'currentBlock' is not nil")
+	}
+	if fn.vars != nil {
+		s.errorf("function transient field 'vars' is not nil")
+	}
+	if fn.results != nil {
+		s.errorf("function transient field 'results' is not nil")
+	}
+	if fn.returnVars != nil {
+		s.errorf("function transient field 'returnVars' is not nil")
+	}
+	if fn.targets != nil {
+		s.errorf("function transient field 'targets' is not nil")
+	}
+	if fn.lblocks != nil {
+		s.errorf("function transient field 'lblocks' is not nil")
+	}
+	if fn.subst != nil {
+		s.errorf("function transient field 'subst' is not nil")
+	}
+	if fn.jump != nil {
+		s.errorf("function transient field 'jump' is not nil")
+	}
+	if fn.deferstack != nil {
+		s.errorf("function transient field 'deferstack' is not nil")
+	}
+	if fn.source != nil {
+		s.errorf("function transient field 'source' is not nil")
+	}
+	if fn.exits != nil {
+		s.errorf("function transient field 'exits' is not nil")
+	}
+	if fn.uniq != 0 {
+		s.errorf("function transient field 'uniq' is not zero")
+	}
+}
+
+func (s *sanity) checkFunction(fn *Function) bool {
+	s.fn = fn
+	s.checkFunctionParams()
+	s.checkTransientFields()
+
+	// TODO(taking): Sanity check origin, typeparams, and typeargs.
+	if fn.Prog == nil {
+		s.errorf("nil Prog")
+	}
+
+	var buf bytes.Buffer
+	_ = fn.String()               // must not crash
+	_ = fn.RelString(fn.relPkg()) // must not crash
+	WriteFunction(&buf, fn)       // must not crash
+
+	// All functions have a package, except delegates (which are
+	// shared across packages, or duplicated as weak symbols in a
+	// separate-compilation model), and error.Error.
+	if fn.Pkg == nil {
+		if strings.HasPrefix(fn.Synthetic, "from type information (on demand)") ||
+			strings.HasPrefix(fn.Synthetic, "wrapper ") ||
+			strings.HasPrefix(fn.Synthetic, "bound ") ||
+			strings.HasPrefix(fn.Synthetic, "thunk ") ||
+			strings.HasSuffix(fn.name, "Error") ||
+			strings.HasPrefix(fn.Synthetic, "instance ") ||
+			strings.HasPrefix(fn.Synthetic, "instantiation ") ||
+			fn.parent != nil && fn.parent.hasTypeArgs() /* anon fun in instance */ {
+			// ok
+		} else {
+			s.errorf("nil Pkg")
+		}
+	}
+	if src, syn := fn.Synthetic == "", fn.Syntax() != nil; src != syn {
+		if fn.hasTypeArgs() && fn.Prog.mode&InstantiateGenerics != 0 {
+			// ok (instantiation with InstantiateGenerics on)
+		} else if fn.hasTypeArgs() && fn.topLevelOrigin != nil {
+			// ok (we always have the syntax set for instantiation)
+		} else if _, rng := fn.syntax.(*ast.RangeStmt); rng && fn.Synthetic == "range-over-func yield" {
+			// ok (range-func-yields are both synthetic and keep syntax)
+		} else {
+			s.errorf("got fromSource=%t, hasSyntax=%t; want same values", src, syn)
+		}
+	}
+
+	// Build the set of valid referrers.
+	s.instrs = make(map[Instruction]struct{})
+
+	// instrs are the instructions that are present in the function.
+	for instr := range fn.instrs() {
+		s.instrs[instr] = unit{}
+	}
+
+	// Check all Locals allocations appear in the function instruction.
+	for i, l := range fn.Locals {
+		if _, present := s.instrs[l]; !present {
+			s.warnf("function doesn't contain Local alloc %s", l.Name())
+		}
+
+		if l.Parent() != fn {
+			s.errorf("Local %s at index %d has wrong parent", l.Name(), i)
+		}
+		if l.Heap {
+			s.errorf("Local %s at index %d has Heap flag set", l.Name(), i)
+		}
+	}
+	for i, p := range fn.Params {
+		if p.Parent() != fn {
+			s.errorf("Param %s at index %d has wrong parent", p.Name(), i)
+		}
+		// Check common suffix of Signature and Params match type.
+		if sig := fn.Signature; sig != nil {
+			j := i - len(fn.Params) + sig.Params().Len() // index within sig.Params
+			if j < 0 {
+				continue
+			}
+			if !types.Identical(p.Type(), sig.Params().At(j).Type()) {
+				s.errorf("Param %s at index %d has wrong type (%s, versus %s in Signature)", p.Name(), i, p.Type(), sig.Params().At(j).Type())
+			}
+		}
+
+		s.checkReferrerList(p)
+	}
+	for i, fv := range fn.FreeVars {
+		if fv.Parent() != fn {
+			s.errorf("FreeVar %s at index %d has wrong parent", fv.Name(), i)
+		}
+		s.checkReferrerList(fv)
+	}
+
+	if fn.Blocks != nil && len(fn.Blocks) == 0 {
+		// Function _had_ blocks (so it's not external) but
+		// they were "optimized" away, even the entry block.
+		s.errorf("Blocks slice is non-nil but empty")
+	}
+	for i, b := range fn.Blocks {
+		if b == nil {
+			s.warnf("nil *BasicBlock at f.Blocks[%d]", i)
+			continue
+		}
+		s.checkBlock(b, i)
+	}
+	if fn.Recover != nil && fn.Blocks[fn.Recover.Index] != fn.Recover {
+		s.errorf("Recover block is not in Blocks slice")
+	}
+
+	s.block = nil
+	for i, anon := range fn.AnonFuncs {
+		if anon.Parent() != fn {
+			s.errorf("AnonFuncs[%d]=%s but %s.Parent()=%s", i, anon, anon, anon.Parent())
+		}
+		if i != int(anon.anonIdx) {
+			s.errorf("AnonFuncs[%d]=%s but %s.anonIdx=%d", i, anon, anon, anon.anonIdx)
+		}
+	}
+	s.fn = nil
+	return !s.insane
+}
+
+// sanityCheckPackage checks invariants of packages upon creation.
+// It does not require that the package is built.
+// Unlike sanityCheck (for functions), it just panics at the first error.
+func sanityCheckPackage(pkg *Package) {
+	if pkg.Pkg == nil {
+		panic(fmt.Sprintf("Package %s has no Object", pkg))
+	}
+	if pkg.info != nil {
+		panic(fmt.Sprintf("package %s field 'info' is not cleared", pkg))
+	}
+	if pkg.files != nil {
+		panic(fmt.Sprintf("package %s field 'files' is not cleared", pkg))
+	}
+	if pkg.created != nil {
+		panic(fmt.Sprintf("package %s field 'created' is not cleared", pkg))
+	}
+	if pkg.initVersion != nil {
+		panic(fmt.Sprintf("package %s field 'initVersion' is not cleared", pkg))
+	}
+
+	_ = pkg.String() // must not crash
+
+	for name, mem := range pkg.Members {
+		if name != mem.Name() {
+			panic(fmt.Sprintf("%s: %T.Name() = %s, want %s",
+				pkg.Pkg.Path(), mem, mem.Name(), name))
+		}
+		obj := mem.Object()
+		if obj == nil {
+			// This check is sound because fields
+			// {Global,Function}.object have type
+			// types.Object.  (If they were declared as
+			// *types.{Var,Func}, we'd have a non-empty
+			// interface containing a nil pointer.)
+
+			continue // not all members have typechecker objects
+		}
+		if obj.Name() != name {
+			if obj.Name() == "init" && strings.HasPrefix(mem.Name(), "init#") {
+				// Ok.  The name of a declared init function varies between
+				// its types.Func ("init") and its ir.Function ("init#%d").
+			} else {
+				panic(fmt.Sprintf("%s: %T.Object().Name() = %s, want %s",
+					pkg.Pkg.Path(), mem, obj.Name(), name))
+			}
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/scc.go b/vendor/honnef.co/go/tools/go/ir/scc.go
new file mode 100644
index 0000000..d7f7408
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/scc.go
@@ -0,0 +1,106 @@
+package ir
+
+import (
+	"math"
+)
+
+type sccState struct {
+	fn    *Function
+	index int
+	lows  BlockMap[int]
+	F     []int
+	sccs  []*SCC
+}
+
+func (s *sccState) scc(v *BasicBlock) {
+	// This is Tarjan's algorithm, with some optimizations from [1] applied.
+	//
+	// [1] R. E. Tarjan and U. Zwick, “Finding strong components using depth-first search,” Apr. 11, 2022, arXiv: arXiv:2201.07197. doi: 10.48550/arXiv.2201.07197.
+	vi := v.Index
+	lows := s.lows
+
+	s.index += 2
+	lows[vi] = s.index
+
+	for _, w := range v.Succs {
+		wi := w.Index
+
+		if lows[wi] == 0 {
+			s.scc(w)
+		}
+
+		if lows[wi] < lows[vi] {
+			lows[vi] = lows[wi] | 1
+		}
+	}
+
+	if lows[vi]&1 == 0 {
+		leaderLow := lows[vi]
+
+		scc := &SCC{
+			Index: len(s.sccs),
+		}
+		F := s.F
+		for lows[F[len(F)-1]] >= leaderLow {
+			x := F[len(F)-1]
+			F = F[:len(F)-1]
+
+			lows[x] = math.MaxInt
+			scc.Blocks = append(scc.Blocks, s.fn.Blocks[x])
+			s.fn.Blocks[x].SCC = scc
+		}
+		s.F = F
+
+		lows[vi] = math.MaxInt
+		scc.Blocks = append(scc.Blocks, v)
+		v.SCC = scc
+		s.sccs = append(s.sccs, scc)
+	} else {
+		s.F = append(s.F, vi)
+	}
+}
+
+// buildSCCs computes the strongly connected components of fn's control flow graph.
+func buildSCCs(fn *Function) {
+	n := len(fn.Blocks)
+
+	if n == 0 {
+		return
+	}
+
+	state := sccState{
+		fn:    fn,
+		index: 0,
+		// The +1 makes space for the sentinel value stored in F.
+		lows: make(BlockMap[int], n+1),
+		F:    []int{n},
+	}
+
+	// All blocks are reachable from the entry block.
+	state.scc(fn.Blocks[0])
+
+	seen := make([]bool, len(state.sccs))
+	for _, scc := range state.sccs {
+		clear(seen)
+		for _, b := range scc.Blocks {
+			for _, succ := range b.Succs {
+				if succ.SCC != b.SCC && !seen[succ.SCC.Index] {
+					b.SCC.Succs = append(b.SCC.Succs, succ.SCC)
+					succ.SCC.Preds = append(succ.SCC.Preds, b.SCC)
+					seen[succ.SCC.Index] = true
+				}
+			}
+		}
+	}
+
+	fn.SCCs = state.sccs
+
+	// This iterates over the SCCs in reverse topological order, i.e., "bottom
+	// up". This allows us to build up reachability sets.
+	for _, scc := range fn.SCCs {
+		scc.reachable.SetBit(&scc.reachable, scc.Index, 1)
+		for _, succ := range scc.Succs {
+			scc.reachable.Or(&scc.reachable, &succ.reachable)
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/source.go b/vendor/honnef.co/go/tools/go/ir/source.go
new file mode 100644
index 0000000..bd05db7
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/source.go
@@ -0,0 +1,273 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file defines utilities for working with source positions
+// or source-level named entities ("objects").
+
+// TODO(adonovan): test that {Value,Instruction}.Pos() positions match
+// the originating syntax, as specified.
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+)
+
+// EnclosingFunction returns the function that contains the syntax
+// node denoted by path.
+//
+// Syntax associated with package-level variable specifications is
+// enclosed by the package's init() function.
+//
+// Returns nil if not found; reasons might include:
+//   - the node is not enclosed by any function.
+//   - the node is within an anonymous function (FuncLit) and
+//     its IR function has not been created yet
+//     (pkg.Build() has not yet been called).
+func EnclosingFunction(pkg *Package, path []ast.Node) *Function {
+	// Start with package-level function...
+	fn := findEnclosingPackageLevelFunction(pkg, path)
+	if fn == nil {
+		return nil // not in any function
+	}
+
+	// ...then walk down the nested anonymous functions.
+	n := len(path)
+outer:
+	for i := range path {
+		if lit, ok := path[n-1-i].(*ast.FuncLit); ok {
+			for _, anon := range fn.AnonFuncs {
+				if anon.Pos() == lit.Type.Func {
+					fn = anon
+					continue outer
+				}
+			}
+			// IR function not found:
+			// - package not yet built, or maybe
+			// - builder skipped FuncLit in dead block
+			//   (in principle; but currently the Builder
+			//   generates even dead FuncLits).
+			return nil
+		}
+	}
+	return fn
+}
+
+// HasEnclosingFunction returns true if the AST node denoted by path
+// is contained within the declaration of some function or
+// package-level variable.
+//
+// Unlike EnclosingFunction, the behaviour of this function does not
+// depend on whether IR code for pkg has been built, so it can be
+// used to quickly reject check inputs that will cause
+// EnclosingFunction to fail, prior to IR building.
+func HasEnclosingFunction(pkg *Package, path []ast.Node) bool {
+	return findEnclosingPackageLevelFunction(pkg, path) != nil
+}
+
+// findEnclosingPackageLevelFunction returns the Function
+// corresponding to the package-level function enclosing path.
+func findEnclosingPackageLevelFunction(pkg *Package, path []ast.Node) *Function {
+	if n := len(path); n >= 2 { // [... {Gen,Func}Decl File]
+		switch decl := path[n-2].(type) {
+		case *ast.GenDecl:
+			if decl.Tok == token.VAR && n >= 3 {
+				// Package-level 'var' initializer.
+				return pkg.init
+			}
+
+		case *ast.FuncDecl:
+			if decl.Recv == nil && decl.Name.Name == "init" {
+				// Explicit init() function.
+				for _, b := range pkg.init.Blocks {
+					for _, instr := range b.Instrs {
+						if instr, ok := instr.(*Call); ok {
+							if callee, ok := instr.Call.Value.(*Function); ok && callee.Pkg == pkg && callee.Pos() == decl.Name.NamePos {
+								return callee
+							}
+						}
+					}
+				}
+				// Hack: return non-nil when IR is not yet
+				// built so that HasEnclosingFunction works.
+				return pkg.init
+			}
+			// Declared function/method.
+			return findNamedFunc(pkg, decl.Name.NamePos)
+		}
+	}
+	return nil // not in any function
+}
+
+// findNamedFunc returns the named function whose FuncDecl.Ident is at
+// position pos.
+func findNamedFunc(pkg *Package, pos token.Pos) *Function {
+	// Look at all package members and method sets of named types.
+	// Not very efficient.
+	for _, mem := range pkg.Members {
+		switch mem := mem.(type) {
+		case *Function:
+			if mem.Pos() == pos {
+				return mem
+			}
+		case *Type:
+			mset := pkg.Prog.MethodSets.MethodSet(types.NewPointer(mem.Type()))
+			for i, n := 0, mset.Len(); i < n; i++ {
+				// Don't call Program.Method: avoid creating wrappers.
+				obj := mset.At(i).Obj().(*types.Func)
+				if obj.Pos() == pos {
+					// obj from MethodSet may not be the origin type.
+					m := obj.Origin()
+					return pkg.values[m].(*Function)
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// ValueForExpr returns the IR Value that corresponds to non-constant
+// expression e.
+//
+// It returns nil if no value was found, e.g.
+//   - the expression is not lexically contained within f;
+//   - f was not built with debug information; or
+//   - e is a constant expression.  (For efficiency, no debug
+//     information is stored for constants. Use
+//     go/types.Info.Types[e].Value instead.)
+//   - e is a reference to nil or a built-in function.
+//   - the value was optimised away.
+//
+// If e is an addressable expression used in an lvalue context,
+// value is the address denoted by e, and isAddr is true.
+//
+// The types of e (or &e, if isAddr) and the result are equal
+// (modulo "untyped" bools resulting from comparisons).
+//
+// (Tip: to find the ir.Value given a source position, use
+// astutil.PathEnclosingInterval to locate the ast.Node, then
+// EnclosingFunction to locate the Function, then ValueForExpr to find
+// the ir.Value.)
+func (f *Function) ValueForExpr(e ast.Expr) (value Value, isAddr bool) {
+	e = ast.Unparen(e)
+	entry := f.exprToValue[e]
+	return entry.v, entry.isAddr
+}
+
+// --- Lookup functions for source-level named entities (types.Objects) ---
+
+// Package returns the IR Package corresponding to the specified
+// type-checker package object.
+// It returns nil if no such IR package has been created.
+func (prog *Program) Package(obj *types.Package) *Package {
+	return prog.packages[obj]
+}
+
+// packageLevelMember returns the package-level member corresponding
+// to the specified symbol, which may be a package-level const
+// (*NamedConst), var (*Global) or func/method (*Function) of some
+// package in prog.
+//
+// It returns nil if the object belongs to a package that has not been
+// created by prog.CreatePackage.
+func (prog *Program) packageLevelMember(obj types.Object) Member {
+	if pkg, ok := prog.packages[obj.Pkg()]; ok {
+		return pkg.values[obj]
+	}
+	return nil
+}
+
+// FuncValue returns the SSA function or (non-interface) method
+// denoted by the specified func symbol. It returns nil if the symbol
+// denotes an interface method, or belongs to a package that was not
+// created by prog.CreatePackage.
+func (prog *Program) FuncValue(obj *types.Func) *Function {
+	fn, _ := prog.packageLevelMember(obj).(*Function)
+	return fn
+}
+
+// ConstValue returns the IR Value denoted by the source-level named
+// constant obj.
+func (prog *Program) ConstValue(obj *types.Const) *Const {
+	// TODO(adonovan): opt: share (don't reallocate)
+	// Consts for const objects and constant ast.Exprs.
+
+	// Universal constant? {true,false,nil}
+	if obj.Parent() == types.Universe {
+		return NewConst(obj.Val(), obj.Type(), nil)
+	}
+	// Package-level named constant?
+	if v := prog.packageLevelMember(obj); v != nil {
+		return v.(*NamedConst).Value
+	}
+	return NewConst(obj.Val(), obj.Type(), nil)
+}
+
+// VarValue returns the IR Value that corresponds to a specific
+// identifier denoting the source-level named variable obj.
+//
+// VarValue returns nil if a local variable was not found, perhaps
+// because its package was not built, the debug information was not
+// requested during IR construction, or the value was optimized away.
+//
+// ref is the path to an ast.Ident (e.g. from PathEnclosingInterval),
+// and that ident must resolve to obj.
+//
+// pkg is the package enclosing the reference.  (A reference to a var
+// always occurs within a function, so we need to know where to find it.)
+//
+// If the identifier is a field selector and its base expression is
+// non-addressable, then VarValue returns the value of that field.
+// For example:
+//
+//	func f() struct {x int}
+//	f().x  // VarValue(x) returns a *Field instruction of type int
+//
+// All other identifiers denote addressable locations (variables).
+// For them, VarValue may return either the variable's address or its
+// value, even when the expression is evaluated only for its value; the
+// situation is reported by isAddr, the second component of the result.
+//
+// If !isAddr, the returned value is the one associated with the
+// specific identifier.  For example,
+//
+//	var x int    // VarValue(x) returns Const 0 here
+//	x = 1        // VarValue(x) returns Const 1 here
+//
+// It is not specified whether the value or the address is returned in
+// any particular case, as it may depend upon optimizations performed
+// during IR code generation, such as registerization, constant
+// folding, avoidance of materialization of subexpressions, etc.
+func (prog *Program) VarValue(obj *types.Var, pkg *Package, ref []ast.Node) (value Value, isAddr bool) {
+	// All references to a var are local to some function, possibly init.
+	fn := EnclosingFunction(pkg, ref)
+	if fn == nil {
+		return // e.g. def of struct field; IR not built?
+	}
+
+	id := ref[0].(*ast.Ident)
+
+	// Defining ident of a parameter?
+	if id.Pos() == obj.Pos() {
+		for _, param := range fn.Params {
+			if param.Object() == obj {
+				return param, false
+			}
+		}
+	}
+
+	// Other ident?
+	if v, ok := fn.exprToValue[id]; ok {
+		return v.v, v.isAddr
+	}
+
+	// Defining ident of package-level var?
+	if v := prog.packageLevelMember(obj); v != nil {
+		return v.(*Global), true
+	}
+
+	return // e.g. debug info not requested, or var optimized away
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/ssa.go b/vendor/honnef.co/go/tools/go/ir/ssa.go
new file mode 100644
index 0000000..e927736
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/ssa.go
@@ -0,0 +1,2241 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This package defines a high-level intermediate representation for
+// Go programs using static single-assignment (SSA) form.
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"iter"
+	"math/big"
+	"reflect"
+	"slices"
+	"strings"
+	"sync"
+	"unsafe"
+
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/xtools-internal/typeparams"
+)
+
+const (
+	// Replace CompositeValue with only constant values with AggregateConst. Currently disabled because it breaks field
+	// tracking in U1000.
+	doSimplifyConstantCompositeValues = false
+)
+
+type ID int
+
+// A Program is a partial or complete Go program converted to IR form.
+type Program struct {
+	Fset       *token.FileSet              // position information for the files of this Program
+	imported   map[string]*Package         // all importable Packages, keyed by import path
+	packages   map[*types.Package]*Package // all created Packages
+	mode       BuilderMode                 // set of mode bits for IR construction
+	MethodSets typeutil.MethodSetCache     // cache of type-checker's method-sets
+
+	canon *canonizer     // type canonicalization map
+	ctxt  *types.Context // cache for type checking instantiations
+
+	methodsMu  sync.Mutex
+	methodSets typeutil.Map[*methodSet] // maps type to its concrete *methodSet
+
+	// memoization of whether a type refers to type parameters
+	hasParamsMu sync.Mutex
+	hasParams   typeparams.Free
+
+	// set of concrete types used as MakeInterface operands
+	makeInterfaceTypesMu sync.Mutex
+	makeInterfaceTypes   map[types.Type]unit // (may contain redundant identical types)
+
+	// objectMethods is a memoization of objectMethod
+	// to avoid creation of duplicate methods from type information.
+	objectMethodsMu sync.Mutex
+	objectMethods   map[*types.Func]*Function
+
+	noReturn func(*types.Func) bool // (optional) predicate that decides whether a given call cannot return
+}
+
+// A Package is a single analyzed Go package containing Members for
+// all package-level functions, variables, constants and types it
+// declares.  These may be accessed directly via Members, or via the
+// type-specific accessor methods Func, Type, Var and Const.
+//
+// Members also contains entries for "init" (the synthetic package
+// initializer) and "init#%d", the nth declared init function,
+// and unspecified other things too.
+type Package struct {
+	Prog      *Program                // the owning program
+	Pkg       *types.Package          // the corresponding go/types.Package
+	Members   map[string]Member       // all package members keyed by name (incl. init and init#%d)
+	Functions []*Function             // all functions, excluding anonymous ones
+	values    map[types.Object]Member // mapping of package objects to members (incl. methods). Contains *NamedConst, *Global, *Function (values but not types)
+	init      *Function               // Func("init"); the package's init function
+	debug     bool                    // include full debug info in this package
+	syntax    bool                    // package was loaded from syntax
+
+	// The following fields are set transiently, then cleared
+	// after building.
+	buildOnce   sync.Once           // ensures package building occurs once
+	ninit       int32               // number of init functions
+	info        *types.Info         // package type information
+	files       []*ast.File         // package ASTs
+	created     []*Function         // members created as a result of building this package (includes declared functions, wrappers)
+	initVersion map[ast.Expr]string // goversion to use for each global var init expr
+}
+
+// A Member is a member of a Go package, implemented by *NamedConst,
+// *Global, *Function, or *Type; they are created by package-level
+// const, var, func and type declarations respectively.
+type Member interface {
+	Name() string                    // declared name of the package member
+	String() string                  // package-qualified name of the package member
+	RelString(*types.Package) string // like String, but relative refs are unqualified
+	Object() types.Object            // typechecker's object for this member, if any
+	Type() types.Type                // type of the package member
+	Token() token.Token              // token.{VAR,FUNC,CONST,TYPE}
+	Package() *Package               // the containing package
+}
+
+// A Type is a Member of a Package representing a package-level named type.
+type Type struct {
+	object *types.TypeName
+	pkg    *Package
+}
+
+// A NamedConst is a Member of a Package representing a package-level
+// named constant.
+//
+// Pos() returns the position of the declaring ast.ValueSpec.Names[*]
+// identifier.
+//
+// NB: a NamedConst is not a Value; it contains a constant Value, which
+// it augments with the name and position of its 'const' declaration.
+type NamedConst struct {
+	object *types.Const
+	Value  *Const
+	pkg    *Package
+}
+
+// A Value is an IR value that can be referenced by an instruction.
+type Value interface {
+	// Name returns the name of this value, and determines how
+	// this Value appears when used as an operand of an
+	// Instruction.
+	//
+	// This is the same as the source name for Parameters,
+	// Builtins, Functions, FreeVars, Globals.
+	// For constants, it is a representation of the constant's value
+	// and type.  For all other Values this is the name of the
+	// virtual register defined by the instruction.
+	//
+	// The name of an IR Value is not semantically significant,
+	// and may not even be unique within a function.
+	Name() string
+
+	// If this value is an Instruction, String returns its
+	// disassembled form; otherwise it returns unspecified
+	// human-readable information about the Value, such as its
+	// kind, name and type.
+	String() string
+
+	// Type returns the type of this value.  Many instructions
+	// (e.g. IndexAddr) change their behaviour depending on the
+	// types of their operands.
+	Type() types.Type
+
+	// Parent returns the function to which this Value belongs.
+	// It returns nil for named Functions, Builtin and Global.
+	Parent() *Function
+
+	// Referrers returns the list of instructions that have this
+	// value as one of their operands; it may contain duplicates
+	// if an instruction has a repeated operand.
+	//
+	// Referrers actually returns a pointer through which the
+	// caller may perform mutations to the object's state.
+	//
+	// Referrers is currently only defined if Parent()!=nil,
+	// i.e. for the function-local values FreeVar, Parameter,
+	// Functions (iff anonymous) and all value-defining instructions.
+	// It returns nil for named Functions, Builtin and Global.
+	//
+	// Instruction.Operands contains the inverse of this relation.
+	Referrers() *[]Instruction
+
+	Operands(rands []*Value) []*Value // nil for non-Instructions
+
+	// Source returns the AST node responsible for creating this
+	// value. A single AST node may be responsible for more than one
+	// value, and not all values have an associated AST node.
+	//
+	// Do not use this method to find a Value given an ast.Expr; use
+	// ValueForExpr instead.
+	Source() ast.Node
+
+	// Pos returns Source().Pos() if Source is not nil, else it
+	// returns token.NoPos.
+	Pos() token.Pos
+}
+
+// An Instruction is an IR instruction that computes a new Value or
+// has some effect.
+//
+// An Instruction that defines a value (e.g. BinOp) also implements
+// the Value interface; an Instruction that only has an effect (e.g. Store)
+// does not.
+type Instruction interface {
+	setSource(ast.Node)
+	setID(ID)
+
+	Comment() string
+
+	// String returns the disassembled form of this value.
+	//
+	// Examples of Instructions that are Values:
+	//       "x + y"     (BinOp)
+	//       "len([])"   (Call)
+	// Note that the name of the Value is not printed.
+	//
+	// Examples of Instructions that are not Values:
+	//       "return x"  (Return)
+	//       "*y = x"    (Store)
+	//
+	// (The separation Value.Name() from Value.String() is useful
+	// for some analyses which distinguish the operation from the
+	// value it defines, e.g., 'y = local int' is both an allocation
+	// of memory 'local int' and a definition of a pointer y.)
+	String() string
+
+	// ID returns the ID of this instruction. IDs are unique within a single
+	// function and are densely numbered, but may contain gaps.
+	// Globally, instructions are identified by their addresses. However,
+	// IDs exist to facilitate efficient storage of mappings between
+	// instructions and data when analysing functions.
+	//
+	// NB: IDs are allocated late in the IR construction process and
+	// are not available to early stages of said process.
+	ID() ID
+
+	// Parent returns the function to which this instruction
+	// belongs.
+	Parent() *Function
+
+	// Block returns the basic block to which this instruction
+	// belongs.
+	Block() *BasicBlock
+
+	// setBlock sets the basic block to which this instruction belongs.
+	setBlock(*BasicBlock)
+
+	// Operands returns the operands of this instruction: the
+	// set of Values it references.
+	//
+	// Specifically, it appends their addresses to rands, a
+	// user-provided slice, and returns the resulting slice,
+	// permitting avoidance of memory allocation.
+	//
+	// The operands are appended in undefined order, but the order
+	// is consistent for a given Instruction; the addresses are
+	// always non-nil but may point to a nil Value.  Clients may
+	// store through the pointers, e.g. to effect a value
+	// renaming.
+	//
+	// Value.Referrers is a subset of the inverse of this
+	// relation.  (Referrers are not tracked for all types of
+	// Values.)
+	Operands(rands []*Value) []*Value
+
+	Referrers() *[]Instruction // nil for non-Values
+
+	// Source returns the AST node responsible for creating this
+	// instruction. A single AST node may be responsible for more than
+	// one instruction, and not all instructions have an associated
+	// AST node.
+	Source() ast.Node
+
+	// Pos returns Source().Pos() if Source is not nil, else it
+	// returns token.NoPos.
+	Pos() token.Pos
+}
+
+// A Node is a node in the IR value graph.  Every concrete type that
+// implements Node is also either a Value, an Instruction, or both.
+//
+// Node contains the methods common to Value and Instruction, plus the
+// Operands and Referrers methods generalized to return nil for
+// non-Instructions and non-Values, respectively.
+//
+// Node is provided to simplify IR graph algorithms.  Clients should
+// use the more specific and informative Value or Instruction
+// interfaces where appropriate.
+type Node interface {
+	// Common methods:
+	String() string
+	Source() ast.Node
+	Pos() token.Pos
+	Parent() *Function
+
+	// Partial methods:
+	Operands(rands []*Value) []*Value // nil for non-Instructions
+	Referrers() *[]Instruction        // nil for non-Values
+}
+
+// Function represents the parameters, results, and code of a function
+// or method.
+//
+// If Blocks is nil, this indicates an external function for which no
+// Go source code is available.  In this case, FreeVars, Locals, and
+// Params are nil too.  Clients performing whole-program analysis must
+// handle external functions specially.
+//
+// Blocks contains the function's control-flow graph (CFG).
+// Blocks[0] is the function entry point; block order is not otherwise
+// semantically significant, though it may affect the readability of
+// the disassembly.
+// To iterate over the blocks in dominance order, use DomPreorder().
+//
+// Recover is an optional second entry point to which control resumes
+// after a recovered panic.  The Recover block may contain only a return
+// statement, preceded by a load of the function's named return
+// parameters, if any.
+//
+// A nested function (Parent()!=nil) that refers to one or more
+// lexically enclosing local variables ("free variables") has FreeVars.
+// Such functions cannot be called directly but require a
+// value created by MakeClosure which, via its Bindings, supplies
+// values for these parameters.
+//
+// If the function is a method (Signature.Recv() != nil) then the first
+// element of Params is the receiver parameter.
+//
+// A Go package may declare many functions called "init".
+// For each one, Object().Name() returns "init" but Name() returns
+// "init#1", etc, in declaration order.
+//
+// Pos() returns the declaring ast.FuncLit.Type.Func or the position
+// of the ast.FuncDecl.Name, if the function was explicit in the
+// source. Synthetic wrappers, for which Synthetic != "", may share
+// the same position as the function they wrap.
+// Syntax.Pos() always returns the position of the declaring "func" token.
+//
+// When the operand of a range statement is an iterator function,
+// the loop body is transformed into a synthetic anonymous function
+// that is passed as the yield argument in a call to the iterator.
+// In that case, Function.Source() is the ast.RangeStmt.
+// and Function.Syntax is the ast.RangeStmt.
+//
+// Synthetic functions, for which Synthetic != "", are functions
+// that do not appear in the source AST. These include:
+//   - method wrappers,
+//   - thunks,
+//   - bound functions,
+//   - empty functions built from loaded type information,
+//   - yield functions created from range-over-func loops,
+//   - package init functions, and
+//   - instantiations of generic functions.
+//
+// Synthetic wrapper functions may share the same position
+// as the function they wrap.
+//
+// Type() returns the function's Signature.
+//
+// A generic function is a function or method that has uninstantiated type
+// parameters (TypeParams() != nil). Consider a hypothetical generic
+// method, (*Map[K,V]).Get. It may be instantiated with all
+// non-parameterized types as (*Map[string,int]).Get or with
+// parameterized types as (*Map[string,U]).Get, where U is a type parameter.
+// In both instantiations, Origin() refers to the instantiated generic
+// method, (*Map[K,V]).Get, TypeParams() refers to the parameters [K,V] of
+// the generic method. TypeArgs() refers to [string,U] or [string,int],
+// respectively, and is nil in the generic method.
+type Function struct {
+	name      string
+	object    *types.Func // symbol for declared function (nil for FuncLit or synthetic init)
+	method    *selection  // info about provenance of synthetic methods; thunk => non-nil
+	Signature *types.Signature
+	pos       token.Pos
+	syntax    ast.Node
+
+	// source information
+	Synthetic string      // provenance of synthetic function; "" for true source functions
+	info      *types.Info // type annotations (if syntax != nil)
+	goversion string      // Go version of syntax (NB: init is special)
+
+	parent *Function // enclosing function if anon; nil if global
+	Pkg    *Package  // enclosing package; nil for shared funcs (wrappers and error.Error)
+	Prog   *Program  // enclosing program
+
+	exprToValue map[ast.Expr]struct {
+		v      Value
+		isAddr bool
+	}
+
+	buildshared *task // wait for a shared function to be done building (may be nil if <=1 builder ever needs to wait)
+
+	// These fields are populated only when the function body is built:
+
+	Params    []*Parameter  // function parameters; for methods, includes receiver
+	FreeVars  []*FreeVar    // free variables whose values must be supplied by closure
+	Locals    []*Alloc      // frame-allocated variables of this function
+	Blocks    []*BasicBlock // basic blocks of the function; nil => external
+	Recover   *BasicBlock   // optional; control transfers here after recovered panic
+	AnonFuncs []*Function   // anonymous functions (from FuncLit, RangeStmt) directly beneath this one
+	referrers []Instruction // referring instructions (iff Parent() != nil)
+	anonIdx   int32         // position of a nested function in parent's AnonFuncs. fn.Parent()!=nil => fn.Parent().AnonFunc[fn.anonIdx] == fn.
+
+	SCCs []*SCC // SCC DAG in reverse topological order
+
+	recvtypeparams *types.TypeParamList // receiver type parameters of this function. recvtypeparams.Len() > 0 => method on generic or instance of generic type
+	recvtypeargs   []types.Type         // type arguments that instantiated recvtypeparams. len(recvtypeargs) > 0 => method on instance of generic type
+	typeparams     *types.TypeParamList // type parameters of this function. typeparams.Len() > 0 => generic or instance of generic function or method
+	typeargs       []types.Type         // type arguments that instantiated typeparams. len(typeargs) > 0 => instance of generic function or method
+	topLevelOrigin *Function            // the origin function if this is an instance of a source function. nil if Parent()!=nil.
+	generic        *generic             // instances of this function, if generic
+
+	// The following fields are cleared after building.
+	build            buildFunc                // algorithm to build function body (nil => built)
+	currentBlock     *BasicBlock              // where to emit code
+	vars             map[*types.Var]Value     // addresses of local variables
+	results          []*Alloc                 // result allocations of the current function
+	returnVars       []*types.Var             // variables for a return statement. Either results or for range-over-func a parent's results
+	targets          *targets                 // linked stack of branch targets
+	lblocks          map[*types.Label]*lblock // labelled blocks
+	subst            *subster                 // type parameter substitutions (if non-nil)
+	jump             *types.Var               // synthetic variable for the yield state (non-nil => range-over-func)
+	deferstack       *types.Var               // synthetic variable holding enclosing ssa:deferstack()
+	source           *Function                // nearest enclosing source function
+	exits            []*exit                  // exits of the function that need to be resolved
+	uniq             int64                    // source of unique ints within the source tree while building
+	liftableBlockMap BlockMap[liftableBlockDesc]
+
+	blocksets [4]BlockSet
+}
+
+// BasicBlock represents an IR basic block.
+//
+// The final element of Instrs is always an explicit transfer of
+// control (If, Jump, Return, Panic, or Unreachable).
+//
+// A block may contain no Instructions only if it is unreachable,
+// i.e., Preds is nil.  Empty blocks are typically pruned.
+//
+// BasicBlocks and their Preds/Succs relation form a (possibly cyclic)
+// graph independent of the IR Value graph: the control-flow graph or
+// CFG.  It is illegal for multiple edges to exist between the same
+// pair of blocks.
+//
+// Each BasicBlock is also a node in the dominator tree of the CFG.
+// The tree may be navigated using Idom()/Dominees() and queried using
+// Dominates().
+//
+// The order of Preds and Succs is significant (to Phi and If
+// instructions, respectively).
+type BasicBlock struct {
+	Index        int            // index of this block within Parent().Blocks
+	Comment      string         // optional label; no semantic significance
+	parent       *Function      // parent function
+	Instrs       []Instruction  // instructions in order
+	Preds, Succs []*BasicBlock  // predecessors and successors
+	SCC          *SCC           // strongly connected component
+	succs2       [2]*BasicBlock // initial space for Succs
+	dom          domInfo        // dominator tree info
+	gaps         int            // number of nil Instrs (transient)
+	rundefers    int            // number of rundefers (transient)
+}
+
+type SCC struct {
+	Index        int
+	Blocks       []*BasicBlock
+	Preds, Succs []*SCC
+	reachable    big.Int
+}
+
+// Pure values ----------------------------------------
+
+// A FreeVar represents a free variable of the function to which it
+// belongs.
+//
+// FreeVars are used to implement anonymous functions, whose free
+// variables are lexically captured in a closure formed by
+// MakeClosure.  The value of such a free var is an Alloc or another
+// FreeVar and is considered a potentially escaping heap address, with
+// pointer type.
+//
+// FreeVars are also used to implement bound method closures.  Such a
+// free var represents the receiver value and may be of any type that
+// has concrete methods.
+//
+// Pos() returns the position of the value that was captured, which
+// belongs to an enclosing function.
+type FreeVar struct {
+	node
+
+	name      string
+	typ       types.Type
+	parent    *Function
+	referrers []Instruction
+
+	// Transiently needed during building.
+	outer Value // the Value captured from the enclosing context.
+}
+
+// A Parameter represents an input parameter of a function.
+type Parameter struct {
+	node
+
+	name      string
+	object    *types.Var // non-nil
+	typ       types.Type
+	parent    *Function
+	referrers []Instruction
+}
+
+// A Const represents a value known at build time.
+//
+// Consts include true constants of boolean, numeric, and string types, as
+// defined by the Go spec; these are represented by a non-nil Value field.
+//
+// Consts also include the "zero" value of any type, of which the nil values
+// of various pointer-like types are a special case; these are represented
+// by a nil Value field.
+//
+// Example printed form:
+//
+//	42:int
+//	"hello":untyped string
+//	3+4i:MyComplex
+//	nil:*int
+//	nil:[]string
+//	[3]int{}:[3]int
+//	struct{x string}{}:struct{x string}
+//	0:interface{int|int64}
+//	nil:interface{bool|int} // no go/constant representation
+type Const struct {
+	node
+
+	typ   types.Type
+	Value constant.Value
+}
+
+type AggregateConst struct {
+	node
+
+	typ    types.Type
+	Values []Value
+}
+
+type CompositeValue struct {
+	register
+
+	// Bitmap records which elements were explicitly provided. For example, [4]byte{2: x} would have a bitmap of 0010.
+	Bitmap big.Int
+	// The number of bits set in Bitmap
+	// TODO(dh): remove NumSet. we can just query the bitmap.
+	NumSet int
+	// Dense list of values in the composite literal. Omitted elements are filled in with zero values.
+	Values []Value
+}
+
+type Constant interface {
+	Value
+	aConstant()
+	RelString(*types.Package) string
+}
+
+func (*Const) aConstant()          {}
+func (*AggregateConst) aConstant() {}
+
+// A Global is a named Value holding the address of a package-level
+// variable.
+//
+// Pos() returns the position of the ast.ValueSpec.Names[*]
+// identifier.
+type Global struct {
+	node
+
+	name   string
+	object types.Object // a *types.Var; may be nil for synthetics e.g. init$guard
+	typ    types.Type
+
+	Pkg *Package
+}
+
+// A Builtin represents a specific use of a built-in function, e.g. len.
+//
+// Builtins are immutable values.  Builtins do not have addresses.
+// Builtins can only appear in CallCommon.Func.
+//
+// Name() indicates the function: one of the built-in functions from the
+// Go spec (excluding "make" and "new") or one of these ir-defined
+// intrinsics:
+//
+//	// wrapnilchk returns ptr if non-nil, panics otherwise.
+//	// (For use in indirection wrappers.)
+//	func ir:wrapnilchk(ptr *T, recvType, methodName string) *T
+//
+//	// noreturnWasPanic returns true if the previously called
+//	// function panicked, false if it exited the process.
+//	func ir:noreturnWasPanic() bool
+//
+// Object() returns a *types.Builtin for built-ins defined by the spec,
+// nil for others.
+//
+// Type() returns a *types.Signature representing the effective
+// signature of the built-in for this call.
+type Builtin struct {
+	node
+
+	name string
+	sig  *types.Signature
+}
+
+// Value-defining instructions  ----------------------------------------
+
+// The Alloc instruction reserves space for a variable of the given type,
+// zero-initializes it, and yields its address.
+//
+// Alloc values are always addresses, and have pointer types, so the
+// type of the allocated variable is actually
+// Type().Underlying().(*types.Pointer).Elem().
+//
+// If Heap is false, Alloc zero-initializes the same local variable in
+// the call frame and returns its address; in this case the Alloc must
+// be present in Function.Locals. We call this a "local" alloc.
+//
+// If Heap is true, Alloc allocates a new zero-initialized variable
+// each time the instruction is executed. We call this a "new" alloc.
+//
+// When Alloc is applied to a channel, map or slice type, it returns
+// the address of an uninitialized (nil) reference of that kind; store
+// the result of MakeSlice, MakeMap or MakeChan in that location to
+// instantiate these types.
+//
+// Pos() returns the ast.CompositeLit.Lbrace for a composite literal,
+// or the ast.CallExpr.Rparen for a call to new() or for a call that
+// allocates a varargs slice.
+//
+// Example printed form:
+//
+//	t0 = local int
+//	t1 = new int
+type Alloc struct {
+	register
+	Heap  bool
+	index int // dense numbering; for lifting
+}
+
+// The Phi instruction represents an SSA φ-node, which combines values
+// that differ across incoming control-flow edges and yields a new
+// value.  Within a block, all φ-nodes must appear before all non-φ
+// nodes.
+//
+// Pos() returns the position of the && or || for short-circuit
+// control-flow joins, or that of the *Alloc for φ-nodes inserted
+// during SSA renaming.
+//
+// Example printed form:
+//
+//	t2 = phi [0: t0, 1: t1]
+type Phi struct {
+	register
+	Edges []Value // Edges[i] is value for Block().Preds[i]
+
+	live bool // used during lifting
+}
+
+// The Call instruction represents a function or method call.
+//
+// The Call instruction yields the function result if there is exactly
+// one.  Otherwise it returns a tuple, the components of which are
+// accessed via Extract.
+//
+// See CallCommon for generic function call documentation.
+//
+// Pos() returns the ast.CallExpr.Lparen, if explicit in the source.
+//
+// Example printed form:
+//
+//	t2 = println(t0, t1)
+//	t4 = t3()
+//	t7 = invoke t5.Println(...t6)
+type Call struct {
+	register
+	Call CallCommon
+}
+
+// The BinOp instruction yields the result of binary operation X Op Y.
+//
+// Pos() returns the ast.BinaryExpr.OpPos, if explicit in the source.
+//
+// Example printed form:
+//
+//	t1 = t0 + 1:int
+type BinOp struct {
+	register
+	// One of:
+	// ADD SUB MUL QUO REM          + - * / %
+	// AND OR XOR SHL SHR AND_NOT   & | ^ << >> &^
+	// EQL NEQ LSS LEQ GTR GEQ      == != < <= < >=
+	Op   token.Token
+	X, Y Value
+}
+
+// The UnOp instruction yields the result of Op X.
+// XOR is bitwise complement.
+// SUB is negation.
+// NOT is logical negation.
+//
+// Example printed form:
+//
+//	t0 = ^x
+type UnOp struct {
+	register
+	Op token.Token // One of: NOT SUB XOR ! - ^
+	X  Value
+}
+
+// The Load instruction loads a value from a memory address.
+//
+// For implicit memory loads, Pos() returns the position of the
+// most closely associated source-level construct; the details are not
+// specified.
+//
+// Example printed form:
+//
+//	t2 = Load  t1
+type Load struct {
+	register
+	X Value
+}
+
+// The ChangeType instruction applies to X a value-preserving type
+// change to Type().
+//
+// Type changes are permitted:
+//   - between a named type and its underlying type.
+//   - between two named types of the same underlying type.
+//   - between (possibly named) pointers to identical base types.
+//   - from a bidirectional channel to a read- or write-channel,
+//     optionally adding/removing a name.
+//   - between a type (t) and an instance of the type (tσ), i.e.
+//     Type() == σ(X.Type()) (or X.Type()== σ(Type())) where
+//     σ is the type substitution of Parent().TypeParams by
+//     Parent().TypeArgs.
+//
+// This operation cannot fail dynamically.
+//
+// Type changes may to be to or from a type parameter (or both). All
+// types in the type set of X.Type() have a value-preserving type
+// change to all types in the type set of Type().
+//
+// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
+// from an explicit conversion in the source.
+//
+// Example printed form:
+//
+//	t1 = changetype *int <- IntPtr (t0)
+type ChangeType struct {
+	register
+	X Value
+}
+
+// The Convert instruction yields the conversion of value X to type
+// Type().  One or both of those types is basic (but possibly named).
+//
+// A conversion may change the value and representation of its operand.
+// Conversions are permitted:
+//   - between real numeric types.
+//   - between complex numeric types.
+//   - between string and []byte or []rune.
+//   - between pointers and unsafe.Pointer.
+//   - between unsafe.Pointer and uintptr.
+//   - from (Unicode) integer to (UTF-8) string.
+//
+// A conversion may imply a type name change also.
+//
+// Conversions may to be to or from a type parameter. All types in
+// the type set of X.Type() can be converted to all types in the type
+// set of Type().
+//
+// This operation cannot fail dynamically.
+//
+// Conversions of untyped string/number/bool constants to a specific
+// representation are eliminated during IR construction.
+//
+// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
+// from an explicit conversion in the source.
+//
+// Example printed form:
+//
+//	t1 = convert []byte <- string (t0)
+type Convert struct {
+	register
+	X Value
+}
+
+// The MultiConvert instruction yields the conversion of value X to type
+// Type(). Either X.Type() or Type() must be a type parameter. Each
+// type in the type set of X.Type() can be converted to each type in the
+// type set of Type().
+//
+// See the documentation for Convert, ChangeType, SliceToArray, and SliceToArrayPointer
+// for the conversions that are permitted.
+//
+// This operation can fail dynamically (see SliceToArrayPointer).
+//
+// Example printed form:
+//
+//	t1 = multiconvert D <- S (t0) [*[2]rune <- []rune | string <- []rune]
+type MultiConvert struct {
+	register
+	X        Value
+	from, to types.Type
+}
+
+// ChangeInterface constructs a value of one interface type from a
+// value of another interface type known to be assignable to it.
+// This operation cannot fail.
+//
+// Pos() returns the ast.CallExpr.Lparen if the instruction arose from
+// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the
+// instruction arose from an explicit e.(T) operation; or token.NoPos
+// otherwise.
+//
+// Example printed form:
+//
+//	t1 = change interface interface{} <- I (t0)
+type ChangeInterface struct {
+	register
+	X Value
+}
+
+// The SliceToArrayPointer instruction yields the conversion of slice X to
+// array pointer.
+//
+// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
+// from an explicit conversion in the source.
+//
+// Conversion may to be to or from a type parameter. All types in
+// the type set of X.Type() must be a slice types that can be converted to
+// all types in the type set of Type() which must all be pointer to array
+// types.
+//
+// This operation can fail dynamically if the length of the slice is less
+// than the length of the array.
+//
+// Example printed form:
+//
+//	t1 = slice to array pointer *[4]byte <- []byte (t0)
+type SliceToArrayPointer struct {
+	register
+	X Value
+}
+
+// The SliceToArray instruction yields the conversion of slice X to
+// array.
+//
+// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
+// from an explicit conversion in the source.
+//
+// Example printed form:
+//
+//	t2 = SliceToArray <[4]byte> t1
+type SliceToArray struct {
+	register
+	X Value
+}
+
+// MakeInterface constructs an instance of an interface type from a
+// value of a concrete type.
+//
+// Use Program.MethodSets.MethodSet(X.Type()) to find the method-set
+// of X, and Program.MethodValue(m) to find the implementation of a method.
+//
+// To construct the zero value of an interface type T, use:
+//
+//	NewConst(constant.MakeNil(), T, pos)
+//
+// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
+// from an explicit conversion in the source.
+//
+// Example printed form:
+//
+//	t1 = make interface{} <- int (42:int)
+//	t1 = make Stringer <- t0
+type MakeInterface struct {
+	register
+	X Value
+}
+
+// The MakeClosure instruction yields a closure value whose code is
+// Fn and whose free variables' values are supplied by Bindings.
+//
+// Type() returns a (possibly named) *types.Signature.
+//
+// Pos() returns the ast.FuncLit.Type.Func for a function literal
+// closure or the ast.SelectorExpr.Sel for a bound method closure.
+//
+// Example printed form:
+//
+//	t0 = make closure anon@1.2 [x y z]
+//	t1 = make closure bound$(main.I).add [i]
+type MakeClosure struct {
+	register
+	Fn       Value   // always a *Function
+	Bindings []Value // values for each free variable in Fn.FreeVars
+}
+
+// The MakeMap instruction creates a new hash-table-based map object
+// and yields a value of kind map.
+//
+// Type() returns a (possibly named) *types.Map.
+//
+// Pos() returns the ast.CallExpr.Lparen, if created by make(map), or
+// the ast.CompositeLit.Lbrack if created by a literal.
+//
+// Example printed form:
+//
+//	t1 = make map[string]int t0
+//	t1 = make StringIntMap t0
+type MakeMap struct {
+	register
+	Reserve Value // initial space reservation; nil => default
+}
+
+// The MakeChan instruction creates a new channel object and yields a
+// value of kind chan.
+//
+// Type() returns a (possibly named) *types.Chan.
+//
+// Pos() returns the ast.CallExpr.Lparen for the make(chan) that
+// created it.
+//
+// Example printed form:
+//
+//	t1 = make chan int t0
+//	t1 = make IntChan t0
+type MakeChan struct {
+	register
+	Size Value // int; size of buffer; zero => synchronous.
+}
+
+// The MakeSlice instruction yields a slice of length Len backed by a
+// newly allocated array of length Cap.
+//
+// Both Len and Cap must be non-nil Values of integer type.
+//
+// (Alloc(types.Array) followed by Slice will not suffice because
+// Alloc can only create arrays of constant length.)
+//
+// Type() returns a (possibly named) *types.Slice.
+//
+// Pos() returns the ast.CallExpr.Lparen for the make([]T) that
+// created it.
+//
+// Example printed form:
+//
+//	t2 = make []string t1 t0
+//	t2 = make StringSlice t1 t0
+type MakeSlice struct {
+	register
+	Len Value
+	Cap Value
+}
+
+// The Slice instruction yields a slice of an existing string, slice
+// or *array X between optional integer bounds Low and High.
+//
+// Dynamically, this instruction panics if X evaluates to a nil *array
+// pointer.
+//
+// Type() returns string if the type of X was string, otherwise a
+// *types.Slice with the same element type as X.
+//
+// Pos() returns the ast.SliceExpr.Lbrack if created by a x[:] slice
+// operation, the ast.CompositeLit.Lbrace if created by a literal, or
+// NoPos if not explicit in the source (e.g. a variadic argument slice).
+//
+// Example printed form:
+//
+//	t2 = slice t0[t1:]
+type Slice struct {
+	register
+	X              Value // slice, string, or *array
+	Low, High, Max Value // each may be nil
+}
+
+// The FieldAddr instruction yields the address of Field of *struct X.
+//
+// The field is identified by its index within the field list of the
+// struct type of X.
+//
+// Dynamically, this instruction panics if X evaluates to a nil
+// pointer.
+//
+// Type() returns a (possibly named) *types.Pointer.
+//
+// Pos() returns the position of the ast.SelectorExpr.Sel for the
+// field, if explicit in the source. For implicit selections, returns
+// the position of the inducing explicit selection. If produced for a
+// struct literal S{f: e}, it returns the position of the colon; for
+// S{e} it returns the start of expression e.
+//
+// Example printed form:
+//
+//	t1 = &t0.name [#1]
+type FieldAddr struct {
+	register
+	X     Value // *struct
+	Field int   // index into CoreType(CoreType(X.Type()).(*types.Pointer).Elem()).(*types.Struct).Fields
+}
+
+// The Field instruction yields the Field of struct X.
+//
+// The field is identified by its index within the field list of the
+// struct type of X; by using numeric indices we avoid ambiguity of
+// package-local identifiers and permit compact representations.
+//
+// Pos() returns the position of the ast.SelectorExpr.Sel for the
+// field, if explicit in the source. For implicit selections, returns
+// the position of the inducing explicit selection.
+//
+// Example printed form:
+//
+//	t1 = t0.name [#1]
+type Field struct {
+	register
+	X     Value // struct
+	Field int   // index into CoreType(X.Type()).(*types.Struct).Fields
+}
+
+// The IndexAddr instruction yields the address of the element at
+// index Index of collection X.  Index is an integer expression.
+//
+// The elements of maps and strings are not addressable; use Lookup (map),
+// Index (string), or MapUpdate instead.
+//
+// Dynamically, this instruction panics if X evaluates to a nil *array
+// pointer.
+//
+// Type() returns a (possibly named) *types.Pointer.
+//
+// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if
+// explicit in the source.
+//
+// Example printed form:
+//
+//	t2 = &t0[t1]
+type IndexAddr struct {
+	register
+	X     Value // *array, slice or type parameter with types array, *array, or slice.
+	Index Value // numeric index
+}
+
+// The Index instruction yields element Index of collection X, an array,
+// string or type parameter containing an array, a string, a pointer to an,
+// array or a slice.
+//
+// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if
+// explicit in the source.
+//
+// Example printed form:
+//
+//	t2 = t0[t1]
+type Index struct {
+	register
+	X     Value // array, string or type parameter with types array, *array, slice, or string.
+	Index Value // integer index
+}
+
+// The MapLookup instruction yields element Index of collection X, a map.
+// Index is the appropriate key type.
+//
+// If CommaOk, the result is a 2-tuple of the value above and a
+// boolean indicating the result of a map membership test for the key.
+// The components of the tuple are accessed using Extract.
+//
+// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source.
+//
+// Example printed form:
+//
+//	t2 = t0[t1]
+//	t5 = t3[t4],ok
+type MapLookup struct {
+	register
+	X       Value // map
+	Index   Value // key-typed index
+	CommaOk bool  // return a value,ok pair
+}
+
+// The StringLookup instruction yields element Index of collection X, a string.
+// Index is an integer expression.
+//
+// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source.
+//
+// Example printed form:
+//
+//	t3 = StringLookup  t2 t1
+type StringLookup struct {
+	register
+	X     Value // string
+	Index Value // numeric index
+}
+
+// SelectState is a helper for Select.
+// It represents one goal state and its corresponding communication.
+type SelectState struct {
+	Dir       types.ChanDir // direction of case (SendOnly or RecvOnly)
+	Chan      Value         // channel to use (for send or receive)
+	Send      Value         // value to send (for send)
+	Pos       token.Pos     // position of token.ARROW
+	DebugNode ast.Node      // ast.SendStmt or ast.UnaryExpr(<-) [debug mode]
+}
+
+// The Select instruction tests whether (or blocks until) one
+// of the specified sent or received states is entered.
+//
+// Let n be the number of States for which Dir==RECV and Tᵢ (0 ≤ i < n)
+// be the element type of each such state's Chan.
+// Select returns an n+2-tuple
+//
+//	(index int, recvOk bool, r₀ T₀, ... rₙ-1 Tₙ-1)
+//
+// The tuple's components, described below, must be accessed via the
+// Extract instruction.
+//
+// If Blocking, select waits until exactly one state holds, i.e. a
+// channel becomes ready for the designated operation of sending or
+// receiving; select chooses one among the ready states
+// pseudorandomly, performs the send or receive operation, and sets
+// 'index' to the index of the chosen channel.
+//
+// If !Blocking, select doesn't block if no states hold; instead it
+// returns immediately with index equal to -1.
+//
+// If the chosen channel was used for a receive, the rᵢ component is
+// set to the received value, where i is the index of that state among
+// all n receive states; otherwise rᵢ has the zero value of type Tᵢ.
+// Note that the receive index i is not the same as the state
+// index index.
+//
+// The second component of the triple, recvOk, is a boolean whose value
+// is true iff the selected operation was a receive and the receive
+// successfully yielded a value.
+//
+// Pos() returns the ast.SelectStmt.Select.
+//
+// Example printed form:
+//
+//	t3 = select nonblocking [<-t0, t1<-t2]
+//	t4 = select blocking []
+type Select struct {
+	register
+	States   []*SelectState
+	Blocking bool
+}
+
+// The Range instruction yields an iterator over the domain and range
+// of X, which must be a string or map.
+//
+// Elements are accessed via Next.
+//
+// Type() returns an opaque and degenerate "rangeIter" type.
+//
+// Pos() returns the ast.RangeStmt.For.
+//
+// Example printed form:
+//
+//	t0 = range "hello":string
+type Range struct {
+	register
+	X Value // string or map
+}
+
+// The Next instruction reads and advances the (map or string)
+// iterator Iter and returns a 3-tuple value (ok, k, v).  If the
+// iterator is not exhausted, ok is true and k and v are the next
+// elements of the domain and range, respectively.  Otherwise ok is
+// false and k and v are undefined.
+//
+// Components of the tuple are accessed using Extract.
+//
+// The IsString field distinguishes iterators over strings from those
+// over maps, as the Type() alone is insufficient: consider
+// map[int]rune.
+//
+// Type() returns a *types.Tuple for the triple (ok, k, v).
+// The types of k and/or v may be types.Invalid.
+//
+// Example printed form:
+//
+//	t1 = next t0
+type Next struct {
+	register
+	Iter     Value
+	IsString bool // true => string iterator; false => map iterator.
+}
+
+// The TypeAssert instruction tests whether interface value X has type
+// AssertedType.
+//
+// If !CommaOk, on success it returns v, the result of the conversion
+// (defined below); on failure it panics.
+//
+// If CommaOk: on success it returns a pair (v, true) where v is the
+// result of the conversion; on failure it returns (z, false) where z
+// is AssertedType's zero value.  The components of the pair must be
+// accessed using the Extract instruction.
+//
+// If Underlying: tests whether interface value X has the underlying
+// type AssertedType.
+//
+// If AssertedType is a concrete type, TypeAssert checks whether the
+// dynamic type in interface X is equal to it, and if so, the result
+// of the conversion is a copy of the value in the interface.
+//
+// If AssertedType is an interface, TypeAssert checks whether the
+// dynamic type of the interface is assignable to it, and if so, the
+// result of the conversion is a copy of the interface value X.
+// If AssertedType is a superinterface of X.Type(), the operation will
+// fail iff the operand is nil.  (Contrast with ChangeInterface, which
+// performs no nil-check.)
+//
+// Type() reflects the actual type of the result, possibly a
+// 2-types.Tuple; AssertedType is the asserted type.
+//
+// Depending on the TypeAssert's purpose, Pos may return:
+//   - the ast.CallExpr.Lparen of an explicit T(e) conversion;
+//   - the ast.TypeAssertExpr.Lparen of an explicit e.(T) operation;
+//   - the ast.CaseClause.Case of a case of a type-switch statement;
+//   - the Ident(m).NamePos of an interface method value i.m
+//     (for which TypeAssert may be used to effect the nil check).
+//
+// Example printed form:
+//
+//	t1 = typeassert t0.(int)
+//	t3 = typeassert,ok t2.(T)
+type TypeAssert struct {
+	register
+	X            Value
+	AssertedType types.Type
+	CommaOk      bool
+}
+
+// The Extract instruction yields component Index of Tuple.
+//
+// This is used to access the results of instructions with multiple
+// return values, such as Call, TypeAssert, Next, Recv,
+// MapLookup and others.
+//
+// Example printed form:
+//
+//	t1 = extract t0 #1
+type Extract struct {
+	register
+	Tuple Value
+	Index int
+}
+
+// Instructions executed for effect.  They do not yield a value. --------------------
+
+// The Jump instruction transfers control to the sole successor of its
+// owning block.
+//
+// A Jump must be the last instruction of its containing BasicBlock.
+//
+// Pos() returns NoPos.
+//
+// Example printed form:
+//
+//	jump done
+type Jump struct {
+	anInstruction
+}
+
+// The Unreachable pseudo-instruction signals that execution cannot
+// continue after the preceding function call because it terminates
+// the process.
+//
+// An Unreachable instruction must be the last instruction of its
+// containing BasicBlock, which must have no successors.
+//
+// Example printed form:
+//
+//	Unreachable
+type Unreachable struct {
+	anInstruction
+}
+
+// The If instruction transfers control to one of the two successors
+// of its owning block, depending on the boolean Cond: the first if
+// true, the second if false.
+//
+// An If instruction must be the last instruction of its containing
+// BasicBlock.
+//
+// Pos() returns the *ast.IfStmt, if explicit in the source.
+//
+// Example printed form:
+//
+//	if t0 goto done else body
+type If struct {
+	anInstruction
+	Cond Value
+}
+
+type ConstantSwitch struct {
+	anInstruction
+	Tag Value
+	// Constant branch conditions. A nil Value denotes the (implicit
+	// or explicit) default branch.
+	Conds []Value
+}
+
+type TypeSwitch struct {
+	register
+	Tag   Value
+	Conds []types.Type
+}
+
+// The Return instruction returns values and control back to the calling
+// function.
+//
+// len(Results) is always equal to the number of results in the
+// function's signature.
+//
+// If len(Results) > 1, Return returns a tuple value with the specified
+// components which the caller must access using Extract instructions.
+//
+// There is no instruction to return a ready-made tuple like those
+// returned by a "value,ok"-mode TypeAssert, MapLookup or Recv or
+// a tail-call to a function with multiple result parameters.
+//
+// Return must be the last instruction of its containing BasicBlock.
+// Such a block has no successors.
+//
+// Pos() returns the ast.ReturnStmt.Return, if explicit in the source.
+//
+// Example printed form:
+//
+//	return
+//	return t0, t1
+type Return struct {
+	anInstruction
+	Results []Value
+}
+
+// The RunDefers instruction pops and invokes the entire stack of
+// procedure calls pushed by Defer instructions in this function.
+//
+// It is legal to encounter multiple 'rundefers' instructions in a
+// single control-flow path through a function; this is useful in
+// the combined init() function, for example.
+//
+// Pos() returns NoPos.
+//
+// Example printed form:
+//
+//	rundefers
+type RunDefers struct {
+	anInstruction
+}
+
+// The Panic instruction initiates a panic with value X.
+//
+// A Panic instruction must be the last instruction of its containing
+// BasicBlock, which must have no successors.
+//
+// NB: 'go panic(x)' and 'defer panic(x)' do not use this instruction;
+// they are treated as calls to a built-in function.
+//
+// Pos() returns the ast.CallExpr.Lparen if this panic was explicit
+// in the source.
+//
+// Example printed form:
+//
+//	panic t0
+type Panic struct {
+	anInstruction
+	X Value // an interface{}
+}
+
+// The Go instruction creates a new goroutine and calls the specified
+// function within it.
+//
+// See CallCommon for generic function call documentation.
+//
+// Pos() returns the ast.GoStmt.Go.
+//
+// Example printed form:
+//
+//	go println(t0, t1)
+//	go t3()
+//	go invoke t5.Println(...t6)
+type Go struct {
+	anInstruction
+	Call CallCommon
+}
+
+// The Defer instruction pushes the specified call onto a stack of
+// functions to be called by a RunDefers instruction or by a panic.
+//
+// If DeferStack != nil, it indicates the defer list that the defer is
+// added to. Defer list values come from the Builtin function
+// ssa:deferstack. Calls to ssa:deferstack() produces the defer stack
+// of the current function frame. DeferStack allows for deferring into an
+// alternative function stack than the current function.
+//
+// See CallCommon for generic function call documentation.
+//
+// Pos() returns the ast.DeferStmt.Defer.
+//
+// Example printed form:
+//
+//	defer println(t0, t1)
+//	defer t3()
+//	defer invoke t5.Println(...t6)
+type Defer struct {
+	anInstruction
+	Call       CallCommon
+	DeferStack Value // stack of deferred functions (from ssa:deferstack() intrinsic) onto which this function is pushed
+}
+
+// The Send instruction sends X on channel Chan.
+//
+// Pos() returns the ast.SendStmt.Arrow, if explicit in the source.
+//
+// Example printed form:
+//
+//	send t0 <- t1
+type Send struct {
+	anInstruction
+	Chan, X Value
+}
+
+// The Recv instruction receives from channel Chan.
+//
+// If CommaOk, the result is a 2-tuple of the value above
+// and a boolean indicating the success of the receive.  The
+// components of the tuple are accessed using Extract.
+//
+// Pos() returns the ast.UnaryExpr.OpPos, if explicit in the source.
+// For receive operations implicit in ranging over a channel,
+// Pos() returns the ast.RangeStmt.For.
+//
+// Example printed form:
+//
+//	t2 = Recv  t1
+//	t3 = Recv <(int, bool)> t1
+type Recv struct {
+	register
+	Chan    Value
+	CommaOk bool
+}
+
+// The Store instruction stores Val at address Addr.
+// Stores can be of arbitrary types.
+//
+// Pos() returns the position of the source-level construct most closely
+// associated with the memory store operation.
+// Since implicit memory stores are numerous and varied and depend upon
+// implementation choices, the details are not specified.
+//
+// Example printed form:
+//
+//	*x = y
+type Store struct {
+	anInstruction
+	Addr Value
+	Val  Value
+}
+
+// The BlankStore instruction is emitted for assignments to the blank
+// identifier.
+//
+// BlankStore is a pseudo-instruction: it has no dynamic effect.
+//
+// Pos() returns NoPos.
+//
+// Example printed form:
+//
+//	BlankStore t1
+type BlankStore struct {
+	anInstruction
+	Val Value
+}
+
+// The MapUpdate instruction updates the association of Map[Key] to
+// Value.
+//
+// Pos() returns the ast.KeyValueExpr.Colon or ast.IndexExpr.Lbrack,
+// if explicit in the source.
+//
+// Example printed form:
+//
+//	t0[t1] = t2
+type MapUpdate struct {
+	anInstruction
+	Map   Value
+	Key   Value
+	Value Value
+}
+
+// A debugRef instruction maps a source-level expression Expr to the
+// IR value X that represents the value (!IsAddr) or address (IsAddr)
+// of that expression.
+//
+// debugRef is a pseudo-instruction: it has no dynamic effect.
+//
+// Pos() returns Expr.Pos(), the start position of the source-level
+// expression.  This is not the same as the "designated" token as
+// documented at Value.Pos(). e.g. CallExpr.Pos() does not return the
+// position of the ("designated") Lparen token.
+//
+// If Expr is an *ast.Ident denoting a var or func, Object() returns
+// the object; though this information can be obtained from the type
+// checker, including it here greatly facilitates debugging.
+// For non-Ident expressions, Object() returns nil.
+//
+// DebugRefs are generated only for functions built with debugging
+// enabled; see Package.SetDebugMode() and the GlobalDebug builder
+// mode flag.
+//
+// DebugRefs are not emitted for ast.Idents referring to constants or
+// predeclared identifiers, since they are trivial and numerous.
+// Nor are they emitted for ast.ParenExprs.
+//
+// (By representing these as instructions, rather than out-of-band,
+// consistency is maintained during transformation passes by the
+// ordinary SSA renaming machinery.)
+//
+// Example printed form:
+//
+//	; *ast.CallExpr @ 102:9 is t5
+//	; var x float64 @ 109:72 is x
+//	; address of *ast.CompositeLit @ 216:10 is t0
+type debugRef struct {
+	anInstruction
+	Expr   ast.Expr     // the referring expression (never *ast.ParenExpr)
+	object types.Object // the identity of the source var/func
+	IsAddr bool         // Expr is addressable and X is the address it denotes
+	X      Value        // the value or address of Expr
+}
+
+// Embeddable mix-ins and helpers for common parts of other structs. -----------
+
+// register is a mix-in embedded by all IR values that are also
+// instructions, i.e. virtual registers, and provides a uniform
+// implementation of most of the Value interface: Value.Name() is a
+// numbered register (e.g. "t0"); the other methods are field accessors.
+//
+// Temporary names are automatically assigned to each register on
+// completion of building a function in IR form.
+type register struct {
+	anInstruction
+	typ       types.Type // type of virtual register
+	referrers []Instruction
+}
+
+type node struct {
+	source ast.Node
+}
+
+func (n *node) setSource(source ast.Node) { n.source = source }
+func (n *node) Source() ast.Node          { return n.source }
+
+func (n *node) Pos() token.Pos {
+	if n.source != nil {
+		return n.source.Pos()
+	}
+	return token.NoPos
+}
+
+// anInstruction is a mix-in embedded by all Instructions.
+// It provides the implementations of the Block and setBlock methods.
+type anInstruction struct {
+	node
+	id      ID
+	block   *BasicBlock // the basic block of this instruction
+	comment string
+}
+
+func (instr *anInstruction) setID(id ID) {
+	instr.id = id
+}
+
+func (instr anInstruction) ID() ID {
+	return instr.id
+}
+
+func (instr anInstruction) Comment() string {
+	return instr.comment
+}
+
+// CallCommon is contained by Go, Defer and Call to hold the
+// common parts of a function or method call.
+//
+// Each CallCommon exists in one of two modes, function call and
+// interface method invocation, or "call" and "invoke" for short.
+//
+// 1. "call" mode: when Method is nil (!IsInvoke), a CallCommon
+// represents an ordinary function call of the value in Value,
+// which may be a *Builtin, a *Function or any other value of kind
+// 'func'.
+//
+// Value may be one of:
+//
+//	(a) a *Function, indicating a statically dispatched call
+//	    to a package-level function, an anonymous function, or
+//	    a method of a named type.
+//	(b) a *MakeClosure, indicating an immediately applied
+//	    function literal with free variables.
+//	(c) a *Builtin, indicating a statically dispatched call
+//	    to a built-in function.
+//	(d) any other value, indicating a dynamically dispatched
+//	    function call.
+//
+// StaticCallee returns the identity of the callee in cases
+// (a) and (b), nil otherwise.
+//
+// Args contains the arguments to the call.  If Value is a method,
+// Args[0] contains the receiver parameter.
+//
+// Example printed form:
+//
+//	t2 = println(t0, t1)
+//	go t3()
+//	defer t5(...t6)
+//
+// 2. "invoke" mode: when Method is non-nil (IsInvoke), a CallCommon
+// represents a dynamically dispatched call to an interface method.
+// In this mode, Value is the interface value and Method is the
+// interface's abstract method. The interface value may be a type
+// parameter. Note: an interface method may be shared by multiple
+// interfaces due to embedding; Value.Type() provides the specific
+// interface used for this call.
+//
+// Value is implicitly supplied to the concrete method implementation
+// as the receiver parameter; in other words, Args[0] holds not the
+// receiver but the first true argument.
+//
+// Example printed form:
+//
+//	t1 = invoke t0.String()
+//	go invoke t3.Run(t2)
+//	defer invoke t4.Handle(...t5)
+//
+// For all calls to variadic functions (Signature().Variadic()),
+// the last element of Args is a slice.
+type CallCommon struct {
+	Value  Value       // receiver (invoke mode) or func value (call mode)
+	Method *types.Func // interface method (invoke mode)
+	Args   []Value     // actual parameters (in static method call, includes receiver)
+
+	source ast.Node
+}
+
+// IsInvoke returns true if this call has "invoke" (not "call") mode.
+func (c *CallCommon) IsInvoke() bool {
+	return c.Method != nil
+}
+
+func (c *CallCommon) Pos() token.Pos {
+	if c.source != nil {
+		return c.source.Pos()
+	}
+	return token.NoPos
+}
+
+// Signature returns the signature of the called function.
+//
+// For an "invoke"-mode call, the signature of the interface method is
+// returned.
+//
+// In either "call" or "invoke" mode, if the callee is a method, its
+// receiver is represented by sig.Recv, not sig.Params().At(0).
+func (c *CallCommon) Signature() *types.Signature {
+	if c.Method != nil {
+		return c.Method.Type().(*types.Signature)
+	}
+	return typeutil.CoreType(c.Value.Type()).(*types.Signature)
+}
+
+// StaticCallee returns the callee if this is a trivially static
+// "call"-mode call to a function.
+func (c *CallCommon) StaticCallee() *Function {
+	switch fn := c.Value.(type) {
+	case *Function:
+		return fn
+	case *MakeClosure:
+		return fn.Fn.(*Function)
+	}
+	return nil
+}
+
+// Description returns a description of the mode of this call suitable
+// for a user interface, e.g., "static method call".
+func (c *CallCommon) Description() string {
+	switch fn := c.Value.(type) {
+	case *Builtin:
+		return "built-in function call"
+	case *MakeClosure:
+		return "static function closure call"
+	case *Function:
+		if fn.Signature.Recv() != nil {
+			return "static method call"
+		}
+		return "static function call"
+	}
+	if c.IsInvoke() {
+		return "dynamic method call" // ("invoke" mode)
+	}
+	return "dynamic function call"
+}
+
+// The CallInstruction interface, implemented by *Go, *Defer and *Call,
+// exposes the common parts of function-calling instructions,
+// yet provides a way back to the Value defined by *Call alone.
+type CallInstruction interface {
+	Instruction
+	Common() *CallCommon // returns the common parts of the call
+	Value() *Call
+}
+
+func (s *Call) Common() *CallCommon  { return &s.Call }
+func (s *Defer) Common() *CallCommon { return &s.Call }
+func (s *Go) Common() *CallCommon    { return &s.Call }
+
+func (s *Call) setSource(source ast.Node)  { s.source = source; s.Call.source = source }
+func (s *Defer) setSource(source ast.Node) { s.source = source; s.Call.source = source }
+func (s *Go) setSource(source ast.Node)    { s.source = source; s.Call.source = source }
+
+func (s *Call) Value() *Call  { return s }
+func (s *Defer) Value() *Call { return nil }
+func (s *Go) Value() *Call    { return nil }
+
+func (v *Builtin) Type() types.Type        { return v.sig }
+func (v *Builtin) Name() string            { return v.name }
+func (*Builtin) Referrers() *[]Instruction { return nil }
+func (v *Builtin) Pos() token.Pos          { return token.NoPos }
+func (v *Builtin) Object() types.Object    { return types.Universe.Lookup(v.name) }
+func (v *Builtin) Parent() *Function       { return nil }
+
+func (v *FreeVar) Type() types.Type          { return v.typ }
+func (v *FreeVar) Name() string              { return v.name }
+func (v *FreeVar) Referrers() *[]Instruction { return &v.referrers }
+func (v *FreeVar) Parent() *Function         { return v.parent }
+
+func (v *Global) Type() types.Type                     { return v.typ }
+func (v *Global) Name() string                         { return v.name }
+func (v *Global) Parent() *Function                    { return nil }
+func (v *Global) Referrers() *[]Instruction            { return nil }
+func (v *Global) Token() token.Token                   { return token.VAR }
+func (v *Global) Object() types.Object                 { return v.object }
+func (v *Global) String() string                       { return v.RelString(nil) }
+func (v *Global) Package() *Package                    { return v.Pkg }
+func (v *Global) RelString(from *types.Package) string { return relString(v, from) }
+
+func (v *Function) Name() string       { return v.name }
+func (v *Function) Type() types.Type   { return v.Signature }
+func (v *Function) Token() token.Token { return token.FUNC }
+func (v *Function) Object() types.Object {
+	if v.object != nil {
+		return types.Object(v.object)
+	}
+	return nil
+}
+func (v *Function) String() string    { return v.RelString(nil) }
+func (v *Function) Package() *Package { return v.Pkg }
+func (v *Function) Parent() *Function { return v.parent }
+func (v *Function) Referrers() *[]Instruction {
+	if v.parent != nil {
+		return &v.referrers
+	}
+	return nil
+}
+
+// Returns returns an iterator over all blocks containing return statements.
+func (v *Function) Returns() iter.Seq[*BasicBlock] {
+	return func(yield func(*BasicBlock) bool) {
+		for _, b := range v.Blocks {
+			if _, ok := b.Control().(*Return); ok {
+				if !yield(b) {
+					return
+				}
+			}
+		}
+	}
+}
+
+// Exits returns an iterator over all blocks that have no successors.
+func (v *Function) Exits() iter.Seq[*BasicBlock] {
+	return func(yield func(*BasicBlock) bool) {
+		for _, b := range v.Blocks {
+			if len(b.Succs) == 0 {
+				if !yield(b) {
+					return
+				}
+			}
+		}
+	}
+}
+
+// Nodes returns an iterator over the basic block indices.
+func (v *Function) Nodes() iter.Seq[int] {
+	return func(yield func(int) bool) {
+		for i := range v.Blocks {
+			if !yield(i) {
+				return
+			}
+		}
+	}
+}
+
+// NumNodes returns the number of basic blocks in the graph.
+func (v *Function) NumNodes() int { return len(v.Blocks) }
+
+// Out returns an iterator over the successor block indices of a given node.
+func (v *Function) Out(node int) iter.Seq[int] {
+	return func(yield func(int) bool) {
+		for _, succ := range v.Blocks[node].Succs {
+			if !yield(succ.Index) {
+				return
+			}
+		}
+	}
+}
+
+func (v *Parameter) Type() types.Type          { return v.typ }
+func (v *Parameter) Name() string              { return v.name }
+func (v *Parameter) Object() types.Object      { return v.object }
+func (v *Parameter) Referrers() *[]Instruction { return &v.referrers }
+func (v *Parameter) Pos() token.Pos            { return v.object.Pos() }
+func (v *Parameter) Parent() *Function         { return v.parent }
+
+// TypeParams are the function's type parameters if generic or the
+// type parameters that were instantiated if fn is an instantiation.
+//
+// Specifically, the resulting list behaves like:
+//
+//	func        f       // []
+//	func        f[P]    // [P]
+//	func (T)    m       // []
+//	func (T)    m[P]    // [P]
+//	func (T[P]) m       // [P]
+//	func (T[P]) m[Q]    // [P (index=0), Q (index=0)]
+//
+// Note that receiver type parameters precede other type parameters.
+// Also, type parameters may have the same index if they come from
+// different source type parameter lists.
+func (fn *Function) TypeParams() *types.TypeParamList {
+	return consTypeParamLists(fn.recvtypeparams, fn.typeparams)
+}
+
+func consTypeParamLists(l, r *types.TypeParamList) *types.TypeParamList {
+	if l.Len() == 0 {
+		return r
+	}
+	if r.Len() == 0 {
+		return l
+	}
+
+	tpars := make([]*types.TypeParam, l.Len()+r.Len())
+	for i := range l.Len() {
+		tpars[i] = l.At(i)
+	}
+	for i := range r.Len() {
+		tpars[i+l.Len()] = r.At(i)
+	}
+	// This logic unsafely assumes (and asserts) that the layout of the
+	// TypeParamList is identical to that of a slice of TypeParams. This
+	// is a hack while we work on getting a constructor for TypeParamList
+	// approved (see go.dev/issue/79603).
+	t := reflect.TypeFor[types.TypeParamList]()
+	if t.NumField() != 1 {
+		panic("TypeParamList has unexpected fields")
+	}
+	if f := t.Field(0); f.Offset != 0 || f.Type != reflect.TypeFor[[]*types.TypeParam]() {
+		panic("TypeParamList field is not []*TypeParam")
+	}
+	return (*types.TypeParamList)(unsafe.Pointer(&tpars))
+}
+
+// TypeArgs are the types that TypeParams() were instantiated by to create fn
+// from fn.Origin().
+//
+// Specifically, the resulting slice behaves like:
+//
+//	f                   // []
+//	f[int]              // [int]
+//	T.m                 // []
+//	T.m[int]            // [int]
+//	T[int].m            // [int]
+//	T[int].m[uint]      // [int, uint]
+//
+// Note that receiver type arguments precede other type arguments.
+func (fn *Function) TypeArgs() []types.Type {
+	return slices.Concat(fn.recvtypeargs, fn.typeargs)
+}
+
+// Origin returns the generic function from which fn was instantiated,
+// or nil if fn is not an instantiation.
+func (fn *Function) Origin() *Function {
+	if fn.parent != nil && fn.parent.hasTypeArgs() {
+		// Nested functions are BUILT at a different time than their instances.
+		// Build declared package if not yet BUILT. This is not an expected use
+		// case, but is simple and robust.
+		fn.declaredPackage().Build()
+	}
+	return origin(fn)
+}
+
+// hasTypeParams returns whether fn has any type parameters
+func (fn *Function) hasTypeParams() bool {
+	return fn.recvtypeparams.Len()+fn.typeparams.Len() > 0
+}
+
+// hasTypeArgs returns whether fn has any type arguments
+func (fn *Function) hasTypeArgs() bool {
+	return len(fn.recvtypeargs)+len(fn.typeargs) > 0
+}
+
+// subrtargs returns fn's receiver type parameters substituted with receiver type arguments
+func (fn *Function) subrtargs(m *types.Func) []types.Type {
+	return fn.subst.types(receiverTypeArgs(m))
+}
+
+// subtargs returns fn's type parameters substituted with (possibly implied) type arguments
+func (fn *Function) subtargs(id *ast.Ident) []types.Type {
+	return fn.subst.types(instanceArgs(fn.info, id))
+}
+
+// targstr returns a comma-separated string of the types in targs
+func targstr(targs []types.Type) string {
+	var sb strings.Builder
+	if len(targs) > 0 {
+		sb.WriteString("[")
+		for i := range targs {
+			if i > 0 {
+				sb.WriteString(", ")
+			}
+			sb.WriteString(targs[i].String())
+		}
+		sb.WriteString("]")
+	}
+	return sb.String()
+}
+
+// origin is the function that fn is an instantiation of. Returns nil if fn is
+// not an instantiation.
+//
+// Precondition: fn and the origin function are done building.
+func origin(fn *Function) *Function {
+	if fn.parent != nil && fn.parent.hasTypeArgs() {
+		return origin(fn.parent).AnonFuncs[fn.anonIdx]
+	}
+	return fn.topLevelOrigin
+}
+
+func (v *Alloc) Type() types.Type          { return v.typ }
+func (v *Alloc) Referrers() *[]Instruction { return &v.referrers }
+
+func (v *register) Type() types.Type          { return v.typ }
+func (v *register) setType(typ types.Type)    { v.typ = typ }
+func (v *register) Name() string              { return fmt.Sprintf("t%d", v.id) }
+func (v *register) Referrers() *[]Instruction { return &v.referrers }
+
+func (v *anInstruction) Parent() *Function          { return v.block.parent }
+func (v *anInstruction) Block() *BasicBlock         { return v.block }
+func (v *anInstruction) setBlock(block *BasicBlock) { v.block = block }
+func (v *anInstruction) Referrers() *[]Instruction  { return nil }
+
+func (t *Type) Name() string                         { return t.object.Name() }
+func (t *Type) Pos() token.Pos                       { return t.object.Pos() }
+func (t *Type) Type() types.Type                     { return t.object.Type() }
+func (t *Type) Token() token.Token                   { return token.TYPE }
+func (t *Type) Object() types.Object                 { return t.object }
+func (t *Type) String() string                       { return t.RelString(nil) }
+func (t *Type) Package() *Package                    { return t.pkg }
+func (t *Type) RelString(from *types.Package) string { return relString(t, from) }
+
+func (c *NamedConst) Name() string                         { return c.object.Name() }
+func (c *NamedConst) Pos() token.Pos                       { return c.object.Pos() }
+func (c *NamedConst) String() string                       { return c.RelString(nil) }
+func (c *NamedConst) Type() types.Type                     { return c.object.Type() }
+func (c *NamedConst) Token() token.Token                   { return token.CONST }
+func (c *NamedConst) Object() types.Object                 { return c.object }
+func (c *NamedConst) Package() *Package                    { return c.pkg }
+func (c *NamedConst) RelString(from *types.Package) string { return relString(c, from) }
+
+func (v *Function) Pos() token.Pos   { return v.pos }
+func (v *Function) Source() ast.Node { return v.syntax }
+
+func (d *debugRef) Object() types.Object { return d.object }
+
+// Func returns the package-level function of the specified name,
+// or nil if not found.
+func (p *Package) Func(name string) (f *Function) {
+	f, _ = p.Members[name].(*Function)
+	return
+}
+
+// Var returns the package-level variable of the specified name,
+// or nil if not found.
+func (p *Package) Var(name string) (g *Global) {
+	g, _ = p.Members[name].(*Global)
+	return
+}
+
+// Const returns the package-level constant of the specified name,
+// or nil if not found.
+func (p *Package) Const(name string) (c *NamedConst) {
+	c, _ = p.Members[name].(*NamedConst)
+	return
+}
+
+// Type returns the package-level type of the specified name,
+// or nil if not found.
+func (p *Package) Type(name string) (t *Type) {
+	t, _ = p.Members[name].(*Type)
+	return
+}
+
+func (s *debugRef) Pos() token.Pos { return s.Expr.Pos() }
+
+// Operands.
+
+func (v *Alloc) Operands(rands []*Value) []*Value {
+	return rands
+}
+
+func (v *BinOp) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X, &v.Y)
+}
+
+func (c *CallCommon) Operands(rands []*Value) []*Value {
+	rands = append(rands, &c.Value)
+	for i := range c.Args {
+		rands = append(rands, &c.Args[i])
+	}
+	return rands
+}
+
+func (s *Go) Operands(rands []*Value) []*Value {
+	return s.Call.Operands(rands)
+}
+
+func (s *Call) Operands(rands []*Value) []*Value {
+	return s.Call.Operands(rands)
+}
+
+func (s *Defer) Operands(rands []*Value) []*Value {
+	return append(s.Call.Operands(rands), &s.DeferStack)
+}
+
+func (v *ChangeInterface) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (v *ChangeType) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (v *Convert) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (v *MultiConvert) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (v *SliceToArrayPointer) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (v *SliceToArray) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (s *debugRef) Operands(rands []*Value) []*Value {
+	return append(rands, &s.X)
+}
+
+func (v *Extract) Operands(rands []*Value) []*Value {
+	return append(rands, &v.Tuple)
+}
+
+func (v *Field) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (v *FieldAddr) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (s *If) Operands(rands []*Value) []*Value {
+	return append(rands, &s.Cond)
+}
+
+func (s *ConstantSwitch) Operands(rands []*Value) []*Value {
+	rands = append(rands, &s.Tag)
+	for i := range s.Conds {
+		rands = append(rands, &s.Conds[i])
+	}
+	return rands
+}
+
+func (s *TypeSwitch) Operands(rands []*Value) []*Value {
+	rands = append(rands, &s.Tag)
+	return rands
+}
+
+func (v *Index) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X, &v.Index)
+}
+
+func (v *IndexAddr) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X, &v.Index)
+}
+
+func (*Jump) Operands(rands []*Value) []*Value {
+	return rands
+}
+
+func (*Unreachable) Operands(rands []*Value) []*Value {
+	return rands
+}
+
+func (v *MapLookup) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X, &v.Index)
+}
+
+func (v *StringLookup) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X, &v.Index)
+}
+
+func (v *MakeChan) Operands(rands []*Value) []*Value {
+	return append(rands, &v.Size)
+}
+
+func (v *MakeClosure) Operands(rands []*Value) []*Value {
+	rands = append(rands, &v.Fn)
+	for i := range v.Bindings {
+		rands = append(rands, &v.Bindings[i])
+	}
+	return rands
+}
+
+func (v *MakeInterface) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (v *MakeMap) Operands(rands []*Value) []*Value {
+	return append(rands, &v.Reserve)
+}
+
+func (v *MakeSlice) Operands(rands []*Value) []*Value {
+	return append(rands, &v.Len, &v.Cap)
+}
+
+func (v *MapUpdate) Operands(rands []*Value) []*Value {
+	return append(rands, &v.Map, &v.Key, &v.Value)
+}
+
+func (v *Next) Operands(rands []*Value) []*Value {
+	return append(rands, &v.Iter)
+}
+
+func (s *Panic) Operands(rands []*Value) []*Value {
+	return append(rands, &s.X)
+}
+
+func (v *Phi) Operands(rands []*Value) []*Value {
+	for i := range v.Edges {
+		rands = append(rands, &v.Edges[i])
+	}
+	return rands
+}
+
+func (v *Range) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (s *Return) Operands(rands []*Value) []*Value {
+	for i := range s.Results {
+		rands = append(rands, &s.Results[i])
+	}
+	return rands
+}
+
+func (*RunDefers) Operands(rands []*Value) []*Value {
+	return rands
+}
+
+func (v *Select) Operands(rands []*Value) []*Value {
+	for i := range v.States {
+		rands = append(rands, &v.States[i].Chan, &v.States[i].Send)
+	}
+	return rands
+}
+
+func (s *Send) Operands(rands []*Value) []*Value {
+	return append(rands, &s.Chan, &s.X)
+}
+
+func (recv *Recv) Operands(rands []*Value) []*Value {
+	return append(rands, &recv.Chan)
+}
+
+func (v *Slice) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X, &v.Low, &v.High, &v.Max)
+}
+
+func (s *Store) Operands(rands []*Value) []*Value {
+	return append(rands, &s.Addr, &s.Val)
+}
+
+func (s *BlankStore) Operands(rands []*Value) []*Value {
+	return append(rands, &s.Val)
+}
+
+func (v *TypeAssert) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (v *UnOp) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (v *Load) Operands(rands []*Value) []*Value {
+	return append(rands, &v.X)
+}
+
+func (v *AggregateConst) Operands(rands []*Value) []*Value {
+	for i := range v.Values {
+		rands = append(rands, &v.Values[i])
+	}
+	return rands
+}
+
+func (v *CompositeValue) Operands(rands []*Value) []*Value {
+	for i := range v.Values {
+		rands = append(rands, &v.Values[i])
+	}
+	return rands
+}
+
+// Non-Instruction Values:
+func (v *Builtin) Operands(rands []*Value) []*Value   { return rands }
+func (v *FreeVar) Operands(rands []*Value) []*Value   { return rands }
+func (v *Const) Operands(rands []*Value) []*Value     { return rands }
+func (v *Function) Operands(rands []*Value) []*Value  { return rands }
+func (v *Global) Operands(rands []*Value) []*Value    { return rands }
+func (v *Parameter) Operands(rands []*Value) []*Value { return rands }
diff --git a/vendor/honnef.co/go/tools/go/ir/subst.go b/vendor/honnef.co/go/tools/go/ir/subst.go
new file mode 100644
index 0000000..07b636a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/subst.go
@@ -0,0 +1,577 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/xtools-internal/aliases"
+)
+
+// subster defines a type substitution operation of a set of type parameters
+// to type parameter free replacement types. Substitution is done within
+// the context of a package-level function instantiation. *Named types
+// declared in the function are unique to the instantiation.
+//
+// For example, given a parameterized function F
+//
+//	  func F[S, T any]() any {
+//	    type X struct{ s S; next *X }
+//		var p *X
+//	    return p
+//	  }
+//
+// calling the instantiation F[string, int]() returns an interface
+// value (*X[string,int], nil) where the underlying value of
+// X[string,int] is a struct{s string; next *X[string,int]}.
+//
+// A nil *subster is a valid, empty substitution map. It always acts as
+// the identity function. This allows for treating parameterized and
+// non-parameterized functions identically while compiling to ssa.
+//
+// Not concurrency-safe.
+//
+// Note: Some may find it helpful to think through some of the most
+// complex substitution cases using lambda calculus inspired notation.
+// subst.typ() solves evaluating a type expression E
+// within the body of a function Fn[m] with the type parameters m
+// once we have applied the type arguments N.
+// We can succinctly write this as a function application:
+//
+//	((λm. E) N)
+//
+// go/types does not provide this interface directly.
+// So what subster provides is a type substitution operation
+//
+//	E[m:=N]
+type subster struct {
+	replacements map[*types.TypeParam]types.Type // values should contain no type params
+	cache        map[types.Type]types.Type       // cache of subst results
+	origin       *types.Func                     // types.Objects declared within this origin function are unique within this context
+	ctxt         *types.Context                  // speeds up repeated instantiations
+	uniqueness   typeutil.Map[types.Type]        // determines the uniqueness of the instantiations within the function
+	// TODO(taking): consider adding Pos
+}
+
+// Returns a subster that replaces rtparams[i] with rtargs[i] and tparams[i] with targs[i].
+// Uses ctxt as a cache. rtargs and targs should not contain any types in rtparams or tparams.
+// fn is the generic function for which we are substituting.
+func makeSubster(ctxt *types.Context, fn *types.Func, rtparams *types.TypeParamList, rtargs []types.Type, tparams *types.TypeParamList, targs []types.Type) *subster {
+	got := len(rtargs) + len(targs)
+	want := rtparams.Len() + tparams.Len()
+	if got != want {
+		panic(fmt.Sprintf("makeSubster argument count must match: got %d; want %d", got, want))
+	}
+
+	subst := &subster{
+		replacements: make(map[*types.TypeParam]types.Type, want),
+		cache:        make(map[types.Type]types.Type),
+		origin:       fn.Origin(),
+		ctxt:         ctxt,
+	}
+	for i := 0; i < rtparams.Len(); i++ {
+		subst.replacements[rtparams.At(i)] = rtargs[i]
+	}
+	for i := 0; i < tparams.Len(); i++ {
+		subst.replacements[tparams.At(i)] = targs[i]
+	}
+	return subst
+}
+
+// typ returns the type of t with the type parameter tparams[i] substituted
+// for the type targs[i] where subst was created using tparams and targs.
+func (subst *subster) typ(t types.Type) (res types.Type) {
+	if subst == nil {
+		return t // A nil subst is type preserving.
+	}
+	if r, ok := subst.cache[t]; ok {
+		return r
+	}
+	defer func() {
+		subst.cache[t] = res
+	}()
+
+	switch t := t.(type) {
+	case *types.TypeParam:
+		if r := subst.replacements[t]; r != nil {
+			return r
+		}
+		return t
+
+	case *types.Basic:
+		return t
+
+	case *types.Array:
+		if r := subst.typ(t.Elem()); r != t.Elem() {
+			return types.NewArray(r, t.Len())
+		}
+		return t
+
+	case *types.Slice:
+		if r := subst.typ(t.Elem()); r != t.Elem() {
+			return types.NewSlice(r)
+		}
+		return t
+
+	case *types.Pointer:
+		if r := subst.typ(t.Elem()); r != t.Elem() {
+			return types.NewPointer(r)
+		}
+		return t
+
+	case *types.Tuple:
+		return subst.tuple(t)
+
+	case *types.Struct:
+		return subst.struct_(t)
+
+	case *types.Map:
+		key := subst.typ(t.Key())
+		elem := subst.typ(t.Elem())
+		if key != t.Key() || elem != t.Elem() {
+			return types.NewMap(key, elem)
+		}
+		return t
+
+	case *types.Chan:
+		if elem := subst.typ(t.Elem()); elem != t.Elem() {
+			return types.NewChan(t.Dir(), elem)
+		}
+		return t
+
+	case *types.Signature:
+		return subst.signature(t)
+
+	case *types.Union:
+		return subst.union(t)
+
+	case *types.Interface:
+		return subst.interface_(t)
+
+	case *types.Alias:
+		return subst.alias(t)
+
+	case *types.Named:
+		return subst.named(t)
+
+	case *typeutil.Iterator:
+		elem := subst.typ(t.Elem())
+		if elem != t.Elem() {
+			return typeutil.NewIterator(elem)
+		}
+		return t
+
+	case *typeutil.DeferStack:
+		return t
+
+	default:
+		panic(fmt.Sprintf("internal error: unhandled type %T", t))
+	}
+}
+
+// types returns the result of {subst.typ(ts[i])}.
+func (subst *subster) types(ts []types.Type) []types.Type {
+	res := make([]types.Type, len(ts))
+	for i := range ts {
+		res[i] = subst.typ(ts[i])
+	}
+	return res
+}
+
+func (subst *subster) tuple(t *types.Tuple) *types.Tuple {
+	if t != nil {
+		if vars := subst.varlist(t); vars != nil {
+			return types.NewTuple(vars...)
+		}
+	}
+	return t
+}
+
+type varlist interface {
+	At(i int) *types.Var
+	Len() int
+}
+
+// fieldlist is an adapter for structs for the varlist interface.
+type fieldlist struct {
+	str *types.Struct
+}
+
+func (fl fieldlist) At(i int) *types.Var { return fl.str.Field(i) }
+func (fl fieldlist) Len() int            { return fl.str.NumFields() }
+
+func (subst *subster) struct_(t *types.Struct) *types.Struct {
+	if t != nil {
+		if fields := subst.varlist(fieldlist{t}); fields != nil {
+			tags := make([]string, t.NumFields())
+			for i, n := 0, t.NumFields(); i < n; i++ {
+				tags[i] = t.Tag(i)
+			}
+			return types.NewStruct(fields, tags)
+		}
+	}
+	return t
+}
+
+// varlist returns subst(in[i]) or return nils if subst(v[i]) == v[i] for all i.
+func (subst *subster) varlist(in varlist) []*types.Var {
+	var out []*types.Var // nil => no updates
+	for i, n := 0, in.Len(); i < n; i++ {
+		v := in.At(i)
+		w := subst.var_(v)
+		if v != w && out == nil {
+			out = make([]*types.Var, n)
+			for j := 0; j < i; j++ {
+				out[j] = in.At(j)
+			}
+		}
+		if out != nil {
+			out[i] = w
+		}
+	}
+	return out
+}
+
+func (subst *subster) var_(v *types.Var) *types.Var {
+	if v != nil {
+		if typ := subst.typ(v.Type()); typ != v.Type() {
+			if v.IsField() {
+				return types.NewField(v.Pos(), v.Pkg(), v.Name(), typ, v.Embedded())
+			}
+			return types.NewParam(v.Pos(), v.Pkg(), v.Name(), typ)
+		}
+	}
+	return v
+}
+
+func (subst *subster) union(u *types.Union) *types.Union {
+	var out []*types.Term // nil => no updates
+
+	for i, n := 0, u.Len(); i < n; i++ {
+		t := u.Term(i)
+		r := subst.typ(t.Type())
+		if r != t.Type() && out == nil {
+			out = make([]*types.Term, n)
+			for j := 0; j < i; j++ {
+				out[j] = u.Term(j)
+			}
+		}
+		if out != nil {
+			out[i] = types.NewTerm(t.Tilde(), r)
+		}
+	}
+
+	if out != nil {
+		return types.NewUnion(out)
+	}
+	return u
+}
+
+func (subst *subster) interface_(iface *types.Interface) *types.Interface {
+	if iface == nil {
+		return nil
+	}
+
+	// methods for the interface. Initially nil if there is no known change needed.
+	// Signatures for the method where recv is nil. NewInterfaceType fills in the receivers.
+	var methods []*types.Func
+	initMethods := func(n int) { // copy first n explicit methods
+		methods = make([]*types.Func, iface.NumExplicitMethods())
+		for i := range n {
+			f := iface.ExplicitMethod(i)
+			norecv := changeRecv(f.Type().(*types.Signature), nil)
+			methods[i] = types.NewFunc(f.Pos(), f.Pkg(), f.Name(), norecv)
+		}
+	}
+	for i := 0; i < iface.NumExplicitMethods(); i++ {
+		f := iface.ExplicitMethod(i)
+		// On interfaces, we need to cycle break on anonymous interface types
+		// being in a cycle with their signatures being in cycles with their receivers
+		// that do not go through a Named.
+		norecv := changeRecv(f.Type().(*types.Signature), nil)
+		sig := subst.typ(norecv)
+		if sig != norecv && methods == nil {
+			initMethods(i)
+		}
+		if methods != nil {
+			methods[i] = types.NewFunc(f.Pos(), f.Pkg(), f.Name(), sig.(*types.Signature))
+		}
+	}
+
+	var embeds []types.Type
+	initEmbeds := func(n int) { // copy first n embedded types
+		embeds = make([]types.Type, iface.NumEmbeddeds())
+		for i := range n {
+			embeds[i] = iface.EmbeddedType(i)
+		}
+	}
+	for i := 0; i < iface.NumEmbeddeds(); i++ {
+		e := iface.EmbeddedType(i)
+		r := subst.typ(e)
+		if e != r && embeds == nil {
+			initEmbeds(i)
+		}
+		if embeds != nil {
+			embeds[i] = r
+		}
+	}
+
+	if methods == nil && embeds == nil {
+		return iface
+	}
+	if methods == nil {
+		initMethods(iface.NumExplicitMethods())
+	}
+	if embeds == nil {
+		initEmbeds(iface.NumEmbeddeds())
+	}
+	return types.NewInterfaceType(methods, embeds).Complete()
+}
+
+func (subst *subster) alias(t *types.Alias) types.Type {
+	// See subster.named. This follows the same strategy.
+	tparams := t.TypeParams()
+	targs := t.TypeArgs()
+	tname := t.Obj()
+	torigin := t.Origin()
+
+	if !declaredWithin(tname, subst.origin) {
+		// t is declared outside of the function origin. So t is a package level type alias.
+		if targs.Len() == 0 {
+			// No type arguments so no instantiation needed.
+			return t
+		}
+
+		// Instantiate with the substituted type arguments.
+		newTArgs := subst.typelist(targs)
+		return subst.instantiate(torigin, newTArgs)
+	}
+
+	if targs.Len() == 0 {
+		// t is declared within the function origin and has no type arguments.
+		//
+		// Example: This corresponds to A or B in F, but not A[int]:
+		//
+		//     func F[T any]() {
+		//       type A[S any] = struct{t T, s S}
+		//       type B = T
+		//       var x A[int]
+		//       ...
+		//     }
+		//
+		// This is somewhat different than *Named as *Alias cannot be created recursively.
+
+		// Copy and substitute type params.
+		var newTParams []*types.TypeParam
+		for cur := range tparams.TypeParams() {
+			cobj := cur.Obj()
+			cname := types.NewTypeName(cobj.Pos(), cobj.Pkg(), cobj.Name(), nil)
+			ntp := types.NewTypeParam(cname, nil)
+			subst.cache[cur] = ntp // See the comment "Note: Subtle" in subster.named.
+			newTParams = append(newTParams, ntp)
+		}
+
+		// Substitute rhs.
+		rhs := subst.typ(t.Rhs())
+
+		// Create the fresh alias.
+		obj := aliases.New(tname.Pos(), tname.Pkg(), tname.Name(), rhs, newTParams)
+
+		// Substitute into all of the constraints after they are created.
+		for i, ntp := range newTParams {
+			bound := tparams.At(i).Constraint()
+			ntp.SetConstraint(subst.typ(bound))
+		}
+		return obj.Type()
+	}
+
+	// t is declared within the function origin and has type arguments.
+	//
+	// Example: This corresponds to A[int] in F. Cases A and B are handled above.
+	//     func F[T any]() {
+	//       type A[S any] = struct{t T, s S}
+	//       type B = T
+	//       var x A[int]
+	//       ...
+	//     }
+	subOrigin := subst.typ(torigin)
+	subTArgs := subst.typelist(targs)
+	return subst.instantiate(subOrigin, subTArgs)
+}
+
+func (subst *subster) named(t *types.Named) types.Type {
+	// A Named type is a user defined type.
+	// Ignoring generics, Named types are canonical: they are identical if
+	// and only if they have the same defining symbol.
+	// Generics complicate things, both if the type definition itself is
+	// parameterized, and if the type is defined within the scope of a
+	// parameterized function. In this case, two named types are identical if
+	// and only if their identifying symbols are identical, and all type
+	// arguments bindings in scope of the named type definition (including the
+	// type parameters of the definition itself) are equivalent.
+	//
+	// Notably:
+	// 1. For type definition type T[P1 any] struct{}, T[A] and T[B] are identical
+	//    only if A and B are identical.
+	// 2. Inside the generic func Fn[m any]() any { type T struct{}; return T{} },
+	//    the result of Fn[A] and Fn[B] have identical type if and only if A and
+	//    B are identical.
+	// 3. Both 1 and 2 could apply, such as in
+	//    func F[m any]() any { type T[x any] struct{}; return T{} }
+	//
+	// A subster replaces type parameters within a function scope, and therefore must
+	// also replace free type parameters in the definitions of local types.
+	//
+	// Note: There are some detailed notes sprinkled throughout that borrow from
+	// lambda calculus notation. These contain some over simplifying math.
+	//
+	// LC: One way to think about subster is that it is  a way of evaluating
+	//   ((λm. E) N) as E[m:=N].
+	// Each Named type t has an object *TypeName within a scope S that binds an
+	// underlying type expression U. U can refer to symbols within S (+ S's ancestors).
+	// Let x = t.TypeParams() and A = t.TypeArgs().
+	// Each Named type t is then either:
+	//   U              where len(x) == 0 && len(A) == 0
+	//   λx. U          where len(x) != 0 && len(A) == 0
+	//   ((λx. U) A)    where len(x) == len(A)
+	// In each case, we will evaluate t[m:=N].
+	tparams := t.TypeParams() // x
+	targs := t.TypeArgs()     // A
+
+	if !declaredWithin(t.Obj(), subst.origin) {
+		// t is declared outside of Fn[m].
+		//
+		// In this case, we can skip substituting t.Underlying().
+		// The underlying type cannot refer to the type parameters.
+		//
+		// LC: Let free(E) be the set of free type parameters in an expression E.
+		// Then whenever m ∉ free(E), then E = E[m:=N].
+		// t ∉ Scope(fn) so therefore m ∉ free(U) and m ∩ x = ∅.
+		if targs.Len() == 0 {
+			// t has no type arguments. So it does not need to be instantiated.
+			//
+			// This is the normal case in real Go code, where t is not parameterized,
+			// declared at some package scope, and m is a TypeParam from a parameterized
+			// function F[m] or method.
+			//
+			// LC: m ∉ free(A) lets us conclude m ∉ free(t). So t=t[m:=N].
+			return t
+		}
+
+		// t is declared outside of Fn[m] and has type arguments.
+		// The type arguments may contain type parameters m so
+		// substitute the type arguments, and instantiate the substituted
+		// type arguments.
+		//
+		// LC: Evaluate this as ((λx. U) A') where A' = A[m := N].
+		newTArgs := subst.typelist(targs)
+		return subst.instantiate(t.Origin(), newTArgs)
+	}
+
+	// t is declared within Fn[m].
+
+	if targs.Len() == 0 { // no type arguments?
+		assert(t == t.Origin(), "local parameterized type abstraction must be an origin type")
+
+		// t has no type arguments.
+		// The underlying type of t may contain the function's type parameters,
+		// replace these, and create a new type.
+		//
+		// Subtle: We short circuit substitution and use a newly created type in
+		// subst, i.e. cache[t]=fresh, to preemptively replace t with fresh
+		// in recursive types during traversal. This both breaks infinite cycles
+		// and allows for constructing types with the replacement applied in
+		// subst.typ(U).
+		//
+		// A new copy of the Named and Typename (and constraints) per function
+		// instantiation matches the semantics of Go, which treats all function
+		// instantiations F[N] as having distinct local types.
+		//
+		// LC: x.Len()=0 can be thought of as a special case of λx. U.
+		// LC: Evaluate (λx. U)[m:=N] as (λx'. U') where U'=U[x:=x',m:=N].
+		tname := t.Obj()
+		obj := types.NewTypeName(tname.Pos(), tname.Pkg(), tname.Name(), nil)
+		fresh := types.NewNamed(obj, nil, nil)
+		var newTParams []*types.TypeParam
+		for cur := range tparams.TypeParams() {
+			cobj := cur.Obj()
+			cname := types.NewTypeName(cobj.Pos(), cobj.Pkg(), cobj.Name(), nil)
+			ntp := types.NewTypeParam(cname, nil)
+			subst.cache[cur] = ntp
+			newTParams = append(newTParams, ntp)
+		}
+		fresh.SetTypeParams(newTParams)
+		subst.cache[t] = fresh
+		subst.cache[fresh] = fresh
+		fresh.SetUnderlying(subst.typ(t.Underlying()))
+		// Substitute into all of the constraints after they are created.
+		for i, ntp := range newTParams {
+			bound := tparams.At(i).Constraint()
+			ntp.SetConstraint(subst.typ(bound))
+		}
+		return fresh
+	}
+
+	// t is defined within Fn[m] and t has type arguments (an instantiation).
+	// We reduce this to the two cases above:
+	// (1) substitute the function's type parameters into t.Origin().
+	// (2) substitute t's type arguments A and instantiate the updated t.Origin() with these.
+	//
+	// LC: Evaluate ((λx. U) A)[m:=N] as (t' A') where t' = (λx. U)[m:=N] and A'=A [m:=N]
+	subOrigin := subst.typ(t.Origin())
+	subTArgs := subst.typelist(targs)
+	return subst.instantiate(subOrigin, subTArgs)
+}
+
+func (subst *subster) instantiate(orig types.Type, targs []types.Type) types.Type {
+	i, err := types.Instantiate(subst.ctxt, orig, targs, false)
+	assert(err == nil, "failed to Instantiate named (Named or Alias) type")
+	if c, _ := subst.uniqueness.At(i); c != nil {
+		return c
+	}
+	subst.uniqueness.Set(i, i)
+	return i
+}
+
+func (subst *subster) typelist(l *types.TypeList) []types.Type {
+	res := make([]types.Type, l.Len())
+	for i := 0; i < l.Len(); i++ {
+		res[i] = subst.typ(l.At(i))
+	}
+	return res
+}
+
+func (subst *subster) signature(t *types.Signature) types.Type {
+	tparams := t.TypeParams()
+
+	// We are choosing not to support tparams.Len() > 0 until a need has been observed in practice.
+	//
+	// There are some known usages for types.Types coming from types.{Eval,CheckExpr}.
+	// To support tparams.Len() > 0, we just need to do the following [pseudocode]:
+	//   targs := {subst.replacements[tparams[i]]]}; Instantiate(ctxt, t, targs, false)
+
+	assert(tparams.Len() == 0, "Substituting types.Signatures with generic functions are currently unsupported.")
+
+	// Either:
+	// (1)non-generic function.
+	//    no type params to substitute
+	// (2)generic method and recv needs to be substituted.
+
+	// Receivers can be either:
+	// named
+	// pointer to named
+	// interface
+	// nil
+	// interface is the problematic case. We need to cycle break there!
+	recv := subst.var_(t.Recv())
+	params := subst.tuple(t.Params())
+	results := subst.tuple(t.Results())
+	if recv != t.Recv() || params != t.Params() || results != t.Results() {
+		return types.NewSignatureType(recv, nil, nil, params, results, t.Variadic())
+	}
+	return t
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/task.go b/vendor/honnef.co/go/tools/go/ir/task.go
new file mode 100644
index 0000000..eaf19a0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/task.go
@@ -0,0 +1,103 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"sync/atomic"
+)
+
+// Each task has two states: it is initially "active",
+// and transitions to "done".
+//
+// tasks form a directed graph. An edge from x to y (with y in x.edges)
+// indicates that the task x waits on the task y to be done.
+// Cycles are permitted.
+//
+// Calling x.wait() blocks the calling goroutine until task x,
+// and all the tasks transitively reachable from x are done.
+//
+// The nil *task is always considered done.
+type task struct {
+	done       chan unit      // close when the task is done.
+	edges      map[*task]unit // set of predecessors of this task.
+	transitive atomic.Bool    // true once it is known all predecessors are done.
+}
+
+func (x *task) isTransitivelyDone() bool { return x == nil || x.transitive.Load() }
+
+// addEdge creates an edge from x to y, indicating that
+// x.wait() will not return before y is done.
+// All calls to x.addEdge(...) should happen before x.markDone().
+func (x *task) addEdge(y *task) {
+	if x == y || y.isTransitivelyDone() {
+		return // no work remaining
+	}
+
+	// heuristic done check
+	select {
+	case <-x.done:
+		panic("cannot add an edge to a done task")
+	default:
+	}
+
+	if x.edges == nil {
+		x.edges = make(map[*task]unit)
+	}
+	x.edges[y] = unit{}
+}
+
+// markDone changes the task's state to markDone.
+func (x *task) markDone() {
+	if x != nil {
+		close(x.done)
+	}
+}
+
+// wait blocks until x and all the tasks it can reach through edges are done.
+func (x *task) wait() {
+	if x.isTransitivelyDone() {
+		return // already known to be done. Skip allocations.
+	}
+
+	// Use BFS to wait on u.done to be closed, for all u transitively
+	// reachable from x via edges.
+	//
+	// This work can be repeated by multiple workers doing wait().
+	//
+	// Note: Tarjan's SCC algorithm is able to mark SCCs as transitively done
+	// as soon as the SCC has been visited. This is theoretically faster, but is
+	// a more complex algorithm. Until we have evidence, we need the more complex
+	// algorithm, the simpler algorithm BFS is implemented.
+	//
+	// In Go 1.23, ssa/TestStdlib reaches <=3 *tasks per wait() in most schedules
+	// On some schedules, there is a cycle building net/http and internal/trace/testtrace
+	// due to slices functions.
+	work := []*task{x}
+	enqueued := map[*task]unit{x: {}}
+	for i := 0; i < len(work); i++ {
+		u := work[i]
+		if u.isTransitivelyDone() { // already transitively done
+			work[i] = nil
+			continue
+		}
+		<-u.done // wait for u to be marked done.
+
+		for v := range u.edges {
+			if _, ok := enqueued[v]; !ok {
+				enqueued[v] = unit{}
+				work = append(work, v)
+			}
+		}
+	}
+
+	// work is transitively closed over dependencies.
+	// u in work is done (or transitively done and skipped).
+	// u is transitively done.
+	for _, u := range work {
+		if u != nil {
+			u.transitive.Store(true)
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/typeset.go b/vendor/honnef.co/go/tools/go/ir/typeset.go
new file mode 100644
index 0000000..6154e4f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/typeset.go
@@ -0,0 +1,175 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"go/types"
+
+	"honnef.co/go/tools/go/types/typeutil"
+)
+
+// Utilities for dealing with type sets.
+
+const debug = false
+
+// typeset is an iterator over the (type/underlying type) pairs of the
+// specific type terms of the type set implied by t.
+// If t is a type parameter, the implied type set is the type set of t's constraint.
+// In that case, if there are no specific terms, typeset calls yield with (nil, nil).
+// If t is not a type parameter, the implied type set consists of just t.
+// In any case, typeset is guaranteed to call yield at least once.
+func typeset(typ types.Type, yield func(t, u types.Type) bool) {
+	switch typ := types.Unalias(typ).(type) {
+	case *types.TypeParam, *types.Interface:
+		terms := termListOf(typ)
+		if len(terms) == 0 {
+			yield(nil, nil)
+			return
+		}
+		for _, term := range terms {
+			u := types.Unalias(term.Type())
+			if !term.Tilde() {
+				u = u.Underlying()
+			}
+			if debug {
+				assert(types.Identical(u, u.Underlying()), "Unalias(x) == under(x) for ~x terms")
+			}
+			if !yield(term.Type(), u) {
+				break
+			}
+		}
+		return
+	default:
+		yield(typ, typ.Underlying())
+	}
+}
+
+// termListOf returns the type set of typ as a normalized term set. Returns an empty set on an error.
+func termListOf(typ types.Type) []*types.Term {
+	return typeutil.NewTypeSet(typ).Terms
+}
+
+// typeSetIsEmpty returns true if a typeset is empty.
+func typeSetIsEmpty(typ types.Type) bool {
+	var empty bool
+	typeset(typ, func(t, _ types.Type) bool {
+		empty = t == nil
+		return false
+	})
+	return empty
+}
+
+// isBytestring returns true if T has the same terms as interface{[]byte | string}.
+// These act like a core type for some operations: slice expressions, append and copy.
+//
+// See https://go.dev/ref/spec#Core_types for the details on bytestring.
+func isBytestring(T types.Type) bool {
+	U := T.Underlying()
+	if _, ok := U.(*types.Interface); !ok {
+		return false
+	}
+
+	hasBytes, hasString := false, false
+	ok := underIs(U, func(t types.Type) bool {
+		switch {
+		case isString(t):
+			hasString = true
+			return true
+		case isByteSlice(t):
+			hasBytes = true
+			return true
+		default:
+			return false
+		}
+	})
+	return ok && hasBytes && hasString
+}
+
+// underIs calls f with the underlying types of the type terms
+// of the type set of typ and reports whether all calls to f returned true.
+// If there are no specific terms, underIs returns the result of f(nil).
+func underIs(typ types.Type, f func(types.Type) bool) bool {
+	var ok bool
+	typeset(typ, func(t, u types.Type) bool {
+		ok = f(u)
+		return ok
+	})
+	return ok
+}
+
+// indexType returns the element type and index mode of a IndexExpr over a type.
+// It returns an invalid mode if the type is not indexable; this should never occur in a well-typed program.
+func indexType(typ types.Type) (types.Type, indexMode) {
+	switch U := typ.Underlying().(type) {
+	case *types.Array:
+		return U.Elem(), ixArrVar
+	case *types.Pointer:
+		if arr, ok := U.Elem().Underlying().(*types.Array); ok {
+			return arr.Elem(), ixVar
+		}
+	case *types.Slice:
+		return U.Elem(), ixVar
+	case *types.Map:
+		return U.Elem(), ixMap
+	case *types.Basic:
+		return tByte, ixValue // must be a string
+	case *types.Interface:
+		var elem types.Type
+		mode := ixInvalid
+		typeset(typ, func(t, _ types.Type) bool {
+			if t == nil {
+				return false // empty set
+			}
+			e, m := indexType(t)
+			if elem == nil {
+				elem, mode = e, m
+			}
+			if debug && !types.Identical(elem, e) { // if type checked, just a sanity check
+				mode = ixInvalid
+				return false
+			}
+			// Update the mode to the most constrained address type.
+			mode = mode.meet(m)
+			return mode != ixInvalid
+		})
+		return elem, mode
+	}
+	return nil, ixInvalid
+}
+
+// An indexMode specifies the (addressing) mode of an index operand.
+//
+// Addressing mode of an index operation is based on the set of
+// underlying types.
+// Hasse diagram of the indexMode meet semi-lattice:
+//
+//	ixVar     ixMap
+//	  |          |
+//	ixArrVar     |
+//	  |          |
+//	ixValue      |
+//	   \        /
+//	  ixInvalid
+type indexMode byte
+
+const (
+	ixInvalid indexMode = iota // index is invalid
+	ixValue                    // index is a computed value (not addressable)
+	ixArrVar                   // like ixVar, but index operand contains an array
+	ixVar                      // index is an addressable variable
+	ixMap                      // index is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
+)
+
+// meet is the address type that is constrained by both x and y.
+func (x indexMode) meet(y indexMode) indexMode {
+	if (x == ixMap || y == ixMap) && x != y {
+		return ixInvalid
+	}
+	// Use int representation and return min.
+	if x < y {
+		return y
+	}
+	return x
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/util.go b/vendor/honnef.co/go/tools/go/ir/util.go
new file mode 100644
index 0000000..32c284d
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/util.go
@@ -0,0 +1,443 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file defines a number of miscellaneous utility functions.
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"io"
+	"os"
+	"sync"
+	_ "unsafe" // for go:linkname hack
+
+	"honnef.co/go/tools/go/types/typeutil"
+
+	"golang.org/x/exp/typeparams"
+)
+
+type unit struct{}
+
+//// AST utilities
+
+// isBlankIdent returns true iff e is an Ident with name "_".
+// They have no associated types.Object, and thus no type.
+func isBlankIdent(e ast.Expr) bool {
+	id, ok := e.(*ast.Ident)
+	return ok && id.Name == "_"
+}
+
+//// Type utilities.  Some of these belong in go/types.
+
+// isString reports whether t is exactly a string type.
+// t is assumed to be an Underlying type (not Named or Alias).
+func isString(t types.Type) bool {
+	basic, ok := t.(*types.Basic)
+	return ok && basic.Info()&types.IsString != 0
+}
+
+// isByteSlice reports whether t is of the form []~bytes.
+// t is assumed to be an Underlying type (not Named or Alias).
+func isByteSlice(t types.Type) bool {
+	if b, ok := t.(*types.Slice); ok {
+		e, _ := b.Elem().Underlying().(*types.Basic)
+		return e != nil && e.Kind() == types.Byte
+	}
+	return false
+}
+
+// isRuneSlice reports whether t is of the form []~runes.
+// t is assumed to be an Underlying type (not Named or Alias).
+func isRuneSlice(t types.Type) bool {
+	if b, ok := t.(*types.Slice); ok {
+		e, _ := b.Elem().Underlying().(*types.Basic)
+		return e != nil && e.Kind() == types.Rune
+	}
+	return false
+}
+
+// isBasicConvTypes returns true when the type set of a type
+// can be one side of a Convert operation. This is when:
+// - All are basic, []byte, or []rune.
+// - At least 1 is basic.
+// - At most 1 is []byte or []rune.
+func isBasicConvTypes(typ types.Type) bool {
+	basics, cnt := 0, 0
+	ok := underIs(typ, func(t types.Type) bool {
+		cnt++
+		if isBasic(t) {
+			basics++
+			return true
+		}
+		return isByteSlice(t) || isRuneSlice(t)
+	})
+	return ok && basics >= 1 && cnt-basics <= 1
+}
+
+// isPointer reports whether t's underlying type is a pointer.
+func isPointer(t types.Type) bool {
+	return is[*types.Pointer](t.Underlying())
+}
+
+// isPointerCore reports whether t's core type is a pointer.
+//
+// (Most pointer manipulation is related to receivers, in which case
+// isPointer is appropriate. tecallers can use isPointer(t).
+func isPointerCore(t types.Type) bool {
+	return is[*types.Pointer](typeutil.CoreType(t))
+}
+
+func is[T any](x any) bool {
+	_, ok := x.(T)
+	return ok
+}
+
+// deref returns a pointer's element type; otherwise it returns typ.
+func deref(typ types.Type) types.Type {
+	orig := typ
+	typ = types.Unalias(typ)
+
+	if t, ok := typ.(*types.TypeParam); ok {
+		if ctyp := typeutil.CoreType(t); ctyp != nil {
+			// This can happen, for example, with len(T) where T is a
+			// type parameter whose core type is a pointer to array.
+			typ = ctyp
+		}
+	}
+	if p, ok := typ.Underlying().(*types.Pointer); ok {
+		return p.Elem()
+	}
+	return orig
+}
+
+// recvType returns the receiver type of method obj.
+func recvType(obj *types.Func) types.Type {
+	return obj.Type().(*types.Signature).Recv().Type()
+}
+
+// fieldOf returns the index'th field of the (core type of) a struct type;
+// otherwise returns nil.
+func fieldOf(typ types.Type, index int) *types.Var {
+	if st, ok := typeutil.CoreType(typ).(*types.Struct); ok {
+		if 0 <= index && index < st.NumFields() {
+			return st.Field(index)
+		}
+	}
+	return nil
+}
+
+// isUntyped reports whether typ is the type of an untyped constant.
+func isUntyped(typ types.Type) bool {
+	// No Underlying/Unalias: untyped constant types cannot be Named or Alias.
+	b, ok := typ.(*types.Basic)
+	return ok && b.Info()&types.IsUntyped != 0
+}
+
+// declaredWithin reports whether an object is declared within a function.
+//
+// obj must not be a method or a field.
+func declaredWithin(obj types.Object, fn *types.Func) bool {
+	if obj.Pos() != token.NoPos {
+		return fn.Scope().Contains(obj.Pos()) // trust the positions if they exist.
+	}
+	if fn.Pkg() != obj.Pkg() {
+		return false // fast path for different packages
+	}
+
+	// Traverse Parent() scopes for fn.Scope().
+	for p := obj.Parent(); p != nil; p = p.Parent() {
+		if p == fn.Scope() {
+			return true
+		}
+	}
+	return false
+}
+
+// logStack prints the formatted "start" message to stderr and
+// returns a closure that prints the corresponding "end" message.
+// Call using 'defer logStack(...)()' to show builder stack on panic.
+// Don't forget trailing parens!
+func logStack(format string, args ...any) func() {
+	msg := fmt.Sprintf(format, args...)
+	io.WriteString(os.Stderr, msg)
+	io.WriteString(os.Stderr, "\n")
+	return func() {
+		io.WriteString(os.Stderr, msg)
+		io.WriteString(os.Stderr, " end\n")
+	}
+}
+
+// newVar creates a 'var' for use in a types.Tuple.
+func newVar(name string, typ types.Type) *types.Var {
+	return types.NewParam(token.NoPos, nil, name, typ)
+}
+
+// anonVar creates an anonymous 'var' for use in a types.Tuple.
+func anonVar(typ types.Type) *types.Var {
+	return newVar("", typ)
+}
+
+var lenResults = types.NewTuple(anonVar(tInt))
+
+// makeLen returns the len builtin specialized to type func(T)int.
+func makeLen(T types.Type) *Builtin {
+	lenParams := types.NewTuple(anonVar(T))
+	return &Builtin{
+		name: "len",
+		sig:  types.NewSignatureType(nil, nil, nil, lenParams, lenResults, false),
+	}
+}
+
+func assert(x bool, msg string) {
+	if !x {
+		panic(msg)
+	}
+}
+
+// BlockMap is a mapping from basic blocks (identified by their indices) to values.
+type BlockMap[T any] []T
+
+// isBasic reports whether t is a basic type.
+func isBasic(t types.Type) bool {
+	_, ok := t.(*types.Basic)
+	return ok
+}
+
+// receiverTypeArgs returns the type arguments to a method's receiver.
+// Returns an empty list if the receiver does not have type arguments.
+func receiverTypeArgs(method *types.Func) []types.Type {
+	recv := method.Signature().Recv()
+	named := func() (named *types.Named) {
+		t := recv.Type()
+		if ptr, ok := types.Unalias(t).(*types.Pointer); ok {
+			t = ptr.Elem()
+		}
+		named, _ = types.Unalias(t).(*types.Named)
+		return named
+	}()
+	if named == nil {
+		return nil // recv is anonymous struct/interface
+	}
+	ts := named.TypeArgs()
+	if ts.Len() == 0 {
+		return nil
+	}
+	targs := make([]types.Type, ts.Len())
+	for i := 0; i < ts.Len(); i++ {
+		targs[i] = ts.At(i)
+	}
+	return targs
+}
+
+// recvAsFirstArg takes a method signature and returns a function
+// signature with receiver as the first parameter.
+func recvAsFirstArg(sig *types.Signature) *types.Signature {
+	params := make([]*types.Var, 0, 1+sig.Params().Len())
+	params = append(params, sig.Recv())
+	for v := range sig.Params().Variables() {
+		params = append(params, v)
+	}
+	return types.NewSignatureType(nil, nil, nil, types.NewTuple(params...), sig.Results(), sig.Variadic())
+}
+
+// instance returns whether an expression is a simple or qualified identifier
+// that is a generic instantiation.
+func instance(info *types.Info, expr ast.Expr) bool {
+	// Compare the logic here against go/types.instantiatedIdent,
+	// which also handles  *IndexExpr and *IndexListExpr.
+	var id *ast.Ident
+	switch x := expr.(type) {
+	case *ast.Ident:
+		id = x
+	case *ast.SelectorExpr:
+		id = x.Sel
+	default:
+		return false
+	}
+	_, ok := info.Instances[id]
+	return ok
+}
+
+// isNonTypeParamInterface reports whether t is an interface type but not a type parameter.
+func isNonTypeParamInterface(t types.Type) bool {
+	return !typeparams.IsTypeParam(t) && types.IsInterface(t)
+}
+
+// instanceArgs returns the Instance[id].TypeArgs as a slice.
+func instanceArgs(info *types.Info, id *ast.Ident) []types.Type {
+	targList := info.Instances[id].TypeArgs
+	if targList == nil {
+		return nil
+	}
+
+	targs := make([]types.Type, targList.Len())
+	for i, n := 0, targList.Len(); i < n; i++ {
+		targs[i] = targList.At(i)
+	}
+	return targs
+}
+
+// Mapping of a type T to a canonical instance C s.t. types.Identical(T, C).
+// Thread-safe.
+type canonizer struct {
+	mu    sync.Mutex
+	types typeutil.Map[types.Type] // map from type to a canonical instance
+	lists typeListMap              // map from a list of types to a canonical instance
+}
+
+func newCanonizer() *canonizer {
+	c := &canonizer{}
+	h := typeutil.MakeHasher()
+	c.types.SetHasher(h)
+	c.lists.hasher = h
+	return c
+}
+
+// List returns a canonical representative of a list of types.
+// Representative of the empty list is nil.
+func (c *canonizer) List(ts []types.Type) *typeList {
+	if len(ts) == 0 {
+		return nil
+	}
+
+	unaliasAll := func(ts []types.Type) []types.Type {
+		// Is there some top level alias?
+		var found bool
+		for _, t := range ts {
+			if _, ok := t.(*types.Alias); ok {
+				found = true
+				break
+			}
+		}
+		if !found {
+			return ts // no top level alias
+		}
+
+		cp := make([]types.Type, len(ts)) // copy with top level aliases removed.
+		for i, t := range ts {
+			cp[i] = types.Unalias(t)
+		}
+		return cp
+	}
+	l := unaliasAll(ts)
+
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	return c.lists.rep(l)
+}
+
+// Type returns a canonical representative of type T.
+// Removes top-level aliases.
+//
+// For performance, reasons the canonical instance is order-dependent,
+// and may contain deeply nested aliases.
+func (c *canonizer) Type(T types.Type) types.Type {
+	T = types.Unalias(T) // remove the top level alias.
+
+	// A Signature's receiver is not part of its type identity, so a method
+	// signature must not stand in for an identical function signature, nor
+	// for a method signature with a different receiver (go.dev/issue/81602).
+	if sig, ok := T.(*types.Signature); ok && sig.Recv() != nil {
+		return T
+	}
+
+	c.mu.Lock()
+	defer c.mu.Unlock()
+
+	if r, _ := c.types.At(T); r != nil {
+		return r
+	}
+	c.types.Set(T, T)
+	return T
+}
+
+// A type for representing a canonized list of types.
+type typeList []types.Type
+
+func (l *typeList) identical(ts []types.Type) bool {
+	if l == nil {
+		return len(ts) == 0
+	}
+	n := len(*l)
+	if len(ts) != n {
+		return false
+	}
+	for i, left := range *l {
+		right := ts[i]
+		if !types.Identical(left, right) {
+			return false
+		}
+	}
+	return true
+}
+
+type typeListMap struct {
+	hasher  typeutil.Hasher
+	buckets map[uint32][]*typeList
+}
+
+// rep returns a canonical representative of a slice of types.
+func (m *typeListMap) rep(ts []types.Type) *typeList {
+	if m == nil || len(ts) == 0 {
+		return nil
+	}
+
+	if m.buckets == nil {
+		m.buckets = make(map[uint32][]*typeList)
+	}
+
+	h := m.hash(ts)
+	bucket := m.buckets[h]
+	for _, l := range bucket {
+		if l.identical(ts) {
+			return l
+		}
+	}
+
+	// not present. create a representative.
+	cp := make(typeList, len(ts))
+	copy(cp, ts)
+	rep := &cp
+
+	m.buckets[h] = append(bucket, rep)
+	return rep
+}
+
+func (m *typeListMap) hash(ts []types.Type) uint32 {
+	if m == nil {
+		return 0
+	}
+	// Some smallish prime far away from typeutil.Hash.
+	n := len(ts)
+	h := uint32(13619) + 2*uint32(n)
+	for i := range n {
+		h += 3 * m.hasher.Hash(ts[i])
+	}
+	return h
+}
+
+// instantiateMethod instantiates m with targs and returns a canonical representative for this method.
+func (canon *canonizer) instantiateMethod(m *types.Func, targs []types.Type, ctxt *types.Context) *types.Func {
+	recv := recvType(m)
+	if p, ok := types.Unalias(recv).(*types.Pointer); ok {
+		recv = p.Elem()
+	}
+	named := types.Unalias(recv).(*types.Named)
+	inst, err := types.Instantiate(ctxt, named.Origin(), targs, false)
+	if err != nil {
+		panic(err)
+	}
+	rep := canon.Type(inst)
+	obj, _, _ := types.LookupFieldOrMethod(rep, true, m.Pkg(), m.Name())
+	return obj.(*types.Func)
+}
+
+// Exposed to irutil using the linkname hack.
+//
+//go:linkname isSyntactic honnef.co/go/tools/go/ir.isSyntactic
+func isSyntactic(pkg *Package) bool { return pkg.syntax }
diff --git a/vendor/honnef.co/go/tools/go/ir/wrappers.go b/vendor/honnef.co/go/tools/go/ir/wrappers.go
new file mode 100644
index 0000000..1d7b3e4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/ir/wrappers.go
@@ -0,0 +1,357 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+// This file defines synthesis of Functions that delegate to declared
+// methods; they come in three kinds:
+//
+// (1) wrappers: methods that wrap declared methods, performing
+//     implicit pointer indirections and embedded field selections.
+//
+// (2) thunks: funcs that wrap declared methods.  Like wrappers,
+//     thunks perform indirections and field selections. The thunk's
+//     first parameter is used as the receiver for the method call.
+//
+// (3) bounds: funcs that wrap declared methods.  The bound's sole
+//     free variable, supplied by a closure, is used as the receiver
+//     for the method call.  No indirections or field selections are
+//     performed since they can be done before the call.
+
+import (
+	"fmt"
+	"go/types"
+)
+
+// -- wrappers -----------------------------------------------------------
+
+// createWrapper returns a synthetic method that delegates to the
+// declared method denoted by meth.Obj(), first performing any
+// necessary pointer indirections or field selections implied by meth.
+//
+// The resulting method's receiver type is meth.Recv().
+//
+// This function is versatile but quite subtle!  Consider the
+// following axes of variation when making changes:
+//   - optional receiver indirection
+//   - optional implicit field selections
+//   - optional method type arguments
+//   - meth.Obj() may denote a concrete or an interface method
+//   - the result may be a thunk or a wrapper.
+func createWrapper(prog *Program, sel *selection, targs []types.Type) *Function {
+	obj := sel.obj.(*types.Func) // the declared function
+	name, sig := maybeInstance(prog, obj.Name(), sel.typ.(*types.Signature), targs)
+
+	var recv *types.Var // wrapper's receiver or thunk's params[0]
+	var description string
+	if sel.kind == types.MethodExpr {
+		name += "$thunk"
+		description = "thunk"
+		recv = sig.Params().At(0)
+	} else {
+		description = "wrapper"
+		recv = sig.Recv()
+	}
+
+	description = fmt.Sprintf("%s for %s", description, obj)
+	if prog.mode&LogSource != 0 {
+		defer logStack("create %s to (%s)", description, recv.Type())()
+	}
+	/* method wrapper */
+	return &Function{
+		name:      name,
+		method:    sel,
+		object:    obj,
+		Signature: sig,
+		Synthetic: description,
+		Prog:      prog,
+		pos:       obj.Pos(),
+		typeargs:  targs,
+		// wrappers have no syntax
+		build:     (*builder).buildWrapper,
+		info:      nil,
+		goversion: "",
+	}
+}
+
+// maybeInstance returns name and sig instantiated to reflect any type arguments in targs.
+func maybeInstance(prog *Program, name string, sig *types.Signature, targs []types.Type) (string, *types.Signature) {
+	if len(targs) > 0 {
+		name = fmt.Sprintf("%s%s", name, targstr(targs))
+		instSig, err := types.Instantiate(prog.ctxt, sig, targs, false)
+		if err != nil {
+			// validate was false, we should never get an error
+			panic(err)
+		}
+		sig = prog.canon.Type(instSig).(*types.Signature)
+	}
+	return name, sig
+}
+
+// buildWrapper builds fn.Body for a method wrapper.
+func (b *builder) buildWrapper(fn *Function) {
+	var recv *types.Var // wrapper's receiver or thunk's params[0]
+	var start int       // first regular param
+	if fn.method.kind == types.MethodExpr {
+		recv = fn.Signature.Params().At(0)
+		start = 1
+	} else {
+		recv = fn.Signature.Recv()
+	}
+
+	fn.startBody()
+	fn.addSpilledParam(recv, nil)
+	createParams(fn, start)
+
+	indices := fn.method.index
+
+	var v Value = fn.Locals[0] // spilled receiver
+	if isPointer(fn.method.recv) {
+		v = emitLoad(fn, v, nil)
+
+		// For simple indirection wrappers, perform an informative nil-check:
+		// "value method (T).f called using nil *T pointer"
+		if len(indices) == 1 && !isPointer(recvType(fn.object)) {
+			var c Call
+			c.Call.Value = &Builtin{
+				name: "ssa:wrapnilchk",
+				sig:  types.NewSignatureType(nil, nil, nil, types.NewTuple(anonVar(fn.method.recv), anonVar(tString), anonVar(tString)), types.NewTuple(anonVar(fn.method.recv)), false),
+			}
+			c.Call.Args = []Value{
+				v,
+				stringConst(deref(fn.method.recv).String(), nil),
+				stringConst(fn.method.obj.Name(), nil),
+			}
+			c.setType(v.Type())
+			v = fn.emit(&c, nil)
+		}
+	}
+
+	// Invariant: v is a pointer, either
+	//   value of *A receiver param, or
+	// address of  A spilled receiver.
+
+	// We use pointer arithmetic (FieldAddr possibly followed by
+	// Load) in preference to value extraction (Field possibly
+	// preceded by Load).
+
+	v = emitImplicitSelections(fn, v, indices[:len(indices)-1], nil)
+
+	// Invariant: v is a pointer, either
+	//   value of implicit *C field, or
+	// address of implicit  C field.
+
+	var c Call
+	if r := recvType(fn.object); !types.IsInterface(r) { // concrete method
+		if !isPointer(r) {
+			v = emitLoad(fn, v, nil)
+		}
+		c.Call.Value = fn.Prog.objectMethod(fn.object, fn.typeargs, b)
+		c.Call.Args = append(c.Call.Args, v)
+	} else {
+		c.Call.Method = fn.object
+		c.Call.Value = emitLoad(fn, v, nil) // interface (possibly a typeparam)
+	}
+	for _, arg := range fn.Params[1:] {
+		c.Call.Args = append(c.Call.Args, arg)
+	}
+	emitTailCall(fn, &c, nil)
+	fn.finishBody()
+}
+
+// createParams creates parameters for wrapper method fn based on its
+// Signature.Params, which do not include the receiver.
+// start is the index of the first regular parameter to use.
+func createParams(fn *Function, start int) {
+	tparams := fn.Signature.Params()
+	for i, n := start, tparams.Len(); i < n; i++ {
+		fn.addParamVar(tparams.At(i), nil)
+	}
+}
+
+// -- bounds -----------------------------------------------------------
+
+// createBound returns a bound method wrapper (or "bound"), a synthetic
+// function that delegates to a concrete or interface method denoted
+// by obj.  The resulting function has no receiver, but has one free
+// variable which will be used as the method's receiver in the
+// tail-call.
+//
+// Use MakeClosure with such a wrapper to construct a bound method
+// closure.  e.g.:
+//
+//	type T int          or:  type T interface { meth() }
+//	func (t T) meth()
+//	var t T
+//	f := t.meth
+//	f() // calls t.meth()
+//
+// f is a closure of a synthetic wrapper defined as if by:
+//
+//	f := func() { return t.meth() }
+//
+// Unlike createWrapper, createBound need perform no indirection or field
+// selections because that can be done before the closure is
+// constructed.
+func createBound(prog *Program, obj *types.Func, targs []types.Type) *Function {
+	description := fmt.Sprintf("bound method wrapper for %s", obj)
+	if prog.mode&LogSource != 0 {
+		defer logStack("%s", description)()
+	}
+	name, sig := maybeInstance(prog, obj.Name(), obj.Type().(*types.Signature), targs)
+
+	/* bound method wrapper */
+	fn := &Function{
+		name:      name + "$bound",
+		object:    obj,
+		Signature: changeRecv(sig, nil), // drop receiver
+		Synthetic: description,
+		Prog:      prog,
+		pos:       obj.Pos(),
+		typeargs:  targs,
+		// wrappers have no syntax
+		build:     (*builder).buildBound,
+		info:      nil,
+		goversion: "",
+	}
+	fn.FreeVars = []*FreeVar{{name: "recv", typ: recvType(obj), parent: fn}} // (cyclic)
+	return fn
+}
+
+// buildBound builds fn.Body for a bound method closure.
+func (b *builder) buildBound(fn *Function) {
+	fn.startBody()
+	createParams(fn, 0)
+	var c Call
+
+	recv := fn.FreeVars[0]
+	if !types.IsInterface(recvType(fn.object)) { // concrete
+		c.Call.Value = fn.Prog.objectMethod(fn.object, fn.typeargs, b)
+		c.Call.Args = []Value{recv}
+	} else {
+		c.Call.Method = fn.object
+		c.Call.Value = recv // interface (possibly a typeparam)
+	}
+	for _, arg := range fn.Params {
+		c.Call.Args = append(c.Call.Args, arg)
+	}
+	emitTailCall(fn, &c, nil)
+	fn.finishBody()
+}
+
+// -- thunks -----------------------------------------------------------
+
+// createThunk returns a thunk, a synthetic function that delegates to a
+// concrete or interface method denoted by sel.obj.  The resulting
+// function has no receiver, but has an additional (first) regular
+// parameter.
+//
+// Precondition: sel.kind == types.MethodExpr.
+//
+//	type T int          or:  type T interface { meth() }
+//	func (t T) meth()
+//	f := T.meth
+//	var t T
+//	f(t) // calls t.meth()
+//
+// f is a synthetic wrapper defined as if by:
+//
+//	f := func(t T) { return t.meth() }
+func createThunk(prog *Program, sel *selection, targs []types.Type) *Function {
+	if sel.kind != types.MethodExpr {
+		panic(sel)
+	}
+
+	fn := createWrapper(prog, sel, targs)
+	if fn.Signature.Recv() != nil {
+		panic(fn) // unexpected receiver
+	}
+	return fn
+}
+
+func changeRecv(s *types.Signature, recv *types.Var) *types.Signature {
+	return types.NewSignatureType(recv, nil, nil, s.Params(), s.Results(), s.Variadic())
+}
+
+// A local version of *types.Selection.
+// Needed for some additional control, such as creating a MethodExpr for an instantiation.
+type selection struct {
+	kind     types.SelectionKind
+	recv     types.Type
+	typ      types.Type
+	obj      types.Object
+	index    []int
+	indirect bool
+}
+
+func toSelection(sel *types.Selection) *selection {
+	return &selection{
+		kind:     sel.Kind(),
+		recv:     sel.Recv(),
+		typ:      sel.Type(),
+		obj:      sel.Obj(),
+		index:    sel.Index(),
+		indirect: sel.Indirect(),
+	}
+}
+
+// -- instantiations --------------------------------------------------
+
+// buildInstantiationWrapper builds the body of an instantiation
+// wrapper fn. The body calls the original generic function,
+// bracketed by ChangeType conversions on its arguments and results.
+func (b *builder) buildInstantiationWrapper(fn *Function) {
+	orig := fn.topLevelOrigin
+	sig := fn.Signature
+
+	fn.startBody()
+	if sig.Recv() != nil {
+		fn.addParamVar(sig.Recv(), nil)
+	}
+	createParams(fn, 0)
+
+	// Create body. Add a call to origin generic function
+	// and make type changes between argument and parameters,
+	// as well as return values.
+	var c Call
+	c.Call.Value = orig
+	if res := orig.Signature.Results(); res.Len() == 1 {
+		c.typ = res.At(0).Type()
+	} else {
+		c.typ = res
+	}
+
+	// parameter of instance becomes an argument to the call
+	// to the original generic function.
+	argOffset := 0
+	for i, arg := range fn.Params {
+		var typ types.Type
+		if i == 0 && sig.Recv() != nil {
+			typ = orig.Signature.Recv().Type()
+			argOffset = 1
+		} else {
+			typ = orig.Signature.Params().At(i - argOffset).Type()
+		}
+		c.Call.Args = append(c.Call.Args, emitTypeCoercion(fn, arg, typ, nil))
+	}
+
+	results := fn.emit(&c, nil)
+	var ret Return
+	switch res := sig.Results(); res.Len() {
+	case 0:
+		// no results, do nothing.
+	case 1:
+		ret.Results = []Value{emitTypeCoercion(fn, results, res.At(0).Type(), nil)}
+	default:
+		for i := 0; i < sig.Results().Len(); i++ {
+			v := emitExtract(fn, results, i, nil)
+			ret.Results = append(ret.Results, emitTypeCoercion(fn, v, res.At(i).Type(), nil))
+		}
+	}
+
+	fn.emit(&ret, nil)
+	fn.currentBlock = nil
+
+	fn.finishBody()
+}
diff --git a/vendor/honnef.co/go/tools/go/loader/hash.go b/vendor/honnef.co/go/tools/go/loader/hash.go
new file mode 100644
index 0000000..8c22cca
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/loader/hash.go
@@ -0,0 +1,98 @@
+package loader
+
+import (
+	"fmt"
+	"runtime"
+	"sort"
+	"strings"
+
+	"honnef.co/go/tools/go/buildid"
+	"honnef.co/go/tools/lintcmd/cache"
+)
+
+// computeHash computes a package's hash. The hash is based on all Go
+// files that make up the package, as well as the hashes of imported
+// packages.
+func computeHash(pkg *PackageSpec) (cache.ActionID, error) {
+	key := cache.NewHash("package " + pkg.PkgPath)
+	fmt.Fprintf(key, "goos %s goarch %s\n", runtime.GOOS, runtime.GOARCH)
+	fmt.Fprintf(key, "import %q\n", pkg.PkgPath)
+
+	// Compute the hashes of all files making up the package. As an
+	// optimization, we use the build ID that Go already computed for us,
+	// because it is virtually identical to hashing all CompiledGoFiles. It is
+	// also sensitive to the Go version declared in go.mod.
+	success := false
+	if pkg.ExportFile != "" {
+		id, err := getBuildid(pkg.ExportFile)
+		if err == nil {
+			if idx := strings.IndexRune(id, '/'); idx > -1 {
+				fmt.Fprintf(key, "files %s\n", id[:idx])
+				success = true
+			}
+		}
+	}
+	if !success {
+		for _, f := range pkg.CompiledGoFiles {
+			h, err := cache.FileHash(f)
+			if err != nil {
+				return cache.ActionID{}, err
+			}
+			fmt.Fprintf(key, "file %s %x\n", f, h)
+		}
+		if pkg.Module != nil && pkg.Module.GoMod != "" {
+			// The go.mod file specifies the language version, which affects how
+			// packages are analyzed.
+			h, err := cache.FileHash(pkg.Module.GoMod)
+			if err != nil {
+				// TODO(dh): this doesn't work for tests because the go.mod file doesn't
+				// exist on disk and is instead provided via an overlay. However, we're
+				// unlikely to get here in the first place, as reading the build ID from
+				// the export file is likely to succeed.
+				return cache.ActionID{}, fmt.Errorf("couldn't hash go.mod: %w", err)
+			} else {
+				fmt.Fprintf(key, "file %s %x\n", pkg.Module.GoMod, h)
+			}
+		}
+	}
+
+	imps := make([]*PackageSpec, 0, len(pkg.Imports))
+	for _, v := range pkg.Imports {
+		imps = append(imps, v)
+	}
+	sort.Slice(imps, func(i, j int) bool {
+		return imps[i].PkgPath < imps[j].PkgPath
+	})
+
+	for _, dep := range imps {
+		if dep.ExportFile == "" {
+			fmt.Fprintf(key, "import %s \n", dep.PkgPath)
+		} else {
+			id, err := getBuildid(dep.ExportFile)
+			if err == nil {
+				fmt.Fprintf(key, "import %s %s\n", dep.PkgPath, id)
+			} else {
+				fh, err := cache.FileHash(dep.ExportFile)
+				if err != nil {
+					return cache.ActionID{}, err
+				}
+				fmt.Fprintf(key, "import %s %x\n", dep.PkgPath, fh)
+			}
+		}
+	}
+	return key.Sum(), nil
+}
+
+var buildidCache = map[string]string{}
+
+func getBuildid(f string) (string, error) {
+	if h, ok := buildidCache[f]; ok {
+		return h, nil
+	}
+	h, err := buildid.ReadFile(f)
+	if err != nil {
+		return "", err
+	}
+	buildidCache[f] = h
+	return h, nil
+}
diff --git a/vendor/honnef.co/go/tools/go/loader/loader.go b/vendor/honnef.co/go/tools/go/loader/loader.go
new file mode 100644
index 0000000..4a8d1a0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/loader/loader.go
@@ -0,0 +1,381 @@
+package loader
+
+import (
+	"errors"
+	"fmt"
+	"go/ast"
+	"go/build"
+	"go/parser"
+	"go/scanner"
+	"go/token"
+	"go/types"
+	"os"
+	"time"
+
+	"honnef.co/go/tools/config"
+	"honnef.co/go/tools/lintcmd/cache"
+
+	"golang.org/x/tools/go/gcexportdata"
+	"golang.org/x/tools/go/packages"
+)
+
+const MaxFileSize = 50 * 1024 * 1024 // 50 MB
+
+var errMaxFileSize = errors.New("file exceeds max file size")
+
+type PackageSpec struct {
+	ID      string
+	Name    string
+	PkgPath string
+	// Errors that occurred while building the import graph. These will
+	// primarily be parse errors or failure to resolve imports, but
+	// may also be other errors.
+	Errors          []packages.Error
+	GoFiles         []string
+	CompiledGoFiles []string
+	OtherFiles      []string
+	ExportFile      string
+	Imports         map[string]*PackageSpec
+	TypesSizes      types.Sizes
+	Hash            cache.ActionID
+	Module          *packages.Module
+
+	Config config.Config
+}
+
+func (spec *PackageSpec) String() string {
+	return spec.ID
+}
+
+type Package struct {
+	*PackageSpec
+
+	// Errors that occurred while loading the package. These will
+	// primarily be parse or type errors, but may also be lower-level
+	// failures such as file-system ones.
+	Errors    []packages.Error
+	Types     *types.Package
+	Fset      *token.FileSet
+	Syntax    []*ast.File
+	TypesInfo *types.Info
+}
+
+// Graph resolves patterns and returns packages with all the
+// information required to later load type information, and optionally
+// syntax trees.
+//
+// The provided config can set any setting with the exception of Mode.
+func Graph(cfg *packages.Config, patterns ...string) ([]*PackageSpec, error) {
+	var dcfg packages.Config
+	if cfg != nil {
+		dcfg = *cfg
+	}
+	dcfg.Mode = packages.NeedName |
+		packages.NeedImports |
+		packages.NeedDeps |
+		packages.NeedExportFile |
+		packages.NeedFiles |
+		packages.NeedCompiledGoFiles |
+		packages.NeedTypesSizes |
+		packages.NeedModule
+	pkgs, err := packages.Load(&dcfg, patterns...)
+	if err != nil {
+		return nil, err
+	}
+
+	m := map[*packages.Package]*PackageSpec{}
+	packages.Visit(pkgs, nil, func(pkg *packages.Package) {
+		spec := &PackageSpec{
+			ID:              pkg.ID,
+			Name:            pkg.Name,
+			PkgPath:         pkg.PkgPath,
+			Errors:          pkg.Errors,
+			GoFiles:         pkg.GoFiles,
+			CompiledGoFiles: pkg.CompiledGoFiles,
+			OtherFiles:      pkg.OtherFiles,
+			ExportFile:      pkg.ExportFile,
+			Imports:         map[string]*PackageSpec{},
+			TypesSizes:      pkg.TypesSizes,
+			Module:          pkg.Module,
+		}
+		for path, imp := range pkg.Imports {
+			spec.Imports[path] = m[imp]
+		}
+		if cdir := config.Dir(pkg.GoFiles); cdir != "" {
+			cfg, err := config.Load(cdir)
+			if err != nil {
+				spec.Errors = append(spec.Errors, convertError(err)...)
+			}
+			spec.Config = cfg
+		} else {
+			spec.Config = config.DefaultConfig
+		}
+		spec.Hash, err = computeHash(spec)
+		if err != nil {
+			spec.Errors = append(spec.Errors, convertError(err)...)
+		}
+		m[pkg] = spec
+	})
+	out := make([]*PackageSpec, 0, len(pkgs))
+	for _, pkg := range pkgs {
+		if len(pkg.CompiledGoFiles) == 0 && len(pkg.Errors) == 0 && pkg.PkgPath != "unsafe" {
+			// If a package consists only of test files, then
+			// go/packages incorrectly(?) returns an empty package for
+			// the non-test variant. Get rid of those packages. See
+			// #646.
+			//
+			// Do not, however, skip packages that have errors. Those,
+			// too, may have no files, but we want to print the
+			// errors.
+			continue
+		}
+		out = append(out, m[pkg])
+	}
+
+	return out, nil
+}
+
+type program struct {
+	fset     *token.FileSet
+	packages map[string]*types.Package
+	options  *Options
+}
+
+type Stats struct {
+	Source time.Duration
+	Export map[*PackageSpec]time.Duration
+}
+
+type Options struct {
+	// The Go language version to use for the type checker. If unset, or if set
+	// to "module", it will default to the Go version specified in the module;
+	// if there is no module, it will default to the version of Go the
+	// executable was built with.
+	GoVersion string
+}
+
+// Load loads the package described in spec. Imports will be loaded
+// from export data, while the package itself will be loaded from
+// source.
+//
+// An error will only be returned for system failures, such as failure
+// to read export data from disk. Syntax and type errors, among
+// others, will only populate the returned package's Errors field.
+func Load(spec *PackageSpec, opts *Options) (*Package, Stats, error) {
+	if opts == nil {
+		opts = &Options{}
+	}
+	if opts.GoVersion == "" {
+		opts.GoVersion = "module"
+	}
+	prog := &program{
+		fset:     token.NewFileSet(),
+		packages: map[string]*types.Package{},
+		options:  opts,
+	}
+
+	stats := Stats{
+		Export: map[*PackageSpec]time.Duration{},
+	}
+	for _, imp := range spec.Imports {
+		if imp.PkgPath == "unsafe" {
+			continue
+		}
+		t := time.Now()
+		_, err := prog.loadFromExport(imp)
+		stats.Export[imp] = time.Since(t)
+		if err != nil {
+			return nil, stats, err
+		}
+	}
+	t := time.Now()
+	pkg, err := prog.loadFromSource(spec)
+	if err == errMaxFileSize {
+		pkg, err = prog.loadFromExport(spec)
+	}
+	stats.Source = time.Since(t)
+	return pkg, stats, err
+}
+
+// loadFromExport loads a package from export data.
+func (prog *program) loadFromExport(spec *PackageSpec) (*Package, error) {
+	// log.Printf("Loading package %s from export", spec)
+	if spec.ExportFile == "" {
+		return nil, fmt.Errorf("no export data for %q", spec.ID)
+	}
+	f, err := os.Open(spec.ExportFile)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	//lint:ignore SA1019 NewReader does exactly what we need: it supports Go
+	//  1.27 compiler export data and Go 1.28 cmd/export data.
+	r, err := gcexportdata.NewReader(f)
+	if err != nil {
+		return nil, err
+	}
+	tpkg, err := gcexportdata.Read(r, prog.fset, prog.packages, spec.PkgPath)
+	if err != nil {
+		return nil, err
+	}
+	pkg := &Package{
+		PackageSpec: spec,
+		Types:       tpkg,
+		Fset:        prog.fset,
+	}
+	// runtime.SetFinalizer(pkg, func(pkg *Package) {
+	// 	log.Println("Unloading package", pkg.PkgPath)
+	// })
+	return pkg, nil
+}
+
+// loadFromSource loads a package from source. All of its dependencies
+// must have been loaded already.
+func (prog *program) loadFromSource(spec *PackageSpec) (*Package, error) {
+	if len(spec.Errors) > 0 {
+		panic("LoadFromSource called on package with errors")
+	}
+
+	pkg := &Package{
+		PackageSpec: spec,
+		Types:       types.NewPackage(spec.PkgPath, spec.Name),
+		Syntax:      make([]*ast.File, len(spec.CompiledGoFiles)),
+		Fset:        prog.fset,
+		TypesInfo: &types.Info{
+			Types:        make(map[ast.Expr]types.TypeAndValue),
+			Defs:         make(map[*ast.Ident]types.Object),
+			Uses:         make(map[*ast.Ident]types.Object),
+			Implicits:    make(map[ast.Node]types.Object),
+			Scopes:       make(map[ast.Node]*types.Scope),
+			Selections:   make(map[*ast.SelectorExpr]*types.Selection),
+			Instances:    make(map[*ast.Ident]types.Instance),
+			FileVersions: make(map[*ast.File]string),
+		},
+	}
+	// runtime.SetFinalizer(pkg, func(pkg *Package) {
+	// 	log.Println("Unloading package", pkg.PkgPath)
+	// })
+
+	// OPT(dh): many packages have few files, much fewer than there
+	// are CPU cores. Additionally, parsing each individual file is
+	// very fast. A naive parallel implementation of this loop won't
+	// be faster, and tends to be slower due to extra scheduling,
+	// bookkeeping and potentially false sharing of cache lines.
+	for i, file := range spec.CompiledGoFiles {
+		f, err := os.Open(file)
+		if err != nil {
+			return nil, err
+		}
+		fi, err := f.Stat()
+		if err != nil {
+			return nil, err
+		}
+		if fi.Size() >= MaxFileSize {
+			return nil, errMaxFileSize
+		}
+		af, err := parser.ParseFile(prog.fset, file, f, parser.ParseComments|parser.SkipObjectResolution)
+		f.Close()
+		if err != nil {
+			pkg.Errors = append(pkg.Errors, convertError(err)...)
+			return pkg, nil
+		}
+		pkg.Syntax[i] = af
+	}
+	importer := func(path string) (*types.Package, error) {
+		if path == "unsafe" {
+			return types.Unsafe, nil
+		}
+		if path == "C" {
+			// go/packages doesn't tell us that cgo preprocessing
+			// failed. When we subsequently try to parse the package,
+			// we'll encounter the raw C import.
+			return nil, errors.New("cgo preprocessing failed")
+		}
+		ispecpkg := spec.Imports[path]
+		if ispecpkg == nil {
+			return nil, fmt.Errorf("trying to import %q in the context of %q returned nil PackageSpec", path, spec)
+		}
+		ipkg := prog.packages[ispecpkg.PkgPath]
+		if ipkg == nil {
+			return nil, fmt.Errorf("trying to import %q (%q) in the context of %q returned nil PackageSpec", ispecpkg.PkgPath, path, spec)
+		}
+		return ipkg, nil
+	}
+	tc := &types.Config{
+		Importer: importerFunc(importer),
+		Error: func(err error) {
+			pkg.Errors = append(pkg.Errors, convertError(err)...)
+		},
+	}
+	if prog.options.GoVersion == "module" {
+		if spec.Module != nil && spec.Module.GoVersion != "" {
+			tc.GoVersion = "go" + spec.Module.GoVersion
+		} else {
+			tags := build.Default.ReleaseTags
+			tc.GoVersion = tags[len(tags)-1]
+		}
+	} else {
+		tc.GoVersion = prog.options.GoVersion
+	}
+	// Note that the type-checker can return a non-nil error even though the Go
+	// compiler has already successfully built this package (which is an
+	// invariant of getting to this point), for example because of the Go
+	// version passed to the type checker.
+	err := types.NewChecker(tc, pkg.Fset, pkg.Types, pkg.TypesInfo).Files(pkg.Syntax)
+	return pkg, err
+}
+
+func convertError(err error) []packages.Error {
+	var errs []packages.Error
+	// taken from go/packages
+	switch err := err.(type) {
+	case packages.Error:
+		// from driver
+		errs = append(errs, err)
+
+	case *os.PathError:
+		// from parser
+		errs = append(errs, packages.Error{
+			Pos:  err.Path + ":1",
+			Msg:  err.Err.Error(),
+			Kind: packages.ParseError,
+		})
+
+	case scanner.ErrorList:
+		// from parser
+		for _, err := range err {
+			errs = append(errs, packages.Error{
+				Pos:  err.Pos.String(),
+				Msg:  err.Msg,
+				Kind: packages.ParseError,
+			})
+		}
+
+	case types.Error:
+		// from type checker
+		errs = append(errs, packages.Error{
+			Pos:  err.Fset.Position(err.Pos).String(),
+			Msg:  err.Msg,
+			Kind: packages.TypeError,
+		})
+
+	case config.ParseError:
+		errs = append(errs, packages.Error{
+			Pos:  fmt.Sprintf("%s:%d:%d", err.Filename, err.Position.Line, err.Position.Col),
+			Msg:  fmt.Sprintf("%s (last key parsed: %q)", err.Message, err.LastKey),
+			Kind: packages.ParseError,
+		})
+	default:
+		errs = append(errs, packages.Error{
+			Pos:  "-",
+			Msg:  err.Error(),
+			Kind: packages.UnknownError,
+		})
+	}
+	return errs
+}
+
+type importerFunc func(path string) (*types.Package, error)
+
+func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }
diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/ext.go b/vendor/honnef.co/go/tools/go/types/typeutil/ext.go
new file mode 100644
index 0000000..19b4ae5
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/types/typeutil/ext.go
@@ -0,0 +1,27 @@
+package typeutil
+
+import (
+	"fmt"
+	"go/types"
+)
+
+type Iterator struct {
+	elem types.Type
+}
+
+func (t *Iterator) Underlying() types.Type { return t }
+func (t *Iterator) String() string         { return fmt.Sprintf("iterator(%s)", t.elem) }
+func (t *Iterator) Elem() types.Type       { return t.elem }
+
+func NewIterator(elem types.Type) *Iterator {
+	return &Iterator{elem: elem}
+}
+
+type DeferStack struct{}
+
+func (t *DeferStack) Underlying() types.Type { return t }
+func (t *DeferStack) String() string         { return "deferStack" }
+
+func NewDeferStack() *DeferStack {
+	return &DeferStack{}
+}
diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/typeparams.go b/vendor/honnef.co/go/tools/go/types/typeutil/typeparams.go
new file mode 100644
index 0000000..a53c095
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/types/typeutil/typeparams.go
@@ -0,0 +1,114 @@
+package typeutil
+
+import (
+	"errors"
+	"go/types"
+	"slices"
+
+	"golang.org/x/exp/typeparams"
+)
+
+type TypeSet struct {
+	Terms []*types.Term
+	empty bool
+}
+
+func NewTypeSet(typ types.Type) TypeSet {
+	terms, err := typeparams.NormalTerms(typ)
+	if err != nil {
+		if errors.Is(err, typeparams.ErrEmptyTypeSet) {
+			return TypeSet{nil, true}
+		} else {
+			// We couldn't determine the type set. Assume it's all types.
+			return TypeSet{nil, false}
+		}
+	}
+	return TypeSet{terms, false}
+}
+
+// CoreType returns the type set's core type, or nil if it has none.
+// The function only looks at type terms and may thus return core types for some empty type sets, such as
+// 'interface { map[int]string; foo() }'
+func (ts TypeSet) CoreType() types.Type {
+	if len(ts.Terms) == 0 {
+		// Either the type set is empty, or it isn't constrained. Either way it doesn't have a core type.
+		return nil
+	}
+	typ := ts.Terms[0].Type().Underlying()
+	for _, term := range ts.Terms[1:] {
+		ut := term.Type().Underlying()
+		if types.Identical(typ, ut) {
+			continue
+		}
+
+		ch1, ok := typ.(*types.Chan)
+		if !ok {
+			return nil
+		}
+		ch2, ok := ut.(*types.Chan)
+		if !ok {
+			return nil
+		}
+		if !types.Identical(ch1.Elem(), ch2.Elem()) {
+			return nil
+		}
+		if ch1.Dir() == types.SendRecv {
+			// typ is currently a bidirectional channel. The term's type is either also bidirectional, or
+			// unidirectional. Use the term's type.
+			typ = ut
+		} else if ch2.Dir() == types.SendRecv {
+			// typ is currently a unidirectional channel and the term's type is bidirectional, which means it has no
+			// effect.
+			continue
+		} else if ch1.Dir() != ch2.Dir() {
+			// typ is not bidirectional and typ and term disagree about the direction
+			return nil
+		}
+	}
+	return typ
+}
+
+// CoreType is a wrapper for NewTypeSet(typ).CoreType()
+func CoreType(typ types.Type) types.Type {
+	return NewTypeSet(typ).CoreType()
+}
+
+// All calls fn for each term in the type set and reports whether all invocations returned true.
+// If the type set is empty or unconstrained, All immediately returns false.
+func (ts TypeSet) All(fn func(*types.Term) bool) bool {
+	if len(ts.Terms) == 0 {
+		return false
+	}
+	for _, term := range ts.Terms {
+		if !fn(term) {
+			return false
+		}
+	}
+	return true
+}
+
+// Any calls fn for each term in the type set and reports whether any invocation returned true.
+// It stops after the first call that returned true.
+func (ts TypeSet) Any(fn func(*types.Term) bool) bool {
+	return slices.ContainsFunc(ts.Terms, fn)
+}
+
+// All is a wrapper for NewTypeSet(typ).All(fn).
+func All(typ types.Type, fn func(*types.Term) bool) bool {
+	return NewTypeSet(typ).All(fn)
+}
+
+// Any is a wrapper for NewTypeSet(typ).Any(fn).
+func Any(typ types.Type, fn func(*types.Term) bool) bool {
+	return NewTypeSet(typ).Any(fn)
+}
+
+func IsType[T types.Type](term *types.Term) bool {
+	_, ok := term.Type().Underlying().(T)
+	return ok
+}
+
+//go:fix inline
+func IsSlice(term *types.Term) bool {
+	return IsType[*types.Slice](term)
+}
diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/unify.go b/vendor/honnef.co/go/tools/go/types/typeutil/unify.go
new file mode 100644
index 0000000..ced507c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/types/typeutil/unify.go
@@ -0,0 +1,345 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The code in this file is copied from
+// x/tools/gopls/internal/golang/implementation.go
+
+package typeutil
+
+import (
+	"fmt"
+	"go/types"
+	"iter"
+	"reflect"
+)
+
+// Unify reports whether the types of x and y match.
+//
+// If unifier is nil, unify reports only whether it succeeded.
+// If unifier is non-nil, it is populated with the values
+// of type parameters determined during a successful unification.
+// If unification succeeds without binding a type parameter, that parameter
+// will not be present in the map.
+//
+// On entry, the unifier's contents are treated as the values of already-bound type
+// parameters, constraining the unification.
+//
+// For example, if unifier is an empty (not nil) map on entry, then the types
+//
+//	func[T any](T, int)
+//
+// and
+//
+//	func[U any](bool, U)
+//
+// will unify, with T=bool and U=int.
+// That is, the contents of unifier after unify returns will be
+//
+//	{T: bool, U: int}
+//
+// where "T" is the type parameter T and "bool" is the basic type for bool.
+//
+// But if unifier is {T: int} is int on entry, then unification will fail, because T
+// does not unify with bool.
+//
+// Unify does not preserve aliases. For example, given the following:
+//
+//	type String = string
+//	type A[T] = T
+//
+// unification succeeds with T bound to string, not String.
+//
+// See also: unify in cache/methodsets/fingerprint, which implements
+// unification for type fingerprints, for the global index.
+//
+// BUG: literal interfaces are not handled properly. But this function is currently
+// used only for signatures, where such types are very rare.
+func Unify(x, y types.Type, unifier map[*types.TypeParam]types.Type) bool {
+	// bindings[tp] is the binding for type parameter tp.
+	// Although type parameters are nominally bound to types, each bindings[tp]
+	// is a pointer to a type, so unbound variables that unify can share a binding.
+	bindings := map[*types.TypeParam]*types.Type{}
+
+	// Bindings is initialized with pointers to the provided types.
+	for tp, t := range unifier {
+		bindings[tp] = &t
+	}
+
+	// bindingFor returns the *types.Type in bindings for tp if tp is not nil,
+	// creating one if needed.
+	bindingFor := func(tp *types.TypeParam) *types.Type {
+		if tp == nil {
+			return nil
+		}
+		b := bindings[tp]
+		if b == nil {
+			b = new(types.Type)
+			bindings[tp] = b
+		}
+		return b
+	}
+
+	// bind sets b to t if b does not occur in t.
+	bind := func(b *types.Type, t types.Type) bool {
+		for tp := range typeParams(t) {
+			if b == bindings[tp] {
+				return false // failed "occurs" check
+			}
+		}
+		*b = t
+		return true
+	}
+
+	// uni performs the actual unification.
+	depth := 0
+	var uni func(x, y types.Type) bool
+	uni = func(x, y types.Type) bool {
+		// Panic if recursion gets too deep, to detect bugs before
+		// overflowing the stack.
+		depth++
+		defer func() { depth-- }()
+		if depth > 100 {
+			panic("unify: max depth exceeded")
+		}
+
+		x = types.Unalias(x)
+		y = types.Unalias(y)
+
+		tpx, _ := x.(*types.TypeParam)
+		tpy, _ := y.(*types.TypeParam)
+		if tpx != nil || tpy != nil {
+			// Identical type params unify.
+			if tpx == tpy {
+				return true
+			}
+			bx := bindingFor(tpx)
+			by := bindingFor(tpy)
+
+			// If both args are type params and neither is bound, have them share a binding.
+			if bx != nil && by != nil && *bx == nil && *by == nil {
+				// Arbitrarily give y's binding to x.
+				bindings[tpx] = by
+				return true
+			}
+			// Treat param bindings like original args in what follows.
+			if bx != nil && *bx != nil {
+				x = *bx
+			}
+			if by != nil && *by != nil {
+				y = *by
+			}
+			// If the x param is unbound, bind it to y.
+			if bx != nil && *bx == nil {
+				return bind(bx, y)
+			}
+			// If the y param is unbound, bind it to x.
+			if by != nil && *by == nil {
+				return bind(by, x)
+			}
+			// Unify the binding of a bound parameter.
+			return uni(x, y)
+		}
+
+		// Neither arg is a type param.
+
+		if reflect.TypeOf(x) != reflect.TypeOf(y) {
+			return false // mismatched types
+		}
+
+		switch x := x.(type) {
+		case *types.Array:
+			y := y.(*types.Array)
+			return x.Len() == y.Len() &&
+				uni(x.Elem(), y.Elem())
+
+		case *types.Basic:
+			y := y.(*types.Basic)
+			return x.Kind() == y.Kind()
+
+		case *types.Chan:
+			y := y.(*types.Chan)
+			return x.Dir() == y.Dir() &&
+				uni(x.Elem(), y.Elem())
+
+		case *types.Interface:
+			y := y.(*types.Interface)
+			// TODO(adonovan,jba): fix: for correctness, we must check
+			// that both interfaces have the same set of methods
+			// modulo type parameters, while avoiding the risk of
+			// unbounded interface recursion.
+			//
+			// Since non-empty interface literals are vanishingly
+			// rare in methods signatures, we ignore this for now.
+			// If more precision is needed we could compare method
+			// names and arities, still without full recursion.
+			return x.NumMethods() == y.NumMethods()
+
+		case *types.Map:
+			y := y.(*types.Map)
+			return uni(x.Key(), y.Key()) &&
+				uni(x.Elem(), y.Elem())
+
+		case *types.Named:
+			y := y.(*types.Named)
+			if x.Origin() != y.Origin() {
+				return false // different named types
+			}
+			xtargs := x.TypeArgs()
+			ytargs := y.TypeArgs()
+			if xtargs.Len() != ytargs.Len() {
+				return false // arity error (ill-typed)
+			}
+			for i := range xtargs.Len() {
+				if !uni(xtargs.At(i), ytargs.At(i)) {
+					return false // mismatched type args
+				}
+			}
+			return true
+
+		case *types.Pointer:
+			y := y.(*types.Pointer)
+			return uni(x.Elem(), y.Elem())
+
+		case *types.Signature:
+			y := y.(*types.Signature)
+			return x.Variadic() == y.Variadic() &&
+				uni(x.Params(), y.Params()) &&
+				uni(x.Results(), y.Results())
+
+		case *types.Slice:
+			y := y.(*types.Slice)
+			return uni(x.Elem(), y.Elem())
+
+		case *types.Struct:
+			y := y.(*types.Struct)
+			if x.NumFields() != y.NumFields() {
+				return false
+			}
+			for i := range x.NumFields() {
+				xf := x.Field(i)
+				yf := y.Field(i)
+				if xf.Embedded() != yf.Embedded() ||
+					xf.Name() != yf.Name() ||
+					x.Tag(i) != y.Tag(i) ||
+					!xf.Exported() && xf.Pkg() != yf.Pkg() ||
+					!uni(xf.Type(), yf.Type()) {
+					return false
+				}
+			}
+			return true
+
+		case *types.Tuple:
+			y := y.(*types.Tuple)
+			if x.Len() != y.Len() {
+				return false
+			}
+			for i := range x.Len() {
+				if !uni(x.At(i).Type(), y.At(i).Type()) {
+					return false
+				}
+			}
+			return true
+
+		default: // incl. *Union, *TypeParam
+			panic(fmt.Sprintf("unexpected Type %#v", x))
+		}
+	}
+
+	if !uni(x, y) {
+		clear(unifier)
+		return false
+	}
+
+	// Populate the input map with the resulting types.
+	if unifier != nil {
+		for tparam, tptr := range bindings {
+			unifier[tparam] = *tptr
+		}
+	}
+	return true
+}
+
+// typeParams yields all the free type parameters within t that are relevant for
+// unification.
+//
+// Note: this function is tailored for the specific needs of the unification algorithm.
+// Don't try to use it for other purposes, see [typeparams.Free] instead.
+func typeParams(t types.Type) iter.Seq[*types.TypeParam] {
+	return func(yield func(*types.TypeParam) bool) {
+		seen := map[*types.TypeParam]bool{} // yield each type param only once
+
+		// tps(t) yields each TypeParam in t and returns false to stop.
+		var tps func(types.Type) bool
+		tps = func(t types.Type) bool {
+			t = types.Unalias(t)
+
+			switch t := t.(type) {
+			case *types.TypeParam:
+				if seen[t] {
+					return true
+				}
+				seen[t] = true
+				return yield(t)
+
+			case *types.Basic:
+				return true
+
+			case *types.Array:
+				return tps(t.Elem())
+
+			case *types.Chan:
+				return tps(t.Elem())
+
+			case *types.Interface:
+				// TODO(jba): implement.
+				return true
+
+			case *types.Map:
+				return tps(t.Key()) && tps(t.Elem())
+
+			case *types.Named:
+				if t.Origin() == t {
+					// generic type: look at type params
+					return every(t.TypeParams().TypeParams(),
+						func(tp *types.TypeParam) bool { return tps(tp) })
+				}
+				// instantiated type: look at type args
+				return every(t.TypeArgs().Types(), tps)
+
+			case *types.Pointer:
+				return tps(t.Elem())
+
+			case *types.Signature:
+				return tps(t.Params()) && tps(t.Results())
+
+			case *types.Slice:
+				return tps(t.Elem())
+
+			case *types.Struct:
+				return every(t.Fields(),
+					func(v *types.Var) bool { return tps(v.Type()) })
+
+			case *types.Tuple:
+				return every(t.Variables(),
+					func(v *types.Var) bool { return tps(v.Type()) })
+
+			default: // incl. *Union
+				panic(fmt.Sprintf("unexpected Type %#v", t))
+			}
+		}
+
+		tps(t)
+	}
+}
+
+// every reports whether every pred(t) for t in seq returns true,
+// stopping at the first false element.
+func every[T any](seq iter.Seq[T], pred func(T) bool) bool {
+	for t := range seq {
+		if !pred(t) {
+			return false
+		}
+	}
+	return true
+}
diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/upstream.go b/vendor/honnef.co/go/tools/go/types/typeutil/upstream.go
new file mode 100644
index 0000000..064964e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/types/typeutil/upstream.go
@@ -0,0 +1,52 @@
+package typeutil
+
+import (
+	"go/ast"
+	"go/types"
+	_ "unsafe"
+
+	"golang.org/x/tools/go/types/typeutil"
+)
+
+type MethodSetCache = typeutil.MethodSetCache
+type Hasher = typeutil.Hasher
+
+func Callee(info *types.Info, call *ast.CallExpr) types.Object {
+	return typeutil.Callee(info, call)
+}
+
+func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection {
+	return typeutil.IntuitiveMethodSet(T, msets)
+}
+
+func MakeHasher() Hasher {
+	return typeutil.MakeHasher()
+}
+
+type Map[V any] struct {
+	m typeutil.Map
+}
+
+func (m *Map[V]) Delete(key types.Type) bool { return m.m.Delete(key) }
+func (m *Map[V]) At(key types.Type) (V, bool) {
+	v := m.m.At(key)
+	if v == nil {
+		var zero V
+		return zero, false
+	} else {
+		return v.(V), true
+	}
+}
+func (m *Map[V]) Set(key types.Type, value V) { m.m.Set(key, value) }
+func (m *Map[V]) Len() int                    { return m.m.Len() }
+func (m *Map[V]) Iterate(f func(key types.Type, value V)) {
+	ff := func(key types.Type, value any) {
+		f(key, value.(V))
+	}
+	m.m.Iterate(ff)
+
+}
+func (m *Map[V]) Keys() []types.Type          { return m.m.Keys() }
+func (m *Map[V]) String() string              { return m.m.String() }
+func (m *Map[V]) KeysString() string          { return m.m.KeysString() }
+func (m *Map[V]) SetHasher(h typeutil.Hasher) { m.m.SetHasher(h) }
diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/util.go b/vendor/honnef.co/go/tools/go/types/typeutil/util.go
new file mode 100644
index 0000000..ffbd483
--- /dev/null
+++ b/vendor/honnef.co/go/tools/go/types/typeutil/util.go
@@ -0,0 +1,212 @@
+package typeutil
+
+import (
+	"bytes"
+	"go/types"
+	"strings"
+	"sync"
+
+	"golang.org/x/exp/typeparams"
+)
+
+var bufferPool = &sync.Pool{
+	New: func() any {
+		buf := bytes.NewBuffer(nil)
+		buf.Grow(64)
+		return buf
+	},
+}
+
+func FuncName(f *types.Func) string {
+	// We don't care about aliases in this function because we use FuncName to check calls
+	// to known methods, and method receivers are determined by the method declaration,
+	// not the call. Thus, even if a user does 'type Alias = *sync.Mutex' and calls
+	// Alias.Lock, we'll still see it as (*sync.Mutex).Lock.
+
+	buf := bufferPool.Get().(*bytes.Buffer)
+	buf.Reset()
+	if f.Type() != nil {
+		sig := f.Type().(*types.Signature)
+		if recv := sig.Recv(); recv != nil {
+			buf.WriteByte('(')
+			if _, ok := recv.Type().(*types.Interface); ok {
+				// gcimporter creates abstract methods of
+				// named interfaces using the interface type
+				// (not the named type) as the receiver.
+				// Don't print it in full.
+				buf.WriteString("interface")
+			} else {
+				types.WriteType(buf, recv.Type(), nil)
+			}
+			buf.WriteByte(')')
+			buf.WriteByte('.')
+		} else if f.Pkg() != nil {
+			writePackage(buf, f.Pkg())
+		}
+	}
+	buf.WriteString(f.Name())
+	s := buf.String()
+	bufferPool.Put(buf)
+	return s
+}
+
+func writePackage(buf *bytes.Buffer, pkg *types.Package) {
+	if pkg == nil {
+		return
+	}
+	s := pkg.Path()
+	if s != "" {
+		buf.WriteString(s)
+		buf.WriteByte('.')
+	}
+}
+
+// Dereference returns a pointer's element type; otherwise it returns
+// T.
+func Dereference(T types.Type) types.Type {
+	if p, ok := T.Underlying().(*types.Pointer); ok {
+		return p.Elem()
+	}
+	return T
+}
+
+// DereferenceR returns a pointer's element type; otherwise it returns
+// T. If the element type is itself a pointer, DereferenceR will be
+// applied recursively.
+func DereferenceR(T types.Type) types.Type {
+	if p, ok := T.Underlying().(*types.Pointer); ok {
+		return DereferenceR(p.Elem())
+	}
+	return T
+}
+
+func IsObject(obj types.Object, name string) bool {
+	var path string
+	if pkg := obj.Pkg(); pkg != nil {
+		path = pkg.Path() + "."
+	}
+	return path+obj.Name() == name
+}
+
+// IsTypeName reports whether obj represents the qualified name. If obj is a type alias,
+// IsTypeName checks both the alias and the aliased type, if the aliased type has a type
+// name.
+func IsTypeName(obj *types.TypeName, name string) bool {
+	var qf string
+	if idx := strings.LastIndex(name, "."); idx != -1 {
+		qf = name[:idx]
+		name = name[idx+1:]
+	}
+	if obj.Name() == name &&
+		((qf == "" && obj.Pkg() == nil) || (obj.Pkg() != nil && obj.Pkg().Path() == qf)) {
+		return true
+	}
+
+	if !obj.IsAlias() {
+		return false
+	}
+
+	// FIXME(dh): we should peel away one layer of alias at a time; this is blocked on
+	// github.com/golang/go/issues/66559
+	if typ, ok := types.Unalias(obj.Type()).(interface{ Obj() *types.TypeName }); ok {
+		return IsTypeName(typ.Obj(), name)
+	}
+
+	return false
+}
+
+func IsPointerToTypeWithName(typ types.Type, name string) bool {
+	ptr, ok := types.Unalias(typ).(*types.Pointer)
+	if !ok {
+		return false
+	}
+	return IsTypeWithName(ptr.Elem(), name)
+}
+
+// IsTypeWithName reports whether typ represents a type with the qualified name, If typ is
+// a type alias, IsTypeWithName checks both the alias and the aliased type. The following
+// types can have names: Basic, Named, Alias.
+func IsTypeWithName(typ types.Type, name string) bool {
+	switch typ := typ.(type) {
+	case *types.Basic:
+		return typ.Name() == name
+	case *types.Named:
+		return IsTypeName(typ.Obj(), name)
+	case *types.Alias:
+		// FIXME(dh): we should peel away one layer of alias at a time; this is blocked on
+		// github.com/golang/go/issues/66559
+
+		// IsTypeName already handles aliases to other aliases or named types; our
+		// fallback is required for aliases to basic types.
+		return IsTypeName(typ.Obj(), name) || IsTypeWithName(types.Unalias(typ), name)
+	default:
+		return false
+	}
+}
+
+// MaybePointerLike returns true if type T is like a pointer. This returns true
+// for all nillable types, unsafe.Pointer, type sets where at least one term is
+// pointer-like, and type sets without structural restrictions..
+func MaybePointerLike(T types.Type) bool {
+	switch T := T.Underlying().(type) {
+	case *types.Interface:
+		if T.IsMethodSet() {
+			return true
+		} else {
+			terms, err := typeparams.NormalTerms(T)
+			if err != nil {
+				return false
+			}
+			for _, term := range terms {
+				if MaybePointerLike(term.Type()) {
+					return true
+				}
+			}
+			return len(terms) == 0
+		}
+	case *types.Chan, *types.Map, *types.Signature, *types.Pointer, *types.Slice:
+		return true
+	case *types.Basic:
+		return T.Kind() == types.UnsafePointer
+	}
+	return false
+}
+
+type Field struct {
+	Var  *types.Var
+	Tag  string
+	Path []int
+}
+
+// FlattenFields recursively flattens T and embedded structs,
+// returning a list of fields. If multiple fields with the same name
+// exist, all will be returned.
+func FlattenFields(T *types.Struct) []Field {
+	return flattenFields(T, nil, nil)
+}
+
+func flattenFields(T *types.Struct, path []int, seen map[types.Type]bool) []Field {
+	if seen == nil {
+		seen = map[types.Type]bool{}
+	}
+	if seen[T] {
+		return nil
+	}
+	seen[T] = true
+	var out []Field
+	for i := 0; i < T.NumFields(); i++ {
+		field := T.Field(i)
+		tag := T.Tag(i)
+		np := append(path[:len(path):len(path)], i)
+		if field.Anonymous() {
+			if s, ok := Dereference(field.Type()).Underlying().(*types.Struct); ok {
+				out = append(out, flattenFields(s, np, seen)...)
+			} else {
+				out = append(out, Field{field, tag, np})
+			}
+		} else {
+			out = append(out, Field{field, tag, np})
+		}
+	}
+	return out
+}
diff --git a/vendor/honnef.co/go/tools/internal/iterutil/iterutil.go b/vendor/honnef.co/go/tools/internal/iterutil/iterutil.go
new file mode 100644
index 0000000..e2f1f09
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/iterutil/iterutil.go
@@ -0,0 +1,21 @@
+package iterutil
+
+import "iter"
+
+func All[T any](seq iter.Seq[T], fn func(T) bool) bool {
+	for v := range seq {
+		if !fn(v) {
+			return false
+		}
+	}
+	return true
+}
+
+func Any[T any](seq iter.Seq[T], fn func(T) bool) bool {
+	for v := range seq {
+		if fn(v) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go b/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go
new file mode 100644
index 0000000..1e2cc49
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go
@@ -0,0 +1,90 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package buildir defines an Analyzer that constructs the IR
+// of an error-free package and returns the set of all
+// functions within it. It does not report any diagnostics itself but
+// may be used as an input to other analyzers.
+//
+// THIS INTERFACE IS EXPERIMENTAL AND MAY BE SUBJECT TO INCOMPATIBLE CHANGE.
+package buildir
+
+import (
+	"reflect"
+
+	"honnef.co/go/tools/go/ir"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/ctrlflow"
+)
+
+var Debug = struct {
+	Mode ir.BuilderMode
+}{}
+
+var Analyzer = &analysis.Analyzer{
+	Name:       "buildir",
+	Doc:        "build IR for later passes",
+	Run:        run,
+	ResultType: reflect.TypeFor[*IR](),
+	Requires:   []*analysis.Analyzer{ctrlflow.Analyzer},
+}
+
+// IR provides intermediate representation for all the
+// source functions in the current package.
+type IR struct {
+	Pkg      *ir.Package
+	SrcFuncs []*ir.Function
+}
+
+func run(pass *analysis.Pass) (any, error) {
+	cfgs := pass.ResultOf[ctrlflow.Analyzer].(*ctrlflow.CFGs)
+
+	// Plundered from ssautil.BuildPackage.
+
+	// We must create a new Program for each Package because the
+	// analysis API provides no place to hang a Program shared by
+	// all Packages. Consequently, IR Packages and Functions do not
+	// have a canonical representation across an analysis session of
+	// multiple packages. This is unlikely to be a problem in
+	// practice because the analysis API essentially forces all
+	// packages to be analysed independently, so any given call to
+	// Analysis.Run on a package will see only IR objects belonging
+	// to a single Program.
+
+	mode := ir.GlobalDebug
+	if Debug.Mode != 0 {
+		mode = Debug.Mode
+	}
+
+	prog := ir.NewProgram(pass.Fset, mode)
+
+	prog.SetNoReturn(cfgs.NoReturn)
+
+	// Create IR packages for direct imports.
+	for _, p := range pass.Pkg.Imports() {
+		prog.CreatePackage(p, nil, nil, true)
+	}
+
+	// Create and build the primary package.
+	irpkg := prog.CreatePackage(pass.Pkg, pass.Files, pass.TypesInfo, false)
+	irpkg.Build()
+
+	// Compute list of source functions, including literals,
+	// in source order.
+	var addAnons func(f *ir.Function)
+	funcs := make([]*ir.Function, len(irpkg.Functions))
+	copy(funcs, irpkg.Functions)
+	addAnons = func(f *ir.Function) {
+		for _, anon := range f.AnonFuncs {
+			funcs = append(funcs, anon)
+			addAnons(anon)
+		}
+	}
+	for _, fn := range irpkg.Functions {
+		addAnons(fn)
+	}
+
+	return &IR{Pkg: irpkg, SrcFuncs: funcs}, nil
+}
diff --git a/vendor/honnef.co/go/tools/internal/renameio/UPSTREAM b/vendor/honnef.co/go/tools/internal/renameio/UPSTREAM
new file mode 100644
index 0000000..84eb321
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/renameio/UPSTREAM
@@ -0,0 +1,2 @@
+This package is a copy of cmd/go/internal/renameio.
+The upstream package no longer exists, as the Go project replaced all of its uses with the lockedfile package.
diff --git a/vendor/honnef.co/go/tools/internal/renameio/renameio.go b/vendor/honnef.co/go/tools/internal/renameio/renameio.go
new file mode 100644
index 0000000..4e02a42
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/renameio/renameio.go
@@ -0,0 +1,93 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package renameio writes files atomically by renaming temporary files.
+package renameio
+
+import (
+	"bytes"
+	"io"
+	"math/rand"
+	"os"
+	"path/filepath"
+	"strconv"
+
+	"honnef.co/go/tools/internal/robustio"
+)
+
+const patternSuffix = ".tmp"
+
+// Pattern returns a glob pattern that matches the unrenamed temporary files
+// created when writing to filename.
+func Pattern(filename string) string {
+	return filepath.Join(filepath.Dir(filename), filepath.Base(filename)+patternSuffix)
+}
+
+// WriteFile is like ioutil.WriteFile, but first writes data to an arbitrary
+// file in the same directory as filename, then renames it atomically to the
+// final name.
+//
+// That ensures that the final location, if it exists, is always a complete file.
+func WriteFile(filename string, data []byte, perm os.FileMode) (err error) {
+	return WriteToFile(filename, bytes.NewReader(data), perm)
+}
+
+// WriteToFile is a variant of WriteFile that accepts the data as an io.Reader
+// instead of a slice.
+func WriteToFile(filename string, data io.Reader, perm os.FileMode) (err error) {
+	f, err := tempFile(filepath.Dir(filename), filepath.Base(filename), perm)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		// Only call os.Remove on f.Name() if we failed to rename it: otherwise,
+		// some other process may have created a new file with the same name after
+		// that.
+		if err != nil {
+			f.Close()
+			os.Remove(f.Name())
+		}
+	}()
+
+	if _, err := io.Copy(f, data); err != nil {
+		return err
+	}
+	// Sync the file before renaming it: otherwise, after a crash the reader may
+	// observe a 0-length file instead of the actual contents.
+	// See https://golang.org/issue/22397#issuecomment-380831736.
+	if err := f.Sync(); err != nil {
+		return err
+	}
+	if err := f.Close(); err != nil {
+		return err
+	}
+
+	return robustio.Rename(f.Name(), filename)
+}
+
+// ReadFile is like ioutil.ReadFile, but on Windows retries spurious errors that
+// may occur if the file is concurrently replaced.
+//
+// Errors are classified heuristically and retries are bounded, so even this
+// function may occasionally return a spurious error on Windows.
+// If so, the error will likely wrap one of:
+//   - syscall.ERROR_ACCESS_DENIED
+//   - syscall.ERROR_FILE_NOT_FOUND
+//   - internal/syscall/windows.ERROR_SHARING_VIOLATION
+func ReadFile(filename string) ([]byte, error) {
+	return robustio.ReadFile(filename)
+}
+
+// tempFile creates a new temporary file with given permission bits.
+func tempFile(dir, prefix string, perm os.FileMode) (f *os.File, err error) {
+	for range 10000 {
+		name := filepath.Join(dir, prefix+strconv.Itoa(rand.Intn(1000000000))+patternSuffix)
+		f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm)
+		if os.IsExist(err) {
+			continue
+		}
+		break
+	}
+	return
+}
diff --git a/vendor/honnef.co/go/tools/internal/robustio/UPSTREAM b/vendor/honnef.co/go/tools/internal/robustio/UPSTREAM
new file mode 100644
index 0000000..b41cf06
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/robustio/UPSTREAM
@@ -0,0 +1,6 @@
+This package is a copy of cmd/go/internal/robustio.
+It is mostly in sync with upstream according to the last commit we've looked at,
+with the exception of still using I/O functions that work with older Go versions.
+
+The last upstream commit we've looked at was:
+dc04f3ba1f25313bc9c97e728620206c235db9ee
diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio.go b/vendor/honnef.co/go/tools/internal/robustio/robustio.go
new file mode 100644
index 0000000..15b3377
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/robustio/robustio.go
@@ -0,0 +1,53 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package robustio wraps I/O functions that are prone to failure on Windows,
+// transparently retrying errors up to an arbitrary timeout.
+//
+// Errors are classified heuristically and retries are bounded, so the functions
+// in this package do not completely eliminate spurious errors. However, they do
+// significantly reduce the rate of failure in practice.
+//
+// If so, the error will likely wrap one of:
+// The functions in this package do not completely eliminate spurious errors,
+// but substantially reduce their rate of occurrence in practice.
+package robustio
+
+// Rename is like os.Rename, but on Windows retries errors that may occur if the
+// file is concurrently read or overwritten.
+//
+// (See golang.org/issue/31247 and golang.org/issue/32188.)
+func Rename(oldpath, newpath string) error {
+	return rename(oldpath, newpath)
+}
+
+// ReadFile is like os.ReadFile, but on Windows retries errors that may
+// occur if the file is concurrently replaced.
+//
+// (See golang.org/issue/31247 and golang.org/issue/32188.)
+func ReadFile(filename string) ([]byte, error) {
+	return readFile(filename)
+}
+
+// RemoveAll is like os.RemoveAll, but on Windows retries errors that may occur
+// if an executable file in the directory has recently been executed.
+//
+// (See golang.org/issue/19491.)
+func RemoveAll(path string) error {
+	return removeAll(path)
+}
+
+// IsEphemeralError reports whether err is one of the errors that the functions
+// in this package attempt to mitigate.
+//
+// Errors considered ephemeral include:
+//   - syscall.ERROR_ACCESS_DENIED
+//   - syscall.ERROR_FILE_NOT_FOUND
+//   - internal/syscall/windows.ERROR_SHARING_VIOLATION
+//
+// This set may be expanded in the future; programs must not rely on the
+// non-ephemerality of any given error.
+func IsEphemeralError(err error) bool {
+	return isEphemeralError(err)
+}
diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_darwin.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_darwin.go
new file mode 100644
index 0000000..99fd8eb
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/robustio/robustio_darwin.go
@@ -0,0 +1,21 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package robustio
+
+import (
+	"errors"
+	"syscall"
+)
+
+const errFileNotFound = syscall.ENOENT
+
+// isEphemeralError returns true if err may be resolved by waiting.
+func isEphemeralError(err error) bool {
+	var errno syscall.Errno
+	if errors.As(err, &errno) {
+		return errno == errFileNotFound
+	}
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_flaky.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_flaky.go
new file mode 100644
index 0000000..c56e36c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/robustio/robustio_flaky.go
@@ -0,0 +1,91 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build windows || darwin
+
+package robustio
+
+import (
+	"errors"
+	"math/rand"
+	"os"
+	"syscall"
+	"time"
+)
+
+const arbitraryTimeout = 2000 * time.Millisecond
+
+// retry retries ephemeral errors from f up to an arbitrary timeout
+// to work around filesystem flakiness on Windows and Darwin.
+func retry(f func() (err error, mayRetry bool)) error {
+	var (
+		bestErr     error
+		lowestErrno syscall.Errno
+		start       time.Time
+		nextSleep   time.Duration = 1 * time.Millisecond
+	)
+	for {
+		err, mayRetry := f()
+		if err == nil || !mayRetry {
+			return err
+		}
+
+		var errno syscall.Errno
+		if errors.As(err, &errno) && (lowestErrno == 0 || errno < lowestErrno) {
+			bestErr = err
+			lowestErrno = errno
+		} else if bestErr == nil {
+			bestErr = err
+		}
+
+		if start.IsZero() {
+			start = time.Now()
+		} else if d := time.Since(start) + nextSleep; d >= arbitraryTimeout {
+			break
+		}
+		time.Sleep(nextSleep)
+		nextSleep += time.Duration(rand.Int63n(int64(nextSleep)))
+	}
+
+	return bestErr
+}
+
+// rename is like os.Rename, but retries ephemeral errors.
+//
+// On Windows it wraps os.Rename, which (as of 2019-06-04) uses MoveFileEx with
+// MOVEFILE_REPLACE_EXISTING.
+//
+// Windows also provides a different system call, ReplaceFile,
+// that provides similar semantics, but perhaps preserves more metadata. (The
+// documentation on the differences between the two is very sparse.)
+//
+// Empirical error rates with MoveFileEx are lower under modest concurrency, so
+// for now we're sticking with what the os package already provides.
+func rename(oldpath, newpath string) (err error) {
+	return retry(func() (err error, mayRetry bool) {
+		err = os.Rename(oldpath, newpath)
+		return err, isEphemeralError(err)
+	})
+}
+
+// readFile is like os.ReadFile, but retries ephemeral errors.
+func readFile(filename string) ([]byte, error) {
+	var b []byte
+	err := retry(func() (err error, mayRetry bool) {
+		b, err = os.ReadFile(filename)
+
+		// Unlike in rename, we do not retry errFileNotFound here: it can occur
+		// as a spurious error, but the file may also genuinely not exist, so the
+		// increase in robustness is probably not worth the extra latency.
+		return err, isEphemeralError(err) && !errors.Is(err, errFileNotFound)
+	})
+	return b, err
+}
+
+func removeAll(path string) error {
+	return retry(func() (err error, mayRetry bool) {
+		err = os.RemoveAll(path)
+		return err, isEphemeralError(err)
+	})
+}
diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_other.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_other.go
new file mode 100644
index 0000000..da9a46e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/robustio/robustio_other.go
@@ -0,0 +1,27 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !windows && !darwin
+
+package robustio
+
+import (
+	"os"
+)
+
+func rename(oldpath, newpath string) error {
+	return os.Rename(oldpath, newpath)
+}
+
+func readFile(filename string) ([]byte, error) {
+	return os.ReadFile(filename)
+}
+
+func removeAll(path string) error {
+	return os.RemoveAll(path)
+}
+
+func isEphemeralError(err error) bool {
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_windows.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_windows.go
new file mode 100644
index 0000000..200070a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/robustio/robustio_windows.go
@@ -0,0 +1,27 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package robustio
+
+import (
+	"errors"
+	"syscall"
+)
+
+const ERROR_SHARING_VIOLATION = 32
+const errFileNotFound = syscall.ERROR_FILE_NOT_FOUND
+
+// isEphemeralError returns true if err may be resolved by waiting.
+func isEphemeralError(err error) bool {
+	var errno syscall.Errno
+	if errors.As(err, &errno) {
+		switch errno {
+		case syscall.ERROR_ACCESS_DENIED,
+			syscall.ERROR_FILE_NOT_FOUND,
+			ERROR_SHARING_VIOLATION:
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go b/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go
new file mode 100644
index 0000000..6bae3f7
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go
@@ -0,0 +1,208 @@
+package sharedcheck
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/facts/tokenfile"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+func CheckRangeStringRunes(pass *analysis.Pass) (any, error) {
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		cb := func(node ast.Node) bool {
+			rng, ok := node.(*ast.RangeStmt)
+			if !ok || !astutil.IsBlank(rng.Key) {
+				return true
+			}
+
+			v, _ := fn.ValueForExpr(rng.X)
+
+			// Check that we're converting from string to []rune
+			val, _ := v.(*ir.Convert)
+			if val == nil {
+				return true
+			}
+			Tsrc, ok := typeutil.CoreType(val.X.Type()).(*types.Basic)
+			if !ok || Tsrc.Kind() != types.String {
+				return true
+			}
+			Tdst, ok := typeutil.CoreType(val.Type()).(*types.Slice)
+			if !ok {
+				return true
+			}
+			TdstElem, ok := types.Unalias(Tdst.Elem()).(*types.Basic)
+			if !ok || TdstElem.Kind() != types.Int32 {
+				return true
+			}
+
+			// Check that the result of the conversion is only used to
+			// range over
+			refs := val.Referrers()
+			if refs == nil {
+				return true
+			}
+
+			// Expect two refs: one for obtaining the length of the slice,
+			// one for accessing the elements
+			if len(*refs) != 2 {
+				// TODO(dh): right now, we check that only one place
+				// refers to our slice. This will miss cases such as
+				// ranging over the slice twice. Ideally, we'd ensure that
+				// the slice is only used for ranging over (without
+				// accessing the key), but that is harder to do because in
+				// IR form, ranging over a slice looks like an ordinary
+				// loop with index increments and slice accesses. We'd
+				// have to look at the associated AST node to check that
+				// it's a range statement.
+				return true
+			}
+
+			pass.Reportf(rng.Pos(), "should range over string, not []rune(string)")
+
+			return true
+		}
+		if source := fn.Source(); source != nil {
+			ast.Inspect(source, cb)
+		}
+	}
+	return nil, nil
+}
+
+// RedundantTypeInDeclarationChecker returns a checker that flags variable declarations with redundantly specified types.
+// That is, it flags 'var v T = e' where e's type is identical to T and 'var v = e' (or 'v := e') would have the same effect.
+//
+// It does not flag variables under the following conditions, to reduce the number of false positives:
+// - global variables – these often specify types to aid godoc
+// - files that use cgo – cgo code generation and pointer checking emits redundant types
+//
+// It does not flag variables under the following conditions, unless flagHelpfulTypes is true, to reduce the number of noisy positives:
+// - packages that import syscall or unsafe – these sometimes use this form of assignment to make sure types are as expected
+// - variables named the blank identifier – a pattern used to confirm the types of variables
+// - untyped expressions on the rhs – the explicitness might aid readability
+func RedundantTypeInDeclarationChecker(verb string, flagHelpfulTypes bool) *analysis.Analyzer {
+	fn := func(pass *analysis.Pass) (any, error) {
+		eval := func(expr ast.Expr) (types.TypeAndValue, error) {
+			info := &types.Info{
+				Types: map[ast.Expr]types.TypeAndValue{},
+			}
+			err := types.CheckExpr(pass.Fset, pass.Pkg, expr.Pos(), expr, info)
+			return info.Types[expr], err
+		}
+
+		if !flagHelpfulTypes {
+			// Don't look at code in low-level packages
+			for _, imp := range pass.Pkg.Imports() {
+				if imp.Path() == "syscall" || imp.Path() == "unsafe" {
+					return nil, nil
+				}
+			}
+		}
+
+		fn := func(node ast.Node) {
+			decl := node.(*ast.GenDecl)
+			if decl.Tok != token.VAR {
+				return
+			}
+
+			gen, _ := code.Generator(pass, decl.Pos())
+			if gen == generated.Cgo {
+				// TODO(dh): remove this exception once we can use UsesCgo
+				return
+			}
+
+			// Delay looking up parent AST nodes until we have to
+			checkedDecl := false
+
+		specLoop:
+			for _, spec := range decl.Specs {
+				spec := spec.(*ast.ValueSpec)
+				if spec.Type == nil {
+					continue
+				}
+				if len(spec.Names) != len(spec.Values) {
+					continue
+				}
+				Tlhs := pass.TypesInfo.TypeOf(spec.Type)
+				for i, v := range spec.Values {
+					if !flagHelpfulTypes && spec.Names[i].Name == "_" {
+						continue specLoop
+					}
+					Trhs := pass.TypesInfo.TypeOf(v)
+					if !types.Identical(Tlhs, Trhs) {
+						continue specLoop
+					}
+
+					// Some expressions are untyped and get converted to the lhs type implicitly.
+					// This applies to untyped constants, shift operations with an untyped lhs, and possibly others.
+					//
+					// Check if the type is truly redundant, i.e. if the type on the lhs doesn't match the default type of the untyped constant.
+					tv, err := eval(v)
+					if err != nil {
+						panic(err)
+					}
+					if b, ok := types.Unalias(tv.Type).(*types.Basic); ok && (b.Info()&types.IsUntyped) != 0 {
+						if Tlhs != types.Default(b) {
+							// The rhs is untyped and its default type differs from the explicit type on the lhs
+							continue specLoop
+						}
+						switch v := v.(type) {
+						case *ast.Ident:
+							// Only flag named constant rhs if it's a predeclared identifier.
+							// Don't flag other named constants, as the explicit type may aid readability.
+							if pass.TypesInfo.ObjectOf(v).Pkg() != nil && !flagHelpfulTypes {
+								continue specLoop
+							}
+						case *ast.BasicLit:
+							// Do flag basic literals
+						default:
+							// Don't flag untyped rhs expressions unless flagHelpfulTypes is set
+							if !flagHelpfulTypes {
+								continue specLoop
+							}
+						}
+					}
+				}
+
+				if !checkedDecl {
+					// Don't flag global variables. These often have explicit types for godoc's sake.
+					path, _ := astutil.PathEnclosingInterval(code.File(pass, decl), decl.Pos(), decl.Pos())
+				pathLoop:
+					for _, el := range path {
+						switch el.(type) {
+						case *ast.FuncDecl, *ast.FuncLit:
+							checkedDecl = true
+							break pathLoop
+						}
+					}
+					if !checkedDecl {
+						// decl is not inside a function
+						break specLoop
+					}
+				}
+
+				report.Report(pass, spec.Type, fmt.Sprintf("%s omit type %s from declaration; it will be inferred from the right-hand side", verb, report.Render(pass, spec.Type)), report.FilterGenerated(),
+					report.Fixes(edit.Fix("Remove redundant type", edit.Delete(spec.Type))))
+			}
+		}
+		code.Preorder(pass, fn, (*ast.GenDecl)(nil))
+		return nil, nil
+	}
+
+	return &analysis.Analyzer{
+		Run:      fn,
+		Requires: []*analysis.Analyzer{generated.Analyzer, inspect.Analyzer, tokenfile.Analyzer},
+	}
+}
diff --git a/vendor/honnef.co/go/tools/internal/sync/sync.go b/vendor/honnef.co/go/tools/internal/sync/sync.go
new file mode 100644
index 0000000..e78ad50
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/sync/sync.go
@@ -0,0 +1,36 @@
+package sync
+
+type Semaphore struct {
+	ch chan struct{}
+}
+
+func NewSemaphore(size int) Semaphore {
+	return Semaphore{
+		ch: make(chan struct{}, size),
+	}
+}
+
+func (sem Semaphore) Acquire() {
+	sem.ch <- struct{}{}
+}
+
+func (sem Semaphore) AcquireMaybe() bool {
+	select {
+	case sem.ch <- struct{}{}:
+		return true
+	default:
+		return false
+	}
+}
+
+func (sem Semaphore) Release() {
+	<-sem.ch
+}
+
+func (sem Semaphore) Len() int {
+	return len(sem.ch)
+}
+
+func (sem Semaphore) Cap() int {
+	return cap(sem.ch)
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/aliases/aliases.go b/vendor/honnef.co/go/tools/internal/xtools-internal/aliases/aliases.go
new file mode 100644
index 0000000..a4ae04b
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/aliases/aliases.go
@@ -0,0 +1,18 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package aliases
+
+import (
+	"go/token"
+	"go/types"
+)
+
+// New creates a new TypeName in Package pkg that
+// is an alias for the type rhs.
+func New(pos token.Pos, pkg *types.Package, name string, rhs types.Type, tparams []*types.TypeParam) *types.TypeName {
+	tname := types.NewTypeName(pos, pkg, name, nil)
+	types.NewAlias(tname, rhs).SetTypeParams(tparams)
+	return tname
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/analysis/typeindex/typeindex.go b/vendor/honnef.co/go/tools/internal/xtools-internal/analysis/typeindex/typeindex.go
new file mode 100644
index 0000000..1bd7b78
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/analysis/typeindex/typeindex.go
@@ -0,0 +1,33 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package typeindex defines an analyzer that provides a
+// [honnef.co/go/tools/internal/xtools-internal/typesinternal/typeindex.Index].
+//
+// Like [golang.org/x/tools/go/analysis/passes/inspect], it is
+// intended to be used as a helper by other analyzers; it reports no
+// diagnostics of its own.
+package typeindex
+
+import (
+	"reflect"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+	"honnef.co/go/tools/internal/xtools-internal/typesinternal/typeindex"
+)
+
+var Analyzer = &analysis.Analyzer{
+	Name: "typeindex",
+	Doc:  "indexes of type information for later passes",
+	URL:  "https://pkg.go.dev/honnef.co/go/tools/internal/xtools-internal/analysis/typeindex",
+	Run: func(pass *analysis.Pass) (any, error) {
+		inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+		return typeindex.New(inspect, pass.Pkg, pass.TypesInfo), nil
+	},
+	RunDespiteErrors: true,
+	Requires:         []*analysis.Analyzer{inspect.Analyzer},
+	ResultType:       reflect.TypeFor[*typeindex.Index](),
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/clone.go b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/clone.go
new file mode 100644
index 0000000..2c9b6bb
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/clone.go
@@ -0,0 +1,71 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astutil
+
+import (
+	"go/ast"
+	"reflect"
+)
+
+// CloneNode returns a deep copy of a Node.
+// It omits pointers to ast.{Scope,Object} variables.
+func CloneNode[T ast.Node](n T) T {
+	return cloneNode(n).(T)
+}
+
+func cloneNode(n ast.Node) ast.Node {
+	var clone func(x reflect.Value) reflect.Value
+	set := func(dst, src reflect.Value) {
+		src = clone(src)
+		if src.IsValid() {
+			dst.Set(src)
+		}
+	}
+	clone = func(x reflect.Value) reflect.Value {
+		switch x.Kind() {
+		case reflect.Pointer:
+			if x.IsNil() {
+				return x
+			}
+			// Skip fields of types potentially involved in cycles.
+			switch x.Interface().(type) {
+			case *ast.Object, *ast.Scope:
+				return reflect.Zero(x.Type())
+			}
+			y := reflect.New(x.Type().Elem())
+			set(y.Elem(), x.Elem())
+			return y
+
+		case reflect.Struct:
+			y := reflect.New(x.Type()).Elem()
+			for i := 0; i < x.Type().NumField(); i++ {
+				set(y.Field(i), x.Field(i))
+			}
+			return y
+
+		case reflect.Slice:
+			if x.IsNil() {
+				return x
+			}
+			y := reflect.MakeSlice(x.Type(), x.Len(), x.Cap())
+			for i := 0; i < x.Len(); i++ {
+				set(y.Index(i), x.Index(i))
+			}
+			return y
+
+		case reflect.Interface:
+			y := reflect.New(x.Type()).Elem()
+			set(y, x.Elem())
+			return y
+
+		case reflect.Array, reflect.Chan, reflect.Func, reflect.Map, reflect.UnsafePointer:
+			panic(x) // unreachable in AST
+
+		default:
+			return x // bool, string, number
+		}
+	}
+	return clone(reflect.ValueOf(n)).Interface().(ast.Node)
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/comment.go b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/comment.go
new file mode 100644
index 0000000..865c8bf
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/comment.go
@@ -0,0 +1,71 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astutil
+
+import (
+	"go/ast"
+	"go/token"
+	"iter"
+	"sort"
+	"strings"
+)
+
+// Deprecation returns the paragraph of the doc comment that starts with the
+// conventional "Deprecation: " marker, as defined by
+// https://go.dev/wiki/Deprecated, or "" if the documented symbol is not
+// deprecated.
+func Deprecation(doc *ast.CommentGroup) string {
+	for p := range strings.SplitSeq(doc.Text(), "\n\n") {
+		// There is still some ambiguity for deprecation message. This function
+		// only returns the paragraph introduced by "Deprecated: ". More
+		// information related to the deprecation may follow in additional
+		// paragraphs, but the deprecation message should be able to stand on
+		// its own. See golang/go#38743.
+		if strings.HasPrefix(p, "Deprecated: ") {
+			return p
+		}
+	}
+	return ""
+}
+
+func Directives(g *ast.CommentGroup) (res []ast.Directive) {
+	if g != nil {
+		// Avoid (*ast.CommentGroup).Text() as it swallows directives.
+		for _, c := range g.List {
+			if d, ok := ast.ParseDirective(c.Slash, c.Text); ok {
+				res = append(res, d)
+			}
+		}
+	}
+	return
+}
+
+// Comments returns an iterator over the comments overlapping the specified interval.
+// Comments are sorted by position in the file, so we can use binary search.
+func Comments(file *ast.File, start, end token.Pos) iter.Seq[*ast.Comment] {
+	return func(yield func(*ast.Comment) bool) {
+		// Find the first comment group that overlaps the range.
+		i := sort.Search(len(file.Comments), func(i int) bool {
+			return file.Comments[i].End() >= start
+		})
+		for _, cg := range file.Comments[i:] {
+			if cg.Pos() > end {
+				return
+			}
+			// Find the first comment in the group that overlaps the range.
+			j := sort.Search(len(cg.List), func(j int) bool {
+				return cg.List[j].End() >= start
+			})
+			for _, co := range cg.List[j:] {
+				if co.Pos() > end {
+					return
+				}
+				if !yield(co) {
+					return
+				}
+			}
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/cursor.go b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/cursor.go
new file mode 100644
index 0000000..74e75d1
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/cursor.go
@@ -0,0 +1,38 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astutil
+
+import (
+	"go/ast"
+
+	"golang.org/x/tools/go/ast/edge"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+// UnparenCursor returns the cursor for an expression with any
+// enclosing parentheses removed, similar to [ast.Unparen].
+// It is often prudent to call this before switching on the
+// type of cur.Node().
+//
+// See also [UnparenEnclosingCursor].
+func UnparenCursor(cur inspector.Cursor) inspector.Cursor {
+	for is[*ast.ParenExpr](cur) {
+		cur, _ = cur.FirstChild()
+	}
+	return cur
+}
+
+// UnparenEnclosingCursor returns the first element of
+// the [Cursor.Enclosing] sequence that is not itself enclosed
+// in parens. It is often prudent to call this before switching on
+// cur.ParentEdge().
+//
+// See also [UnparenCursor].
+func UnparenEnclosingCursor(cur inspector.Cursor) inspector.Cursor {
+	for cur.ParentEdgeKind() == edge.ParenExpr_X {
+		cur = cur.Parent()
+	}
+	return cur
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/equal.go b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/equal.go
new file mode 100644
index 0000000..210f392
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/equal.go
@@ -0,0 +1,107 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astutil
+
+import (
+	"go/ast"
+	"go/token"
+	"reflect"
+)
+
+// Equal reports whether two nodes are structurally equal,
+// ignoring fields of type [token.Pos], [ast.Object],
+// and [ast.Scope], and comments.
+//
+// The operands x and y may be nil.
+// A nil slice is not equal to an empty slice.
+//
+// The provided function determines whether two identifiers
+// should be considered identical.
+func Equal(x, y ast.Node, identical func(x, y *ast.Ident) bool) bool {
+	if x == nil || y == nil {
+		return x == y
+	}
+	return equal(reflect.ValueOf(x), reflect.ValueOf(y), identical)
+}
+
+// EqualSyntax reports whether x and y are equal.
+// Identifiers are considered equal if they are spelled the same.
+// Comments are ignored.
+func EqualSyntax(x, y ast.Expr) bool {
+	sameName := func(x, y *ast.Ident) bool { return x.Name == y.Name }
+	return Equal(x, y, sameName)
+}
+
+func equal(x, y reflect.Value, identical func(x, y *ast.Ident) bool) bool {
+	// Ensure types are the same
+	if x.Type() != y.Type() {
+		return false
+	}
+	switch x.Kind() {
+	case reflect.Pointer:
+		if x.IsNil() || y.IsNil() {
+			return x.IsNil() == y.IsNil()
+		}
+		switch t := x.Interface().(type) {
+		// Skip fields of types potentially involved in cycles.
+		case *ast.Object, *ast.Scope, *ast.CommentGroup:
+			return true
+		case *ast.Ident:
+			return identical(t, y.Interface().(*ast.Ident))
+		default:
+			return equal(x.Elem(), y.Elem(), identical)
+		}
+
+	case reflect.Interface:
+		if x.IsNil() || y.IsNil() {
+			return x.IsNil() == y.IsNil()
+		}
+		return equal(x.Elem(), y.Elem(), identical)
+
+	case reflect.Struct:
+		for i := range x.NumField() {
+			xf := x.Field(i)
+			yf := y.Field(i)
+			// Skip position fields.
+			if xpos, ok := xf.Interface().(token.Pos); ok {
+				ypos := yf.Interface().(token.Pos)
+				// Numeric value of a Pos is not significant but its "zeroness" is,
+				// because it is often significant, e.g. CallExpr.Variadic(Ellipsis), ChanType.Arrow.
+				if xpos.IsValid() != ypos.IsValid() {
+					return false
+				}
+			} else if !equal(xf, yf, identical) {
+				return false
+			}
+		}
+		return true
+
+	case reflect.Slice:
+		if x.IsNil() || y.IsNil() {
+			return x.IsNil() == y.IsNil()
+		}
+		if x.Len() != y.Len() {
+			return false
+		}
+		for i := range x.Len() {
+			if !equal(x.Index(i), y.Index(i), identical) {
+				return false
+			}
+		}
+		return true
+
+	case reflect.String:
+		return x.String() == y.String()
+
+	case reflect.Bool:
+		return x.Bool() == y.Bool()
+
+	case reflect.Int:
+		return x.Int() == y.Int()
+
+	default:
+		panic(x)
+	}
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/fields.go b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/fields.go
new file mode 100644
index 0000000..8b81ea4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/fields.go
@@ -0,0 +1,35 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astutil
+
+import (
+	"go/ast"
+	"iter"
+)
+
+// FlatFields 'flattens' an ast.FieldList, returning an iterator over each
+// (name, field) combination in the list. For unnamed fields, the identifier is
+// nil.
+func FlatFields(list *ast.FieldList) iter.Seq2[*ast.Ident, *ast.Field] {
+	return func(yield func(*ast.Ident, *ast.Field) bool) {
+		if list == nil {
+			return
+		}
+
+		for _, field := range list.List {
+			if len(field.Names) == 0 {
+				if !yield(nil, field) {
+					return
+				}
+			} else {
+				for _, name := range field.Names {
+					if !yield(name, field) {
+						return
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/purge.go b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/purge.go
new file mode 100644
index 0000000..d0a3941
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/purge.go
@@ -0,0 +1,93 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package astutil provides various AST utility functions for gopls.
+package astutil
+
+import (
+	"bytes"
+	"go/scanner"
+	"go/token"
+)
+
+// PurgeFuncBodies returns a copy of src in which the contents of each
+// outermost {...} region have been deleted, except for struct and
+// interface type bodies and the bodies of length-elided array
+// literals ([...]T), whose element count is part of the type. It
+// includes function bodies, function-literal bodies, and the bodies
+// of slice, map, and explicitly-sized array composite literals (whose
+// contents don't affect the type of the enclosing declaration). This
+// reduces the amount of work required to parse the top-level
+// declarations.
+//
+// PurgeFuncBodies does not preserve newlines or position information.
+// Also, if the input is invalid, parsing the output of
+// PurgeFuncBodies may result in a different tree due to its effects
+// on parser error recovery.
+func PurgeFuncBodies(src []byte) []byte {
+	// Destroy the content of any {...}-bracketed regions that are
+	// not immediately preceded by a "struct" or "interface" token,
+	// and that are not the body of a length-elided array literal.
+	// That includes function bodies, switch/select bodies, and most
+	// composite literals; this will lead to non-void functions that
+	// don't have return statements, which of course is a type error,
+	// but that's ok.
+
+	var out bytes.Buffer
+	file := token.NewFileSet().AddFile("", -1, len(src))
+	var sc scanner.Scanner
+	sc.Init(file, src, nil, 0)
+	var prev token.Token
+	var cursor int         // last consumed src offset
+	var braces []token.Pos // stack of unclosed braces, or -1 for a region we preserve
+	var ellipsis bool      // saw "[...]" not yet consumed by a literal-body "{"
+	for {
+		pos, tok, _ := sc.Scan()
+		if tok == token.EOF {
+			break
+		}
+		switch tok {
+		case token.COMMENT:
+			// TODO(adonovan): opt: skip, to save an estimated 20% of time.
+
+		case token.SEMICOLON:
+			ellipsis = false
+
+		case token.RBRACK:
+			// "...]" occurs only in the array-type prefix of a
+			// composite literal; variadic "..." is followed by
+			// a type or ")", never "]".
+			if prev == token.ELLIPSIS {
+				ellipsis = true
+			}
+
+		case token.LBRACE:
+			if prev == token.STRUCT || prev == token.INTERFACE {
+				pos = -1 // type body: preserve (don't consume ellipsis)
+			} else if ellipsis {
+				pos = -1 // [...]T literal body: preserve
+				ellipsis = false
+			}
+			braces = append(braces, pos)
+
+		case token.RBRACE:
+			if last := len(braces) - 1; last >= 0 {
+				top := braces[last]
+				braces = braces[:last]
+				if top < 0 {
+					// preserve
+				} else if len(braces) == 0 { // toplevel only
+					// Delete {...} body.
+					start := file.Offset(top)
+					end := file.Offset(pos)
+					out.Write(src[cursor : start+len("{")])
+					cursor = end
+				}
+			}
+		}
+		prev = tok
+	}
+	out.Write(src[cursor:])
+	return out.Bytes()
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/stringlit.go b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/stringlit.go
new file mode 100644
index 0000000..eb49d45
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/stringlit.go
@@ -0,0 +1,103 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astutil
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strconv"
+	"unicode/utf8"
+)
+
+// RangeInStringLiteral calculates the positional range within a string literal
+// corresponding to the specified start and end byte offsets within the logical string.
+func RangeInStringLiteral(lit *ast.BasicLit, start, end int) (Range, error) {
+	startPos, err := PosInStringLiteral(lit, start)
+	if err != nil {
+		return Range{}, fmt.Errorf("start: %v", err)
+	}
+	endPos, err := PosInStringLiteral(lit, end)
+	if err != nil {
+		return Range{}, fmt.Errorf("end: %v", err)
+	}
+	return Range{startPos, endPos}, nil
+}
+
+// PosInStringLiteral returns the position within a string literal
+// corresponding to the specified byte offset within the logical
+// string that it denotes.
+func PosInStringLiteral(lit *ast.BasicLit, offset int) (token.Pos, error) {
+	raw := lit.Value
+
+	value, err := strconv.Unquote(raw)
+	if err != nil {
+		return 0, err
+	}
+	if !(0 <= offset && offset <= len(value)) {
+		return 0, fmt.Errorf("invalid offset")
+	}
+
+	pos, _ := walkStringLiteral(lit, lit.End(), offset)
+	return pos, nil
+}
+
+// OffsetInStringLiteral returns the byte offset within the logical (unquoted)
+// string corresponding to the specified source position.
+func OffsetInStringLiteral(lit *ast.BasicLit, pos token.Pos) (int, error) {
+	if !NodeContainsPos(lit, pos) {
+		return 0, fmt.Errorf("invalid position")
+	}
+
+	raw := lit.Value
+
+	value, err := strconv.Unquote(raw)
+	if err != nil {
+		return 0, err
+	}
+
+	_, offset := walkStringLiteral(lit, pos, len(value))
+	return offset, nil
+}
+
+// walkStringLiteral iterates through the raw string literal to map between
+// a file position and a logical byte offset. It stops when it reaches
+// either the targetPos or the targetOffset.
+//
+// TODO(hxjiang): consider making an iterator.
+func walkStringLiteral(lit *ast.BasicLit, targetPos token.Pos, targetOffset int) (token.Pos, int) {
+	raw := lit.Value
+	norm := int(lit.End()-lit.Pos()) > len(lit.Value)
+
+	// remove quotes
+	quote := raw[0] // '"' or '`'
+	raw = raw[1 : len(raw)-1]
+
+	var (
+		i   = 0             // byte index within logical value
+		pos = lit.Pos() + 1 // position within literal
+	)
+
+	for raw != "" {
+		r, _, rest, _ := strconv.UnquoteChar(raw, quote) // can't fail
+		sz := len(raw) - len(rest)                       // length of literal char in raw bytes
+
+		nextPos := pos + token.Pos(sz)
+		if norm && r == '\n' {
+			nextPos++
+		}
+		nextI := i + utf8.RuneLen(r) // length of logical char in "cooked" bytes
+
+		if nextPos > targetPos || nextI > targetOffset {
+			break
+		}
+
+		raw = raw[sz:]
+		i = nextI
+		pos = nextPos
+	}
+
+	return pos, i
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/unpack.go b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/unpack.go
new file mode 100644
index 0000000..3d2fb04
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/unpack.go
@@ -0,0 +1,61 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astutil
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/internal/xtools-internal/typeparams"
+)
+
+// UnpackRecv unpacks a receiver type expression, reporting whether it is a
+// pointer receiver, along with the type name identifier and any receiver type
+// parameter identifiers.
+//
+// Copied (with modifications) from go/types.
+func UnpackRecv(rtyp ast.Expr) (ptr bool, rname *ast.Ident, tparams []*ast.Ident) {
+L: // unpack receiver type
+	// This accepts invalid receivers such as ***T and does not
+	// work for other invalid receivers, but we don't care. The
+	// validity of receiver expressions is checked elsewhere.
+	for {
+		switch t := rtyp.(type) {
+		case *ast.ParenExpr:
+			rtyp = t.X
+		case *ast.StarExpr:
+			ptr = true
+			rtyp = t.X
+		default:
+			break L
+		}
+	}
+
+	// unpack type parameters, if any
+	switch rtyp.(type) {
+	case *ast.IndexExpr, *ast.IndexListExpr:
+		var indices []ast.Expr
+		rtyp, _, indices, _ = typeparams.UnpackIndexExpr(rtyp)
+		for _, arg := range indices {
+			var par *ast.Ident
+			switch arg := arg.(type) {
+			case *ast.Ident:
+				par = arg
+			default:
+				// ignore errors
+			}
+			if par == nil {
+				par = &ast.Ident{NamePos: arg.Pos(), Name: "_"}
+			}
+			tparams = append(tparams, par)
+		}
+	}
+
+	// unpack receiver name
+	if name, _ := rtyp.(*ast.Ident); name != nil {
+		rname = name
+	}
+
+	return
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/util.go b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/util.go
new file mode 100644
index 0000000..6d974db
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/astutil/util.go
@@ -0,0 +1,261 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astutil
+
+import (
+	"fmt"
+	"go/ast"
+	"go/printer"
+	"go/token"
+	"strings"
+
+	"golang.org/x/tools/go/ast/inspector"
+	"honnef.co/go/tools/internal/xtools-internal/moreiters"
+)
+
+// NodeContains reports whether the Pos/End range of node n encloses
+// the given range.
+//
+// It is inclusive of both end points, to allow hovering (etc) when
+// the cursor is immediately after a node.
+//
+// Like [NodeRange], it treats the range of an [ast.File] as the
+// file's complete extent.
+//
+// Precondition: n must not be nil.
+func NodeContains(n ast.Node, rng Range) bool {
+	return NodeRange(n).Contains(rng)
+}
+
+// NodeContainsPos reports whether the Pos/End range of node n encloses
+// the given pos.
+//
+// Like [NodeRange], it treats the range of an [ast.File] as the
+// file's complete extent.
+func NodeContainsPos(n ast.Node, pos token.Pos) bool {
+	return NodeRange(n).ContainsPos(pos)
+}
+
+// EnclosingFile returns the syntax tree for the file enclosing c.
+//
+// TODO(adonovan): promote this to a method of Cursor.
+func EnclosingFile(c inspector.Cursor) *ast.File {
+	c, _ = moreiters.First(c.Enclosing((*ast.File)(nil)))
+	return c.Node().(*ast.File)
+}
+
+// DocComment returns the doc comment for a node, if any.
+func DocComment(n ast.Node) *ast.CommentGroup {
+	switch n := n.(type) {
+	case *ast.FuncDecl:
+		return n.Doc
+	case *ast.GenDecl:
+		return n.Doc
+	case *ast.ValueSpec:
+		return n.Doc
+	case *ast.TypeSpec:
+		return n.Doc
+	case *ast.File:
+		return n.Doc
+	case *ast.ImportSpec:
+		return n.Doc
+	case *ast.Field:
+		return n.Doc
+	}
+	return nil
+}
+
+// Format returns a string representation of the node n.
+func Format(fset *token.FileSet, n ast.Node) string {
+	var buf strings.Builder
+	printer.Fprint(&buf, fset, n) // ignore errors
+	return buf.String()
+}
+
+// -- Range --
+
+// Range is a Pos interval.
+// It implements [analysis.Range] and [ast.Node].
+type Range struct{ Start, EndPos token.Pos }
+
+// RangeOf constructs a Range.
+//
+// RangeOf exists to pacify the "unkeyed literal" (composites) vet
+// check. It would be nice if there were a way for a type to add
+// itself to the allowlist.
+func RangeOf(start, end token.Pos) Range { return Range{start, end} }
+
+// NodeRange returns the extent of node n as a Range.
+//
+// For unfortunate historical reasons, the Pos/End extent of an
+// ast.File runs from the start of its package declaration---excluding
+// copyright comments, build tags, and package documentation---to the
+// end of its last declaration, excluding any trailing comments. So,
+// as a special case, if n is an [ast.File], NodeContains uses
+// n.FileStart <= pos && pos <= n.FileEnd to report whether the
+// position lies anywhere within the file.
+func NodeRange(n ast.Node) Range {
+	if file, ok := n.(*ast.File); ok {
+		return Range{file.FileStart, file.FileEnd} // entire file
+	}
+	return Range{n.Pos(), n.End()}
+}
+
+func (r Range) Pos() token.Pos { return r.Start }
+func (r Range) End() token.Pos { return r.EndPos }
+
+// ContainsPos reports whether the range (inclusive of both end points)
+// includes the specified position.
+func (r Range) ContainsPos(pos token.Pos) bool {
+	return r.Contains(RangeOf(pos, pos))
+}
+
+// Contains reports whether the range (inclusive of both end points)
+// includes the specified range.
+func (r Range) Contains(rng Range) bool {
+	return r.Start <= rng.Start && rng.EndPos <= r.EndPos
+}
+
+// IsValid reports whether the range is valid.
+func (r Range) IsValid() bool { return r.Start.IsValid() && r.Start <= r.EndPos }
+
+// --
+
+// Select returns the syntax nodes identified by a user's text
+// selection. It returns three nodes: the innermost node that wholly
+// encloses the selection; and the first and last nodes that are
+// wholly enclosed by the selection.
+//
+// For example, given this selection:
+//
+//	{ f(); g(); /* comment */ }
+//	  ~~~~~~~~~~~
+//
+// Select returns the enclosing BlockStmt, the f() CallExpr, and the g() CallExpr.
+//
+// If the selection does not wholly enclose any nodes, Select returns an error
+// and invalid start/end nodes, but it may return a valid enclosing node.
+//
+// Callers that require exactly one syntax tree (e.g. just f() or just
+// g()) should check that the returned start and end nodes are
+// identical.
+//
+// This function is intended to be called early in the handling of a
+// user's request, since it is tolerant of sloppy selection including
+// extraneous whitespace and comments. Use it in new code instead of
+// PathEnclosingInterval. When the exact extent of a node is known,
+// use [Cursor.FindByPos] instead.
+//
+// TODO(hxjiang): Consider refactoring the function signature. It is currently
+// confusing that an error is returned even when a valid enclosing node is
+// successfully found. Consider grouping all cursors into one struct.
+func Select(curFile inspector.Cursor, start, end token.Pos) (_enclosing, _start, _end inspector.Cursor, _ error) {
+	curEnclosing, ok := curFile.FindByPos(start, end)
+	if !ok {
+		return noCursor, noCursor, noCursor, fmt.Errorf("invalid selection")
+	}
+
+	// Find the first and last node wholly within the (start, end) range.
+	// We'll narrow the effective selection to them, to exclude whitespace.
+	// (This matches the functionality of PathEnclosingInterval.)
+	var curStart, curEnd inspector.Cursor
+	rng := RangeOf(start, end)
+	for cur := range curEnclosing.Preorder() {
+		if rng.Contains(NodeRange(cur.Node())) {
+			// The start node has the least Pos.
+			if !curStart.Valid() {
+				curStart = cur
+			}
+			// The end node has the greatest End.
+			// End positions do not change monotonically,
+			// so we must compute the max.
+			if !curEnd.Valid() ||
+				cur.Node().End() > curEnd.Node().End() {
+				curEnd = cur
+			}
+		}
+	}
+	if !curStart.Valid() {
+		// The selection is valid (inside curEnclosing) but contains no
+		// complete nodes. This happens for point selections (start == end),
+		// or selections covering only only spaces, comments, and punctuation
+		// tokens.
+		// Return the enclosing node so the caller can still use the context.
+		return curEnclosing, noCursor, noCursor, fmt.Errorf("invalid selection")
+	}
+	return curEnclosing, curStart, curEnd, nil
+}
+
+var noCursor inspector.Cursor
+
+// MaybeParenthesize returns new, possibly wrapped in parens if needed
+// to preserve operator precedence when it replaces old, whose parent
+// is parentNode.
+//
+// (This would be more naturally written in terms of Cursor, but one of
+// the callers--the inliner--does not have cursors handy.)
+func MaybeParenthesize(parentNode ast.Node, old, new ast.Expr) ast.Expr {
+	if needsParens(parentNode, old, new) {
+		new = &ast.ParenExpr{X: new}
+	}
+	return new
+}
+
+func needsParens(parentNode ast.Node, old, new ast.Expr) bool {
+	// An expression beneath a non-expression
+	// has no precedence ambiguity.
+	parent, ok := parentNode.(ast.Expr)
+	if !ok {
+		return false
+	}
+
+	precedence := func(n ast.Node) int {
+		switch n := n.(type) {
+		case *ast.UnaryExpr, *ast.StarExpr:
+			return token.UnaryPrec
+		case *ast.BinaryExpr:
+			return n.Op.Precedence()
+		}
+		return -1
+	}
+
+	// Parens are not required if the new node
+	// is not unary or binary.
+	newprec := precedence(new)
+	if newprec < 0 {
+		return false
+	}
+
+	// Parens are required if parent and child are both
+	// unary or binary and the parent has higher precedence.
+	if precedence(parent) > newprec {
+		return true
+	}
+
+	// Was the old node the operand of a postfix operator?
+	//  f().sel
+	//  f()[i:j]
+	//  f()[i]
+	//  f().(T)
+	//  f()(x)
+	switch parent := parent.(type) {
+	case *ast.SelectorExpr:
+		return parent.X == old
+	case *ast.IndexExpr:
+		return parent.X == old
+	case *ast.SliceExpr:
+		return parent.X == old
+	case *ast.TypeAssertExpr:
+		return parent.X == old
+	case *ast.CallExpr:
+		return parent.Fun == old
+	}
+	return false
+}
+
+func is[T any](n any) bool {
+	_, ok := n.(T)
+	return ok
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/graph/allpaths.go b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/allpaths.go
new file mode 100644
index 0000000..4473255
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/allpaths.go
@@ -0,0 +1,24 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package graph
+
+// AllPaths returns the set of nodes that are part of at least one path from src to dst.
+func AllPaths[NodeID comparable](g Graph[NodeID], src, dst NodeID) map[NodeID]bool {
+	// We intersect the forward closure of 'src' with
+	// the reverse closure of 'dst'. This is not the most
+	// efficient implementation, but it's the clearest,
+	// and the previous one had bugs.
+
+	fwd := Reachable(g, src)
+	rev := Reachable(Transpose(g), dst)
+
+	// Intersection
+	for n := range fwd {
+		if !rev[n] {
+			delete(fwd, n)
+		}
+	}
+	return fwd
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/graph/compact.go b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/compact.go
new file mode 100644
index 0000000..ae32706
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/compact.go
@@ -0,0 +1,89 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package graph
+
+import "iter"
+
+// A CompactGraph is a Graph with nodes that are compactly numbered from [0,
+// NumNodes()).
+//
+// Compactly numbered graphs are useful for many graph algorithms, and many
+// graph representations are naturally compact.
+//
+// To compact an arbitrary graph, use [Compact].
+type CompactGraph interface {
+	Graph[int]
+	IsCompact()
+}
+
+// A nodePreserving graph is a transformation of another graph that preserves
+// node IDs.
+type nodePreserving interface {
+	Graph[int]
+	unwrapPreservingNodes() Graph[int]
+}
+
+// Compact takes a Graph with arbitrary NodeIDs and returns a compact graph.
+//
+// If g implements [CompactGraph], it assumes g is already compact and simply
+// returns g and an identity mapping.
+func Compact[NodeID comparable](g Graph[NodeID]) (CompactGraph, *Index[NodeID]) {
+	// If it's already compact, simply return it.
+	if gc, ok := g.(CompactGraph); ok {
+		// The above assertion ensures NodeID is int, so we know this type
+		// assertion will always succeed.
+		return gc, any(NewIdentityIndex(gc.NumNodes())).(*Index[NodeID])
+	}
+
+	// If it's a transformation and the underlying graph is compact, we can use
+	// an identity index. Though we still need to build a compactGraph to
+	// satisfy the CompactGraph interface.
+	g2, _ := g.(nodePreserving)
+	for g2 != nil {
+		unwrapped := g2.unwrapPreservingNodes()
+		if gc, ok := unwrapped.(CompactGraph); ok {
+			index := any(NewIdentityIndex(gc.NumNodes())).(*Index[NodeID])
+			cg := compactGraph[NodeID]{g, index}
+			return &cg, index
+		}
+		g2, _ = unwrapped.(nodePreserving)
+	}
+
+	// Nope, just build an index.
+	cg := compactGraph[NodeID]{g, NewIndex(g.Nodes())}
+	return &cg, cg.m
+}
+
+type compactGraph[NodeID comparable] struct {
+	g Graph[NodeID]
+	m *Index[NodeID]
+}
+
+func (g *compactGraph[NodeID]) Nodes() iter.Seq[int] {
+	return func(yield func(int) bool) {
+		for i := range g.g.NumNodes() {
+			if !yield(i) {
+				break
+			}
+		}
+	}
+}
+
+func (g *compactGraph[NodeID]) NumNodes() int {
+	return g.g.NumNodes()
+}
+
+func (g *compactGraph[NodeID]) Out(node int) iter.Seq[int] {
+	id := g.m.Value(node)
+	return func(yield func(int) bool) {
+		for nid := range g.g.Out(id) {
+			if !yield(g.m.Index(nid)) {
+				break
+			}
+		}
+	}
+}
+
+func (g *compactGraph[NodeID]) IsCompact() {}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/graph/graph.go b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/graph.go
new file mode 100644
index 0000000..fdea880
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/graph.go
@@ -0,0 +1,33 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package graph provides a common abstraction for directed graphs and standard
+// graph algorithms.
+//
+// In general, this package does not provide or assume any concrete graph
+// representation. It's up to the caller of this package to implement the
+// [Graph] interface, either directly or as an adapter around another type.
+package graph
+
+import "iter"
+
+// A Graph implements a directed graph where nodes in the graph are identified
+// by the NodeID type.
+//
+// If a concrete graph type stores additional information about nodes and/or
+// edges, it will conventionally provide methods of the form:
+//
+//	Node(node NodeID) nodeInfo
+//	Edge(from, to NodeID) edgeInfo
+type Graph[NodeID comparable] interface {
+	// Nodes yields all nodes in this graph.
+	Nodes() iter.Seq[NodeID]
+
+	// NumNodes returns the total number of nodes in this graph.
+	NumNodes() int
+
+	// Out yields the out-edges of node. Out must be deterministic, though
+	// otherwise there is no constraint on the order of the returned sequence.
+	Out(node NodeID) iter.Seq[NodeID]
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/graph/index.go b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/index.go
new file mode 100644
index 0000000..394213e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/index.go
@@ -0,0 +1,96 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package graph
+
+import (
+	"fmt"
+	"iter"
+	"slices"
+)
+
+// An Index is an immutable, bijective map between [0, N) and an ordered list of keys.
+type Index[Key comparable] struct {
+	// There are three Index representations:
+	//
+	// - If identN > 0, an identity map of [0, identN).
+	// - If index == nil, a sorted integer index in values.
+	// - Otherwise, a full index in values and index.
+
+	identN int
+	values []Key
+	index  map[Key]int
+}
+
+// NewIndex returns an index for the specified list of values.
+func NewIndex[Key comparable](values iter.Seq[Key]) *Index[Key] {
+	vs := slices.Collect(values)
+	if len(vs) == 0 {
+		return new(Index[Key])
+	}
+
+	// Fast path: a naturally sorted list needs no index. (Sadly, there's no way
+	// to ask "is Key ordered?")
+	if vi, ok := any(vs).([]int); ok && slices.IsSorted(vi) {
+		return &Index[Key]{values: vs}
+	}
+
+	index := make(map[Key]int, len(vs))
+	for i, v := range vs {
+		index[v] = i
+	}
+	return &Index[Key]{values: vs, index: index}
+}
+
+// NewIdentityIndex returns an index that maps [0, n) to [0, n).
+func NewIdentityIndex(n int) *Index[int] {
+	if n < 0 {
+		panic("n < 0")
+	}
+	// If n == 0, this is actually a "sorted integer index", but it doesn't
+	// matter because everything is out of bounds either way.
+	return &Index[int]{identN: n}
+}
+
+// Value maps an index to a key.
+func (ix *Index[Key]) Value(index int) Key {
+	if ix.identN > 0 {
+		if index < 0 || index >= ix.identN {
+			panic(fmt.Sprintf("index %d out of range [0, %d)", index, ix.identN))
+		}
+		return any(index).(Key)
+	}
+	if index < 0 || index >= len(ix.values) {
+		panic(fmt.Sprintf("index %d out of range [0, %d)", index, ix.identN))
+	}
+	return ix.values[index]
+}
+
+// Index maps a key to an index.
+func (ix *Index[Key]) Index(key Key) int {
+	if key, ok := any(key).(int); ok {
+		// Integer-only optimizations.
+		switch {
+		case ix.identN > 0:
+			// Identity.
+			if 0 <= key && key < ix.identN {
+				return key
+			}
+			goto oob
+
+		case ix.index == nil:
+			// Sorted integers.
+			if i, ok := slices.BinarySearch(any(ix.values).([]int), key); ok {
+				return i
+			}
+			goto oob
+		}
+	}
+	if i, ok := ix.index[key]; ok {
+		return i
+	}
+
+oob:
+	panic(fmt.Sprintf("key %v not in index", key))
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/graph/order.go b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/order.go
new file mode 100644
index 0000000..795a434
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/order.go
@@ -0,0 +1,94 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package graph
+
+import "slices"
+
+// Postorder returns the sequence of nodes in the spanning DAG of g, in
+// postorder.
+//
+// For rootless subgraphs, it breaks cycles by starting at the lowest numbered
+// node.
+//
+// This algorithm runs in O(V + E) time and O(V + E) space.
+func Postorder[NodeID comparable](g Graph[NodeID]) []NodeID {
+	cg, nodeMap := Compact(g)
+
+	numNodes := cg.NumNodes()
+	if numNodes == 0 {
+		return nil
+	}
+
+	result := make([]NodeID, 0, numNodes)
+	visited := newBitset(numNodes)
+	onStack := newBitset(numNodes)
+
+	// visit performs a Depth-First Search.
+	var visit func(u int)
+	visit = func(u int) {
+		if !visited.add(u) {
+			return
+		}
+		onStack.add(u)
+
+		for v := range cg.Out(u) {
+			if onStack.contains(v) {
+				// Cycle detected (back-edge).
+				// To resolve, we simply skip processing this edge further in the
+				// current recursion, effectively "breaking" the cycle at this point.
+				continue
+			}
+			visit(v)
+		}
+
+		onStack.remove(u)
+		// Post-order: add to result after all descendants are processed.
+		result = append(result, nodeMap.Value(u))
+	}
+
+	// Visit every node in ascending order to ensure stability.
+	for u := range numNodes {
+		visit(u)
+	}
+
+	return result
+}
+
+// ReversePostorder returns the nodes of the graph in reverse post-order.
+//
+// If g is a directed acyclic graph (DAG), the result is a topological sort of
+// g.
+//
+// See [Postorder] for how this handles back-edges and cycles.
+//
+// This algorithm runs in O(V + E) time and O(V + E) space.
+func ReversePostorder[NodeID comparable](g Graph[NodeID]) []NodeID {
+	result := Postorder(g)
+	slices.Reverse(result)
+	return result
+}
+
+// bitset is a simple fixed-size bitset used to reduce memory overhead.
+type bitset []uint64
+
+func newBitset(n int) bitset {
+	return make(bitset, (n+63)/64)
+}
+
+func (b bitset) add(u int) bool {
+	if b.contains(u) {
+		return false
+	}
+	b[u/64] |= 1 << (u % 64)
+	return true
+}
+
+func (b bitset) remove(u int) {
+	b[u/64] &= ^(1 << (u % 64))
+}
+
+func (b bitset) contains(u int) bool {
+	return b[u/64]&(1<<(u%64)) != 0
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/graph/reachable.go b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/reachable.go
new file mode 100644
index 0000000..dd14eae
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/reachable.go
@@ -0,0 +1,23 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package graph
+
+// Reachable returns the set of nodes reachable from the given roots.
+func Reachable[NodeID comparable](g Graph[NodeID], roots ...NodeID) map[NodeID]bool {
+	seen := make(map[NodeID]bool)
+	var visit func(node NodeID)
+	visit = func(node NodeID) {
+		if !seen[node] {
+			seen[node] = true
+			for e := range g.Out(node) {
+				visit(e)
+			}
+		}
+	}
+	for _, root := range roots {
+		visit(root)
+	}
+	return seen
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/graph/scc.go b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/scc.go
new file mode 100644
index 0000000..fb4764f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/scc.go
@@ -0,0 +1,39 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package graph
+
+import "slices"
+
+// SCCs computes the strongly connected components of the graph g.
+func SCCs[NodeID comparable](g Graph[NodeID]) [][]NodeID {
+	// Use Kosaraju's algorithm. Tarjan is overkill here.
+
+	// Forward pass
+	S := Postorder(g)
+
+	// Reverse pass
+	gt := Transpose(g)
+	seen := make(map[NodeID]bool)
+	var scc []NodeID
+	var sccs [][]NodeID
+	var rvisit func(NodeID)
+	rvisit = func(u NodeID) {
+		if !seen[u] {
+			seen[u] = true
+			scc = append(scc, u)
+			for v := range gt.Out(u) {
+				rvisit(v)
+			}
+		}
+	}
+	for _, root := range slices.Backward(S) {
+		if !seen[root] {
+			scc = nil
+			rvisit(root)
+			sccs = append(sccs, scc)
+		}
+	}
+	return sccs
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/graph/shortest.go b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/shortest.go
new file mode 100644
index 0000000..e7457e8
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/shortest.go
@@ -0,0 +1,45 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package graph
+
+import "slices"
+
+// ShortestPath returns a shortest path from src to dst in g.
+// It returns the path as a slice of nodes starting with src and ending with dst.
+// If no path is found, it returns nil.
+func ShortestPath[NodeID comparable](g Graph[NodeID], src, dst NodeID) []NodeID {
+	if src == dst {
+		return []NodeID{src}
+	}
+
+	pred := make(map[NodeID]NodeID)
+	queue := []NodeID{src}
+	// Mark src as seen.
+	pred[src] = src
+
+	for len(queue) > 0 {
+		n := queue[0]
+		queue = queue[1:]
+
+		if n == dst {
+			// Reconstruct path
+			var path []NodeID
+			for curr := dst; curr != src; curr = pred[curr] {
+				path = append(path, curr)
+			}
+			path = append(path, src)
+			slices.Reverse(path)
+			return path
+		}
+
+		for v := range g.Out(n) {
+			if _, seen := pred[v]; !seen {
+				pred[v] = n
+				queue = append(queue, v)
+			}
+		}
+	}
+	return nil
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/graph/transpose.go b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/transpose.go
new file mode 100644
index 0000000..431fc5f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/graph/transpose.go
@@ -0,0 +1,51 @@
+// Copyright 2026 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package graph
+
+import (
+	"iter"
+	"slices"
+)
+
+type transpose[NodeID comparable] struct {
+	Graph Graph[NodeID]
+	preds map[NodeID][]NodeID
+}
+
+// transpose returns a graph like g but with all edges reversed. Node IDs are
+// identical to the underlying graph.
+//
+// Transpose preserves compactness.
+func Transpose[NodeID comparable](g Graph[NodeID]) Graph[NodeID] {
+	if g, ok := g.(transpose[NodeID]); ok {
+		// Transpose(Transpose(g)) == g
+		return g.Graph
+	}
+
+	preds := make(map[NodeID][]NodeID)
+	for nid := range g.Nodes() {
+		for succ := range g.Out(nid) {
+			preds[succ] = append(preds[succ], nid)
+		}
+	}
+	return transpose[NodeID]{g, preds}
+}
+
+func (t transpose[NodeID]) NumNodes() int {
+	return len(t.preds)
+}
+
+func (t transpose[NodeID]) Nodes() iter.Seq[NodeID] {
+	return t.Graph.Nodes()
+}
+
+func (t transpose[NodeID]) Out(n NodeID) iter.Seq[NodeID] {
+	return slices.Values(t.preds[n])
+}
+
+//lint:ignore U1000 False positive in Staticcheck 2026.1 and older.
+func (t transpose[NodeID]) unwrapPreservingNodes() Graph[NodeID] {
+	return t.Graph
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/moreiters/iters.go b/vendor/honnef.co/go/tools/internal/xtools-internal/moreiters/iters.go
new file mode 100644
index 0000000..3dc81c4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/moreiters/iters.go
@@ -0,0 +1,63 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package moreiters
+
+import "iter"
+
+// First returns the first value of seq and true.
+// If seq is empty, it returns the zero value of T and false.
+func First[T any](seq iter.Seq[T]) (z T, ok bool) {
+	for t := range seq {
+		return t, true
+	}
+	return z, false
+}
+
+// Contains reports whether x is an element of the sequence seq.
+func Contains[T comparable](seq iter.Seq[T], x T) bool {
+	for cand := range seq {
+		if cand == x {
+			return true
+		}
+	}
+	return false
+}
+
+// Every reports whether every pred(t) for t in seq returns true,
+// stopping at the first false element.
+func Every[T any](seq iter.Seq[T], pred func(T) bool) bool {
+	for t := range seq {
+		if !pred(t) {
+			return false
+		}
+	}
+	return true
+}
+
+// Any reports whether any pred(t) for t in seq returns true.
+func Any[T any](seq iter.Seq[T], pred func(T) bool) bool {
+	for t := range seq {
+		if pred(t) {
+			return true
+		}
+	}
+	return false
+}
+
+// Len returns the number of elements in the sequence (by iterating).
+func Len[T any](seq iter.Seq[T]) (n int) {
+	for range seq {
+		n++
+	}
+	return
+}
+
+// Empty reports whether the sequence contains no elements.
+func Empty[T any](seq iter.Seq[T]) bool {
+	for range seq {
+		return false
+	}
+	return true
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/common.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/common.go
new file mode 100644
index 0000000..cdae2b8
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/common.go
@@ -0,0 +1,68 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package typeparams contains common utilities for writing tools that
+// interact with generic Go code, as introduced with Go 1.18. It
+// supplements the standard library APIs. Notably, the StructuralTerms
+// API computes a minimal representation of the structural
+// restrictions on a type parameter.
+//
+// An external version of these APIs is available in the
+// golang.org/x/exp/typeparams module.
+package typeparams
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+)
+
+// UnpackIndexExpr extracts data from AST nodes that represent index
+// expressions.
+//
+// For an ast.IndexExpr, the resulting indices slice will contain exactly one
+// index expression. For an ast.IndexListExpr (go1.18+), it may have a variable
+// number of index expressions.
+//
+// For nodes that don't represent index expressions, the first return value of
+// UnpackIndexExpr will be nil.
+func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) {
+	switch e := n.(type) {
+	case *ast.IndexExpr:
+		return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack
+	case *ast.IndexListExpr:
+		return e.X, e.Lbrack, e.Indices, e.Rbrack
+	}
+	return nil, token.NoPos, nil, token.NoPos
+}
+
+// PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on
+// the cardinality of indices. Calling PackIndexExpr with len(indices) == 0
+// will panic.
+func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr {
+	switch len(indices) {
+	case 0:
+		panic("empty indices")
+	case 1:
+		return &ast.IndexExpr{
+			X:      x,
+			Lbrack: lbrack,
+			Index:  indices[0],
+			Rbrack: rbrack,
+		}
+	default:
+		return &ast.IndexListExpr{
+			X:       x,
+			Lbrack:  lbrack,
+			Indices: indices,
+			Rbrack:  rbrack,
+		}
+	}
+}
+
+// IsTypeParam reports whether t is a type parameter (or an alias of one).
+func IsTypeParam(t types.Type) bool {
+	_, ok := types.Unalias(t).(*types.TypeParam)
+	return ok
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/coretype.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/coretype.go
new file mode 100644
index 0000000..2e05de4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/coretype.go
@@ -0,0 +1,157 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeparams
+
+import (
+	"fmt"
+	"go/types"
+)
+
+// CoreType returns the core type of T or nil if T does not have a core type.
+//
+// As of Go1.25, the notion of a core type has been removed from the language spec.
+// See https://go.dev/blog/coretypes for more details.
+// TODO(mkalil): We should eventually consider removing all uses of CoreType.
+func CoreType(T types.Type) types.Type {
+	U := T.Underlying()
+	if _, ok := U.(*types.Interface); !ok {
+		return U // for non-interface types,
+	}
+
+	terms, err := NormalTerms(U)
+	if len(terms) == 0 || err != nil {
+		// len(terms) -> empty type set of interface.
+		// err != nil => U is invalid, exceeds complexity bounds, or has an empty type set.
+		return nil // no core type.
+	}
+
+	U = terms[0].Type().Underlying()
+	var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying())
+	for identical = 1; identical < len(terms); identical++ {
+		if !types.Identical(U, terms[identical].Type().Underlying()) {
+			break
+		}
+	}
+
+	if identical == len(terms) {
+		// From the deprecated core types spec:
+		// "There is a single type U which is the underlying type of all types in the type set of T"
+		return U
+	}
+	ch, ok := U.(*types.Chan)
+	if !ok {
+		return nil // no core type as identical < len(terms) and U is not a channel.
+	}
+	// From the deprecated core types spec:
+	// "the type chan E if T contains only bidirectional channels, or the type chan<- E or
+	// <-chan E depending on the direction of the directional channels present."
+	for chans := identical; chans < len(terms); chans++ {
+		curr, ok := terms[chans].Type().Underlying().(*types.Chan)
+		if !ok {
+			return nil
+		}
+		if !types.Identical(ch.Elem(), curr.Elem()) {
+			return nil // channel elements are not identical.
+		}
+		if ch.Dir() == types.SendRecv {
+			// ch is bidirectional. We can safely always use curr's direction.
+			ch = curr
+		} else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() {
+			// ch and curr are not bidirectional and not the same direction.
+			return nil
+		}
+	}
+	return ch
+}
+
+// NormalTerms returns a slice of terms representing the normalized structural
+// type restrictions of a type, if any.
+//
+// For all types other than *types.TypeParam, *types.Interface, and
+// *types.Union, this is just a single term with Tilde() == false and
+// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see
+// below.
+//
+// Structural type restrictions of a type parameter are created via
+// non-interface types embedded in its constraint interface (directly, or via a
+// chain of interface embeddings). For example, in the declaration type
+// T[P interface{~int; m()}] int the structural restriction of the type
+// parameter P is ~int.
+//
+// With interface embedding and unions, the specification of structural type
+// restrictions may be arbitrarily complex. For example, consider the
+// following:
+//
+//	type A interface{ ~string|~[]byte }
+//
+//	type B interface{ int|string }
+//
+//	type C interface { ~string|~int }
+//
+//	type T[P interface{ A|B; C }] int
+//
+// In this example, the structural type restriction of P is ~string|int: A|B
+// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
+// which when intersected with C (~string|~int) yields ~string|int.
+//
+// NormalTerms computes these expansions and reductions, producing a
+// "normalized" form of the embeddings. A structural restriction is normalized
+// if it is a single union containing no interface terms, and is minimal in the
+// sense that removing any term changes the set of types satisfying the
+// constraint. It is left as a proof for the reader that, modulo sorting, there
+// is exactly one such normalized form.
+//
+// Because the minimal representation always takes this form, NormalTerms
+// returns a slice of tilde terms corresponding to the terms of the union in
+// the normalized structural restriction. An error is returned if the type is
+// invalid, exceeds complexity bounds, or has an empty type set. In the latter
+// case, NormalTerms returns ErrEmptyTypeSet.
+//
+// NormalTerms makes no guarantees about the order of terms, except that it
+// is deterministic.
+func NormalTerms(T types.Type) ([]*types.Term, error) {
+	// typeSetOf(T) == typeSetOf(Unalias(T))
+	typ := types.Unalias(T)
+	if named, ok := typ.(*types.Named); ok {
+		typ = named.Underlying()
+	}
+	switch typ := typ.(type) {
+	case *types.TypeParam:
+		return StructuralTerms(typ)
+	case *types.Union:
+		return UnionTermSet(typ)
+	case *types.Interface:
+		return InterfaceTermSet(typ)
+	default:
+		return []*types.Term{types.NewTerm(false, T)}, nil
+	}
+}
+
+// Deref returns the type of the variable pointed to by t,
+// if t's core type is a pointer; otherwise it returns t.
+//
+// Do not assume that Deref(T)==T implies T is not a pointer:
+// consider "type T *T", for example.
+//
+// TODO(adonovan): ideally this would live in typesinternal, but that
+// creates an import cycle. Move there when we melt this package down.
+func Deref(t types.Type) types.Type {
+	if ptr, ok := CoreType(t).(*types.Pointer); ok {
+		return ptr.Elem()
+	}
+	return t
+}
+
+// MustDeref returns the type of the variable pointed to by t.
+// It panics if t's core type is not a pointer.
+//
+// TODO(adonovan): ideally this would live in typesinternal, but that
+// creates an import cycle. Move there when we melt this package down.
+func MustDeref(t types.Type) types.Type {
+	if ptr, ok := CoreType(t).(*types.Pointer); ok {
+		return ptr.Elem()
+	}
+	panic(fmt.Sprintf("%v is not a pointer", t))
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/free.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/free.go
new file mode 100644
index 0000000..4c39187
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/free.go
@@ -0,0 +1,129 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeparams
+
+import (
+	"go/types"
+)
+
+// Free is a memoization of the set of free type parameters within a
+// type. It makes a sequence of calls to [Free.Has] for overlapping
+// types more efficient. The zero value is ready for use.
+//
+// NOTE: Adapted from go/types/infer.go. If it is later exported, factor.
+type Free struct {
+	seen map[types.Type]bool
+}
+
+// Has reports whether the specified type has a free type parameter.
+func (w *Free) Has(typ types.Type) (res bool) {
+	// detect cycles
+	if x, ok := w.seen[typ]; ok {
+		return x
+	}
+	if w.seen == nil {
+		w.seen = make(map[types.Type]bool)
+	}
+	w.seen[typ] = false
+	defer func() {
+		w.seen[typ] = res
+	}()
+
+	switch t := typ.(type) {
+	case nil, *types.Basic: // TODO(gri) should nil be handled here?
+		break
+
+	case *types.Alias:
+		if t.TypeParams().Len() > t.TypeArgs().Len() {
+			return true // This is an uninstantiated Alias.
+		}
+		// The expansion of an alias can have free type parameters,
+		// whether or not the alias itself has type parameters:
+		//
+		//   func _[K comparable]() {
+		//     type Set      = map[K]bool // free(Set)      = {K}
+		//     type MapTo[V] = map[K]V    // free(Map[foo]) = {V}
+		//   }
+		//
+		// So, we must Unalias.
+		return w.Has(types.Unalias(t))
+
+	case *types.Array:
+		return w.Has(t.Elem())
+
+	case *types.Slice:
+		return w.Has(t.Elem())
+
+	case *types.Struct:
+		for i, n := 0, t.NumFields(); i < n; i++ {
+			if w.Has(t.Field(i).Type()) {
+				return true
+			}
+		}
+
+	case *types.Pointer:
+		return w.Has(t.Elem())
+
+	case *types.Tuple:
+		n := t.Len()
+		for i := range n {
+			if w.Has(t.At(i).Type()) {
+				return true
+			}
+		}
+
+	case *types.Signature:
+		// t.tparams may not be nil if we are looking at a signature
+		// of a generic function type (or an interface method) that is
+		// part of the type we're testing. We don't care about these type
+		// parameters.
+		// Similarly, the receiver of a method may declare (rather than
+		// use) type parameters, we don't care about those either.
+		// Thus, we only need to look at the input and result parameters.
+		return w.Has(t.Params()) || w.Has(t.Results())
+
+	case *types.Interface:
+		for i, n := 0, t.NumMethods(); i < n; i++ {
+			if w.Has(t.Method(i).Type()) {
+				return true
+			}
+		}
+		terms, err := InterfaceTermSet(t)
+		if err != nil {
+			return false // ill typed
+		}
+		for _, term := range terms {
+			if w.Has(term.Type()) {
+				return true
+			}
+		}
+
+	case *types.Map:
+		return w.Has(t.Key()) || w.Has(t.Elem())
+
+	case *types.Chan:
+		return w.Has(t.Elem())
+
+	case *types.Named:
+		args := t.TypeArgs()
+		if params := t.TypeParams(); params.Len() > args.Len() {
+			return true // this is an uninstantiated named type.
+		}
+		for i, n := 0, args.Len(); i < n; i++ {
+			if w.Has(args.At(i)) {
+				return true
+			}
+		}
+		return w.Has(t.Underlying()) // recurse for types local to parameterized functions
+
+	case *types.TypeParam:
+		return true
+
+	default:
+		panic(t) // unreachable
+	}
+
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/normalize.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/normalize.go
new file mode 100644
index 0000000..ba36787
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/normalize.go
@@ -0,0 +1,214 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeparams
+
+import (
+	"errors"
+	"fmt"
+	"go/types"
+	"os"
+	"strings"
+)
+
+const debug = false
+
+var ErrEmptyTypeSet = errors.New("empty type set")
+
+// StructuralTerms returns a slice of terms representing the normalized
+// structural type restrictions of a type parameter, if any.
+//
+// Structural type restrictions of a type parameter are created via
+// non-interface types embedded in its constraint interface (directly, or via a
+// chain of interface embeddings). For example, in the declaration
+//
+//	type T[P interface{~int; m()}] int
+//
+// the structural restriction of the type parameter P is ~int.
+//
+// With interface embedding and unions, the specification of structural type
+// restrictions may be arbitrarily complex. For example, consider the
+// following:
+//
+//	type A interface{ ~string|~[]byte }
+//
+//	type B interface{ int|string }
+//
+//	type C interface { ~string|~int }
+//
+//	type T[P interface{ A|B; C }] int
+//
+// In this example, the structural type restriction of P is ~string|int: A|B
+// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
+// which when intersected with C (~string|~int) yields ~string|int.
+//
+// StructuralTerms computes these expansions and reductions, producing a
+// "normalized" form of the embeddings. A structural restriction is normalized
+// if it is a single union containing no interface terms, and is minimal in the
+// sense that removing any term changes the set of types satisfying the
+// constraint. It is left as a proof for the reader that, modulo sorting, there
+// is exactly one such normalized form.
+//
+// Because the minimal representation always takes this form, StructuralTerms
+// returns a slice of tilde terms corresponding to the terms of the union in
+// the normalized structural restriction. An error is returned if the
+// constraint interface is invalid, exceeds complexity bounds, or has an empty
+// type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet.
+//
+// StructuralTerms makes no guarantees about the order of terms, except that it
+// is deterministic.
+func StructuralTerms(tparam *types.TypeParam) ([]*types.Term, error) {
+	constraint := tparam.Constraint()
+	if constraint == nil {
+		return nil, fmt.Errorf("%s has nil constraint", tparam)
+	}
+	iface, _ := constraint.Underlying().(*types.Interface)
+	if iface == nil {
+		return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying())
+	}
+	return InterfaceTermSet(iface)
+}
+
+// InterfaceTermSet computes the normalized terms for a constraint interface,
+// returning an error if the term set cannot be computed or is empty. In the
+// latter case, the error will be ErrEmptyTypeSet.
+//
+// See the documentation of StructuralTerms for more information on
+// normalization.
+func InterfaceTermSet(iface *types.Interface) ([]*types.Term, error) {
+	return computeTermSet(iface)
+}
+
+// UnionTermSet computes the normalized terms for a union, returning an error
+// if the term set cannot be computed or is empty. In the latter case, the
+// error will be ErrEmptyTypeSet.
+//
+// See the documentation of StructuralTerms for more information on
+// normalization.
+func UnionTermSet(union *types.Union) ([]*types.Term, error) {
+	return computeTermSet(union)
+}
+
+func computeTermSet(typ types.Type) ([]*types.Term, error) {
+	tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0)
+	if err != nil {
+		return nil, err
+	}
+	if tset.terms.isEmpty() {
+		return nil, ErrEmptyTypeSet
+	}
+	if tset.terms.isAll() {
+		return nil, nil
+	}
+	var terms []*types.Term
+	for _, term := range tset.terms {
+		terms = append(terms, types.NewTerm(term.tilde, term.typ))
+	}
+	return terms, nil
+}
+
+// A termSet holds the normalized set of terms for a given type.
+//
+// The name termSet is intentionally distinct from 'type set': a type set is
+// all types that implement a type (and includes method restrictions), whereas
+// a term set just represents the structural restrictions on a type.
+type termSet struct {
+	complete bool
+	terms    termlist
+}
+
+func indentf(depth int, format string, args ...any) {
+	fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...)
+}
+
+func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) {
+	if t == nil {
+		panic("nil type")
+	}
+
+	if debug {
+		indentf(depth, "%s", t.String())
+		defer func() {
+			if err != nil {
+				indentf(depth, "=> %s", err)
+			} else {
+				indentf(depth, "=> %s", res.terms.String())
+			}
+		}()
+	}
+
+	const maxTermCount = 100
+	if tset, ok := seen[t]; ok {
+		if !tset.complete {
+			return nil, fmt.Errorf("cycle detected in the declaration of %s", t)
+		}
+		return tset, nil
+	}
+
+	// Mark the current type as seen to avoid infinite recursion.
+	tset := new(termSet)
+	defer func() {
+		tset.complete = true
+	}()
+	seen[t] = tset
+
+	switch u := t.Underlying().(type) {
+	case *types.Interface:
+		// The term set of an interface is the intersection of the term sets of its
+		// embedded types.
+		tset.terms = allTermlist
+		for embedded := range u.EmbeddedTypes() {
+			if _, ok := embedded.Underlying().(*types.TypeParam); ok {
+				return nil, fmt.Errorf("invalid embedded type %T", embedded)
+			}
+			tset2, err := computeTermSetInternal(embedded, seen, depth+1)
+			if err != nil {
+				return nil, err
+			}
+			tset.terms = tset.terms.intersect(tset2.terms)
+		}
+	case *types.Union:
+		// The term set of a union is the union of term sets of its terms.
+		tset.terms = nil
+		for t := range u.Terms() {
+			var terms termlist
+			switch t.Type().Underlying().(type) {
+			case *types.Interface:
+				tset2, err := computeTermSetInternal(t.Type(), seen, depth+1)
+				if err != nil {
+					return nil, err
+				}
+				terms = tset2.terms
+			case *types.TypeParam, *types.Union:
+				// A stand-alone type parameter or union is not permitted as union
+				// term.
+				return nil, fmt.Errorf("invalid union term %T", t)
+			default:
+				if t.Type() == types.Typ[types.Invalid] {
+					continue
+				}
+				terms = termlist{{t.Tilde(), t.Type()}}
+			}
+			tset.terms = tset.terms.union(terms)
+			if len(tset.terms) > maxTermCount {
+				return nil, fmt.Errorf("exceeded max term count %d", maxTermCount)
+			}
+		}
+	case *types.TypeParam:
+		panic("unreachable")
+	default:
+		// For all other types, the term set is just a single non-tilde term
+		// holding the type itself.
+		if u != types.Typ[types.Invalid] {
+			tset.terms = termlist{{false, t}}
+		}
+	}
+	return tset, nil
+}
+
+// under is a facade for the go/types internal function of the same name. It is
+// used by typeterm.go.
+func under(t types.Type) types.Type {
+	return t.Underlying()
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/termlist.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/termlist.go
new file mode 100644
index 0000000..9bc2914
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/termlist.go
@@ -0,0 +1,169 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+// Source: ../../cmd/compile/internal/types2/termlist.go
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by copytermlist.go DO NOT EDIT.
+
+package typeparams
+
+import (
+	"go/types"
+	"strings"
+)
+
+// A termlist represents the type set represented by the union
+// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn.
+// A termlist is in normal form if all terms are disjoint.
+// termlist operations don't require the operands to be in
+// normal form.
+type termlist []*term
+
+// allTermlist represents the set of all types.
+// It is in normal form.
+var allTermlist = termlist{new(term)}
+
+// termSep is the separator used between individual terms.
+const termSep = " | "
+
+// String prints the termlist exactly (without normalization).
+func (xl termlist) String() string {
+	if len(xl) == 0 {
+		return "∅"
+	}
+	var buf strings.Builder
+	for i, x := range xl {
+		if i > 0 {
+			buf.WriteString(termSep)
+		}
+		buf.WriteString(x.String())
+	}
+	return buf.String()
+}
+
+// isEmpty reports whether the termlist xl represents the empty set of types.
+func (xl termlist) isEmpty() bool {
+	// If there's a non-nil term, the entire list is not empty.
+	// If the termlist is in normal form, this requires at most
+	// one iteration.
+	for _, x := range xl {
+		if x != nil {
+			return false
+		}
+	}
+	return true
+}
+
+// isAll reports whether the termlist xl represents the set of all types.
+func (xl termlist) isAll() bool {
+	// If there's a 𝓤 term, the entire list is 𝓤.
+	// If the termlist is in normal form, this requires at most
+	// one iteration.
+	for _, x := range xl {
+		if x != nil && x.typ == nil {
+			return true
+		}
+	}
+	return false
+}
+
+// norm returns the normal form of xl.
+func (xl termlist) norm() termlist {
+	// Quadratic algorithm, but good enough for now.
+	// TODO(gri) fix asymptotic performance
+	used := make([]bool, len(xl))
+	var rl termlist
+	for i, xi := range xl {
+		if xi == nil || used[i] {
+			continue
+		}
+		for j := i + 1; j < len(xl); j++ {
+			xj := xl[j]
+			if xj == nil || used[j] {
+				continue
+			}
+			if u1, u2 := xi.union(xj); u2 == nil {
+				// If we encounter a 𝓤 term, the entire list is 𝓤.
+				// Exit early.
+				// (Note that this is not just an optimization;
+				// if we continue, we may end up with a 𝓤 term
+				// and other terms and the result would not be
+				// in normal form.)
+				if u1.typ == nil {
+					return allTermlist
+				}
+				xi = u1
+				used[j] = true // xj is now unioned into xi - ignore it in future iterations
+			}
+		}
+		rl = append(rl, xi)
+	}
+	return rl
+}
+
+// union returns the union xl ∪ yl.
+func (xl termlist) union(yl termlist) termlist {
+	return append(xl, yl...).norm()
+}
+
+// intersect returns the intersection xl ∩ yl.
+func (xl termlist) intersect(yl termlist) termlist {
+	if xl.isEmpty() || yl.isEmpty() {
+		return nil
+	}
+
+	// Quadratic algorithm, but good enough for now.
+	// TODO(gri) fix asymptotic performance
+	var rl termlist
+	for _, x := range xl {
+		for _, y := range yl {
+			if r := x.intersect(y); r != nil {
+				rl = append(rl, r)
+			}
+		}
+	}
+	return rl.norm()
+}
+
+// equal reports whether xl and yl represent the same type set.
+func (xl termlist) equal(yl termlist) bool {
+	// TODO(gri) this should be more efficient
+	return xl.subsetOf(yl) && yl.subsetOf(xl)
+}
+
+// includes reports whether t ∈ xl.
+func (xl termlist) includes(t types.Type) bool {
+	for _, x := range xl {
+		if x.includes(t) {
+			return true
+		}
+	}
+	return false
+}
+
+// supersetOf reports whether y ⊆ xl.
+func (xl termlist) supersetOf(y *term) bool {
+	for _, x := range xl {
+		if y.subsetOf(x) {
+			return true
+		}
+	}
+	return false
+}
+
+// subsetOf reports whether xl ⊆ yl.
+func (xl termlist) subsetOf(yl termlist) bool {
+	if yl.isEmpty() {
+		return xl.isEmpty()
+	}
+
+	// each term x of xl must be a subset of yl
+	for _, x := range xl {
+		if !yl.supersetOf(x) {
+			return false // x is not a subset yl
+		}
+	}
+	return true
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/typeterm.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/typeterm.go
new file mode 100644
index 0000000..fa758cd
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typeparams/typeterm.go
@@ -0,0 +1,172 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+// Source: ../../cmd/compile/internal/types2/typeterm.go
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by copytermlist.go DO NOT EDIT.
+
+package typeparams
+
+import "go/types"
+
+// A term describes elementary type sets:
+//
+//	 ∅:  (*term)(nil)     == ∅                      // set of no types (empty set)
+//	 𝓤:  &term{}          == 𝓤                      // set of all types (𝓤niverse)
+//	 T:  &term{false, T}  == {T}                    // set of type T
+//	~t:  &term{true, t}   == {t' | under(t') == t}  // set of types with underlying type t
+type term struct {
+	tilde bool // valid if typ != nil
+	typ   types.Type
+}
+
+func (x *term) String() string {
+	switch {
+	case x == nil:
+		return "∅"
+	case x.typ == nil:
+		return "𝓤"
+	case x.tilde:
+		return "~" + x.typ.String()
+	default:
+		return x.typ.String()
+	}
+}
+
+// equal reports whether x and y represent the same type set.
+func (x *term) equal(y *term) bool {
+	// easy cases
+	switch {
+	case x == nil || y == nil:
+		return x == y
+	case x.typ == nil || y.typ == nil:
+		return x.typ == y.typ
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	return x.tilde == y.tilde && types.Identical(x.typ, y.typ)
+}
+
+// union returns the union x ∪ y: zero, one, or two non-nil terms.
+func (x *term) union(y *term) (_, _ *term) {
+	// easy cases
+	switch {
+	case x == nil && y == nil:
+		return nil, nil // ∅ ∪ ∅ == ∅
+	case x == nil:
+		return y, nil // ∅ ∪ y == y
+	case y == nil:
+		return x, nil // x ∪ ∅ == x
+	case x.typ == nil:
+		return x, nil // 𝓤 ∪ y == 𝓤
+	case y.typ == nil:
+		return y, nil // x ∪ 𝓤 == 𝓤
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	if x.disjoint(y) {
+		return x, y // x ∪ y == (x, y) if x ∩ y == ∅
+	}
+	// x.typ == y.typ
+
+	// ~t ∪ ~t == ~t
+	// ~t ∪  T == ~t
+	//  T ∪ ~t == ~t
+	//  T ∪  T ==  T
+	if x.tilde || !y.tilde {
+		return x, nil
+	}
+	return y, nil
+}
+
+// intersect returns the intersection x ∩ y.
+func (x *term) intersect(y *term) *term {
+	// easy cases
+	switch {
+	case x == nil || y == nil:
+		return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅
+	case x.typ == nil:
+		return y // 𝓤 ∩ y == y
+	case y.typ == nil:
+		return x // x ∩ 𝓤 == x
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	if x.disjoint(y) {
+		return nil // x ∩ y == ∅ if x ∩ y == ∅
+	}
+	// x.typ == y.typ
+
+	// ~t ∩ ~t == ~t
+	// ~t ∩  T ==  T
+	//  T ∩ ~t ==  T
+	//  T ∩  T ==  T
+	if !x.tilde || y.tilde {
+		return x
+	}
+	return y
+}
+
+// includes reports whether t ∈ x.
+func (x *term) includes(t types.Type) bool {
+	// easy cases
+	switch {
+	case x == nil:
+		return false // t ∈ ∅ == false
+	case x.typ == nil:
+		return true // t ∈ 𝓤 == true
+	}
+	// ∅ ⊂ x ⊂ 𝓤
+
+	u := t
+	if x.tilde {
+		u = under(u)
+	}
+	return types.Identical(x.typ, u)
+}
+
+// subsetOf reports whether x ⊆ y.
+func (x *term) subsetOf(y *term) bool {
+	// easy cases
+	switch {
+	case x == nil:
+		return true // ∅ ⊆ y == true
+	case y == nil:
+		return false // x ⊆ ∅ == false since x != ∅
+	case y.typ == nil:
+		return true // x ⊆ 𝓤 == true
+	case x.typ == nil:
+		return false // 𝓤 ⊆ y == false since y != 𝓤
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	if x.disjoint(y) {
+		return false // x ⊆ y == false if x ∩ y == ∅
+	}
+	// x.typ == y.typ
+
+	// ~t ⊆ ~t == true
+	// ~t ⊆ T == false
+	//  T ⊆ ~t == true
+	//  T ⊆  T == true
+	return !x.tilde || y.tilde
+}
+
+// disjoint reports whether x ∩ y == ∅.
+// x.typ and y.typ must not be nil.
+func (x *term) disjoint(y *term) bool {
+	if debug && (x.typ == nil || y.typ == nil) {
+		panic("invalid argument(s)")
+	}
+	ux := x.typ
+	if y.tilde {
+		ux = under(ux)
+	}
+	uy := y.typ
+	if x.tilde {
+		uy = under(uy)
+	}
+	return !types.Identical(ux, uy)
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/classify_call.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/classify_call.go
new file mode 100644
index 0000000..c7305cd
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/classify_call.go
@@ -0,0 +1,194 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+)
+
+// CallKind describes the function position of an [*ast.CallExpr].
+type CallKind int
+
+const (
+	CallStatic     CallKind = iota // static call to known function
+	CallInterface                  // dynamic call through an interface method
+	CallDynamic                    // dynamic call of a func value
+	CallBuiltin                    // call to a builtin function
+	CallConversion                 // a conversion (not a call)
+)
+
+var callKindNames = []string{
+	"CallStatic",
+	"CallInterface",
+	"CallDynamic",
+	"CallBuiltin",
+	"CallConversion",
+}
+
+func (k CallKind) String() string {
+	if i := int(k); i >= 0 && i < len(callKindNames) {
+		return callKindNames[i]
+	}
+	return fmt.Sprintf("typeutil.CallKind(%d)", k)
+}
+
+// ClassifyCall classifies the function position of a call expression ([*ast.CallExpr]).
+// It distinguishes among true function calls, calls to builtins, and type conversions,
+// and further classifies function calls as static calls (where the function is known),
+// dynamic interface calls, and other dynamic calls.
+//
+// For the declarations:
+//
+//	func f() {}
+//	func g[T any]() {}
+//	var v func()
+//	var s []func()
+//	type I interface { M() }
+//	var i I
+//
+// ClassifyCall returns the following:
+//
+//	f()           CallStatic
+//	g[int]()      CallStatic
+//	i.M()         CallInterface
+//	min(1, 2)     CallBuiltin
+//	v()           CallDynamic
+//	s[0]()        CallDynamic
+//	int(x)        CallConversion
+//	[]byte("")    CallConversion
+func ClassifyCall(info *types.Info, call *ast.CallExpr) CallKind {
+	if info.Types == nil {
+		panic("ClassifyCall: info.Types is nil")
+	}
+	tv := info.Types[call.Fun]
+	if tv.IsType() {
+		return CallConversion
+	}
+	if tv.IsBuiltin() {
+		return CallBuiltin
+	}
+	id := UsedIdent(info, call.Fun)
+	if id == nil {
+		return CallDynamic
+	}
+	obj := info.Uses[id]
+	// Classify the call by the type of the object, if any.
+	switch obj := obj.(type) {
+	case *types.Func:
+		if isInterfaceMethod(obj) {
+			return CallInterface
+		}
+		return CallStatic
+	default:
+		return CallDynamic
+	}
+}
+
+// UsedIdent returns the identifier such that info.Uses[UsedIdent(info, e)]
+// is the [types.Object] used by e, if any.
+//
+// If e is one of various forms of reference:
+//
+//	f, c, v, T           lexical reference
+//	pkg.X                qualified identifier
+//	f[T] or pkg.F[K,V]   instantiations of the above kinds
+//	expr.f               field or method value selector
+//	T.f                  method expression selector
+//
+// UsedIdent returns the identifier whose is associated value in [types.Info.Uses]
+// is the object to which it refers.
+//
+// For the declarations:
+//
+//	func F[T any] {...}
+//	type I interface { M() }
+//	var (
+//	  x int
+//	  s struct { f  int }
+//	  a []int
+//	  i I
+//	)
+//
+// UsedIdent returns the following:
+//
+//	Expr          UsedIdent
+//	x             x
+//	s.f           f
+//	F[int]        F
+//	i.M           M
+//	I.M           M
+//	min           min
+//	int           int
+//	1             nil
+//	a[0]          nil
+//	[]byte        nil
+//
+// Note: if e is an instantiated function or method, UsedIdent returns
+// the corresponding generic function or method on the generic type.
+func UsedIdent(info *types.Info, e ast.Expr) *ast.Ident {
+	if info.Types == nil || info.Uses == nil {
+		panic("one of info.Types or info.Uses is nil; both must be populated")
+	}
+	// Look through type instantiation if necessary.
+	switch d := ast.Unparen(e).(type) {
+	case *ast.IndexExpr:
+		if info.Types[d.Index].IsType() {
+			e = d.X
+		}
+	case *ast.IndexListExpr:
+		e = d.X
+	}
+	switch e := ast.Unparen(e).(type) {
+	// info.Uses always has the object we want, even for selector expressions.
+	// We don't need info.Selections.
+	// See go/types/recording.go:recordSelection.
+	case *ast.Ident:
+		return e
+	case *ast.SelectorExpr:
+		return e.Sel
+	}
+	return nil
+}
+
+// See [golang.org/x/tools/go/types/typeutil.Callee].
+func Callee(info *types.Info, call *ast.CallExpr) types.Object {
+	id := UsedIdent(info, call.Fun)
+	if id == nil {
+		return nil
+	}
+	obj := info.Uses[id]
+	if obj == nil {
+		return nil
+	}
+	if _, ok := obj.(*types.TypeName); ok {
+		return nil
+	}
+	return obj
+}
+
+// See [golang.org/x/tools/go/types/typeutil.StaticCallee].
+func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func {
+	id := UsedIdent(info, call.Fun)
+	if id == nil {
+		return nil
+	}
+	obj := info.Uses[id]
+	if obj == nil {
+		return nil
+	}
+	fn, _ := obj.(*types.Func)
+	if fn == nil || isInterfaceMethod(fn) {
+		return nil
+	}
+	return fn
+}
+
+// isInterfaceMethod reports whether its argument is a method of an interface.
+func isInterfaceMethod(f *types.Func) bool {
+	recv := f.Signature().Recv()
+	return recv != nil && types.IsInterface(recv.Type())
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/element.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/element.go
new file mode 100644
index 0000000..6e0613c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/element.go
@@ -0,0 +1,135 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"fmt"
+	"go/types"
+)
+
+// ForEachElement calls f for type T and each type reachable from its
+// type through reflection. It does this by recursively stripping off
+// type constructors; in addition, for each named type N, the type *N
+// is added to the result as it may have additional methods.
+//
+// The result of f indicates whether the caller has seen this type
+// already, so we can prune the traversal.
+//
+// TODO(adonovan): share/harmonize with go/callgraph/rta.
+//
+// methodSetOf abstracts (*typeutil.MethodSetCache).MethodSet,
+// avoiding an import cycle.
+func ForEachElement(methodSetOf func(types.Type) *types.MethodSet, T types.Type, f func(types.Type) bool) {
+	var visit func(T types.Type, skip bool)
+	visit = func(T types.Type, skip bool) {
+		if !skip {
+			// notify caller of element type
+			if f(T) {
+				return // duplicate; prune descent
+			}
+		}
+
+		// Recursion over signatures of each method.
+		tmset := methodSetOf(T)
+		for method := range tmset.Methods() {
+			sig := method.Type().(*types.Signature)
+			if sig.TypeParams() != nil {
+				continue // skip type-parameterized methods
+			}
+
+			// It is tempting to call visit(sig, false)
+			// but, as noted in golang.org/cl/65450043,
+			// the Signature.Recv field is ignored by
+			// types.Identical and typeutil.Map, which
+			// is confusing at best.
+			//
+			// More importantly, the true signature rtype
+			// reachable from a method using reflection
+			// has no receiver but an extra ordinary parameter.
+			// For the Read method of io.Reader we want:
+			//   func(Reader, []byte) (int, error)
+			// but here sig is:
+			//   func([]byte) (int, error)
+			// with .Recv = Reader (though it is hard to
+			// notice because it doesn't affect Signature.String
+			// or types.Identical).
+			//
+			// TODO(adonovan): construct and visit the correct
+			// non-method signature with an extra parameter
+			// (though since unnamed func types have no methods
+			// there is essentially no actual demand for this).
+			//
+			// TODO(adonovan): document whether or not it is
+			// safe to skip non-exported methods (as RTA does).
+			visit(sig.Params(), true)  // skip the Tuple
+			visit(sig.Results(), true) // skip the Tuple
+		}
+
+		switch T := T.(type) {
+		case *types.Alias:
+			visit(types.Unalias(T), skip) // emulates the pre-Alias behavior
+
+		case *types.Basic:
+			// nop
+
+		case *types.Interface:
+			// nop---handled by recursion over method set.
+
+		case *types.Pointer:
+			visit(T.Elem(), false)
+
+		case *types.Slice:
+			visit(T.Elem(), false)
+
+		case *types.Chan:
+			visit(T.Elem(), false)
+
+		case *types.Map:
+			visit(T.Key(), false)
+			visit(T.Elem(), false)
+
+		case *types.Signature:
+			if T.Recv() != nil {
+				panic(fmt.Sprintf("Signature %s has Recv %s", T, T.Recv()))
+			}
+			visit(T.Params(), true)  // skip the Tuple
+			visit(T.Results(), true) // skip the Tuple
+
+		case *types.Named:
+			// A pointer-to-named type can be derived from a named
+			// type via reflection.  It may have methods too.
+			visit(types.NewPointer(T), false)
+
+			// Consider 'type T struct{S}' where S has methods.
+			// Reflection provides no way to get from T to struct{S},
+			// only to S, so the method set of struct{S} is unwanted,
+			// so set 'skip' flag during recursion.
+			visit(T.Underlying(), true) // skip the unnamed type
+
+		case *types.Array:
+			visit(T.Elem(), false)
+
+		case *types.Struct:
+			for i, n := 0, T.NumFields(); i < n; i++ {
+				// TODO(adonovan): document whether or not
+				// it is safe to skip non-exported fields.
+				visit(T.Field(i).Type(), false)
+			}
+
+		case *types.Tuple:
+			for i, n := 0, T.Len(); i < n; i++ {
+				visit(T.At(i).Type(), false)
+			}
+
+		case *types.TypeParam, *types.Union:
+			// forEachReachable must not be called on parameterized types.
+			panic(fmt.Sprintf("ForEachElement called on type containing %T", T))
+
+		default:
+			panic(fmt.Sprintf("ForEachElement called on unexpected type %T", T))
+		}
+	}
+	visit(T, false)
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/errorcode.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/errorcode.go
new file mode 100644
index 0000000..bd94474
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/errorcode.go
@@ -0,0 +1,1558 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+type ErrorCode int
+
+// This file defines the error codes that can be produced during type-checking.
+// Collectively, these codes provide an identifier that may be used to
+// implement special handling for certain types of errors.
+//
+// Error codes should be fine-grained enough that the exact nature of the error
+// can be easily determined, but coarse enough that they are not an
+// implementation detail of the type checking algorithm. As a rule-of-thumb,
+// errors should be considered equivalent if there is a theoretical refactoring
+// of the type checker in which they are emitted in exactly one place. For
+// example, the type checker emits different error messages for "too many
+// arguments" and "too few arguments", but one can imagine an alternative type
+// checker where this check instead just emits a single "wrong number of
+// arguments", so these errors should have the same code.
+//
+// Error code names should be as brief as possible while retaining accuracy and
+// distinctiveness. In most cases names should start with an adjective
+// describing the nature of the error (e.g. "invalid", "unused", "misplaced"),
+// and end with a noun identifying the relevant language object. For example,
+// "DuplicateDecl" or "InvalidSliceExpr". For brevity, naming follows the
+// convention that "bad" implies a problem with syntax, and "invalid" implies a
+// problem with types.
+
+const (
+	// InvalidSyntaxTree occurs if an invalid syntax tree is provided
+	// to the type checker. It should never happen.
+	InvalidSyntaxTree ErrorCode = -1
+)
+
+const (
+	_ ErrorCode = iota
+
+	// Test is reserved for errors that only apply while in self-test mode.
+	Test
+
+	/* package names */
+
+	// BlankPkgName occurs when a package name is the blank identifier "_".
+	//
+	// Per the spec:
+	//  "The PackageName must not be the blank identifier."
+	BlankPkgName
+
+	// MismatchedPkgName occurs when a file's package name doesn't match the
+	// package name already established by other files.
+	MismatchedPkgName
+
+	// InvalidPkgUse occurs when a package identifier is used outside of a
+	// selector expression.
+	//
+	// Example:
+	//  import "fmt"
+	//
+	//  var _ = fmt
+	InvalidPkgUse
+
+	/* imports */
+
+	// BadImportPath occurs when an import path is not valid.
+	BadImportPath
+
+	// BrokenImport occurs when importing a package fails.
+	//
+	// Example:
+	//  import "amissingpackage"
+	BrokenImport
+
+	// ImportCRenamed occurs when the special import "C" is renamed. "C" is a
+	// pseudo-package, and must not be renamed.
+	//
+	// Example:
+	//  import _ "C"
+	ImportCRenamed
+
+	// UnusedImport occurs when an import is unused.
+	//
+	// Example:
+	//  import "fmt"
+	//
+	//  func main() {}
+	UnusedImport
+
+	/* initialization */
+
+	// InvalidInitCycle occurs when an invalid cycle is detected within the
+	// initialization graph.
+	//
+	// Example:
+	//  var x int = f()
+	//
+	//  func f() int { return x }
+	InvalidInitCycle
+
+	/* decls */
+
+	// DuplicateDecl occurs when an identifier is declared multiple times.
+	//
+	// Example:
+	//  var x = 1
+	//  var x = 2
+	DuplicateDecl
+
+	// InvalidDeclCycle occurs when a declaration cycle is not valid.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type T struct {
+	//  	a [n]int
+	//  }
+	//
+	//  var n = unsafe.Sizeof(T{})
+	InvalidDeclCycle
+
+	// InvalidTypeCycle occurs when a cycle in type definitions results in a
+	// type that is not well-defined.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type T [unsafe.Sizeof(T{})]int
+	InvalidTypeCycle
+
+	/* decls > const */
+
+	// InvalidConstInit occurs when a const declaration has a non-constant
+	// initializer.
+	//
+	// Example:
+	//  var x int
+	//  const _ = x
+	InvalidConstInit
+
+	// InvalidConstVal occurs when a const value cannot be converted to its
+	// target type.
+	//
+	// TODO(findleyr): this error code and example are not very clear. Consider
+	// removing it.
+	//
+	// Example:
+	//  const _ = 1 << "hello"
+	InvalidConstVal
+
+	// InvalidConstType occurs when the underlying type in a const declaration
+	// is not a valid constant type.
+	//
+	// Example:
+	//  const c *int = 4
+	InvalidConstType
+
+	/* decls > var (+ other variable assignment codes) */
+
+	// UntypedNilUse occurs when the predeclared (untyped) value nil is used to
+	// initialize a variable declared without an explicit type.
+	//
+	// Example:
+	//  var x = nil
+	UntypedNilUse
+
+	// WrongAssignCount occurs when the number of values on the right-hand side
+	// of an assignment or initialization expression does not match the number
+	// of variables on the left-hand side.
+	//
+	// Example:
+	//  var x = 1, 2
+	WrongAssignCount
+
+	// UnassignableOperand occurs when the left-hand side of an assignment is
+	// not assignable.
+	//
+	// Example:
+	//  func f() {
+	//  	const c = 1
+	//  	c = 2
+	//  }
+	UnassignableOperand
+
+	// NoNewVar occurs when a short variable declaration (':=') does not declare
+	// new variables.
+	//
+	// Example:
+	//  func f() {
+	//  	x := 1
+	//  	x := 2
+	//  }
+	NoNewVar
+
+	// MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does
+	// not have single-valued left-hand or right-hand side.
+	//
+	// Per the spec:
+	//  "In assignment operations, both the left- and right-hand expression lists
+	//  must contain exactly one single-valued expression"
+	//
+	// Example:
+	//  func f() int {
+	//  	x, y := 1, 2
+	//  	x, y += 1
+	//  	return x + y
+	//  }
+	MultiValAssignOp
+
+	// InvalidIfaceAssign occurs when a value of type T is used as an
+	// interface, but T does not implement a method of the expected interface.
+	//
+	// Example:
+	//  type I interface {
+	//  	f()
+	//  }
+	//
+	//  type T int
+	//
+	//  var x I = T(1)
+	InvalidIfaceAssign
+
+	// InvalidChanAssign occurs when a chan assignment is invalid.
+	//
+	// Per the spec, a value x is assignable to a channel type T if:
+	//  "x is a bidirectional channel value, T is a channel type, x's type V and
+	//  T have identical element types, and at least one of V or T is not a
+	//  defined type."
+	//
+	// Example:
+	//  type T1 chan int
+	//  type T2 chan int
+	//
+	//  var x T1
+	//  // Invalid assignment because both types are named
+	//  var _ T2 = x
+	InvalidChanAssign
+
+	// IncompatibleAssign occurs when the type of the right-hand side expression
+	// in an assignment cannot be assigned to the type of the variable being
+	// assigned.
+	//
+	// Example:
+	//  var x []int
+	//  var _ int = x
+	IncompatibleAssign
+
+	// UnaddressableFieldAssign occurs when trying to assign to a struct field
+	// in a map value.
+	//
+	// Example:
+	//  func f() {
+	//  	m := make(map[string]struct{i int})
+	//  	m["foo"].i = 42
+	//  }
+	UnaddressableFieldAssign
+
+	/* decls > type (+ other type expression codes) */
+
+	// NotAType occurs when the identifier used as the underlying type in a type
+	// declaration or the right-hand side of a type alias does not denote a type.
+	//
+	// Example:
+	//  var S = 2
+	//
+	//  type T S
+	NotAType
+
+	// InvalidArrayLen occurs when an array length is not a constant value.
+	//
+	// Example:
+	//  var n = 3
+	//  var _ = [n]int{}
+	InvalidArrayLen
+
+	// BlankIfaceMethod occurs when a method name is '_'.
+	//
+	// Per the spec:
+	//  "The name of each explicitly specified method must be unique and not
+	//  blank."
+	//
+	// Example:
+	//  type T interface {
+	//  	_(int)
+	//  }
+	BlankIfaceMethod
+
+	// IncomparableMapKey occurs when a map key type does not support the == and
+	// != operators.
+	//
+	// Per the spec:
+	//  "The comparison operators == and != must be fully defined for operands of
+	//  the key type; thus the key type must not be a function, map, or slice."
+	//
+	// Example:
+	//  var x map[T]int
+	//
+	//  type T []int
+	IncomparableMapKey
+
+	// InvalidIfaceEmbed occurs when a non-interface type is embedded in an
+	// interface.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func (T) m()
+	//
+	//  type I interface {
+	//  	T
+	//  }
+	InvalidIfaceEmbed
+
+	// InvalidPtrEmbed occurs when an embedded field is of the pointer form *T,
+	// and T itself is itself a pointer, an unsafe.Pointer, or an interface.
+	//
+	// Per the spec:
+	//  "An embedded field must be specified as a type name T or as a pointer to
+	//  a non-interface type name *T, and T itself may not be a pointer type."
+	//
+	// Example:
+	//  type T *int
+	//
+	//  type S struct {
+	//  	*T
+	//  }
+	InvalidPtrEmbed
+
+	/* decls > func and method */
+
+	// BadRecv occurs when a method declaration does not have exactly one
+	// receiver parameter.
+	//
+	// Example:
+	//  func () _() {}
+	BadRecv
+
+	// InvalidRecv occurs when a receiver type expression is not of the form T
+	// or *T, or T is a pointer type.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func (**T) m() {}
+	InvalidRecv
+
+	// DuplicateFieldAndMethod occurs when an identifier appears as both a field
+	// and method name.
+	//
+	// Example:
+	//  type T struct {
+	//  	m int
+	//  }
+	//
+	//  func (T) m() {}
+	DuplicateFieldAndMethod
+
+	// DuplicateMethod occurs when two methods on the same receiver type have
+	// the same name.
+	//
+	// Example:
+	//  type T struct {}
+	//  func (T) m() {}
+	//  func (T) m(i int) int { return i }
+	DuplicateMethod
+
+	/* decls > special */
+
+	// InvalidBlank occurs when a blank identifier is used as a value or type.
+	//
+	// Per the spec:
+	//  "The blank identifier may appear as an operand only on the left-hand side
+	//  of an assignment."
+	//
+	// Example:
+	//  var x = _
+	InvalidBlank
+
+	// InvalidIota occurs when the predeclared identifier iota is used outside
+	// of a constant declaration.
+	//
+	// Example:
+	//  var x = iota
+	InvalidIota
+
+	// MissingInitBody occurs when an init function is missing its body.
+	//
+	// Example:
+	//  func init()
+	MissingInitBody
+
+	// InvalidInitSig occurs when an init function declares parameters or
+	// results.
+	//
+	// Example:
+	//  func init() int { return 1 }
+	InvalidInitSig
+
+	// InvalidInitDecl occurs when init is declared as anything other than a
+	// function.
+	//
+	// Example:
+	//  var init = 1
+	InvalidInitDecl
+
+	// InvalidMainDecl occurs when main is declared as anything other than a
+	// function, in a main package.
+	InvalidMainDecl
+
+	/* exprs */
+
+	// TooManyValues occurs when a function returns too many values for the
+	// expression context in which it is used.
+	//
+	// Example:
+	//  func ReturnTwo() (int, int) {
+	//  	return 1, 2
+	//  }
+	//
+	//  var x = ReturnTwo()
+	TooManyValues
+
+	// NotAnExpr occurs when a type expression is used where a value expression
+	// is expected.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func f() {
+	//  	T
+	//  }
+	NotAnExpr
+
+	/* exprs > const */
+
+	// TruncatedFloat occurs when a float constant is truncated to an integer
+	// value.
+	//
+	// Example:
+	//  var _ int = 98.6
+	TruncatedFloat
+
+	// NumericOverflow occurs when a numeric constant overflows its target type.
+	//
+	// Example:
+	//  var x int8 = 1000
+	NumericOverflow
+
+	/* exprs > operation */
+
+	// UndefinedOp occurs when an operator is not defined for the type(s) used
+	// in an operation.
+	//
+	// Example:
+	//  var c = "a" - "b"
+	UndefinedOp
+
+	// MismatchedTypes occurs when operand types are incompatible in a binary
+	// operation.
+	//
+	// Example:
+	//  var a = "hello"
+	//  var b = 1
+	//  var c = a - b
+	MismatchedTypes
+
+	// DivByZero occurs when a division operation is provable at compile
+	// time to be a division by zero.
+	//
+	// Example:
+	//  const divisor = 0
+	//  var x int = 1/divisor
+	DivByZero
+
+	// NonNumericIncDec occurs when an increment or decrement operator is
+	// applied to a non-numeric value.
+	//
+	// Example:
+	//  func f() {
+	//  	var c = "c"
+	//  	c++
+	//  }
+	NonNumericIncDec
+
+	/* exprs > ptr */
+
+	// UnaddressableOperand occurs when the & operator is applied to an
+	// unaddressable expression.
+	//
+	// Example:
+	//  var x = &1
+	UnaddressableOperand
+
+	// InvalidIndirection occurs when a non-pointer value is indirected via the
+	// '*' operator.
+	//
+	// Example:
+	//  var x int
+	//  var y = *x
+	InvalidIndirection
+
+	/* exprs > [] */
+
+	// NonIndexableOperand occurs when an index operation is applied to a value
+	// that cannot be indexed.
+	//
+	// Example:
+	//  var x = 1
+	//  var y = x[1]
+	NonIndexableOperand
+
+	// InvalidIndex occurs when an index argument is not of integer type,
+	// negative, or out-of-bounds.
+	//
+	// Example:
+	//  var s = [...]int{1,2,3}
+	//  var x = s[5]
+	//
+	// Example:
+	//  var s = []int{1,2,3}
+	//  var _ = s[-1]
+	//
+	// Example:
+	//  var s = []int{1,2,3}
+	//  var i string
+	//  var _ = s[i]
+	InvalidIndex
+
+	// SwappedSliceIndices occurs when constant indices in a slice expression
+	// are decreasing in value.
+	//
+	// Example:
+	//  var _ = []int{1,2,3}[2:1]
+	SwappedSliceIndices
+
+	/* operators > slice */
+
+	// NonSliceableOperand occurs when a slice operation is applied to a value
+	// whose type is not sliceable, or is unaddressable.
+	//
+	// Example:
+	//  var x = [...]int{1, 2, 3}[:1]
+	//
+	// Example:
+	//  var x = 1
+	//  var y = 1[:1]
+	NonSliceableOperand
+
+	// InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is
+	// applied to a string.
+	//
+	// Example:
+	//  var s = "hello"
+	//  var x = s[1:2:3]
+	InvalidSliceExpr
+
+	/* exprs > shift */
+
+	// InvalidShiftCount occurs when the right-hand side of a shift operation is
+	// either non-integer, negative, or too large.
+	//
+	// Example:
+	//  var (
+	//  	x string
+	//  	y int = 1 << x
+	//  )
+	InvalidShiftCount
+
+	// InvalidShiftOperand occurs when the shifted operand is not an integer.
+	//
+	// Example:
+	//  var s = "hello"
+	//  var x = s << 2
+	InvalidShiftOperand
+
+	/* exprs > chan */
+
+	// InvalidReceive occurs when there is a channel receive from a value that
+	// is either not a channel, or is a send-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x = 1
+	//  	<-x
+	//  }
+	InvalidReceive
+
+	// InvalidSend occurs when there is a channel send to a value that is not a
+	// channel, or is a receive-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x = 1
+	//  	x <- "hello!"
+	//  }
+	InvalidSend
+
+	/* exprs > literal */
+
+	// DuplicateLitKey occurs when an index is duplicated in a slice, array, or
+	// map literal.
+	//
+	// Example:
+	//  var _ = []int{0:1, 0:2}
+	//
+	// Example:
+	//  var _ = map[string]int{"a": 1, "a": 2}
+	DuplicateLitKey
+
+	// MissingLitKey occurs when a map literal is missing a key expression.
+	//
+	// Example:
+	//  var _ = map[string]int{1}
+	MissingLitKey
+
+	// InvalidLitIndex occurs when the key in a key-value element of a slice or
+	// array literal is not an integer constant.
+	//
+	// Example:
+	//  var i = 0
+	//  var x = []string{i: "world"}
+	InvalidLitIndex
+
+	// OversizeArrayLit occurs when an array literal exceeds its length.
+	//
+	// Example:
+	//  var _ = [2]int{1,2,3}
+	OversizeArrayLit
+
+	// MixedStructLit occurs when a struct literal contains a mix of positional
+	// and named elements.
+	//
+	// Example:
+	//  var _ = struct{i, j int}{i: 1, 2}
+	MixedStructLit
+
+	// InvalidStructLit occurs when a positional struct literal has an incorrect
+	// number of values.
+	//
+	// Example:
+	//  var _ = struct{i, j int}{1,2,3}
+	InvalidStructLit
+
+	// MissingLitField occurs when a struct literal refers to a field that does
+	// not exist on the struct type.
+	//
+	// Example:
+	//  var _ = struct{i int}{j: 2}
+	MissingLitField
+
+	// DuplicateLitField occurs when a struct literal contains duplicated
+	// fields.
+	//
+	// Example:
+	//  var _ = struct{i int}{i: 1, i: 2}
+	DuplicateLitField
+
+	// UnexportedLitField occurs when a positional struct literal implicitly
+	// assigns an unexported field of an imported type.
+	UnexportedLitField
+
+	// InvalidLitField occurs when a field name is not a valid identifier.
+	//
+	// Example:
+	//  var _ = struct{i int}{1: 1}
+	InvalidLitField
+
+	// UntypedLit occurs when a composite literal omits a required type
+	// identifier.
+	//
+	// Example:
+	//  type outer struct{
+	//  	inner struct { i int }
+	//  }
+	//
+	//  var _ = outer{inner: {1}}
+	UntypedLit
+
+	// InvalidLit occurs when a composite literal expression does not match its
+	// type.
+	//
+	// Example:
+	//  type P *struct{
+	//  	x int
+	//  }
+	//  var _ = P {}
+	InvalidLit
+
+	/* exprs > selector */
+
+	// AmbiguousSelector occurs when a selector is ambiguous.
+	//
+	// Example:
+	//  type E1 struct { i int }
+	//  type E2 struct { i int }
+	//  type T struct { E1; E2 }
+	//
+	//  var x T
+	//  var _ = x.i
+	AmbiguousSelector
+
+	// UndeclaredImportedName occurs when a package-qualified identifier is
+	// undeclared by the imported package.
+	//
+	// Example:
+	//  import "go/types"
+	//
+	//  var _ = types.NotAnActualIdentifier
+	UndeclaredImportedName
+
+	// UnexportedName occurs when a selector refers to an unexported identifier
+	// of an imported package.
+	//
+	// Example:
+	//  import "reflect"
+	//
+	//  type _ reflect.flag
+	UnexportedName
+
+	// UndeclaredName occurs when an identifier is not declared in the current
+	// scope.
+	//
+	// Example:
+	//  var x T
+	UndeclaredName
+
+	// MissingFieldOrMethod occurs when a selector references a field or method
+	// that does not exist.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  var x = T{}.f
+	MissingFieldOrMethod
+
+	/* exprs > ... */
+
+	// BadDotDotDotSyntax occurs when a "..." occurs in a context where it is
+	// not valid.
+	//
+	// Example:
+	//  var _ = map[int][...]int{0: {}}
+	BadDotDotDotSyntax
+
+	// NonVariadicDotDotDot occurs when a "..." is used on the final argument to
+	// a non-variadic function.
+	//
+	// Example:
+	//  func printArgs(s []string) {
+	//  	for _, a := range s {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func f() {
+	//  	s := []string{"a", "b", "c"}
+	//  	printArgs(s...)
+	//  }
+	NonVariadicDotDotDot
+
+	// MisplacedDotDotDot occurs when a "..." is used somewhere other than the
+	// final argument to a function call.
+	//
+	// Example:
+	//  func printArgs(args ...int) {
+	//  	for _, a := range args {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func f() {
+	//  	a := []int{1,2,3}
+	//  	printArgs(0, a...)
+	//  }
+	MisplacedDotDotDot
+
+	// InvalidDotDotDotOperand occurs when a "..." operator is applied to a
+	// single-valued operand.
+	//
+	// Example:
+	//  func printArgs(args ...int) {
+	//  	for _, a := range args {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func f() {
+	//  	a := 1
+	//  	printArgs(a...)
+	//  }
+	//
+	// Example:
+	//  func args() (int, int) {
+	//  	return 1, 2
+	//  }
+	//
+	//  func printArgs(args ...int) {
+	//  	for _, a := range args {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func g() {
+	//  	printArgs(args()...)
+	//  }
+	InvalidDotDotDotOperand
+
+	// InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in
+	// function.
+	//
+	// Example:
+	//  var s = []int{1, 2, 3}
+	//  var l = len(s...)
+	InvalidDotDotDot
+
+	/* exprs > built-in */
+
+	// UncalledBuiltin occurs when a built-in function is used as a
+	// function-valued expression, instead of being called.
+	//
+	// Per the spec:
+	//  "The built-in functions do not have standard Go types, so they can only
+	//  appear in call expressions; they cannot be used as function values."
+	//
+	// Example:
+	//  var _ = copy
+	UncalledBuiltin
+
+	// InvalidAppend occurs when append is called with a first argument that is
+	// not a slice.
+	//
+	// Example:
+	//  var _ = append(1, 2)
+	InvalidAppend
+
+	// InvalidCap occurs when an argument to the cap built-in function is not of
+	// supported type.
+	//
+	// See https://golang.org/ref/spec#Length_and_capacity for information on
+	// which underlying types are supported as arguments to cap and len.
+	//
+	// Example:
+	//  var s = 2
+	//  var x = cap(s)
+	InvalidCap
+
+	// InvalidClose occurs when close(...) is called with an argument that is
+	// not of channel type, or that is a receive-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x int
+	//  	close(x)
+	//  }
+	InvalidClose
+
+	// InvalidCopy occurs when the arguments are not of slice type or do not
+	// have compatible type.
+	//
+	// See https://golang.org/ref/spec#Appending_and_copying_slices for more
+	// information on the type requirements for the copy built-in.
+	//
+	// Example:
+	//  func f() {
+	//  	var x []int
+	//  	y := []int64{1,2,3}
+	//  	copy(x, y)
+	//  }
+	InvalidCopy
+
+	// InvalidComplex occurs when the complex built-in function is called with
+	// arguments with incompatible types.
+	//
+	// Example:
+	//  var _ = complex(float32(1), float64(2))
+	InvalidComplex
+
+	// InvalidDelete occurs when the delete built-in function is called with a
+	// first argument that is not a map.
+	//
+	// Example:
+	//  func f() {
+	//  	m := "hello"
+	//  	delete(m, "e")
+	//  }
+	InvalidDelete
+
+	// InvalidImag occurs when the imag built-in function is called with an
+	// argument that does not have complex type.
+	//
+	// Example:
+	//  var _ = imag(int(1))
+	InvalidImag
+
+	// InvalidLen occurs when an argument to the len built-in function is not of
+	// supported type.
+	//
+	// See https://golang.org/ref/spec#Length_and_capacity for information on
+	// which underlying types are supported as arguments to cap and len.
+	//
+	// Example:
+	//  var s = 2
+	//  var x = len(s)
+	InvalidLen
+
+	// SwappedMakeArgs occurs when make is called with three arguments, and its
+	// length argument is larger than its capacity argument.
+	//
+	// Example:
+	//  var x = make([]int, 3, 2)
+	SwappedMakeArgs
+
+	// InvalidMake occurs when make is called with an unsupported type argument.
+	//
+	// See https://golang.org/ref/spec#Making_slices_maps_and_channels for
+	// information on the types that may be created using make.
+	//
+	// Example:
+	//  var x = make(int)
+	InvalidMake
+
+	// InvalidReal occurs when the real built-in function is called with an
+	// argument that does not have complex type.
+	//
+	// Example:
+	//  var _ = real(int(1))
+	InvalidReal
+
+	/* exprs > assertion */
+
+	// InvalidAssert occurs when a type assertion is applied to a
+	// value that is not of interface type.
+	//
+	// Example:
+	//  var x = 1
+	//  var _ = x.(float64)
+	InvalidAssert
+
+	// ImpossibleAssert occurs for a type assertion x.(T) when the value x of
+	// interface cannot have dynamic type T, due to a missing or mismatching
+	// method on T.
+	//
+	// Example:
+	//  type T int
+	//
+	//  func (t *T) m() int { return int(*t) }
+	//
+	//  type I interface { m() int }
+	//
+	//  var x I
+	//  var _ = x.(T)
+	ImpossibleAssert
+
+	/* exprs > conversion */
+
+	// InvalidConversion occurs when the argument type cannot be converted to the
+	// target.
+	//
+	// See https://golang.org/ref/spec#Conversions for the rules of
+	// convertibility.
+	//
+	// Example:
+	//  var x float64
+	//  var _ = string(x)
+	InvalidConversion
+
+	// InvalidUntypedConversion occurs when there is no valid implicit
+	// conversion from an untyped value satisfying the type constraints of the
+	// context in which it is used.
+	//
+	// Example:
+	//  var _ = 1 + ""
+	InvalidUntypedConversion
+
+	/* offsetof */
+
+	// BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument
+	// that is not a selector expression.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Offsetof(x)
+	BadOffsetofSyntax
+
+	// InvalidOffsetof occurs when unsafe.Offsetof is called with a method
+	// selector, rather than a field selector, or when the field is embedded via
+	// a pointer.
+	//
+	// Per the spec:
+	//
+	//  "If f is an embedded field, it must be reachable without pointer
+	//  indirections through fields of the struct. "
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type T struct { f int }
+	//  type S struct { *T }
+	//  var s S
+	//  var _ = unsafe.Offsetof(s.f)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type S struct{}
+	//
+	//  func (S) m() {}
+	//
+	//  var s S
+	//  var _ = unsafe.Offsetof(s.m)
+	InvalidOffsetof
+
+	/* control flow > scope */
+
+	// UnusedExpr occurs when a side-effect free expression is used as a
+	// statement. Such a statement has no effect.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	i*i
+	//  }
+	UnusedExpr
+
+	// UnusedVar occurs when a variable is declared but unused.
+	//
+	// Example:
+	//  func f() {
+	//  	x := 1
+	//  }
+	UnusedVar
+
+	// MissingReturn occurs when a function with results is missing a return
+	// statement.
+	//
+	// Example:
+	//  func f() int {}
+	MissingReturn
+
+	// WrongResultCount occurs when a return statement returns an incorrect
+	// number of values.
+	//
+	// Example:
+	//  func ReturnOne() int {
+	//  	return 1, 2
+	//  }
+	WrongResultCount
+
+	// OutOfScopeResult occurs when the name of a value implicitly returned by
+	// an empty return statement is shadowed in a nested scope.
+	//
+	// Example:
+	//  func factor(n int) (i int) {
+	//  	for i := 2; i < n; i++ {
+	//  		if n%i == 0 {
+	//  			return
+	//  		}
+	//  	}
+	//  	return 0
+	//  }
+	OutOfScopeResult
+
+	/* control flow > if */
+
+	// InvalidCond occurs when an if condition is not a boolean expression.
+	//
+	// Example:
+	//  func checkReturn(i int) {
+	//  	if i {
+	//  		panic("non-zero return")
+	//  	}
+	//  }
+	InvalidCond
+
+	/* control flow > for */
+
+	// InvalidPostDecl occurs when there is a declaration in a for-loop post
+	// statement.
+	//
+	// Example:
+	//  func f() {
+	//  	for i := 0; i < 10; j := 0 {}
+	//  }
+	InvalidPostDecl
+
+	// InvalidChanRange occurs when a send-only channel used in a range
+	// expression.
+	//
+	// Example:
+	//  func sum(c chan<- int) {
+	//  	s := 0
+	//  	for i := range c {
+	//  		s += i
+	//  	}
+	//  }
+	InvalidChanRange
+
+	// InvalidIterVar occurs when two iteration variables are used while ranging
+	// over a channel.
+	//
+	// Example:
+	//  func f(c chan int) {
+	//  	for k, v := range c {
+	//  		println(k, v)
+	//  	}
+	//  }
+	InvalidIterVar
+
+	// InvalidRangeExpr occurs when the type of a range expression is not array,
+	// slice, string, map, or channel.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	for j := range i {
+	//  		println(j)
+	//  	}
+	//  }
+	InvalidRangeExpr
+
+	/* control flow > switch */
+
+	// MisplacedBreak occurs when a break statement is not within a for, switch,
+	// or select statement of the innermost function definition.
+	//
+	// Example:
+	//  func f() {
+	//  	break
+	//  }
+	MisplacedBreak
+
+	// MisplacedContinue occurs when a continue statement is not within a for
+	// loop of the innermost function definition.
+	//
+	// Example:
+	//  func sumeven(n int) int {
+	//  	proceed := func() {
+	//  		continue
+	//  	}
+	//  	sum := 0
+	//  	for i := 1; i <= n; i++ {
+	//  		if i % 2 != 0 {
+	//  			proceed()
+	//  		}
+	//  		sum += i
+	//  	}
+	//  	return sum
+	//  }
+	MisplacedContinue
+
+	// MisplacedFallthrough occurs when a fallthrough statement is not within an
+	// expression switch.
+	//
+	// Example:
+	//  func typename(i interface{}) string {
+	//  	switch i.(type) {
+	//  	case int64:
+	//  		fallthrough
+	//  	case int:
+	//  		return "int"
+	//  	}
+	//  	return "unsupported"
+	//  }
+	MisplacedFallthrough
+
+	// DuplicateCase occurs when a type or expression switch has duplicate
+	// cases.
+	//
+	// Example:
+	//  func printInt(i int) {
+	//  	switch i {
+	//  	case 1:
+	//  		println("one")
+	//  	case 1:
+	//  		println("One")
+	//  	}
+	//  }
+	DuplicateCase
+
+	// DuplicateDefault occurs when a type or expression switch has multiple
+	// default clauses.
+	//
+	// Example:
+	//  func printInt(i int) {
+	//  	switch i {
+	//  	case 1:
+	//  		println("one")
+	//  	default:
+	//  		println("One")
+	//  	default:
+	//  		println("1")
+	//  	}
+	//  }
+	DuplicateDefault
+
+	// BadTypeKeyword occurs when a .(type) expression is used anywhere other
+	// than a type switch.
+	//
+	// Example:
+	//  type I interface {
+	//  	m()
+	//  }
+	//  var t I
+	//  var _ = t.(type)
+	BadTypeKeyword
+
+	// InvalidTypeSwitch occurs when .(type) is used on an expression that is
+	// not of interface type.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	switch x := i.(type) {}
+	//  }
+	InvalidTypeSwitch
+
+	// InvalidExprSwitch occurs when a switch expression is not comparable.
+	//
+	// Example:
+	//  func _() {
+	//  	var a struct{ _ func() }
+	//  	switch a /* ERROR cannot switch on a */ {
+	//  	}
+	//  }
+	InvalidExprSwitch
+
+	/* control flow > select */
+
+	// InvalidSelectCase occurs when a select case is not a channel send or
+	// receive.
+	//
+	// Example:
+	//  func checkChan(c <-chan int) bool {
+	//  	select {
+	//  	case c:
+	//  		return true
+	//  	default:
+	//  		return false
+	//  	}
+	//  }
+	InvalidSelectCase
+
+	/* control flow > labels and jumps */
+
+	// UndeclaredLabel occurs when an undeclared label is jumped to.
+	//
+	// Example:
+	//  func f() {
+	//  	goto L
+	//  }
+	UndeclaredLabel
+
+	// DuplicateLabel occurs when a label is declared more than once.
+	//
+	// Example:
+	//  func f() int {
+	//  L:
+	//  L:
+	//  	return 1
+	//  }
+	DuplicateLabel
+
+	// MisplacedLabel occurs when a break or continue label is not on a for,
+	// switch, or select statement.
+	//
+	// Example:
+	//  func f() {
+	//  L:
+	//  	a := []int{1,2,3}
+	//  	for _, e := range a {
+	//  		if e > 10 {
+	//  			break L
+	//  		}
+	//  		println(a)
+	//  	}
+	//  }
+	MisplacedLabel
+
+	// UnusedLabel occurs when a label is declared but not used.
+	//
+	// Example:
+	//  func f() {
+	//  L:
+	//  }
+	UnusedLabel
+
+	// JumpOverDecl occurs when a label jumps over a variable declaration.
+	//
+	// Example:
+	//  func f() int {
+	//  	goto L
+	//  	x := 2
+	//  L:
+	//  	x++
+	//  	return x
+	//  }
+	JumpOverDecl
+
+	// JumpIntoBlock occurs when a forward jump goes to a label inside a nested
+	// block.
+	//
+	// Example:
+	//  func f(x int) {
+	//  	goto L
+	//  	if x > 0 {
+	//  	L:
+	//  		print("inside block")
+	//  	}
+	// }
+	JumpIntoBlock
+
+	/* control flow > calls */
+
+	// InvalidMethodExpr occurs when a pointer method is called but the argument
+	// is not addressable.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func (*T) m() int { return 1 }
+	//
+	//  var _ = T.m(T{})
+	InvalidMethodExpr
+
+	// WrongArgCount occurs when too few or too many arguments are passed by a
+	// function call.
+	//
+	// Example:
+	//  func f(i int) {}
+	//  var x = f()
+	WrongArgCount
+
+	// InvalidCall occurs when an expression is called that is not of function
+	// type.
+	//
+	// Example:
+	//  var x = "x"
+	//  var y = x()
+	InvalidCall
+
+	/* control flow > suspended */
+
+	// UnusedResults occurs when a restricted expression-only built-in function
+	// is suspended via go or defer. Such a suspension discards the results of
+	// these side-effect free built-in functions, and therefore is ineffectual.
+	//
+	// Example:
+	//  func f(a []int) int {
+	//  	defer len(a)
+	//  	return i
+	//  }
+	UnusedResults
+
+	// InvalidDefer occurs when a deferred expression is not a function call,
+	// for example if the expression is a type conversion.
+	//
+	// Example:
+	//  func f(i int) int {
+	//  	defer int32(i)
+	//  	return i
+	//  }
+	InvalidDefer
+
+	// InvalidGo occurs when a go expression is not a function call, for example
+	// if the expression is a type conversion.
+	//
+	// Example:
+	//  func f(i int) int {
+	//  	go int32(i)
+	//  	return i
+	//  }
+	InvalidGo
+
+	// All codes below were added in Go 1.17.
+
+	/* decl */
+
+	// BadDecl occurs when a declaration has invalid syntax.
+	BadDecl
+
+	// RepeatedDecl occurs when an identifier occurs more than once on the left
+	// hand side of a short variable declaration.
+	//
+	// Example:
+	//  func _() {
+	//  	x, y, y := 1, 2, 3
+	//  }
+	RepeatedDecl
+
+	/* unsafe */
+
+	// InvalidUnsafeAdd occurs when unsafe.Add is called with a
+	// length argument that is not of integer type.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var p unsafe.Pointer
+	//  var _ = unsafe.Add(p, float64(1))
+	InvalidUnsafeAdd
+
+	// InvalidUnsafeSlice occurs when unsafe.Slice is called with a
+	// pointer argument that is not of pointer type or a length argument
+	// that is not of integer type, negative, or out of bounds.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(x, 1)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, float64(1))
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, -1)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, uint64(1) << 63)
+	InvalidUnsafeSlice
+
+	// All codes below were added in Go 1.18.
+
+	/* features */
+
+	// UnsupportedFeature occurs when a language feature is used that is not
+	// supported at this Go version.
+	UnsupportedFeature
+
+	/* type params */
+
+	// NotAGenericType occurs when a non-generic type is used where a generic
+	// type is expected: in type or function instantiation.
+	//
+	// Example:
+	//  type T int
+	//
+	//  var _ T[int]
+	NotAGenericType
+
+	// WrongTypeArgCount occurs when a type or function is instantiated with an
+	// incorrect number of type arguments, including when a generic type or
+	// function is used without instantiation.
+	//
+	// Errors involving failed type inference are assigned other error codes.
+	//
+	// Example:
+	//  type T[p any] int
+	//
+	//  var _ T[int, string]
+	//
+	// Example:
+	//  func f[T any]() {}
+	//
+	//  var x = f
+	WrongTypeArgCount
+
+	// CannotInferTypeArgs occurs when type or function type argument inference
+	// fails to infer all type arguments.
+	//
+	// Example:
+	//  func f[T any]() {}
+	//
+	//  func _() {
+	//  	f()
+	//  }
+	//
+	// Example:
+	//   type N[P, Q any] struct{}
+	//
+	//   var _ N[int]
+	CannotInferTypeArgs
+
+	// InvalidTypeArg occurs when a type argument does not satisfy its
+	// corresponding type parameter constraints.
+	//
+	// Example:
+	//  type T[P ~int] struct{}
+	//
+	//  var _ T[string]
+	InvalidTypeArg // arguments? InferenceFailed
+
+	// InvalidInstanceCycle occurs when an invalid cycle is detected
+	// within the instantiation graph.
+	//
+	// Example:
+	//  func f[T any]() { f[*T]() }
+	InvalidInstanceCycle
+
+	// InvalidUnion occurs when an embedded union or approximation element is
+	// not valid.
+	//
+	// Example:
+	//  type _ interface {
+	//   	~int | interface{ m() }
+	//  }
+	InvalidUnion
+
+	// MisplacedConstraintIface occurs when a constraint-type interface is used
+	// outside of constraint position.
+	//
+	// Example:
+	//   type I interface { ~int }
+	//
+	//   var _ I
+	MisplacedConstraintIface
+
+	// InvalidMethodTypeParams occurs when methods have type parameters.
+	//
+	// It cannot be encountered with an AST parsed using go/parser.
+	InvalidMethodTypeParams
+
+	// MisplacedTypeParam occurs when a type parameter is used in a place where
+	// it is not permitted.
+	//
+	// Example:
+	//  type T[P any] P
+	//
+	// Example:
+	//  type T[P any] struct{ *P }
+	MisplacedTypeParam
+
+	// InvalidUnsafeSliceData occurs when unsafe.SliceData is called with
+	// an argument that is not of slice type. It also occurs if it is used
+	// in a package compiled for a language version before go1.20.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.SliceData(x)
+	InvalidUnsafeSliceData
+
+	// InvalidUnsafeString occurs when unsafe.String is called with
+	// a length argument that is not of integer type, negative, or
+	// out of bounds. It also occurs if it is used in a package
+	// compiled for a language version before go1.20.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var b [10]byte
+	//  var _ = unsafe.String(&b[0], -1)
+	InvalidUnsafeString
+
+	// InvalidUnsafeStringData occurs if it is used in a package
+	// compiled for a language version before go1.20.
+	_ // not used anymore
+
+)
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/errorcode_string.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/errorcode_string.go
new file mode 100644
index 0000000..15ecf7c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/errorcode_string.go
@@ -0,0 +1,179 @@
+// Code generated by "stringer -type=ErrorCode"; DO NOT EDIT.
+
+package typesinternal
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[InvalidSyntaxTree - -1]
+	_ = x[Test-1]
+	_ = x[BlankPkgName-2]
+	_ = x[MismatchedPkgName-3]
+	_ = x[InvalidPkgUse-4]
+	_ = x[BadImportPath-5]
+	_ = x[BrokenImport-6]
+	_ = x[ImportCRenamed-7]
+	_ = x[UnusedImport-8]
+	_ = x[InvalidInitCycle-9]
+	_ = x[DuplicateDecl-10]
+	_ = x[InvalidDeclCycle-11]
+	_ = x[InvalidTypeCycle-12]
+	_ = x[InvalidConstInit-13]
+	_ = x[InvalidConstVal-14]
+	_ = x[InvalidConstType-15]
+	_ = x[UntypedNilUse-16]
+	_ = x[WrongAssignCount-17]
+	_ = x[UnassignableOperand-18]
+	_ = x[NoNewVar-19]
+	_ = x[MultiValAssignOp-20]
+	_ = x[InvalidIfaceAssign-21]
+	_ = x[InvalidChanAssign-22]
+	_ = x[IncompatibleAssign-23]
+	_ = x[UnaddressableFieldAssign-24]
+	_ = x[NotAType-25]
+	_ = x[InvalidArrayLen-26]
+	_ = x[BlankIfaceMethod-27]
+	_ = x[IncomparableMapKey-28]
+	_ = x[InvalidIfaceEmbed-29]
+	_ = x[InvalidPtrEmbed-30]
+	_ = x[BadRecv-31]
+	_ = x[InvalidRecv-32]
+	_ = x[DuplicateFieldAndMethod-33]
+	_ = x[DuplicateMethod-34]
+	_ = x[InvalidBlank-35]
+	_ = x[InvalidIota-36]
+	_ = x[MissingInitBody-37]
+	_ = x[InvalidInitSig-38]
+	_ = x[InvalidInitDecl-39]
+	_ = x[InvalidMainDecl-40]
+	_ = x[TooManyValues-41]
+	_ = x[NotAnExpr-42]
+	_ = x[TruncatedFloat-43]
+	_ = x[NumericOverflow-44]
+	_ = x[UndefinedOp-45]
+	_ = x[MismatchedTypes-46]
+	_ = x[DivByZero-47]
+	_ = x[NonNumericIncDec-48]
+	_ = x[UnaddressableOperand-49]
+	_ = x[InvalidIndirection-50]
+	_ = x[NonIndexableOperand-51]
+	_ = x[InvalidIndex-52]
+	_ = x[SwappedSliceIndices-53]
+	_ = x[NonSliceableOperand-54]
+	_ = x[InvalidSliceExpr-55]
+	_ = x[InvalidShiftCount-56]
+	_ = x[InvalidShiftOperand-57]
+	_ = x[InvalidReceive-58]
+	_ = x[InvalidSend-59]
+	_ = x[DuplicateLitKey-60]
+	_ = x[MissingLitKey-61]
+	_ = x[InvalidLitIndex-62]
+	_ = x[OversizeArrayLit-63]
+	_ = x[MixedStructLit-64]
+	_ = x[InvalidStructLit-65]
+	_ = x[MissingLitField-66]
+	_ = x[DuplicateLitField-67]
+	_ = x[UnexportedLitField-68]
+	_ = x[InvalidLitField-69]
+	_ = x[UntypedLit-70]
+	_ = x[InvalidLit-71]
+	_ = x[AmbiguousSelector-72]
+	_ = x[UndeclaredImportedName-73]
+	_ = x[UnexportedName-74]
+	_ = x[UndeclaredName-75]
+	_ = x[MissingFieldOrMethod-76]
+	_ = x[BadDotDotDotSyntax-77]
+	_ = x[NonVariadicDotDotDot-78]
+	_ = x[MisplacedDotDotDot-79]
+	_ = x[InvalidDotDotDotOperand-80]
+	_ = x[InvalidDotDotDot-81]
+	_ = x[UncalledBuiltin-82]
+	_ = x[InvalidAppend-83]
+	_ = x[InvalidCap-84]
+	_ = x[InvalidClose-85]
+	_ = x[InvalidCopy-86]
+	_ = x[InvalidComplex-87]
+	_ = x[InvalidDelete-88]
+	_ = x[InvalidImag-89]
+	_ = x[InvalidLen-90]
+	_ = x[SwappedMakeArgs-91]
+	_ = x[InvalidMake-92]
+	_ = x[InvalidReal-93]
+	_ = x[InvalidAssert-94]
+	_ = x[ImpossibleAssert-95]
+	_ = x[InvalidConversion-96]
+	_ = x[InvalidUntypedConversion-97]
+	_ = x[BadOffsetofSyntax-98]
+	_ = x[InvalidOffsetof-99]
+	_ = x[UnusedExpr-100]
+	_ = x[UnusedVar-101]
+	_ = x[MissingReturn-102]
+	_ = x[WrongResultCount-103]
+	_ = x[OutOfScopeResult-104]
+	_ = x[InvalidCond-105]
+	_ = x[InvalidPostDecl-106]
+	_ = x[InvalidChanRange-107]
+	_ = x[InvalidIterVar-108]
+	_ = x[InvalidRangeExpr-109]
+	_ = x[MisplacedBreak-110]
+	_ = x[MisplacedContinue-111]
+	_ = x[MisplacedFallthrough-112]
+	_ = x[DuplicateCase-113]
+	_ = x[DuplicateDefault-114]
+	_ = x[BadTypeKeyword-115]
+	_ = x[InvalidTypeSwitch-116]
+	_ = x[InvalidExprSwitch-117]
+	_ = x[InvalidSelectCase-118]
+	_ = x[UndeclaredLabel-119]
+	_ = x[DuplicateLabel-120]
+	_ = x[MisplacedLabel-121]
+	_ = x[UnusedLabel-122]
+	_ = x[JumpOverDecl-123]
+	_ = x[JumpIntoBlock-124]
+	_ = x[InvalidMethodExpr-125]
+	_ = x[WrongArgCount-126]
+	_ = x[InvalidCall-127]
+	_ = x[UnusedResults-128]
+	_ = x[InvalidDefer-129]
+	_ = x[InvalidGo-130]
+	_ = x[BadDecl-131]
+	_ = x[RepeatedDecl-132]
+	_ = x[InvalidUnsafeAdd-133]
+	_ = x[InvalidUnsafeSlice-134]
+	_ = x[UnsupportedFeature-135]
+	_ = x[NotAGenericType-136]
+	_ = x[WrongTypeArgCount-137]
+	_ = x[CannotInferTypeArgs-138]
+	_ = x[InvalidTypeArg-139]
+	_ = x[InvalidInstanceCycle-140]
+	_ = x[InvalidUnion-141]
+	_ = x[MisplacedConstraintIface-142]
+	_ = x[InvalidMethodTypeParams-143]
+	_ = x[MisplacedTypeParam-144]
+	_ = x[InvalidUnsafeSliceData-145]
+	_ = x[InvalidUnsafeString-146]
+}
+
+const (
+	_ErrorCode_name_0 = "InvalidSyntaxTree"
+	_ErrorCode_name_1 = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilUseWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParamInvalidUnsafeSliceDataInvalidUnsafeString"
+)
+
+var (
+	_ErrorCode_index_1 = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 218, 234, 253, 261, 277, 295, 312, 330, 354, 362, 377, 393, 411, 428, 443, 450, 461, 484, 499, 511, 522, 537, 551, 566, 581, 594, 603, 617, 632, 643, 658, 667, 683, 703, 721, 740, 752, 771, 790, 806, 823, 842, 856, 867, 882, 895, 910, 926, 940, 956, 971, 988, 1006, 1021, 1031, 1041, 1058, 1080, 1094, 1108, 1128, 1146, 1166, 1184, 1207, 1223, 1238, 1251, 1261, 1273, 1284, 1298, 1311, 1322, 1332, 1347, 1358, 1369, 1382, 1398, 1415, 1439, 1456, 1471, 1481, 1490, 1503, 1519, 1535, 1546, 1561, 1577, 1591, 1607, 1621, 1638, 1658, 1671, 1687, 1701, 1718, 1735, 1752, 1767, 1781, 1795, 1806, 1818, 1831, 1848, 1861, 1872, 1885, 1897, 1906, 1913, 1925, 1941, 1959, 1977, 1992, 2009, 2028, 2042, 2062, 2074, 2098, 2121, 2139, 2161, 2180}
+)
+
+func (i ErrorCode) String() string {
+	switch {
+	case i == -1:
+		return _ErrorCode_name_0
+	case 1 <= i && i <= 146:
+		i -= 1
+		return _ErrorCode_name_1[_ErrorCode_index_1[i]:_ErrorCode_index_1[i+1]]
+	default:
+		return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")"
+	}
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/fx.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/fx.go
new file mode 100644
index 0000000..c846a53
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/fx.go
@@ -0,0 +1,88 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+)
+
+// NoEffects reports whether the expression has no side effects, i.e., it
+// does not modify the memory state. This function is conservative: it may
+// return false even when the expression has no effect.
+func NoEffects(info *types.Info, expr ast.Expr) bool {
+	noEffects := true
+	ast.Inspect(expr, func(n ast.Node) bool {
+		switch v := n.(type) {
+		case nil, *ast.Ident, *ast.BasicLit, *ast.BinaryExpr, *ast.ParenExpr,
+			*ast.SelectorExpr, *ast.IndexExpr, *ast.SliceExpr, *ast.TypeAssertExpr,
+			*ast.StarExpr, *ast.CompositeLit,
+			// non-expressions that may appear within expressions
+			*ast.KeyValueExpr,
+			*ast.FieldList,
+			*ast.Field,
+			*ast.Ellipsis,
+			*ast.IndexListExpr:
+			// No effect.
+
+		case *ast.ArrayType,
+			*ast.StructType,
+			*ast.ChanType,
+			*ast.FuncType,
+			*ast.MapType,
+			*ast.InterfaceType:
+			// Type syntax: no effects, recursively.
+			// Prune descent.
+			return false
+
+		case *ast.UnaryExpr:
+			// Channel send <-ch has effects.
+			if v.Op == token.ARROW {
+				noEffects = false
+			}
+
+		case *ast.CallExpr:
+			// Type conversion has no effects.
+			if !info.Types[v.Fun].IsType() {
+				if CallsPureBuiltin(info, v) {
+					// A call such as len(e) has no effects of its
+					// own, though the subexpression e might.
+				} else {
+					noEffects = false
+				}
+			}
+
+		case *ast.FuncLit:
+			// A FuncLit has no effects, but do not descend into it.
+			return false
+
+		default:
+			// All other expressions have effects
+			noEffects = false
+		}
+
+		return noEffects
+	})
+	return noEffects
+}
+
+// CallsPureBuiltin reports whether call is a call of a built-in
+// function that is a pure computation over its operands (analogous to
+// a + operator). Because it does not depend on program state, it may
+// be evaluated at any point--though not necessarily at multiple
+// points (consider new, make).
+func CallsPureBuiltin(info *types.Info, call *ast.CallExpr) bool {
+	if id, ok := ast.Unparen(call.Fun).(*ast.Ident); ok {
+		if b, ok := info.ObjectOf(id).(*types.Builtin); ok {
+			switch b.Name() {
+			case "len", "cap", "complex", "imag", "real", "make", "new", "max", "min":
+				return true
+			}
+			// Not: append clear close copy delete panic print println recover
+		}
+	}
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/isnamed.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/isnamed.go
new file mode 100644
index 0000000..e0d63c4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/isnamed.go
@@ -0,0 +1,71 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/types"
+	"slices"
+)
+
+// IsTypeNamed reports whether t is (or is an alias for) a
+// package-level defined type with the given package path and one of
+// the given names. It returns false if t is nil.
+//
+// This function avoids allocating the concatenation of "pkg.Name",
+// which is important for the performance of syntax matching.
+func IsTypeNamed(t types.Type, pkgPath string, names ...string) bool {
+	if named, ok := types.Unalias(t).(*types.Named); ok {
+		tname := named.Obj()
+		return tname != nil &&
+			IsPackageLevel(tname) &&
+			tname.Pkg().Path() == pkgPath &&
+			slices.Contains(names, tname.Name())
+	}
+	return false
+}
+
+// IsPointerToNamed reports whether t is (or is an alias for) a pointer to a
+// package-level defined type with the given package path and one of the given
+// names. It returns false if t is not a pointer type.
+func IsPointerToNamed(t types.Type, pkgPath string, names ...string) bool {
+	r := Unpointer(t)
+	if r == t {
+		return false
+	}
+	return IsTypeNamed(r, pkgPath, names...)
+}
+
+// IsFunctionNamed reports whether obj is a package-level function
+// defined in the given package and has one of the given names.
+// It returns false if obj is nil.
+//
+// This function avoids allocating the concatenation of "pkg.Name",
+// which is important for the performance of syntax matching.
+func IsFunctionNamed(obj types.Object, pkgPath string, names ...string) bool {
+	f, ok := obj.(*types.Func)
+	return ok &&
+		IsPackageLevel(obj) &&
+		f.Pkg().Path() == pkgPath &&
+		f.Signature().Recv() == nil &&
+		slices.Contains(names, f.Name())
+}
+
+// IsMethodNamed reports whether obj is a method defined on a
+// package-level type with the given package and type name, and has
+// one of the given names. It returns false if obj is nil.
+//
+// This function avoids allocating the concatenation of "pkg.TypeName.Name",
+// which is important for the performance of syntax matching.
+func IsMethodNamed(obj types.Object, pkgPath string, typeName string, names ...string) bool {
+	if fn, ok := obj.(*types.Func); ok {
+		if recv := fn.Signature().Recv(); recv != nil {
+			_, T := ReceiverNamed(recv)
+			return T != nil &&
+				IsTypeNamed(T, pkgPath, typeName) &&
+				slices.Contains(names, fn.Name())
+		}
+	}
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/qualifier.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/qualifier.go
new file mode 100644
index 0000000..4e2756f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/qualifier.go
@@ -0,0 +1,54 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/ast"
+	"go/types"
+	"strconv"
+)
+
+// FileQualifier returns a [types.Qualifier] function that qualifies
+// imported symbols appropriately based on the import environment of a given
+// file.
+// If the same package is imported multiple times, the last appearance is
+// recorded.
+//
+// TODO(adonovan): this function ignores the effect of shadowing. It
+// should accept a [token.Pos] and a [types.Info] and compute only the
+// set of imports that are not shadowed at that point, analogous to
+// [analysis.AddImport]. It could also compute (as a side
+// effect) the set of additional imports required to ensure that there
+// is an accessible import for each necessary package, making it
+// converge even more closely with AddImport.
+func FileQualifier(f *ast.File, pkg *types.Package) types.Qualifier {
+	// Construct mapping of import paths to their defined names.
+	// It is only necessary to look at renaming imports.
+	imports := make(map[string]string)
+	for _, imp := range f.Imports {
+		if imp.Name != nil && imp.Name.Name != "_" {
+			path, _ := strconv.Unquote(imp.Path.Value)
+			imports[path] = imp.Name.Name
+		}
+	}
+
+	// Define qualifier to replace full package paths with names of the imports.
+	return func(p *types.Package) string {
+		if p == nil || p == pkg {
+			return ""
+		}
+
+		if name, ok := imports[p.Path()]; ok {
+			if name == "." {
+				return ""
+			} else {
+				return name
+			}
+		}
+
+		// If there is no local renaming, fall back to the package name.
+		return p.Name()
+	}
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/recv.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/recv.go
new file mode 100644
index 0000000..8352ea7
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/recv.go
@@ -0,0 +1,44 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/types"
+)
+
+// ReceiverNamed returns the named type (if any) associated with the
+// type of recv, which may be of the form N or *N, or aliases thereof.
+// It also reports whether a Pointer was present.
+//
+// The named result may be nil if recv is from a method on an
+// anonymous interface or struct types or in ill-typed code.
+func ReceiverNamed(recv *types.Var) (isPtr bool, named *types.Named) {
+	t := recv.Type()
+	if ptr, ok := types.Unalias(t).(*types.Pointer); ok {
+		isPtr = true
+		t = ptr.Elem()
+	}
+	named, _ = types.Unalias(t).(*types.Named)
+	return
+}
+
+// Unpointer returns T given *T or an alias thereof.
+// For all other types it is the identity function.
+// It does not look at underlying types.
+// The result may be an alias.
+//
+// Use this function to strip off the optional pointer on a receiver
+// in a field or method selection, without losing the named type
+// (which is needed to compute the method set).
+//
+// See also [typeparams.MustDeref], which removes one level of
+// indirection from the type, regardless of named types (analogous to
+// a LOAD instruction).
+func Unpointer(t types.Type) types.Type {
+	if ptr, ok := types.Unalias(t).(*types.Pointer); ok {
+		return ptr.Elem()
+	}
+	return t
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/typeindex/typeindex.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/typeindex/typeindex.go
new file mode 100644
index 0000000..9a8ac36
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/typeindex/typeindex.go
@@ -0,0 +1,256 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package typeindex provides an [Index] of type information for a
+// package, allowing efficient lookup of, say, whether a given symbol
+// is referenced and, if so, where from; or of the [inspector.Cursor] for
+// the declaration of a particular [types.Object] symbol.
+package typeindex
+
+import (
+	"encoding/binary"
+	"go/ast"
+	"go/types"
+	"iter"
+
+	"golang.org/x/tools/go/ast/edge"
+	"golang.org/x/tools/go/ast/inspector"
+	"golang.org/x/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/xtools-internal/astutil"
+	"honnef.co/go/tools/internal/xtools-internal/typesinternal"
+)
+
+// New constructs an Index for the package of type-annotated syntax
+//
+// TODO(adonovan): accept a FileSet too?
+// We regret not requiring one in inspector.New.
+func New(inspect *inspector.Inspector, pkg *types.Package, info *types.Info) *Index {
+	ix := &Index{
+		inspect:  inspect,
+		info:     info,
+		packages: make(map[string]*types.Package),
+		def:      make(map[types.Object]inspector.Cursor),
+		uses:     make(map[types.Object]*uses),
+	}
+
+	addPackage := func(pkg2 *types.Package) {
+		if pkg2 != nil && pkg2 != pkg {
+			ix.packages[pkg2.Path()] = pkg2
+		}
+	}
+
+	for cur := range inspect.Root().Preorder((*ast.ImportSpec)(nil), (*ast.Ident)(nil)) {
+		switch n := cur.Node().(type) {
+		case *ast.ImportSpec:
+			// Index direct imports, including blank ones.
+			if pkgname := info.PkgNameOf(n); pkgname != nil {
+				addPackage(pkgname.Imported())
+			}
+
+		case *ast.Ident:
+			// Index all defining and using identifiers.
+			if obj := info.Defs[n]; obj != nil {
+				ix.def[obj] = cur
+			}
+
+			if obj := info.Uses[n]; obj != nil {
+				// Index indirect dependencies (via fields and methods).
+				if !typesinternal.IsPackageLevel(obj) {
+					addPackage(obj.Pkg())
+				}
+
+				for {
+					us, ok := ix.uses[obj]
+					if !ok {
+						us = &uses{}
+						us.code = us.initial[:0]
+						ix.uses[obj] = us
+					}
+					delta := cur.Index() - us.last
+					if delta < 0 {
+						panic("non-monotonic")
+					}
+					us.code = binary.AppendUvarint(us.code, uint64(delta))
+					us.last = cur.Index()
+
+					// If n is a selection of a field or method of an instantiated
+					// type, also record a use of the generic field or method.
+					obj, ok = objectOrigin(obj)
+					if !ok {
+						break
+					}
+				}
+			}
+		}
+	}
+	return ix
+}
+
+// objectOrigin returns the generic object for obj if it is a field or
+// method of an instantied type; zero otherwise.
+//
+// (This operation is appropriate only for selections.
+// Lexically resolved references always resolve to the generic.
+// Although Named and Alias types also use Origin to express
+// an instance/generic distinction, that's in the domain
+// of Types; their TypeName objects always refer to the generic.)
+func objectOrigin(obj types.Object) (types.Object, bool) {
+	var origin types.Object
+	switch obj := obj.(type) {
+	case *types.Func:
+		if obj.Signature().Recv() != nil {
+			origin = obj.Origin() // G[int].method -> G[T].method
+		}
+	case *types.Var:
+		if obj.IsField() {
+			origin = obj.Origin() // G[int].field  -> G[T].field
+		}
+	}
+	if origin != nil && origin != obj {
+		return origin, true
+	}
+	return nil, false
+}
+
+// An Index holds an index mapping [types.Object] symbols to their syntax.
+// In effect, it is the inverse of [types.Info].
+type Index struct {
+	inspect  *inspector.Inspector
+	info     *types.Info
+	packages map[string]*types.Package         // packages of all symbols referenced from this package
+	def      map[types.Object]inspector.Cursor // Cursor of *ast.Ident that defines the Object
+	uses     map[types.Object]*uses            // Cursors of *ast.Idents that use the Object
+}
+
+// A uses holds the list of Cursors of Idents that use a given symbol.
+//
+// The Uses map of [types.Info] is substantial, so it pays to compress
+// its inverse mapping here, both in space and in CPU due to reduced
+// allocation. A Cursor is 2 words; a Cursor.Index is 4 bytes; but
+// since Cursors are naturally delivered in ascending order, we can
+// use varint-encoded deltas at a cost of only ~1.7-2.2 bytes per use.
+//
+// Many variables have only one or two uses, so their encoded uses may
+// fit in the 4 bytes of initial, saving further CPU and space
+// essentially for free since the struct's size class is 4 words.
+type uses struct {
+	code    []byte  // varint-encoded deltas of successive Cursor.Index values
+	last    int32   // most recent Cursor.Index value; used during encoding
+	initial [4]byte // use slack in size class as initial space for code
+}
+
+// Uses returns the sequence of Cursors of [*ast.Ident]s in this package
+// that refer to obj. If obj is nil, the sequence is empty.
+//
+// Uses, unlike the Uses field of [types.Info], records additional
+// entries mapping fields and methods of generic types to references
+// through their corresponding instantiated objects.
+func (ix *Index) Uses(obj types.Object) iter.Seq[inspector.Cursor] {
+	return func(yield func(inspector.Cursor) bool) {
+		if uses := ix.uses[obj]; uses != nil {
+			var last int32
+			for code := uses.code; len(code) > 0; {
+				delta, n := binary.Uvarint(code)
+				last += int32(delta)
+				if !yield(ix.inspect.At(last)) {
+					return
+				}
+				code = code[n:]
+			}
+		}
+	}
+}
+
+// Used reports whether any of the specified objects are used, in
+// other words, obj != nil && Uses(obj) is non-empty for some obj in objs.
+//
+// (This treatment of nil allows Used to be called directly on the
+// result of [Index.Object] so that analyzers can conveniently skip
+// packages that don't use a symbol of interest.)
+func (ix *Index) Used(objs ...types.Object) bool {
+	for _, obj := range objs {
+		if obj != nil && ix.uses[obj] != nil {
+			return true
+		}
+	}
+	return false
+}
+
+// Def returns the Cursor of the [*ast.Ident] in this package
+// that declares the specified object, if any.
+func (ix *Index) Def(obj types.Object) (inspector.Cursor, bool) {
+	cur, ok := ix.def[obj]
+	return cur, ok
+}
+
+// Package returns the package of the specified path,
+// or nil if it is not referenced from this package.
+func (ix *Index) Package(path string) *types.Package {
+	return ix.packages[path]
+}
+
+// Object returns the package-level symbol name within the package of
+// the specified path, or nil if the package or symbol does not exist
+// or is not visible from this package.
+func (ix *Index) Object(path, name string) types.Object {
+	if pkg := ix.Package(path); pkg != nil {
+		return pkg.Scope().Lookup(name)
+	}
+	return nil
+}
+
+// Selection returns the named method or field belonging to the
+// package-level type returned by Object(path, typename).
+func (ix *Index) Selection(path, typename, name string) types.Object {
+	if obj := ix.Object(path, typename); obj != nil {
+		if tname, ok := obj.(*types.TypeName); ok {
+			obj, _, _ := types.LookupFieldOrMethod(tname.Type(), true, obj.Pkg(), name)
+			return obj
+		}
+	}
+	return nil
+}
+
+// Calls returns the sequence of cursors for *ast.CallExpr nodes that
+// call the specified callee, as defined by [typeutil.Callee].
+// If callee is nil, the sequence is empty.
+func (ix *Index) Calls(callee types.Object) iter.Seq[inspector.Cursor] {
+	return func(yield func(inspector.Cursor) bool) {
+		for cur := range ix.Uses(callee) {
+			// The call may be of the form f() or x.f(),
+			// optionally with parens; ascend from f to call.
+			// See logic in [typesinternal.UsedIdent], to which this is dual.
+			//
+			// It is tempting but wrong to use the first
+			// CallExpr ancestor: we have to make sure the
+			// ident is in the CallExpr.Fun position, otherwise
+			// f(f, f) would have two spurious matches.
+			// Avoiding Enclosing is also significantly faster.
+
+			// inverse unparen: f -> (f)
+			cur = astutil.UnparenEnclosingCursor(cur)
+
+			// ascend selector (or qualified identifier): f -> x.f
+			if cur.ParentEdgeKind() == edge.SelectorExpr_Sel {
+				cur = astutil.UnparenEnclosingCursor(cur.Parent())
+			}
+
+			// ascend typeparams: f -> f[T]; f -> f[T1, T2]
+			if ek := cur.ParentEdgeKind(); ek == edge.IndexExpr_X || ek == edge.IndexListExpr_X {
+				cur = astutil.UnparenEnclosingCursor(cur.Parent())
+			}
+
+			// ascend from f or x.f to call
+			if cur.ParentEdgeKind() == edge.CallExpr_Fun {
+				curCall := cur.Parent()
+				call := curCall.Node().(*ast.CallExpr)
+				if typeutil.Callee(ix.info, call) == callee {
+					if !yield(curCall) {
+						return
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/types.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/types.go
new file mode 100644
index 0000000..50942b7
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/types.go
@@ -0,0 +1,272 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package typesinternal provides helpful operators for dealing with
+// go/types:
+//
+//   - operators for querying typed syntax trees (e.g. [Imports], [IsFunctionNamed]);
+//   - functions for converting types to strings or syntax (e.g. [TypeExpr], FileQualifier]);
+//   - helpers for working with the [go/types] API (e.g. [NewTypesInfo]);
+//   - access to internal go/types APIs that are not yet
+//     exported (e.g. [SetUsesCgo], [ErrorCodeStartEnd], [VarKind]); and
+//   - common algorithms related to types (e.g. [TooNewStdSymbols]).
+//
+// See also:
+//   - [honnef.co/go/tools/internal/xtools-internal/astutil], for operations on untyped syntax;
+//   - [honnef.co/go/tools/internal/xtools-internal/analysisinernal], for helpers for analyzers;
+//   - [honnef.co/go/tools/internal/xtools-internal/refactor], for operators to compute text edits.
+package typesinternal
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+	"iter"
+	"reflect"
+
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+func SetUsesCgo(conf *types.Config) bool {
+	v := reflect.ValueOf(conf).Elem()
+
+	f := v.FieldByName("go115UsesCgo")
+	if !f.IsValid() {
+		f = v.FieldByName("UsesCgo")
+		if !f.IsValid() {
+			return false
+		}
+	}
+
+	*(*bool)(f.Addr().UnsafePointer()) = true
+
+	return true
+}
+
+// ErrorCodeStartEnd extracts additional information from types.Error values
+// generated by Go version 1.16 and later: the error code, start position, and
+// end position. If all positions are valid, start <= err.Pos <= end.
+//
+// If the data could not be read, the final result parameter will be false.
+//
+// TODO(adonovan): eliminate start/end when proposal #71803 is accepted.
+func ErrorCodeStartEnd(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) {
+	var data [3]int
+	// By coincidence all of these fields are ints, which simplifies things.
+	v := reflect.ValueOf(err)
+	for i, name := range []string{"go116code", "go116start", "go116end"} {
+		f := v.FieldByName(name)
+		if !f.IsValid() {
+			return 0, 0, 0, false
+		}
+		data[i] = int(f.Int())
+	}
+	return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true
+}
+
+// NameRelativeTo returns a types.Qualifier that qualifies members of
+// all packages other than pkg, using only the package name.
+// (By contrast, [types.RelativeTo] uses the complete package path,
+// which is often excessive.)
+//
+// If pkg is nil, it is equivalent to [*types.Package.Name].
+//
+// TODO(adonovan): all uses of this with TypeString should be
+// eliminated when https://go.dev/issues/75604 is resolved.
+func NameRelativeTo(pkg *types.Package) types.Qualifier {
+	return func(other *types.Package) string {
+		if pkg != nil && pkg == other {
+			return "" // same package; unqualified
+		}
+		return other.Name()
+	}
+}
+
+// TypeNameFor returns the type name symbol for the specified type, if
+// it is a [*types.Alias], [*types.Named], [*types.TypeParam], or a
+// [*types.Basic] representing a type.
+//
+// For all other types, and for Basic types representing a builtin,
+// constant, or nil, it returns nil. Be careful not to convert the
+// resulting nil pointer to a [types.Object]!
+//
+// If t is the type of a constant, it may be an "untyped" type, which
+// has no TypeName. To access the name of such types (e.g. "untyped
+// int"), use [types.Basic.Name].
+func TypeNameFor(t types.Type) *types.TypeName {
+	switch t := t.(type) {
+	case *types.Alias:
+		return t.Obj()
+	case *types.Named:
+		return t.Obj()
+	case *types.TypeParam:
+		return t.Obj()
+	case *types.Basic:
+		// See issues #71886 and #66890 for some history.
+		if tname, ok := types.Universe.Lookup(t.Name()).(*types.TypeName); ok {
+			return tname
+		}
+	}
+	return nil
+}
+
+// A NamedOrAlias is a [types.Type] that is named (as
+// defined by the spec) and capable of bearing type parameters: it
+// abstracts aliases ([types.Alias]) and defined types
+// ([types.Named]).
+//
+// Every type declared by an explicit "type" declaration is a
+// NamedOrAlias. (Built-in type symbols may additionally
+// have type [types.Basic], which is not a NamedOrAlias,
+// though the spec regards them as "named"; see [TypeNameFor].)
+//
+// NamedOrAlias cannot expose the Origin method, because
+// [types.Alias.Origin] and [types.Named.Origin] have different
+// (covariant) result types; use [Origin] instead.
+type NamedOrAlias interface {
+	types.Type
+	Obj() *types.TypeName
+	TypeArgs() *types.TypeList
+	TypeParams() *types.TypeParamList
+	SetTypeParams(tparams []*types.TypeParam)
+}
+
+var (
+	_ NamedOrAlias = (*types.Alias)(nil)
+	_ NamedOrAlias = (*types.Named)(nil)
+)
+
+// Origin returns the generic type of the Named or Alias type t if it
+// is instantiated, otherwise it returns t.
+func Origin(t NamedOrAlias) NamedOrAlias {
+	switch t := t.(type) {
+	case *types.Alias:
+		return t.Origin()
+	case *types.Named:
+		return t.Origin()
+	}
+	return t
+}
+
+// IsPackageLevel reports whether obj is a package-level symbol.
+func IsPackageLevel(obj types.Object) bool {
+	return obj.Pkg() != nil && obj.Parent() == obj.Pkg().Scope()
+}
+
+// NewTypesInfo returns a *types.Info with all maps populated.
+func NewTypesInfo() *types.Info {
+	return &types.Info{
+		Types:        map[ast.Expr]types.TypeAndValue{},
+		Instances:    map[*ast.Ident]types.Instance{},
+		Defs:         map[*ast.Ident]types.Object{},
+		Uses:         map[*ast.Ident]types.Object{},
+		Implicits:    map[ast.Node]types.Object{},
+		Selections:   map[*ast.SelectorExpr]*types.Selection{},
+		Scopes:       map[ast.Node]*types.Scope{},
+		FileVersions: map[*ast.File]string{},
+	}
+}
+
+// EnclosingScope returns the innermost block logically enclosing the cursor.
+func EnclosingScope(info *types.Info, cur inspector.Cursor) *types.Scope {
+	for cur := range cur.Enclosing() {
+		n := cur.Node()
+		// A function's Scope is associated with its FuncType.
+		switch f := n.(type) {
+		case *ast.FuncDecl:
+			n = f.Type
+		case *ast.FuncLit:
+			n = f.Type
+		}
+		if b := info.Scopes[n]; b != nil {
+			return b
+		}
+	}
+	panic("no Scope for *ast.File")
+}
+
+// Imports reports whether path is imported by pkg.
+func Imports(pkg *types.Package, path string) bool {
+	for _, imp := range pkg.Imports() {
+		if imp.Path() == path {
+			return true
+		}
+	}
+	return false
+}
+
+// ObjectKind returns a description of the object's kind.
+//
+// from objectKind in go/types
+func ObjectKind(obj types.Object) string {
+	switch obj := obj.(type) {
+	case *types.PkgName:
+		return "package name"
+	case *types.Const:
+		return "constant"
+	case *types.TypeName:
+		if obj.IsAlias() {
+			return "type alias"
+		} else if _, ok := obj.Type().(*types.TypeParam); ok {
+			return "type parameter"
+		} else {
+			return "defined type"
+		}
+	case *types.Var:
+		switch obj.Kind() {
+		case PackageVar:
+			return "package-level variable"
+		case LocalVar:
+			return "local variable"
+		case RecvVar:
+			return "receiver"
+		case ParamVar:
+			return "parameter"
+		case ResultVar:
+			return "result variable"
+		case FieldVar:
+			return "struct field"
+		}
+	case *types.Func:
+		if obj.Signature().Recv() != nil {
+			return "method"
+		} else {
+			return "function"
+		}
+	case *types.Label:
+		return "label"
+	case *types.Builtin:
+		return "built-in function"
+	case *types.Nil:
+		return "untyped nil"
+	}
+	return "unknown symbol"
+}
+
+// ImplicitFieldSelections returns the sequence of implicit embedded fields
+// traversed by the given selection. It skips the final leaf field or method.
+// The boolean component indicates whether the traversal traversed a pointer.
+func ImplicitFieldSelections(seln types.Selection) iter.Seq2[*types.Var, bool] {
+	return func(yield func(*types.Var, bool) bool) {
+		var (
+			t       = seln.Recv()
+			indices = seln.Index()
+		)
+		for _, idx := range indices[:len(indices)-1] {
+			ptr, isPtr := t.Underlying().(*types.Pointer)
+			if isPtr {
+				t = ptr.Elem()
+			}
+			structType, ok := t.Underlying().(*types.Struct)
+			if !ok {
+				break
+			}
+			field := structType.Field(idx)
+			if !yield(field, isPtr) {
+				break
+			}
+			t = field.Type()
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/varkind.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/varkind.go
new file mode 100644
index 0000000..26499cd
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/varkind.go
@@ -0,0 +1,23 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.25
+
+package typesinternal
+
+import "go/types"
+
+type VarKind = types.VarKind
+
+const (
+	PackageVar = types.PackageVar
+	LocalVar   = types.LocalVar
+	RecvVar    = types.RecvVar
+	ParamVar   = types.ParamVar
+	ResultVar  = types.ResultVar
+	FieldVar   = types.FieldVar
+)
+
+func GetVarKind(v *types.Var) VarKind       { return v.Kind() }
+func SetVarKind(v *types.Var, kind VarKind) { v.SetKind(kind) }
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/varkind_go124.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/varkind_go124.go
new file mode 100644
index 0000000..17b1804
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/varkind_go124.go
@@ -0,0 +1,39 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.25
+
+package typesinternal
+
+import "go/types"
+
+type VarKind uint8
+
+const (
+	_          VarKind = iota // (not meaningful)
+	PackageVar                // a package-level variable
+	LocalVar                  // a local variable
+	RecvVar                   // a method receiver variable
+	ParamVar                  // a function parameter variable
+	ResultVar                 // a function result variable
+	FieldVar                  // a struct field
+)
+
+func (kind VarKind) String() string {
+	return [...]string{
+		0:          "VarKind(0)",
+		PackageVar: "PackageVar",
+		LocalVar:   "LocalVar",
+		RecvVar:    "RecvVar",
+		ParamVar:   "ParamVar",
+		ResultVar:  "ResultVar",
+		FieldVar:   "FieldVar",
+	}[kind]
+}
+
+// GetVarKind returns an invalid VarKind.
+func GetVarKind(v *types.Var) VarKind { return 0 }
+
+// SetVarKind has no effect.
+func SetVarKind(v *types.Var, kind VarKind) {}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/zerovalue.go b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/zerovalue.go
new file mode 100644
index 0000000..d612a71
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/typesinternal/zerovalue.go
@@ -0,0 +1,381 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"strings"
+)
+
+// ZeroString returns the string representation of the zero value for any type t.
+// The boolean result indicates whether the type is or contains an invalid type
+// or a non-basic (constraint) interface type.
+//
+// Even for invalid input types, ZeroString may return a partially correct
+// string representation. The caller should use the returned isValid boolean
+// to determine the validity of the expression.
+//
+// When assigning to a wider type (such as 'any'), it's the caller's
+// responsibility to handle any necessary type conversions.
+//
+// This string can be used on the right-hand side of an assignment where the
+// left-hand side has that explicit type.
+// References to named types are qualified by an appropriate (optional)
+// qualifier function.
+// Exception: This does not apply to tuples. Their string representation is
+// informational only and cannot be used in an assignment.
+//
+// See [ZeroExpr] for a variant that returns an [ast.Expr].
+func ZeroString(t types.Type, qual types.Qualifier) (_ string, isValid bool) {
+	switch t := t.(type) {
+	case *types.Basic:
+		switch {
+		case t.Info()&types.IsBoolean != 0:
+			return "false", true
+		case t.Info()&types.IsNumeric != 0:
+			return "0", true
+		case t.Info()&types.IsString != 0:
+			return `""`, true
+		case t.Kind() == types.UnsafePointer:
+			fallthrough
+		case t.Kind() == types.UntypedNil:
+			return "nil", true
+		case t.Kind() == types.Invalid:
+			return "invalid", false
+		default:
+			panic(fmt.Sprintf("ZeroString for unexpected type %v", t))
+		}
+
+	case *types.Pointer, *types.Slice, *types.Chan, *types.Map, *types.Signature:
+		return "nil", true
+
+	case *types.Interface:
+		if !t.IsMethodSet() {
+			return "invalid", false
+		}
+		return "nil", true
+
+	case *types.Named:
+		switch under := t.Underlying().(type) {
+		case *types.Struct, *types.Array:
+			return types.TypeString(t, qual) + "{}", true
+		default:
+			return ZeroString(under, qual)
+		}
+
+	case *types.Alias:
+		switch t.Underlying().(type) {
+		case *types.Struct, *types.Array:
+			return types.TypeString(t, qual) + "{}", true
+		default:
+			// A type parameter can have alias but alias type's underlying type
+			// can never be a type parameter.
+			// Use types.Unalias to preserve the info of type parameter instead
+			// of call Underlying() going right through and get the underlying
+			// type of the type parameter which is always an interface.
+			return ZeroString(types.Unalias(t), qual)
+		}
+
+	case *types.Array, *types.Struct:
+		return types.TypeString(t, qual) + "{}", true
+
+	case *types.TypeParam:
+		// Assumes func new is not shadowed.
+		return "*new(" + types.TypeString(t, qual) + ")", true
+
+	case *types.Tuple:
+		// Tuples are not normal values.
+		// We are currently format as "(t[0], ..., t[n])". Could be something else.
+		isValid := true
+		components := make([]string, t.Len())
+		for i := 0; i < t.Len(); i++ {
+			comp, ok := ZeroString(t.At(i).Type(), qual)
+
+			components[i] = comp
+			isValid = isValid && ok
+		}
+		return "(" + strings.Join(components, ", ") + ")", isValid
+
+	case *types.Union:
+		// Variables of these types cannot be created, so it makes
+		// no sense to ask for their zero value.
+		panic(fmt.Sprintf("invalid type for a variable: %v", t))
+
+	default:
+		panic(t) // unreachable.
+	}
+}
+
+// ZeroExpr returns the ast.Expr representation of the zero value for any type t.
+// The boolean result indicates whether the type is or contains an invalid type
+// or a non-basic (constraint) interface type.
+//
+// Even for invalid input types, ZeroExpr may return a partially correct ast.Expr
+// representation. The caller should use the returned isValid boolean to determine
+// the validity of the expression.
+//
+// This function is designed for types suitable for variables and should not be
+// used with Tuple or Union types.References to named types are qualified by an
+// appropriate (optional) qualifier function.
+//
+// See [ZeroString] for a variant that returns a string.
+func ZeroExpr(t types.Type, qual types.Qualifier) (_ ast.Expr, isValid bool) {
+	switch t := t.(type) {
+	case *types.Basic:
+		switch {
+		case t.Info()&types.IsBoolean != 0:
+			return &ast.Ident{Name: "false"}, true
+		case t.Info()&types.IsNumeric != 0:
+			return &ast.BasicLit{Kind: token.INT, Value: "0"}, true
+		case t.Info()&types.IsString != 0:
+			return &ast.BasicLit{Kind: token.STRING, Value: `""`}, true
+		case t.Kind() == types.UnsafePointer:
+			fallthrough
+		case t.Kind() == types.UntypedNil:
+			return ast.NewIdent("nil"), true
+		case t.Kind() == types.Invalid:
+			return &ast.BasicLit{Kind: token.STRING, Value: `"invalid"`}, false
+		default:
+			panic(fmt.Sprintf("ZeroExpr for unexpected type %v", t))
+		}
+
+	case *types.Pointer, *types.Slice, *types.Chan, *types.Map, *types.Signature:
+		return ast.NewIdent("nil"), true
+
+	case *types.Interface:
+		if !t.IsMethodSet() {
+			return &ast.BasicLit{Kind: token.STRING, Value: `"invalid"`}, false
+		}
+		return ast.NewIdent("nil"), true
+
+	case *types.Named:
+		switch under := t.Underlying().(type) {
+		case *types.Struct, *types.Array:
+			return &ast.CompositeLit{
+				Type: TypeExpr(t, qual),
+			}, true
+		default:
+			return ZeroExpr(under, qual)
+		}
+
+	case *types.Alias:
+		switch t.Underlying().(type) {
+		case *types.Struct, *types.Array:
+			return &ast.CompositeLit{
+				Type: TypeExpr(t, qual),
+			}, true
+		default:
+			return ZeroExpr(types.Unalias(t), qual)
+		}
+
+	case *types.Array, *types.Struct:
+		return &ast.CompositeLit{
+			Type: TypeExpr(t, qual),
+		}, true
+
+	case *types.TypeParam:
+		return &ast.StarExpr{ // *new(T)
+			X: &ast.CallExpr{
+				// Assumes func new is not shadowed.
+				Fun: ast.NewIdent("new"),
+				Args: []ast.Expr{
+					ast.NewIdent(t.Obj().Name()),
+				},
+			},
+		}, true
+
+	case *types.Tuple:
+		// Unlike ZeroString, there is no ast.Expr can express tuple by
+		// "(t[0], ..., t[n])".
+		panic(fmt.Sprintf("invalid type for a variable: %v", t))
+
+	case *types.Union:
+		// Variables of these types cannot be created, so it makes
+		// no sense to ask for their zero value.
+		panic(fmt.Sprintf("invalid type for a variable: %v", t))
+
+	default:
+		panic(t) // unreachable.
+	}
+}
+
+// TypeExpr returns syntax for the specified type. References to named types
+// are qualified by an appropriate (optional) qualifier function.
+// It may panic for types such as Tuple or Union.
+//
+// See also https://go.dev/issues/75604, which will provide a robust
+// Type-to-valid-Go-syntax formatter.
+func TypeExpr(t types.Type, qual types.Qualifier) ast.Expr {
+	switch t := t.(type) {
+	case *types.Basic:
+		switch t.Kind() {
+		case types.UnsafePointer:
+			return &ast.SelectorExpr{X: ast.NewIdent(qual(types.NewPackage("unsafe", "unsafe"))), Sel: ast.NewIdent("Pointer")}
+		default:
+			return ast.NewIdent(t.Name())
+		}
+
+	case *types.Pointer:
+		return &ast.UnaryExpr{
+			Op: token.MUL,
+			X:  TypeExpr(t.Elem(), qual),
+		}
+
+	case *types.Array:
+		return &ast.ArrayType{
+			Len: &ast.BasicLit{
+				Kind:  token.INT,
+				Value: fmt.Sprintf("%d", t.Len()),
+			},
+			Elt: TypeExpr(t.Elem(), qual),
+		}
+
+	case *types.Slice:
+		return &ast.ArrayType{
+			Elt: TypeExpr(t.Elem(), qual),
+		}
+
+	case *types.Map:
+		return &ast.MapType{
+			Key:   TypeExpr(t.Key(), qual),
+			Value: TypeExpr(t.Elem(), qual),
+		}
+
+	case *types.Chan:
+		dir := ast.ChanDir(t.Dir())
+		if t.Dir() == types.SendRecv {
+			dir = ast.SEND | ast.RECV
+		}
+		return &ast.ChanType{
+			Dir:   dir,
+			Value: TypeExpr(t.Elem(), qual),
+		}
+
+	case *types.Signature:
+		var params []*ast.Field
+		for v := range t.Params().Variables() {
+			params = append(params, &ast.Field{
+				Type: TypeExpr(v.Type(), qual),
+				Names: []*ast.Ident{
+					{
+						Name: v.Name(),
+					},
+				},
+			})
+		}
+		if t.Variadic() {
+			last := params[len(params)-1]
+			last.Type = &ast.Ellipsis{Elt: last.Type.(*ast.ArrayType).Elt}
+		}
+		var returns []*ast.Field
+		for v := range t.Results().Variables() {
+			returns = append(returns, &ast.Field{
+				Type: TypeExpr(v.Type(), qual),
+			})
+		}
+		return &ast.FuncType{
+			Params: &ast.FieldList{
+				List: params,
+			},
+			Results: &ast.FieldList{
+				List: returns,
+			},
+		}
+
+	case *types.TypeParam:
+		pkgName := qual(t.Obj().Pkg())
+		if pkgName == "" || t.Obj().Pkg() == nil {
+			return ast.NewIdent(t.Obj().Name())
+		}
+		return &ast.SelectorExpr{
+			X:   ast.NewIdent(pkgName),
+			Sel: ast.NewIdent(t.Obj().Name()),
+		}
+
+	// types.TypeParam also implements interface NamedOrAlias. To differentiate,
+	// case TypeParam need to be present before case NamedOrAlias.
+	// TODO(hxjiang): remove this comment once TypeArgs() is added to interface
+	// NamedOrAlias.
+	case NamedOrAlias:
+		var expr ast.Expr = ast.NewIdent(t.Obj().Name())
+		if pkgName := qual(t.Obj().Pkg()); pkgName != "." && pkgName != "" {
+			expr = &ast.SelectorExpr{
+				X:   ast.NewIdent(pkgName),
+				Sel: expr.(*ast.Ident),
+			}
+		}
+
+		// TODO(hxjiang): call t.TypeArgs after adding method TypeArgs() to
+		// typesinternal.NamedOrAlias.
+		if hasTypeArgs, ok := t.(interface{ TypeArgs() *types.TypeList }); ok {
+			if typeArgs := hasTypeArgs.TypeArgs(); typeArgs != nil && typeArgs.Len() > 0 {
+				var indices []ast.Expr
+				for t0 := range typeArgs.Types() {
+					indices = append(indices, TypeExpr(t0, qual))
+				}
+				expr = &ast.IndexListExpr{
+					X:       expr,
+					Indices: indices,
+				}
+			}
+		}
+
+		return expr
+
+	case *types.Struct:
+		return ast.NewIdent(t.String())
+
+	case *types.Interface:
+		return ast.NewIdent(t.String())
+
+	case *types.Union:
+		if t.Len() == 0 {
+			panic("Union type should have at least one term")
+		}
+		// Same as go/ast, the return expression will put last term in the
+		// Y field at topmost level of BinaryExpr.
+		// For union of type "float32 | float64 | int64", the structure looks
+		// similar to:
+		// {
+		// 	X: {
+		// 		X: float32,
+		// 		Op: |
+		// 		Y: float64,
+		// 	}
+		// 	Op: |,
+		// 	Y: int64,
+		// }
+		var union ast.Expr
+		for i := range t.Len() {
+			term := t.Term(i)
+			termExpr := TypeExpr(term.Type(), qual)
+			if term.Tilde() {
+				termExpr = &ast.UnaryExpr{
+					Op: token.TILDE,
+					X:  termExpr,
+				}
+			}
+			if i == 0 {
+				union = termExpr
+			} else {
+				union = &ast.BinaryExpr{
+					X:  union,
+					Op: token.OR,
+					Y:  termExpr,
+				}
+			}
+		}
+		return union
+
+	case *types.Tuple:
+		panic("invalid input type types.Tuple")
+
+	default:
+		panic("unreachable")
+	}
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/versions/features.go b/vendor/honnef.co/go/tools/internal/xtools-internal/versions/features.go
new file mode 100644
index 0000000..360a5b5
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/versions/features.go
@@ -0,0 +1,49 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package versions
+
+// This file contains predicates for working with file versions to
+// decide when a tool should consider a language feature enabled.
+
+// named constants, to avoid misspelling
+const (
+	Go1_17 = "go1.17"
+	Go1_18 = "go1.18"
+	Go1_19 = "go1.19"
+	Go1_20 = "go1.20"
+	Go1_21 = "go1.21"
+	Go1_22 = "go1.22"
+	Go1_23 = "go1.23"
+	Go1_24 = "go1.24"
+	Go1_25 = "go1.25"
+	Go1_26 = "go1.26"
+	Go1_27 = "go1.27"
+)
+
+// Future is an invalid unknown Go version sometime in the future.
+// Do not use directly with Compare.
+const Future = ""
+
+// AtLeast reports whether the file version v comes after a Go release.
+//
+// Use this predicate to enable a behavior once a certain Go release
+// has happened (and stays enabled in the future).
+func AtLeast(v, release string) bool {
+	if v == Future {
+		return true // an unknown future version is always after y.
+	}
+	return Compare(Lang(v), Lang(release)) >= 0
+}
+
+// Before reports whether the file version v is strictly before a Go release.
+//
+// Use this predicate to disable a behavior once a certain Go release
+// has happened (and stays enabled in the future).
+func Before(v, release string) bool {
+	if v == Future {
+		return false // an unknown future version happens after y.
+	}
+	return Compare(Lang(v), Lang(release)) < 0
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/versions/gover.go b/vendor/honnef.co/go/tools/internal/xtools-internal/versions/gover.go
new file mode 100644
index 0000000..bbabcd2
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/versions/gover.go
@@ -0,0 +1,172 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This is a fork of internal/gover for use by x/tools until
+// go1.21 and earlier are no longer supported by x/tools.
+
+package versions
+
+import "strings"
+
+// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]]
+// The numbers are the original decimal strings to avoid integer overflows
+// and since there is very little actual math. (Probably overflow doesn't matter in practice,
+// but at the time this code was written, there was an existing test that used
+// go1.99999999999, which does not fit in an int on 32-bit platforms.
+// The "big decimal" representation avoids the problem entirely.)
+type gover struct {
+	major string // decimal
+	minor string // decimal or ""
+	patch string // decimal or ""
+	kind  string // "", "alpha", "beta", "rc"
+	pre   string // decimal or ""
+}
+
+// compare returns -1, 0, or +1 depending on whether
+// x < y, x == y, or x > y, interpreted as toolchain versions.
+// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21".
+// Malformed versions compare less than well-formed versions and equal to each other.
+// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0".
+func compare(x, y string) int {
+	vx := parse(x)
+	vy := parse(y)
+
+	if c := cmpInt(vx.major, vy.major); c != 0 {
+		return c
+	}
+	if c := cmpInt(vx.minor, vy.minor); c != 0 {
+		return c
+	}
+	if c := cmpInt(vx.patch, vy.patch); c != 0 {
+		return c
+	}
+	if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc
+		return c
+	}
+	if c := cmpInt(vx.pre, vy.pre); c != 0 {
+		return c
+	}
+	return 0
+}
+
+// lang returns the Go language version. For example, lang("1.2.3") == "1.2".
+func lang(x string) string {
+	v := parse(x)
+	if v.minor == "" || v.major == "1" && v.minor == "0" {
+		return v.major
+	}
+	return v.major + "." + v.minor
+}
+
+// isValid reports whether the version x is valid.
+func isValid(x string) bool {
+	return parse(x) != gover{}
+}
+
+// parse parses the Go version string x into a version.
+// It returns the zero version if x is malformed.
+func parse(x string) gover {
+	var v gover
+
+	// Parse major version.
+	var ok bool
+	v.major, x, ok = cutInt(x)
+	if !ok {
+		return gover{}
+	}
+	if x == "" {
+		// Interpret "1" as "1.0.0".
+		v.minor = "0"
+		v.patch = "0"
+		return v
+	}
+
+	// Parse . before minor version.
+	if x[0] != '.' {
+		return gover{}
+	}
+
+	// Parse minor version.
+	v.minor, x, ok = cutInt(x[1:])
+	if !ok {
+		return gover{}
+	}
+	if x == "" {
+		// Patch missing is same as "0" for older versions.
+		// Starting in Go 1.21, patch missing is different from explicit .0.
+		if cmpInt(v.minor, "21") < 0 {
+			v.patch = "0"
+		}
+		return v
+	}
+
+	// Parse patch if present.
+	if x[0] == '.' {
+		v.patch, x, ok = cutInt(x[1:])
+		if !ok || x != "" {
+			// Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != "").
+			// Allowing them would be a bit confusing because we already have:
+			//	1.21 < 1.21rc1
+			// But a prerelease of a patch would have the opposite effect:
+			//	1.21.3rc1 < 1.21.3
+			// We've never needed them before, so let's not start now.
+			return gover{}
+		}
+		return v
+	}
+
+	// Parse prerelease.
+	i := 0
+	for i < len(x) && (x[i] < '0' || '9' < x[i]) {
+		if x[i] < 'a' || 'z' < x[i] {
+			return gover{}
+		}
+		i++
+	}
+	if i == 0 {
+		return gover{}
+	}
+	v.kind, x = x[:i], x[i:]
+	if x == "" {
+		return v
+	}
+	v.pre, x, ok = cutInt(x)
+	if !ok || x != "" {
+		return gover{}
+	}
+
+	return v
+}
+
+// cutInt scans the leading decimal number at the start of x to an integer
+// and returns that value and the rest of the string.
+func cutInt(x string) (n, rest string, ok bool) {
+	i := 0
+	for i < len(x) && '0' <= x[i] && x[i] <= '9' {
+		i++
+	}
+	if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero
+		return "", "", false
+	}
+	return x[:i], x[i:], true
+}
+
+// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers.
+// (Copied from golang.org/x/mod/semver's compareInt.)
+func cmpInt(x, y string) int {
+	if x == y {
+		return 0
+	}
+	if len(x) < len(y) {
+		return -1
+	}
+	if len(x) > len(y) {
+		return +1
+	}
+	if x < y {
+		return -1
+	} else {
+		return +1
+	}
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/versions/types.go b/vendor/honnef.co/go/tools/internal/xtools-internal/versions/types.go
new file mode 100644
index 0000000..0fc10ce
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/versions/types.go
@@ -0,0 +1,33 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package versions
+
+import (
+	"go/ast"
+	"go/types"
+)
+
+// FileVersion returns a file's Go version.
+// The reported version is an unknown Future version if a
+// version cannot be determined.
+func FileVersion(info *types.Info, file *ast.File) string {
+	// In tools built with Go >= 1.22, the Go version of a file
+	// follow a cascades of sources:
+	// 1) types.Info.FileVersion, which follows the cascade:
+	//   1.a) file version (ast.File.GoVersion),
+	//   1.b) the package version (types.Config.GoVersion), or
+	// 2) is some unknown Future version.
+	//
+	// File versions require a valid package version to be provided to types
+	// in Config.GoVersion. Config.GoVersion is either from the package's module
+	// or the toolchain (go run). This value should be provided by go/packages
+	// or unitchecker.Config.GoVersion.
+	if v := info.FileVersions[file]; IsValid(v) {
+		return v
+	}
+	// Note: we could instead return runtime.Version() [if valid].
+	// This would act as a max version on what a tool can support.
+	return Future
+}
diff --git a/vendor/honnef.co/go/tools/internal/xtools-internal/versions/versions.go b/vendor/honnef.co/go/tools/internal/xtools-internal/versions/versions.go
new file mode 100644
index 0000000..8d1f745
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/xtools-internal/versions/versions.go
@@ -0,0 +1,57 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package versions
+
+import (
+	"strings"
+)
+
+// Note: If we use build tags to use go/versions when go >=1.22,
+// we run into go.dev/issue/53737. Under some operations users would see an
+// import of "go/versions" even if they would not compile the file.
+// For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include
+// For this reason, this library just a clone of go/versions for the moment.
+
+// Lang returns the Go language version for version x.
+// If x is not a valid version, Lang returns the empty string.
+// For example:
+//
+//	Lang("go1.21rc2") = "go1.21"
+//	Lang("go1.21.2") = "go1.21"
+//	Lang("go1.21") = "go1.21"
+//	Lang("go1") = "go1"
+//	Lang("bad") = ""
+//	Lang("1.21") = ""
+func Lang(x string) string {
+	v := lang(stripGo(x))
+	if v == "" {
+		return ""
+	}
+	return x[:2+len(v)] // "go"+v without allocation
+}
+
+// Compare returns -1, 0, or +1 depending on whether
+// x < y, x == y, or x > y, interpreted as Go versions.
+// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21".
+// Invalid versions, including the empty string, compare less than
+// valid versions and equal to each other.
+// The language version "go1.21" compares less than the
+// release candidate and eventual releases "go1.21rc1" and "go1.21.0".
+// Custom toolchain suffixes are ignored during comparison:
+// "go1.21.0" and "go1.21.0-bigcorp" are equal.
+func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) }
+
+// IsValid reports whether the version x is valid.
+func IsValid(x string) bool { return isValid(stripGo(x)) }
+
+// stripGo converts from a "go1.21" version to a "1.21" version.
+// If v does not start with "go", stripGo returns the empty string (a known invalid version).
+func stripGo(v string) string {
+	v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix.
+	if len(v) < 2 || v[:2] != "go" {
+		return ""
+	}
+	return v[2:]
+}
diff --git a/vendor/honnef.co/go/tools/knowledge/arg.go b/vendor/honnef.co/go/tools/knowledge/arg.go
new file mode 100644
index 0000000..c477ec4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/knowledge/arg.go
@@ -0,0 +1,79 @@
+package knowledge
+
+var Args = map[string]int{
+	"(*sync.Pool).Put.x":                     0,
+	"(*text/template.Template).Parse.text":   0,
+	"(io.Seeker).Seek.offset":                0,
+	"(time.Time).Sub.u":                      0,
+	"append.elems":                           1,
+	"append.slice":                           0,
+	"bytes.Equal.a":                          0,
+	"bytes.Equal.b":                          1,
+	"encoding/ascii85.Encode.dst":            0,
+	"encoding/ascii85.Encode.src":            1,
+	"(*encoding/base32.Encoding).Encode.dst": 0,
+	"(*encoding/base32.Encoding).Encode.src": 1,
+	"(*encoding/base64.Encoding).Encode.dst": 0,
+	"(*encoding/base64.Encoding).Encode.src": 1,
+	"encoding/binary.Write.data":             2,
+	"encoding/hex.Encode.dst":                0,
+	"encoding/hex.Encode.src":                1,
+	"(*encoding/json.Decoder).Decode.v":      0,
+	"(*encoding/json.Encoder).Encode.v":      0,
+	"(*encoding/xml.Decoder).Decode.v":       0,
+	"(*encoding/xml.Encoder).Encode.v":       0,
+	"errors.New.text":                        0,
+	"fmt.Fprintf.format":                     1,
+	"fmt.Printf.format":                      0,
+	"fmt.Sprintf.a[0]":                       1,
+	"fmt.Sprintf.format":                     0,
+	"json.Marshal.v":                         0,
+	"json.MarshalIndent.v":                   0,
+	"json.Unmarshal.v":                       1,
+	"len.v":                                  0,
+	"make.size[0]":                           1,
+	"make.size[1]":                           2,
+	"make.t":                                 0,
+	"net/url.Parse.rawurl":                   0,
+	"os.OpenFile.flag":                       1,
+	"os/exec.Command.name":                   0,
+	"os/signal.Notify.c":                     0,
+	"regexp.Compile.expr":                    0,
+	"runtime.SetFinalizer.finalizer":         1,
+	"runtime.SetFinalizer.obj":               0,
+	"sort.Sort.data":                         0,
+	"strconv.AppendFloat.bitSize":            4,
+	"strconv.AppendFloat.fmt":                2,
+	"strconv.AppendInt.base":                 2,
+	"strconv.AppendUint.base":                2,
+	"strconv.FormatComplex.bitSize":          3,
+	"strconv.FormatComplex.fmt":              1,
+	"strconv.FormatFloat.bitSize":            3,
+	"strconv.FormatFloat.fmt":                1,
+	"strconv.FormatInt.base":                 1,
+	"strconv.FormatUint.base":                1,
+	"strconv.ParseComplex.bitSize":           1,
+	"strconv.ParseFloat.bitSize":             1,
+	"strconv.ParseInt.base":                  1,
+	"strconv.ParseInt.bitSize":               2,
+	"strconv.ParseUint.base":                 1,
+	"strconv.ParseUint.bitSize":              2,
+	"time.Parse.layout":                      0,
+	"time.Sleep.d":                           0,
+	"xml.Marshal.v":                          0,
+	"xml.MarshalIndent.v":                    0,
+	"xml.Unmarshal.v":                        1,
+}
+
+// Arg turns the name of an argument into an argument index.
+// Indices are zero-based and method receivers do not count as arguments.
+//
+// Arg refers to a manually compiled mapping (see the Args variable.)
+// Modify the knowledge package to add new arguments.
+func Arg(name string) int {
+	n, ok := Args[name]
+	if !ok {
+		panic("unknown argument " + name)
+	}
+	return n
+}
diff --git a/vendor/honnef.co/go/tools/knowledge/deprecated.go b/vendor/honnef.co/go/tools/knowledge/deprecated.go
new file mode 100644
index 0000000..256f375
--- /dev/null
+++ b/vendor/honnef.co/go/tools/knowledge/deprecated.go
@@ -0,0 +1,256 @@
+package knowledge
+
+const (
+	// DeprecatedNeverUse indicates that an API should never be used, regardless of Go version.
+	DeprecatedNeverUse = "never"
+	// DeprecatedUseNoLonger indicates that an API has no use anymore.
+	DeprecatedUseNoLonger = "no longer"
+)
+
+// Deprecation describes when a Go API has been deprecated.
+type Deprecation struct {
+	// The minor Go version since which this API has been deprecated.
+	DeprecatedSince string
+	// The minor Go version since which an alternative API has been available.
+	// May also be one of DeprecatedNeverUse or DeprecatedUseNoLonger.
+	AlternativeAvailableSince string
+}
+
+// go/importer.ForCompiler contains "Deprecated:", but it refers to a single argument, not the whole function.
+// Luckily, the notice starts in the middle of a paragraph, and as such isn't detected by us.
+
+// TODO(dh): StdlibDeprecations doesn't contain entries for internal packages and unexported API. That's fine for normal
+// users, but makes the Deprecated check less useful for people working on Go itself.
+
+// StdlibDeprecations contains a mapping of Go API (such as variables, methods, or fields, among others)
+// to information about when it has been deprecated.
+var StdlibDeprecations = map[string]Deprecation{
+	// FIXME(dh): AllowBinary isn't being detected as deprecated
+	// because the comment has a newline right after "Deprecated:"
+	"go/build.AllowBinary":                      {"go1.7", "go1.7"},
+	"(archive/zip.FileHeader).CompressedSize":   {"go1.1", "go1.1"},
+	"(archive/zip.FileHeader).UncompressedSize": {"go1.1", "go1.1"},
+	"(archive/zip.FileHeader).ModifiedTime":     {"go1.10", "go1.10"},
+	"(archive/zip.FileHeader).ModifiedDate":     {"go1.10", "go1.10"},
+	"(*archive/zip.FileHeader).ModTime":         {"go1.10", "go1.10"},
+	"(*archive/zip.FileHeader).SetModTime":      {"go1.10", "go1.10"},
+	"(go/doc.Package).Bugs":                     {"go1.1", "go1.1"},
+	"os.SEEK_SET":                               {"go1.7", "go1.7"},
+	"os.SEEK_CUR":                               {"go1.7", "go1.7"},
+	"os.SEEK_END":                               {"go1.7", "go1.7"},
+	"(net.Dialer).Cancel":                       {"go1.7", "go1.7"},
+	"runtime.CPUProfile":                        {"go1.9", "go1.0"},
+	"compress/flate.ReadError":                  {"go1.6", DeprecatedUseNoLonger},
+	"compress/flate.WriteError":                 {"go1.6", DeprecatedUseNoLonger},
+	"path/filepath.HasPrefix":                   {"go1.0", DeprecatedNeverUse},
+	"(net/http.Transport).Dial":                 {"go1.7", "go1.7"},
+	"(net/http.Transport).DialTLS":              {"go1.14", "go1.14"},
+	"(*net/http.Transport).CancelRequest":       {"go1.6", "go1.5"},
+	"net/http.ErrWriteAfterFlush":               {"go1.7", DeprecatedUseNoLonger},
+	"net/http.ErrHeaderTooLong":                 {"go1.8", DeprecatedUseNoLonger},
+	"net/http.ErrShortBody":                     {"go1.8", DeprecatedUseNoLonger},
+	"net/http.ErrMissingContentLength":          {"go1.8", DeprecatedUseNoLonger},
+	"net/http/httputil.ErrPersistEOF":           {"go1.0", DeprecatedUseNoLonger},
+	"net/http/httputil.ErrClosed":               {"go1.0", DeprecatedUseNoLonger},
+	"net/http/httputil.ErrPipeline":             {"go1.0", DeprecatedUseNoLonger},
+	"net/http/httputil.ServerConn":              {"go1.0", "go1.0"},
+	"net/http/httputil.NewServerConn":           {"go1.0", "go1.0"},
+	"net/http/httputil.ClientConn":              {"go1.0", "go1.0"},
+	"net/http/httputil.NewClientConn":           {"go1.0", "go1.0"},
+	"net/http/httputil.NewProxyClientConn":      {"go1.0", "go1.0"},
+	"(net/http.Request).Cancel":                 {"go1.7", "go1.7"},
+	"(text/template/parse.PipeNode).Line":       {"go1.1", DeprecatedUseNoLonger},
+	"(text/template/parse.ActionNode).Line":     {"go1.1", DeprecatedUseNoLonger},
+	"(text/template/parse.BranchNode).Line":     {"go1.1", DeprecatedUseNoLonger},
+	"(text/template/parse.TemplateNode).Line":   {"go1.1", DeprecatedUseNoLonger},
+	"database/sql/driver.ColumnConverter":       {"go1.9", "go1.9"},
+	"database/sql/driver.Execer":                {"go1.8", "go1.8"},
+	"database/sql/driver.Queryer":               {"go1.8", "go1.8"},
+	"(database/sql/driver.Conn).Begin":          {"go1.8", "go1.8"},
+	"(database/sql/driver.Stmt).Exec":           {"go1.8", "go1.8"},
+	"(database/sql/driver.Stmt).Query":          {"go1.8", "go1.8"},
+	"syscall.StringByteSlice":                   {"go1.1", "go1.1"},
+	"syscall.StringBytePtr":                     {"go1.1", "go1.1"},
+	"syscall.StringSlicePtr":                    {"go1.1", "go1.1"},
+	"syscall.StringToUTF16":                     {"go1.1", "go1.1"},
+	"syscall.StringToUTF16Ptr":                  {"go1.1", "go1.1"},
+	"(*regexp.Regexp).Copy":                     {"go1.12", DeprecatedUseNoLonger},
+	"(archive/tar.Header).Xattrs":               {"go1.10", "go1.10"},
+	"archive/tar.TypeRegA":                      {"go1.11", "go1.1"},
+	"go/types.NewInterface":                     {"go1.11", "go1.11"},
+	"(*go/types.Interface).Embedded":            {"go1.11", "go1.11"},
+	"go/importer.For":                           {"go1.12", "go1.12"},
+	"encoding/json.InvalidUTF8Error":            {"go1.2", DeprecatedUseNoLonger},
+	"encoding/json.UnmarshalFieldError":         {"go1.2", DeprecatedUseNoLonger},
+	"encoding/csv.ErrTrailingComma":             {"go1.2", DeprecatedUseNoLonger},
+	"(encoding/csv.Reader).TrailingComma":       {"go1.2", DeprecatedUseNoLonger},
+	"(net.Dialer).DualStack":                    {"go1.12", "go1.12"},
+	"net/http.ErrUnexpectedTrailer":             {"go1.12", DeprecatedUseNoLonger},
+	"net/http.CloseNotifier":                    {"go1.11", "go1.7"},
+	// This is hairy. The notice says "Not all errors in the http package related to protocol errors are of type ProtocolError", but doesn't that imply that some errors do?
+	"net/http.ProtocolError":                       {"go1.8", DeprecatedUseNoLonger},
+	"(crypto/x509.CertificateRequest).Attributes":  {"go1.5", "go1.3"},
+	"(*crypto/x509.Certificate).CheckCRLSignature": {"go1.19", "go1.19"},
+	"crypto/x509.ParseCRL":                         {"go1.19", "go1.19"},
+	"crypto/x509.ParseDERCRL":                      {"go1.19", "go1.19"},
+	"(*crypto/x509.Certificate).CreateCRL":         {"go1.19", "go1.19"},
+	"crypto/x509/pkix.TBSCertificateList":          {"go1.19", "go1.19"},
+	"crypto/x509/pkix.RevokedCertificate":          {"go1.19", "go1.19"},
+	"go/doc.ToHTML":                                {"go1.20", "go1.20"},
+	"go/doc.ToText":                                {"go1.20", "go1.20"},
+	"go/doc.Synopsis":                              {"go1.20", "go1.20"},
+	"math/rand.Seed":                               {"go1.20", "go1.0"},
+	"math/rand.Read":                               {"go1.20", DeprecatedNeverUse},
+
+	// These functions have no direct alternative, but they are insecure and should no longer be used.
+	"crypto/x509.IsEncryptedPEMBlock": {"go1.16", DeprecatedNeverUse},
+	"crypto/x509.DecryptPEMBlock":     {"go1.16", DeprecatedNeverUse},
+	"crypto/x509.EncryptPEMBlock":     {"go1.16", DeprecatedNeverUse},
+	"crypto/dsa":                      {"go1.16", DeprecatedNeverUse},
+
+	// This function has no alternative, but also no purpose.
+	"(*crypto/rc4.Cipher).Reset":                     {"go1.12", DeprecatedNeverUse},
+	"(net/http/httptest.ResponseRecorder).HeaderMap": {"go1.11", "go1.7"},
+	"image.ZP":                                    {"go1.13", "go1.0"},
+	"image.ZR":                                    {"go1.13", "go1.0"},
+	"(*debug/gosym.LineTable).LineToPC":           {"go1.2", "go1.2"},
+	"(*debug/gosym.LineTable).PCToLine":           {"go1.2", "go1.2"},
+	"crypto/tls.VersionSSL30":                     {"go1.13", DeprecatedNeverUse},
+	"(crypto/tls.Config).NameToCertificate":       {"go1.14", DeprecatedUseNoLonger},
+	"(*crypto/tls.Config).BuildNameToCertificate": {"go1.14", DeprecatedUseNoLonger},
+	"(crypto/tls.Config).SessionTicketKey":        {"go1.16", "go1.5"},
+	// No alternative, no use
+	"(crypto/tls.ConnectionState).NegotiatedProtocolIsMutual": {"go1.16", DeprecatedNeverUse},
+	// No alternative, but insecure
+	"(crypto/tls.ConnectionState).TLSUnique": {"go1.16", DeprecatedNeverUse},
+	"image/jpeg.Reader":                      {"go1.4", DeprecatedNeverUse},
+
+	// All of these have been deprecated in favour of external libraries
+	"syscall.AttachLsf":                     {"go1.7", "go1.0"},
+	"syscall.DetachLsf":                     {"go1.7", "go1.0"},
+	"syscall.LsfSocket":                     {"go1.7", "go1.0"},
+	"syscall.SetLsfPromisc":                 {"go1.7", "go1.0"},
+	"syscall.LsfJump":                       {"go1.7", "go1.0"},
+	"syscall.LsfStmt":                       {"go1.7", "go1.0"},
+	"syscall.BpfStmt":                       {"go1.7", "go1.0"},
+	"syscall.BpfJump":                       {"go1.7", "go1.0"},
+	"syscall.BpfBuflen":                     {"go1.7", "go1.0"},
+	"syscall.SetBpfBuflen":                  {"go1.7", "go1.0"},
+	"syscall.BpfDatalink":                   {"go1.7", "go1.0"},
+	"syscall.SetBpfDatalink":                {"go1.7", "go1.0"},
+	"syscall.SetBpfPromisc":                 {"go1.7", "go1.0"},
+	"syscall.FlushBpf":                      {"go1.7", "go1.0"},
+	"syscall.BpfInterface":                  {"go1.7", "go1.0"},
+	"syscall.SetBpfInterface":               {"go1.7", "go1.0"},
+	"syscall.BpfTimeout":                    {"go1.7", "go1.0"},
+	"syscall.SetBpfTimeout":                 {"go1.7", "go1.0"},
+	"syscall.BpfStats":                      {"go1.7", "go1.0"},
+	"syscall.SetBpfImmediate":               {"go1.7", "go1.0"},
+	"syscall.SetBpf":                        {"go1.7", "go1.0"},
+	"syscall.CheckBpfVersion":               {"go1.7", "go1.0"},
+	"syscall.BpfHeadercmpl":                 {"go1.7", "go1.0"},
+	"syscall.SetBpfHeadercmpl":              {"go1.7", "go1.0"},
+	"syscall.RouteRIB":                      {"go1.8", "go1.0"},
+	"syscall.RoutingMessage":                {"go1.8", "go1.0"},
+	"syscall.RouteMessage":                  {"go1.8", "go1.0"},
+	"syscall.InterfaceMessage":              {"go1.8", "go1.0"},
+	"syscall.InterfaceAddrMessage":          {"go1.8", "go1.0"},
+	"syscall.ParseRoutingMessage":           {"go1.8", "go1.0"},
+	"syscall.ParseRoutingSockaddr":          {"go1.8", "go1.0"},
+	"syscall.InterfaceAnnounceMessage":      {"go1.7", "go1.0"},
+	"syscall.InterfaceMulticastAddrMessage": {"go1.7", "go1.0"},
+	"syscall.FormatMessage":                 {"go1.5", "go1.0"},
+	"syscall.PostQueuedCompletionStatus":    {"go1.17", "go1.0"},
+	"syscall.GetQueuedCompletionStatus":     {"go1.17", "go1.0"},
+	"syscall.CreateIoCompletionPort":        {"go1.17", "go1.0"},
+
+	// We choose to only track the package itself, even though all functions are deprecated individually, too. Anyone
+	// using ioutil directly will have to import it, and this keeps the noise down.
+	"io/ioutil": {"go1.19", "go1.19"},
+
+	"bytes.Title":   {"go1.18", "go1.0"},
+	"strings.Title": {"go1.18", "go1.0"},
+	"(crypto/tls.Config).PreferServerCipherSuites": {"go1.18", DeprecatedUseNoLonger},
+	// It's not clear if Subjects was okay to use in the past, so we err on the less noisy side of assuming that it was.
+	"(*crypto/x509.CertPool).Subjects": {"go1.18", DeprecatedUseNoLonger},
+	"go/types.NewSignature":            {"go1.18", "go1.18"},
+	"(net.Error).Temporary":            {"go1.18", DeprecatedNeverUse},
+	// InterfaceData is another tricky case. It was deprecated in Go 1.18, but has been useless since Go 1.4, and an
+	// "alternative" (using your own unsafe hacks) has existed forever. We don't want to get into hairsplitting with
+	// users who somehow successfully used this between 1.4 and 1.18, so we'll just tag it as deprecated since 1.18.
+	"(reflect.Value).InterfaceData": {"go1.18", "go1.18"},
+
+	// The following objects are only deprecated on Windows.
+	"syscall.Syscall":   {"go1.18", "go1.18"},
+	"syscall.Syscall12": {"go1.18", "go1.18"},
+	"syscall.Syscall15": {"go1.18", "go1.18"},
+	"syscall.Syscall18": {"go1.18", "go1.18"},
+	"syscall.Syscall6":  {"go1.18", "go1.18"},
+	"syscall.Syscall9":  {"go1.18", "go1.18"},
+
+	"reflect.SliceHeader":                           {"go1.21", "go1.17"},
+	"reflect.StringHeader":                          {"go1.21", "go1.20"},
+	"crypto/elliptic.GenerateKey":                   {"go1.21", "go1.21"},
+	"crypto/elliptic.Marshal":                       {"go1.21", "go1.21"},
+	"crypto/elliptic.Unmarshal":                     {"go1.21", "go1.21"},
+	"(*crypto/elliptic.CurveParams).Add":            {"go1.21", "go1.21"},
+	"(*crypto/elliptic.CurveParams).Double":         {"go1.21", "go1.21"},
+	"(*crypto/elliptic.CurveParams).IsOnCurve":      {"go1.21", "go1.21"},
+	"(*crypto/elliptic.CurveParams).ScalarBaseMult": {"go1.21", "go1.21"},
+	"(*crypto/elliptic.CurveParams).ScalarMult":     {"go1.21", "go1.21"},
+	"(crypto/elliptic.Curve).Add":                   {"go1.21", "go1.21"},
+	"(crypto/elliptic.Curve).Double":                {"go1.21", "go1.21"},
+	"(crypto/elliptic.Curve).IsOnCurve":             {"go1.21", "go1.21"},
+	"(crypto/elliptic.Curve).ScalarBaseMult":        {"go1.21", "go1.21"},
+	"(crypto/elliptic.Curve).ScalarMult":            {"go1.21", "go1.21"},
+
+	"crypto/rsa.GenerateMultiPrimeKey":                 {"go1.21", DeprecatedNeverUse},
+	"(crypto/rsa.PrecomputedValues).CRTValues":         {"go1.21", DeprecatedNeverUse},
+	"(crypto/x509.RevocationList).RevokedCertificates": {"go1.21", "go1.21"},
+
+	"go/ast.NewPackage":           {"go1.22", "go1.0"},
+	"go/ast.Importer":             {"go1.22", "go1.0"},
+	"go/ast.Object":               {"go1.22", "go1.0"},
+	"go/ast.Package":              {"go1.22", "go1.0"},
+	"go/ast.Scope":                {"go1.22", "go1.0"},
+	"html/template.ErrJSTemplate": {"go1.22", DeprecatedUseNoLonger},
+	"reflect.PtrTo":               {"go1.22", "go1.18"},
+
+	// Technically, runtime.GOROOT could be considered DeprecatedNeverUse, but
+	// using it used to be a lot more common and accepted.
+	"runtime.GOROOT": {"go1.24", DeprecatedUseNoLonger},
+	// These are never safe to use; a concrete alternative was added in Go 1.2 (crypto/cipher.AEAD).
+	"crypto/cipher.NewCFBDecrypter": {"go1.24", "go1.2"},
+	"crypto/cipher.NewCFBEncrypter": {"go1.24", "go1.2"},
+	"crypto/cipher.NewOFB":          {"go1.24", "go1.2"},
+
+	"go/ast.FilterFuncDuplicates":       {"go1.25", "go1.0"},
+	"go/ast.FilterImportDuplicates":     {"go1.25", "go1.0"},
+	"go/ast.FilterUnassociatedComments": {"go1.25", "go1.0"},
+	"go/ast.FilterPackage":              {"go1.25", "go1.0"},
+	"go/ast.MergePackageFiles":          {"go1.25", "go1.0"},
+	"go/ast.PackageExports":             {"go1.25", "go1.0"},
+	"go/ast.MergeMode":                  {"go1.25", "go1.0"},
+	// Go 1.11 because that's around the time x/tools/go/packages was released.
+	"go/parser.ParseDir": {"go1.25", "go1.11"},
+
+	// Go 1.25 is the first version to provide all of the alternatives mentioned
+	// by the deprecation note.
+	"(crypto/ecdsa.PublicKey).X":  {"go1.26", "go1.25"},
+	"(crypto/ecdsa.PublicKey).Y":  {"go1.26", "go1.25"},
+	"(crypto/ecdsa.PrivateKey).D": {"go1.26", "go1.25"},
+
+	"crypto/rsa.DecryptPKCS1v15":           {"go1.26", DeprecatedNeverUse},
+	"crypto/rsa.DecryptPKCS1v15SessionKey": {"go1.26", DeprecatedNeverUse},
+	"crypto/rsa.PKCS1v15DecryptOptions":    {"go1.26", DeprecatedNeverUse},
+	"crypto/rsa.EncryptPKCS1v15":           {"go1.26", DeprecatedNeverUse},
+
+	"(net/http/httputil.ReverseProxy).Director": {"go1.26", "go1.20"},
+
+	// Note that the available alternative, testing/cryptotest.SetGlobalRandom
+	// is only an alternative for testing, not all possible uses of the
+	// deprecated field.
+	"(crypto/tls.Config).Rand": {"go1.27", "go1.26"},
+}
+
+// Last imported from GOROOT/api/go1.26.txt at d3ddc4854429185e6e06ca1f7628bb790404abb5.
diff --git a/vendor/honnef.co/go/tools/knowledge/doc.go b/vendor/honnef.co/go/tools/knowledge/doc.go
new file mode 100644
index 0000000..72ff524
--- /dev/null
+++ b/vendor/honnef.co/go/tools/knowledge/doc.go
@@ -0,0 +1,2 @@
+// Package knowledge contains manually collected information about Go APIs.
+package knowledge
diff --git a/vendor/honnef.co/go/tools/knowledge/signatures.go b/vendor/honnef.co/go/tools/knowledge/signatures.go
new file mode 100644
index 0000000..03f4d53
--- /dev/null
+++ b/vendor/honnef.co/go/tools/knowledge/signatures.go
@@ -0,0 +1,107 @@
+package knowledge
+
+import (
+	"go/token"
+	"go/types"
+)
+
+var Signatures = map[string]*types.Signature{
+	"(io.Seeker).Seek": types.NewSignatureType(nil, nil, nil,
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.Int64]),
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.Int]),
+		),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.Int64]),
+			types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
+		),
+		false,
+	),
+
+	"(io.Writer).Write": types.NewSignatureType(nil, nil, nil,
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])),
+		),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.Int]),
+			types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
+		),
+		false,
+	),
+
+	"(io.StringWriter).WriteString": types.NewSignatureType(nil, nil, nil,
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.String]),
+		),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.Int]),
+			types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
+		),
+		false,
+	),
+
+	"(encoding.TextMarshaler).MarshalText": types.NewSignatureType(nil, nil, nil,
+		types.NewTuple(),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])),
+			types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
+		),
+		false,
+	),
+
+	"(encoding/json.Marshaler).MarshalJSON": types.NewSignatureType(nil, nil, nil,
+		types.NewTuple(),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])),
+			types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()),
+		),
+		false,
+	),
+
+	"(fmt.Stringer).String": types.NewSignatureType(nil, nil, nil,
+		types.NewTuple(),
+		types.NewTuple(
+			types.NewParam(token.NoPos, nil, "", types.Typ[types.String]),
+		),
+		false,
+	),
+}
+
+var Interfaces = map[string]*types.Interface{
+	"fmt.Stringer": types.NewInterfaceType(
+		[]*types.Func{
+			types.NewFunc(token.NoPos, nil, "String", Signatures["(fmt.Stringer).String"]),
+		},
+		nil,
+	).Complete(),
+
+	"error": types.Universe.Lookup("error").Type().Underlying().(*types.Interface),
+
+	"io.Writer": types.NewInterfaceType(
+		[]*types.Func{
+			types.NewFunc(token.NoPos, nil, "Write", Signatures["(io.Writer).Write"]),
+		},
+		nil,
+	).Complete(),
+
+	"io.StringWriter": types.NewInterfaceType(
+		[]*types.Func{
+			types.NewFunc(token.NoPos, nil, "WriteString", Signatures["(io.StringWriter).WriteString"]),
+		},
+		nil,
+	).Complete(),
+
+	"encoding.TextMarshaler": types.NewInterfaceType(
+		[]*types.Func{
+			types.NewFunc(token.NoPos, nil, "MarshalText", Signatures["(encoding.TextMarshaler).MarshalText"]),
+		},
+		nil,
+	).Complete(),
+
+	"encoding/json.Marshaler": types.NewInterfaceType(
+		[]*types.Func{
+			types.NewFunc(token.NoPos, nil, "MarshalJSON", Signatures["(encoding/json.Marshaler).MarshalJSON"]),
+		},
+		nil,
+	).Complete(),
+}
diff --git a/vendor/honnef.co/go/tools/knowledge/targets.go b/vendor/honnef.co/go/tools/knowledge/targets.go
new file mode 100644
index 0000000..d9c44f8
--- /dev/null
+++ b/vendor/honnef.co/go/tools/knowledge/targets.go
@@ -0,0 +1,38 @@
+package knowledge
+
+var KnownGOOS = map[string]struct{}{
+	"aix":       {},
+	"android":   {},
+	"darwin":    {},
+	"dragonfly": {},
+	"freebsd":   {},
+	"hurd":      {},
+	"illumos":   {},
+	"ios":       {},
+	"js":        {},
+	"linux":     {},
+	"netbsd":    {},
+	"openbsd":   {},
+	"plan9":     {},
+	"solaris":   {},
+	"wasip1":    {},
+	"windows":   {},
+}
+
+var KnownGOARCH = map[string]struct{}{
+	"386":      {},
+	"amd64":    {},
+	"arm":      {},
+	"arm64":    {},
+	"loong64":  {},
+	"mips":     {},
+	"mipsle":   {},
+	"mips64":   {},
+	"mips64le": {},
+	"ppc64":    {},
+	"ppc64le":  {},
+	"riscv64":  {},
+	"s390x":    {},
+	"sparc64":  {},
+	"wasm":     {},
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/cache/UPSTREAM b/vendor/honnef.co/go/tools/lintcmd/cache/UPSTREAM
new file mode 100644
index 0000000..2b0b42f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/cache/UPSTREAM
@@ -0,0 +1,10 @@
+This package is a copy of cmd/go/internal/cache.
+
+Differences from upstream:
+- we continue to use renameio instead of lockedfile for writing trim.txt
+- we still use I/O helpers that work with earlier versions of Go.
+- we use a cache directory specific to Staticcheck
+- we use a Staticcheck-specific salt
+
+The last upstream commit we've looked at was:
+06ac303f6a14b133254f757e54599c48e3c2a4ad
diff --git a/vendor/honnef.co/go/tools/lintcmd/cache/cache.go b/vendor/honnef.co/go/tools/lintcmd/cache/cache.go
new file mode 100644
index 0000000..d0f4a57
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/cache/cache.go
@@ -0,0 +1,566 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package cache implements a build artifact cache.
+//
+// This package is a slightly modified fork of Go's
+// cmd/go/internal/cache package.
+package cache
+
+import (
+	"bytes"
+	"crypto/sha256"
+	"encoding/hex"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+
+	"honnef.co/go/tools/internal/renameio"
+)
+
+// An ActionID is a cache action key, the hash of a complete description of a
+// repeatable computation (command line, environment variables,
+// input file contents, executable contents).
+type ActionID [HashSize]byte
+
+// An OutputID is a cache output key, the hash of an output of a computation.
+type OutputID [HashSize]byte
+
+// Cache is the interface for a build artifact cache.
+type Cache interface {
+	// Get returns the cache entry for the provided ActionID.
+	// On miss, the error type should be of type *entryNotFoundError.
+	Get(ActionID) (Entry, error)
+
+	// Put adds an item to the cache. The seeker is only used to seek to
+	// the beginning. After a call to Put, the seek position is not
+	// guaranteed to be in any particular state.
+	//
+	// As a special case, if the ReadSeeker is of type noVerifyReadSeeker,
+	// the verification from GODEBUG=gocacheverify=1 is skipped.
+	Put(ActionID, io.ReadSeeker) (OutputID, int64, error)
+
+	// Close closes the cache and releases any resources. For DiskCache
+	// this trims old entries.
+	Close() error
+
+	// OutputFile returns the path to the on-disk file for the given OutputID.
+	OutputFile(OutputID) string
+}
+
+// A DiskCache is a package cache backed by a file system directory tree.
+type DiskCache struct {
+	dir string
+	now func() time.Time
+}
+
+// Open opens and returns the cache in the given directory.
+//
+// It is safe for multiple processes on a single machine to use the
+// same cache directory in a local file system simultaneously.
+// They will coordinate using operating system file locks and may
+// duplicate effort but will not corrupt the cache.
+//
+// However, it is NOT safe for multiple processes on different machines
+// to share a cache directory (for example, if the directory were stored
+// in a network file system). File locking is notoriously unreliable in
+// network file systems and may not suffice to protect the cache.
+func Open(dir string) (*DiskCache, error) {
+	info, err := os.Stat(dir)
+	if err != nil {
+		return nil, err
+	}
+	if !info.IsDir() {
+		return nil, &os.PathError{Op: "open", Path: dir, Err: fmt.Errorf("not a directory")}
+	}
+	for i := range 256 {
+		name := filepath.Join(dir, fmt.Sprintf("%02x", i))
+		if err := os.MkdirAll(name, 0777); err != nil {
+			return nil, err
+		}
+	}
+	c := &DiskCache{
+		dir: dir,
+		now: time.Now,
+	}
+	return c, nil
+}
+
+// fileName returns the name of the file corresponding to the given id.
+func (c *DiskCache) fileName(id [HashSize]byte, key string) string {
+	return filepath.Join(c.dir, fmt.Sprintf("%02x", id[0]), fmt.Sprintf("%x", id)+"-"+key)
+}
+
+// An entryNotFoundError indicates that a cache entry was not found, with an
+// optional underlying reason.
+type entryNotFoundError struct {
+	Err error
+}
+
+func (e *entryNotFoundError) Error() string {
+	if e.Err == nil {
+		return "cache entry not found"
+	}
+	return fmt.Sprintf("cache entry not found: %v", e.Err)
+}
+
+func (e *entryNotFoundError) Unwrap() error {
+	return e.Err
+}
+
+const (
+	// action entry file is "v1    \n"
+	hexSize   = HashSize * 2
+	entrySize = 2 + 1 + hexSize + 1 + hexSize + 1 + 20 + 1 + 20 + 1
+)
+
+// verify controls whether to run the cache in verify mode.
+// In verify mode, the cache always returns errMissing from Get
+// but then double-checks in Put that the data being written
+// exactly matches any existing entry. This provides an easy
+// way to detect program behavior that would have been different
+// had the cache entry been returned from Get.
+//
+// verify is enabled by setting the environment variable
+// GODEBUG=gocacheverify=1.
+var verify = false
+
+var errVerifyMode = errors.New("gocacheverify=1")
+
+// DebugTest is set when GODEBUG=gocachetest=1 is in the environment.
+var DebugTest = false
+
+func init() { initEnv() }
+
+func initEnv() {
+	verify = false
+	debugHash = false
+	debug := strings.SplitSeq(os.Getenv("GODEBUG"), ",")
+	for f := range debug {
+		if f == "gocacheverify=1" {
+			verify = true
+		}
+		if f == "gocachehash=1" {
+			debugHash = true
+		}
+		if f == "gocachetest=1" {
+			DebugTest = true
+		}
+	}
+}
+
+// Get looks up the action ID in the cache,
+// returning the corresponding output ID and file size, if any.
+// Note that finding an output ID does not guarantee that the
+// saved file for that output ID is still available.
+func (c *DiskCache) Get(id ActionID) (Entry, error) {
+	if verify {
+		return Entry{}, &entryNotFoundError{Err: errVerifyMode}
+	}
+	return c.get(id)
+}
+
+type Entry struct {
+	OutputID OutputID
+	Size     int64
+	Time     time.Time
+}
+
+// get is Get but does not respect verify mode, so that Put can use it.
+func (c *DiskCache) get(id ActionID) (Entry, error) {
+	missing := func(reason error) (Entry, error) {
+		return Entry{}, &entryNotFoundError{Err: reason}
+	}
+	f, err := os.Open(c.fileName(id, "a"))
+	if err != nil {
+		return missing(err)
+	}
+	defer f.Close()
+	entry := make([]byte, entrySize+1) // +1 to detect whether f is too long
+	if n, err := io.ReadFull(f, entry); n > entrySize {
+		return missing(errors.New("too long"))
+	} else if err != io.ErrUnexpectedEOF {
+		if err == io.EOF {
+			return missing(errors.New("file is empty"))
+		}
+		return missing(err)
+	} else if n < entrySize {
+		return missing(errors.New("entry file incomplete"))
+	}
+	if entry[0] != 'v' || entry[1] != '1' || entry[2] != ' ' || entry[3+hexSize] != ' ' || entry[3+hexSize+1+hexSize] != ' ' || entry[3+hexSize+1+hexSize+1+20] != ' ' || entry[entrySize-1] != '\n' {
+		return missing(errors.New("invalid header"))
+	}
+	eid, entry := entry[3:3+hexSize], entry[3+hexSize:]
+	eout, entry := entry[1:1+hexSize], entry[1+hexSize:]
+	esize, entry := entry[1:1+20], entry[1+20:]
+	//lint:ignore SA4006 See https://github.com/dominikh/go-tools/issues/465
+	etime, entry := entry[1:1+20], entry[1+20:]
+	var buf [HashSize]byte
+	if _, err := hex.Decode(buf[:], eid); err != nil {
+		return missing(fmt.Errorf("decoding ID: %v", err))
+	} else if buf != id {
+		return missing(errors.New("mismatched ID"))
+	}
+	if _, err := hex.Decode(buf[:], eout); err != nil {
+		return missing(fmt.Errorf("decoding output ID: %v", err))
+	}
+	i := 0
+	for i < len(esize) && esize[i] == ' ' {
+		i++
+	}
+	size, err := strconv.ParseInt(string(esize[i:]), 10, 64)
+	if err != nil {
+		return missing(fmt.Errorf("parsing size: %v", err))
+	} else if size < 0 {
+		return missing(errors.New("negative size"))
+	}
+	i = 0
+	for i < len(etime) && etime[i] == ' ' {
+		i++
+	}
+	tm, err := strconv.ParseInt(string(etime[i:]), 10, 64)
+	if err != nil {
+		return missing(fmt.Errorf("parsing timestamp: %v", err))
+	} else if tm < 0 {
+		return missing(errors.New("negative timestamp"))
+	}
+
+	c.used(c.fileName(id, "a"))
+
+	return Entry{buf, size, time.Unix(0, tm)}, nil
+}
+
+// GetFile looks up the action ID in the cache and returns
+// the name of the corresponding data file.
+func GetFile(c Cache, id ActionID) (file string, entry Entry, err error) {
+	entry, err = c.Get(id)
+	if err != nil {
+		return "", Entry{}, err
+	}
+	file = c.OutputFile(entry.OutputID)
+	info, err := os.Stat(file)
+	if err != nil {
+		return "", Entry{}, &entryNotFoundError{Err: err}
+	}
+	if info.Size() != entry.Size {
+		return "", Entry{}, &entryNotFoundError{Err: errors.New("file incomplete")}
+	}
+	return file, entry, nil
+}
+
+// GetBytes looks up the action ID in the cache and returns
+// the corresponding output bytes.
+// GetBytes should only be used for data that can be expected to fit in memory.
+func GetBytes(c Cache, id ActionID) ([]byte, Entry, error) {
+	entry, err := c.Get(id)
+	if err != nil {
+		return nil, entry, err
+	}
+	data, _ := os.ReadFile(c.OutputFile(entry.OutputID))
+	if sha256.Sum256(data) != entry.OutputID {
+		return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")}
+	}
+	return data, entry, nil
+}
+
+// OutputFile returns the name of the cache file storing output with the given OutputID.
+func (c *DiskCache) OutputFile(out OutputID) string {
+	file := c.fileName(out, "d")
+	c.used(file)
+	return file
+}
+
+// Time constants for cache expiration.
+//
+// We set the mtime on a cache file on each use, but at most one per mtimeInterval (1 hour),
+// to avoid causing many unnecessary inode updates. The mtimes therefore
+// roughly reflect "time of last use" but may in fact be older by at most an hour.
+//
+// We scan the cache for entries to delete at most once per trimInterval (1 day).
+//
+// When we do scan the cache, we delete entries that have not been used for
+// at least trimLimit (5 days). Statistics gathered from a month of usage by
+// Go developers found that essentially all reuse of cached entries happened
+// within 5 days of the previous reuse. See golang.org/issue/22990.
+const (
+	mtimeInterval = 1 * time.Hour
+	trimInterval  = 24 * time.Hour
+	trimLimit     = 5 * 24 * time.Hour
+)
+
+// used makes a best-effort attempt to update mtime on file,
+// so that mtime reflects cache access time.
+//
+// Because the reflection only needs to be approximate,
+// and to reduce the amount of disk activity caused by using
+// cache entries, used only updates the mtime if the current
+// mtime is more than an hour old. This heuristic eliminates
+// nearly all of the mtime updates that would otherwise happen,
+// while still keeping the mtimes useful for cache trimming.
+func (c *DiskCache) used(file string) {
+	info, err := os.Stat(file)
+	if err == nil && c.now().Sub(info.ModTime()) < mtimeInterval {
+		return
+	}
+	os.Chtimes(file, c.now(), c.now())
+}
+
+// Trim removes old cache entries that are likely not to be reused.
+func (c *DiskCache) Trim() {
+	now := c.now()
+
+	// We maintain in dir/trim.txt the time of the last completed cache trim.
+	// If the cache has been trimmed recently enough, do nothing.
+	// This is the common case.
+	data, _ := renameio.ReadFile(filepath.Join(c.dir, "trim.txt"))
+	t, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64)
+	if err == nil && now.Sub(time.Unix(t, 0)) < trimInterval {
+		return
+	}
+
+	// Trim each of the 256 subdirectories.
+	// We subtract an additional mtimeInterval
+	// to account for the imprecision of our "last used" mtimes.
+	cutoff := now.Add(-trimLimit - mtimeInterval)
+	for i := range 256 {
+		subdir := filepath.Join(c.dir, fmt.Sprintf("%02x", i))
+		c.trimSubdir(subdir, cutoff)
+	}
+
+	// Ignore errors from here: if we don't write the complete timestamp, the
+	// cache will appear older than it is, and we'll trim it again next time.
+	renameio.WriteFile(filepath.Join(c.dir, "trim.txt"), fmt.Appendf(nil, "%d", now.Unix()), 0666)
+}
+
+// Close trims the cache and releases resources.
+func (c *DiskCache) Close() error {
+	c.Trim()
+	return nil
+}
+
+// trimSubdir trims a single cache subdirectory.
+func (c *DiskCache) trimSubdir(subdir string, cutoff time.Time) {
+	// Read all directory entries from subdir before removing
+	// any files, in case removing files invalidates the file offset
+	// in the directory scan. Also, ignore error from f.Readdirnames,
+	// because we don't care about reporting the error and we still
+	// want to process any entries found before the error.
+	f, err := os.Open(subdir)
+	if err != nil {
+		return
+	}
+	names, _ := f.Readdirnames(-1)
+	f.Close()
+
+	for _, name := range names {
+		// Remove only cache entries (xxxx-a and xxxx-d).
+		if !strings.HasSuffix(name, "-a") && !strings.HasSuffix(name, "-d") {
+			continue
+		}
+		entry := filepath.Join(subdir, name)
+		info, err := os.Stat(entry)
+		if err == nil && info.ModTime().Before(cutoff) {
+			os.Remove(entry)
+		}
+	}
+}
+
+// putIndexEntry adds an entry to the cache recording that executing the action
+// with the given id produces an output with the given output id (hash) and size.
+func (c *DiskCache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify bool) error {
+	// Note: We expect that for one reason or another it may happen
+	// that repeating an action produces a different output hash
+	// (for example, if the output contains a time stamp or temp dir name).
+	// While not ideal, this is also not a correctness problem, so we
+	// don't make a big deal about it. In particular, we leave the action
+	// cache entries writable specifically so that they can be overwritten.
+	//
+	// Setting GODEBUG=gocacheverify=1 does make a big deal:
+	// in verify mode we are double-checking that the cache entries
+	// are entirely reproducible. As just noted, this may be unrealistic
+	// in some cases but the check is also useful for shaking out real bugs.
+	entry := fmt.Sprintf("v1 %x %x %20d %20d\n", id, out, size, time.Now().UnixNano())
+	if verify && allowVerify {
+		old, err := c.get(id)
+		if err == nil && (old.OutputID != out || old.Size != size) {
+			// panic to show stack trace, so we can see what code is generating this cache entry.
+			msg := fmt.Sprintf("go: internal cache error: cache verify failed: id=%x changed:<<<\n%s\n>>>\nold: %x %d\nnew: %x %d", id, reverseHash(id), out, size, old.OutputID, old.Size)
+			panic(msg)
+		}
+	}
+	file := c.fileName(id, "a")
+
+	// Copy file to cache directory.
+	mode := os.O_WRONLY | os.O_CREATE
+	f, err := os.OpenFile(file, mode, 0666)
+	if err != nil {
+		return err
+	}
+	_, err = f.WriteString(entry)
+	if err == nil {
+		// Truncate the file only *after* writing it.
+		// (This should be a no-op, but truncate just in case of previous corruption.)
+		//
+		// This differs from ioutil.WriteFile, which truncates to 0 *before* writing
+		// via os.O_TRUNC. Truncating only after writing ensures that a second write
+		// of the same content to the same file is idempotent, and does not — even
+		// temporarily! — undo the effect of the first write.
+		err = f.Truncate(int64(len(entry)))
+	}
+	if closeErr := f.Close(); err == nil {
+		err = closeErr
+	}
+	if err != nil {
+		// TODO(bcmills): This Remove potentially races with another go command writing to file.
+		// Can we eliminate it?
+		os.Remove(file)
+		return err
+	}
+	os.Chtimes(file, c.now(), c.now()) // mainly for tests
+
+	return nil
+}
+
+// Put stores the given output in the cache as the output for the action ID.
+// It may read file twice. The content of file must not change between the two passes.
+func (c *DiskCache) Put(id ActionID, file io.ReadSeeker) (OutputID, int64, error) {
+	// Unwrap noVerifyReadSeeker to determine verify mode.
+	allowVerify := true
+	if nv, ok := file.(noVerifyReadSeeker); ok {
+		allowVerify = false
+		file = nv.ReadSeeker
+	}
+	return c.put(id, file, allowVerify)
+}
+
+// noVerifyReadSeeker is an io.ReadSeeker wrapper that indicates that
+// the Put should skip GODEBUG=gocacheverify=1 verification.
+type noVerifyReadSeeker struct {
+	io.ReadSeeker
+}
+
+// PutNoVerify is like Cache.Put but disables the verify check
+// when GODEBUG=gocacheverify=1 is set.
+// It is meant for data that is OK to cache but that we expect to vary slightly
+// from run to run, like test output containing times and the like.
+func PutNoVerify(c Cache, id ActionID, file io.ReadSeeker) (OutputID, int64, error) {
+	return c.Put(id, noVerifyReadSeeker{file})
+}
+
+func (c *DiskCache) put(id ActionID, file io.ReadSeeker, allowVerify bool) (OutputID, int64, error) {
+	// Compute output ID.
+	h := sha256.New()
+	if _, err := file.Seek(0, 0); err != nil {
+		return OutputID{}, 0, err
+	}
+	size, err := io.Copy(h, file)
+	if err != nil {
+		return OutputID{}, 0, err
+	}
+	var out OutputID
+	h.Sum(out[:0])
+
+	// Copy to cached output file (if not already present).
+	if err := c.copyFile(file, out, size); err != nil {
+		return out, size, err
+	}
+
+	// Add to cache index.
+	return out, size, c.putIndexEntry(id, out, size, allowVerify)
+}
+
+// PutBytes stores the given bytes in the cache as the output for the action ID.
+func PutBytes(c Cache, id ActionID, data []byte) error {
+	_, _, err := c.Put(id, bytes.NewReader(data))
+	return err
+}
+
+// copyFile copies file into the cache, expecting it to have the given
+// output ID and size, if that file is not present already.
+func (c *DiskCache) copyFile(file io.ReadSeeker, out OutputID, size int64) error {
+	name := c.fileName(out, "d")
+	info, err := os.Stat(name)
+	if err == nil && info.Size() == size {
+		// Check hash.
+		if f, err := os.Open(name); err == nil {
+			h := sha256.New()
+			io.Copy(h, f)
+			f.Close()
+			var out2 OutputID
+			h.Sum(out2[:0])
+			if out == out2 {
+				return nil
+			}
+		}
+		// Hash did not match. Fall through and rewrite file.
+	}
+
+	// Copy file to cache directory.
+	mode := os.O_RDWR | os.O_CREATE
+	if err == nil && info.Size() > size { // shouldn't happen but fix in case
+		mode |= os.O_TRUNC
+	}
+	f, err := os.OpenFile(name, mode, 0666)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+	if size == 0 {
+		// File now exists with correct size.
+		// Only one possible zero-length file, so contents are OK too.
+		// Early return here makes sure there's a "last byte" for code below.
+		return nil
+	}
+
+	// From here on, if any of the I/O writing the file fails,
+	// we make a best-effort attempt to truncate the file f
+	// before returning, to avoid leaving bad bytes in the file.
+
+	// Copy file to f, but also into h to double-check hash.
+	if _, err := file.Seek(0, 0); err != nil {
+		f.Truncate(0)
+		return err
+	}
+	h := sha256.New()
+	w := io.MultiWriter(f, h)
+	if _, err := io.CopyN(w, file, size-1); err != nil {
+		f.Truncate(0)
+		return err
+	}
+	// Check last byte before writing it; writing it will make the size match
+	// what other processes expect to find and might cause them to start
+	// using the file.
+	buf := make([]byte, 1)
+	if _, err := file.Read(buf); err != nil {
+		f.Truncate(0)
+		return err
+	}
+	h.Write(buf)
+	sum := h.Sum(nil)
+	if !bytes.Equal(sum, out[:]) {
+		f.Truncate(0)
+		return fmt.Errorf("file content changed underfoot")
+	}
+
+	// Commit cache file entry.
+	if _, err := f.Write(buf); err != nil {
+		f.Truncate(0)
+		return err
+	}
+	if err := f.Close(); err != nil {
+		// Data might not have been written,
+		// but file may look like it is the right size.
+		// To be extra careful, remove cached file.
+		os.Remove(name)
+		return err
+	}
+	os.Chtimes(name, c.now(), c.now()) // mainly for tests
+
+	return nil
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/cache/cacheprog/cacheprog.go b/vendor/honnef.co/go/tools/lintcmd/cache/cacheprog/cacheprog.go
new file mode 100644
index 0000000..6d7e4e7
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/cache/cacheprog/cacheprog.go
@@ -0,0 +1,111 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package cacheprog defines the protocol for a GOCACHEPROG program.
+//
+// This is a port of cmd/go/internal/cacheprog from the Go standard library,
+// adapted for use with staticcheck.
+package cacheprog
+
+import (
+	"io"
+	"time"
+)
+
+// Cmd is a command that can be issued to a child process.
+//
+// If the interface needs to grow, new commands or new versioned commands like
+// "get2" can be added in the future. The initial [Response] from the child
+// process indicates which commands it supports.
+type Cmd string
+
+const (
+	// CmdPut tells the cache program to store an object in the cache.
+	//
+	// [Request.ActionID] is the cache key of this object. The cache should
+	// store [Request.OutputID] and [Request.Body] under this key for a
+	// later "get" request. It must also store the Body in a file in the local
+	// file system and return the path to that file in [Response.DiskPath],
+	// which must exist at least until a "close" request.
+	CmdPut = Cmd("put")
+
+	// CmdGet tells the cache program to retrieve an object from the cache.
+	//
+	// [Request.ActionID] specifies the key of the object to get. If the
+	// cache does not contain this object, it should set [Response.Miss] to
+	// true. Otherwise, it should populate the fields of [Response],
+	// including setting [Response.OutputID] to the OutputID of the original
+	// "put" request and [Response.DiskPath] to the path of a local file
+	// containing the Body of the original "put" request. That file must
+	// continue to exist at least until a "close" request.
+	CmdGet = Cmd("get")
+
+	// CmdClose requests that the cache program exit gracefully.
+	//
+	// The cache program should reply to this request and then exit
+	// (thus closing its stdout).
+	CmdClose = Cmd("close")
+)
+
+// Request is the JSON-encoded message that's sent from staticcheck to
+// the GOCACHEPROG child process over stdin. Each JSON object is on
+// its own line. A Request of type "put" with BodySize > 0 will be followed by
+// a line containing a base64-encoded JSON string literal of the body.
+type Request struct {
+	// ID is a unique number per process across all requests.
+	// It must be echoed in the Response from the child.
+	ID int64
+
+	// Command is the type of request.
+	// Only commands that were declared as supported by the child will be sent.
+	Command Cmd
+
+	// ActionID is the cache key for "put" and "get" requests.
+	ActionID []byte `json:",omitempty"` // or nil if not used
+
+	// OutputID is stored with the body for "put" requests.
+	OutputID []byte `json:",omitempty"` // or nil if not used
+
+	// Body is the body for "put" requests. It's sent after the JSON object
+	// as a base64-encoded JSON string when BodySize is non-zero.
+	Body io.Reader `json:"-"`
+
+	// BodySize is the number of bytes of Body. If zero, the body isn't written.
+	BodySize int64 `json:",omitempty"`
+}
+
+// Response is the JSON response from the child process to staticcheck.
+//
+// With the exception of the first protocol message that the child writes to its
+// stdout with ID==0 and KnownCommands populated, these are only sent in
+// response to a Request from staticcheck.
+//
+// Responses can be sent in any order. The ID must match the request they're
+// replying to.
+type Response struct {
+	ID  int64  // that corresponds to Request; they can be answered out of order
+	Err string `json:",omitempty"` // if non-empty, the error
+
+	// KnownCommands is included in the first message that cache helper program
+	// writes to stdout on startup (with ID==0). It includes the
+	// Request.Command types that are supported by the program.
+	//
+	// This lets the protocol be extended gracefully over time (adding
+	// "get2", etc), or fail gracefully when needed. It also lets us
+	// verify the program wants to be a cache helper.
+	KnownCommands []Cmd `json:",omitempty"`
+
+	// For "get" requests.
+
+	Miss     bool       `json:",omitempty"` // cache miss
+	OutputID []byte     `json:",omitempty"` // the OutputID stored with the body
+	Size     int64      `json:",omitempty"` // body size in bytes
+	Time     *time.Time `json:",omitempty"` // when the object was put in the cache (optional; used for cache expiration)
+
+	// For "get" and "put" requests.
+
+	// DiskPath is the absolute path on disk of the body corresponding to a
+	// "get" (on cache hit) or "put" request's ActionID.
+	DiskPath string `json:",omitempty"`
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/cache/default.go b/vendor/honnef.co/go/tools/lintcmd/cache/default.go
new file mode 100644
index 0000000..dad28b4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/cache/default.go
@@ -0,0 +1,89 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cache
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"path/filepath"
+	"sync"
+)
+
+// Default returns the default cache to use.
+func Default() (Cache, error) {
+	defaultOnce.Do(initDefaultCache)
+	return defaultCache, defaultDirErr
+}
+
+var (
+	defaultOnce  sync.Once
+	defaultCache Cache
+)
+
+// cacheREADME is a message stored in a README in the cache directory.
+// Because the cache lives outside the normal Go trees, we leave the
+// README as a courtesy to explain where it came from.
+const cacheREADME = `This directory holds cached build artifacts from staticcheck.
+`
+
+// initDefaultCache does the work of finding the default cache
+// the first time Default is called.
+func initDefaultCache() {
+	dir := DefaultDir()
+	if err := os.MkdirAll(dir, 0777); err != nil {
+		log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err)
+	}
+	if _, err := os.Stat(filepath.Join(dir, "README")); err != nil {
+		// Best effort.
+		os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666)
+	}
+
+	c, err := Open(dir)
+	if err != nil {
+		log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err)
+	}
+
+	if prog := os.Getenv("GOCACHEPROG"); prog != "" {
+		defaultCache = startCacheProg(prog)
+	} else {
+		defaultCache = c
+	}
+}
+
+var (
+	defaultDirOnce sync.Once
+	defaultDir     string
+	defaultDirErr  error
+)
+
+// DefaultDir returns the effective STATICCHECK_CACHE setting.
+func DefaultDir() string {
+	// Save the result of the first call to DefaultDir for later use in
+	// initDefaultCache. cmd/go/main.go explicitly sets GOCACHE so that
+	// subprocesses will inherit it, but that means initDefaultCache can't
+	// otherwise distinguish between an explicit "off" and a UserCacheDir error.
+
+	defaultDirOnce.Do(func() {
+		defaultDir = os.Getenv("STATICCHECK_CACHE")
+		if filepath.IsAbs(defaultDir) {
+			return
+		}
+		if defaultDir != "" {
+			defaultDirErr = fmt.Errorf("STATICCHECK_CACHE is not an absolute path")
+			return
+		}
+
+		// Compute default location.
+		dir, err := os.UserCacheDir()
+		if err != nil {
+			defaultDirErr = fmt.Errorf("STATICCHECK_CACHE is not defined and %v", err)
+			return
+		}
+		defaultDir = filepath.Join(dir, "staticcheck")
+	})
+
+	return defaultDir
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/cache/hash.go b/vendor/honnef.co/go/tools/lintcmd/cache/hash.go
new file mode 100644
index 0000000..75c70ff
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/cache/hash.go
@@ -0,0 +1,176 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cache
+
+import (
+	"bytes"
+	"crypto/sha256"
+	"fmt"
+	"hash"
+	"io"
+	"os"
+	"sync"
+)
+
+var debugHash = false // set when GODEBUG=gocachehash=1
+
+// HashSize is the number of bytes in a hash.
+const HashSize = 32
+
+// hashSalt is an optional salt prepended to every hash created by NewHash.
+// When set (via SetSalt), it is typically the build ID of the current binary,
+// so that cache entries are invalidated when the binary changes.
+var hashSalt []byte
+
+// A Hash provides access to the canonical hash function used to index the cache.
+// The current implementation uses salted SHA256, but clients must not assume this.
+type Hash struct {
+	h    hash.Hash
+	name string        // for debugging
+	buf  *bytes.Buffer // for verify
+}
+
+// Subkey returns an action ID corresponding to mixing a parent
+// action ID with a string description of the subkey.
+func Subkey(parent ActionID, desc string) ActionID {
+	h := sha256.New()
+	h.Write([]byte("subkey:"))
+	h.Write(parent[:])
+	h.Write([]byte(desc))
+	var out ActionID
+	h.Sum(out[:0])
+	if debugHash {
+		fmt.Fprintf(os.Stderr, "HASH subkey %x %q = %x\n", parent, desc, out)
+	}
+	if verify {
+		hashDebug.Lock()
+		hashDebug.m[out] = fmt.Sprintf("subkey %x %q", parent, desc)
+		hashDebug.Unlock()
+	}
+	return out
+}
+
+// SetSalt sets an optional salt that is prepended to every hash created by
+// NewHash. This is typically the build ID of the current binary, ensuring that
+// cache entries are invalidated when the binary changes. If not called,
+// NewHash operates without a salt.
+func SetSalt(b []byte) {
+	hashSalt = b
+}
+
+// NewHash returns a new Hash.
+// The caller is expected to Write data to it and then call Sum.
+func NewHash(name string) *Hash {
+	h := &Hash{h: sha256.New(), name: name}
+	if debugHash {
+		fmt.Fprintf(os.Stderr, "HASH[%s]\n", h.name)
+	}
+	h.Write(hashSalt)
+	if verify {
+		h.buf = new(bytes.Buffer)
+	}
+	return h
+}
+
+// Write writes data to the running hash.
+func (h *Hash) Write(b []byte) (int, error) {
+	if debugHash {
+		fmt.Fprintf(os.Stderr, "HASH[%s]: %q\n", h.name, b)
+	}
+	if h.buf != nil {
+		h.buf.Write(b)
+	}
+	return h.h.Write(b)
+}
+
+// Sum returns the hash of the data written previously.
+func (h *Hash) Sum() [HashSize]byte {
+	var out [HashSize]byte
+	h.h.Sum(out[:0])
+	if debugHash {
+		fmt.Fprintf(os.Stderr, "HASH[%s]: %x\n", h.name, out)
+	}
+	if h.buf != nil {
+		hashDebug.Lock()
+		if hashDebug.m == nil {
+			hashDebug.m = make(map[[HashSize]byte]string)
+		}
+		hashDebug.m[out] = h.buf.String()
+		hashDebug.Unlock()
+	}
+	return out
+}
+
+// In GODEBUG=gocacheverify=1 mode,
+// hashDebug holds the input to every computed hash ID,
+// so that we can work backward from the ID involved in a
+// cache entry mismatch to a description of what should be there.
+var hashDebug struct {
+	sync.Mutex
+	m map[[HashSize]byte]string
+}
+
+// reverseHash returns the input used to compute the hash id.
+func reverseHash(id [HashSize]byte) string {
+	hashDebug.Lock()
+	s := hashDebug.m[id]
+	hashDebug.Unlock()
+	return s
+}
+
+var hashFileCache struct {
+	sync.Mutex
+	m map[string][HashSize]byte
+}
+
+// FileHash returns the hash of the named file.
+// It caches repeated lookups for a given file,
+// and the cache entry for a file can be initialized
+// using SetFileHash.
+// The hash used by FileHash is not the same as
+// the hash used by NewHash.
+func FileHash(file string) ([HashSize]byte, error) {
+	hashFileCache.Lock()
+	out, ok := hashFileCache.m[file]
+	hashFileCache.Unlock()
+
+	if ok {
+		return out, nil
+	}
+
+	h := sha256.New()
+	f, err := os.Open(file)
+	if err != nil {
+		if debugHash {
+			fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err)
+		}
+		return [HashSize]byte{}, err
+	}
+	_, err = io.Copy(h, f)
+	f.Close()
+	if err != nil {
+		if debugHash {
+			fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err)
+		}
+		return [HashSize]byte{}, err
+	}
+	h.Sum(out[:0])
+	if debugHash {
+		fmt.Fprintf(os.Stderr, "HASH %s: %x\n", file, out)
+	}
+
+	SetFileHash(file, out)
+	return out, nil
+}
+
+// SetFileHash sets the hash returned by FileHash for file.
+func SetFileHash(file string, sum [HashSize]byte) {
+	hashFileCache.Lock()
+	if hashFileCache.m == nil {
+		hashFileCache.m = make(map[string][HashSize]byte)
+	}
+	hashFileCache.m[file] = sum
+	hashFileCache.Unlock()
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/cache/prog.go b/vendor/honnef.co/go/tools/lintcmd/cache/prog.go
new file mode 100644
index 0000000..3c134cb
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/cache/prog.go
@@ -0,0 +1,353 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cache
+
+import (
+	"bufio"
+	"context"
+	"crypto/sha256"
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"os/exec"
+	"strings"
+	"sync"
+	"sync/atomic"
+	"time"
+
+	"honnef.co/go/tools/lintcmd/cache/cacheprog"
+)
+
+// ProgCache implements Cache via JSON messages over stdin/stdout to a child
+// helper process which can then implement whatever caching policy/mechanism it
+// wants.
+//
+// See https://github.com/golang/go/issues/59719
+type ProgCache struct {
+	cmd    *exec.Cmd
+	stdout io.ReadCloser  // from the child process
+	stdin  io.WriteCloser // to the child process
+	bw     *bufio.Writer  // to stdin
+	jenc   *json.Encoder  // to bw
+
+	// can are the commands that the child process declared that it supports.
+	// This is effectively the versioning mechanism.
+	can map[cacheprog.Cmd]bool
+
+	closing      atomic.Bool
+	ctx          context.Context    // valid until Close via ctxCancel
+	ctxCancel    context.CancelFunc // called on Close
+	readLoopDone chan struct{}      // closed when readLoop returns
+
+	mu         sync.Mutex // guards following fields
+	nextID     int64
+	inFlight   map[int64]chan<- *cacheprog.Response
+	outputFile map[OutputID]string // object => abs path on disk
+
+	// writeMu serializes writing to the child process.
+	// It must never be held at the same time as mu.
+	writeMu sync.Mutex
+}
+
+// startCacheProg starts the prog binary (with optional space-separated flags)
+// and returns a Cache implementation that talks to it.
+//
+// It blocks a few seconds to wait for the child process to successfully start
+// and advertise its capabilities.
+func startCacheProg(progAndArgs string) Cache {
+	args := strings.Fields(progAndArgs)
+	var prog string
+	if len(args) > 0 {
+		prog = args[0]
+		args = args[1:]
+	}
+
+	ctx, ctxCancel := context.WithCancel(context.Background())
+
+	cmd := exec.CommandContext(ctx, prog, args...)
+	out, err := cmd.StdoutPipe()
+	if err != nil {
+		log.Fatalf("StdoutPipe to GOCACHEPROG: %v", err)
+	}
+	in, err := cmd.StdinPipe()
+	if err != nil {
+		log.Fatalf("StdinPipe to GOCACHEPROG: %v", err)
+	}
+	cmd.Stderr = os.Stderr
+	// On close, we cancel the context. Rather than killing the helper,
+	// close its stdin.
+	cmd.Cancel = in.Close
+
+	if err := cmd.Start(); err != nil {
+		log.Fatalf("error starting GOCACHEPROG program %q: %v", prog, err)
+	}
+
+	pc := &ProgCache{
+		ctx:          ctx,
+		ctxCancel:    ctxCancel,
+		cmd:          cmd,
+		stdout:       out,
+		stdin:        in,
+		bw:           bufio.NewWriter(in),
+		inFlight:     make(map[int64]chan<- *cacheprog.Response),
+		outputFile:   make(map[OutputID]string),
+		readLoopDone: make(chan struct{}),
+	}
+
+	// Register our interest in the initial protocol message from the child to
+	// us, saying what it can do.
+	capResc := make(chan *cacheprog.Response, 1)
+	pc.inFlight[0] = capResc
+
+	pc.jenc = json.NewEncoder(pc.bw)
+	go pc.readLoop(pc.readLoopDone)
+
+	// Give the child process a few seconds to report its capabilities. This
+	// should be instant and not require any slow work by the program.
+	timer := time.NewTicker(5 * time.Second)
+	defer timer.Stop()
+	for {
+		select {
+		case <-timer.C:
+			log.Printf("# still waiting for GOCACHEPROG %v ...", prog)
+		case capRes := <-capResc:
+			can := map[cacheprog.Cmd]bool{}
+			for _, cmd := range capRes.KnownCommands {
+				can[cmd] = true
+			}
+			if len(can) == 0 {
+				log.Fatalf("GOCACHEPROG %v declared no supported commands", prog)
+			}
+			pc.can = can
+			return pc
+		}
+	}
+}
+
+func (c *ProgCache) readLoop(readLoopDone chan<- struct{}) {
+	defer close(readLoopDone)
+	jd := json.NewDecoder(c.stdout)
+	for {
+		res := new(cacheprog.Response)
+		if err := jd.Decode(res); err != nil {
+			if c.closing.Load() {
+				c.mu.Lock()
+				for _, ch := range c.inFlight {
+					close(ch)
+				}
+				c.inFlight = nil
+				c.mu.Unlock()
+				return // quietly
+			}
+			if err == io.EOF {
+				c.mu.Lock()
+				inFlight := len(c.inFlight)
+				c.mu.Unlock()
+				log.Fatalf("GOCACHEPROG exited pre-Close with %v pending requests", inFlight)
+			}
+			log.Fatalf("error reading JSON from GOCACHEPROG: %v", err)
+		}
+		c.mu.Lock()
+		ch, ok := c.inFlight[res.ID]
+		delete(c.inFlight, res.ID)
+		c.mu.Unlock()
+		if ok {
+			ch <- res
+		} else {
+			log.Fatalf("GOCACHEPROG sent response for unknown request ID %v", res.ID)
+		}
+	}
+}
+
+var errCacheprogClosed = errors.New("GOCACHEPROG program closed unexpectedly")
+
+func (c *ProgCache) send(ctx context.Context, req *cacheprog.Request) (*cacheprog.Response, error) {
+	resc := make(chan *cacheprog.Response, 1)
+	if err := c.writeToChild(req, resc); err != nil {
+		return nil, err
+	}
+	select {
+	case res := <-resc:
+		if res == nil {
+			return nil, errCacheprogClosed
+		}
+		if res.Err != "" {
+			return nil, errors.New(res.Err)
+		}
+		return res, nil
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	}
+}
+
+func (c *ProgCache) writeToChild(req *cacheprog.Request, resc chan<- *cacheprog.Response) (err error) {
+	c.mu.Lock()
+	if c.inFlight == nil {
+		c.mu.Unlock()
+		return errCacheprogClosed
+	}
+	c.nextID++
+	req.ID = c.nextID
+	c.inFlight[req.ID] = resc
+	c.mu.Unlock()
+
+	defer func() {
+		if err != nil {
+			c.mu.Lock()
+			if c.inFlight != nil {
+				delete(c.inFlight, req.ID)
+			}
+			c.mu.Unlock()
+		}
+	}()
+
+	c.writeMu.Lock()
+	defer c.writeMu.Unlock()
+
+	if err := c.jenc.Encode(req); err != nil {
+		return err
+	}
+	if err := c.bw.WriteByte('\n'); err != nil {
+		return err
+	}
+	if req.Body != nil && req.BodySize > 0 {
+		if err := c.bw.WriteByte('"'); err != nil {
+			return err
+		}
+		e := base64.NewEncoder(base64.StdEncoding, c.bw)
+		wrote, err := io.Copy(e, req.Body)
+		if err != nil {
+			return err
+		}
+		if err := e.Close(); err != nil {
+			return nil
+		}
+		if wrote != req.BodySize {
+			return fmt.Errorf("short write writing body to GOCACHEPROG for action %x, output %x: wrote %v; expected %v",
+				req.ActionID, req.OutputID, wrote, req.BodySize)
+		}
+		if _, err := c.bw.WriteString("\"\n"); err != nil {
+			return err
+		}
+	}
+	if err := c.bw.Flush(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (c *ProgCache) Get(a ActionID) (Entry, error) {
+	if !c.can[cacheprog.CmdGet] {
+		// They can't do a "get". Maybe they're a write-only cache.
+		return Entry{}, &entryNotFoundError{}
+	}
+	res, err := c.send(c.ctx, &cacheprog.Request{
+		Command:  cacheprog.CmdGet,
+		ActionID: a[:],
+	})
+	if err != nil {
+		return Entry{}, err
+	}
+	if res.Miss {
+		return Entry{}, &entryNotFoundError{}
+	}
+	e := Entry{
+		Size: res.Size,
+	}
+	if res.Time != nil {
+		e.Time = *res.Time
+	} else {
+		e.Time = time.Now()
+	}
+	if res.DiskPath == "" {
+		return Entry{}, &entryNotFoundError{errors.New("GOCACHEPROG didn't populate DiskPath on get hit")}
+	}
+	if copy(e.OutputID[:], res.OutputID) != len(res.OutputID) {
+		return Entry{}, &entryNotFoundError{errors.New("incomplete ProgResponse OutputID")}
+	}
+	c.noteOutputFile(e.OutputID, res.DiskPath)
+	return e, nil
+}
+
+func (c *ProgCache) noteOutputFile(o OutputID, diskPath string) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	c.outputFile[o] = diskPath
+}
+
+func (c *ProgCache) OutputFile(o OutputID) string {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	return c.outputFile[o]
+}
+
+func (c *ProgCache) Put(a ActionID, file io.ReadSeeker) (_ OutputID, size int64, _ error) {
+	// Unwrap noVerifyReadSeeker; ProgCache doesn't use the verify mode.
+	if nv, ok := file.(noVerifyReadSeeker); ok {
+		file = nv.ReadSeeker
+	}
+
+	// Compute output ID.
+	h := sha256.New()
+	if _, err := file.Seek(0, 0); err != nil {
+		return OutputID{}, 0, err
+	}
+	size, err := io.Copy(h, file)
+	if err != nil {
+		return OutputID{}, 0, err
+	}
+	var out OutputID
+	h.Sum(out[:0])
+
+	if _, err := file.Seek(0, 0); err != nil {
+		return OutputID{}, 0, err
+	}
+
+	if !c.can[cacheprog.CmdPut] {
+		// Child is a read-only cache. Do nothing.
+		return out, size, nil
+	}
+
+	res, err := c.send(c.ctx, &cacheprog.Request{
+		Command:  cacheprog.CmdPut,
+		ActionID: a[:],
+		OutputID: out[:],
+		Body:     file,
+		BodySize: size,
+	})
+	if err != nil {
+		return OutputID{}, 0, err
+	}
+	if res.DiskPath == "" {
+		return OutputID{}, 0, errors.New("GOCACHEPROG didn't return DiskPath in put response")
+	}
+	c.noteOutputFile(out, res.DiskPath)
+	return out, size, err
+}
+
+func (c *ProgCache) Close() error {
+	c.closing.Store(true)
+	var err error
+
+	// First write a "close" message to the child so it can exit nicely
+	// and clean up if it wants. Only after that exchange do we cancel
+	// the context that kills the process.
+	if c.can[cacheprog.CmdClose] {
+		_, err = c.send(c.ctx, &cacheprog.Request{Command: cacheprog.CmdClose})
+		if errors.Is(err, errCacheprogClosed) {
+			// Allow the child to quit without responding to close.
+			err = nil
+		}
+	}
+	// Cancel the context, which will close the helper's stdin.
+	c.ctxCancel()
+	// Wait until the helper closes its stdout.
+	<-c.readLoopDone
+	return err
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/cmd.go b/vendor/honnef.co/go/tools/lintcmd/cmd.go
new file mode 100644
index 0000000..a6bda8f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/cmd.go
@@ -0,0 +1,831 @@
+// Package lintcmd implements the frontend of an analysis runner.
+// It serves as the entry-point for the staticcheck command, and can also be used to implement custom linters that behave like staticcheck.
+package lintcmd
+
+import (
+	"bufio"
+	"encoding/gob"
+	"flag"
+	"fmt"
+	"go/token"
+	stdversion "go/version"
+	"io"
+	"log"
+	"maps"
+	"os"
+	"path/filepath"
+	"reflect"
+	"runtime"
+	"runtime/pprof"
+	"runtime/trace"
+	"slices"
+	"sort"
+	"strings"
+	"sync"
+	"time"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/config"
+	"honnef.co/go/tools/go/loader"
+	"honnef.co/go/tools/lintcmd/version"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/buildutil"
+)
+
+type buildConfig struct {
+	Name  string
+	Envs  []string
+	Flags []string
+}
+
+type caseFoldedString struct {
+	s string
+}
+
+func makeCaseFoldedString(s string) caseFoldedString {
+	return caseFoldedString{strings.ToLower(s)}
+}
+
+func makeCaseFoldedStrings(ss []string) []caseFoldedString {
+	out := make([]caseFoldedString, len(ss))
+	for i, s := range ss {
+		out[i] = makeCaseFoldedString(s)
+	}
+	return out
+}
+
+func (cs caseFoldedString) String() string {
+	return cs.s
+}
+
+func (cs caseFoldedString) Index(idx int) byte {
+	return cs.s[idx]
+}
+
+func (cs caseFoldedString) Slice(start, end int) caseFoldedString {
+	if end == -1 {
+		end = len(cs.s)
+	}
+	return caseFoldedString{cs.s[start:end]}
+}
+
+func (cs caseFoldedString) Length() int {
+	return len(cs.s)
+}
+
+// Command represents a linter command line tool.
+type Command struct {
+	name           string
+	analyzers      map[caseFoldedString]*lint.Analyzer
+	version        string
+	machineVersion string
+
+	flags struct {
+		fs *flag.FlagSet
+
+		tags        string
+		tests       bool
+		showIgnored bool
+		formatter   string
+
+		// mutually exclusive mode flags
+		explain      string
+		printVersion bool
+		listChecks   bool
+		merge        bool
+
+		matrix bool
+
+		debugCpuprofile       string
+		debugMemprofile       string
+		debugVersion          bool
+		debugNoCompileErrors  bool
+		debugMeasureAnalyzers string
+		debugTrace            string
+
+		checks    list
+		fail      list
+		goVersion versionFlag
+	}
+}
+
+// NewCommand returns a new Command.
+func NewCommand(name string) *Command {
+	cmd := &Command{
+		name:           name,
+		analyzers:      map[caseFoldedString]*lint.Analyzer{},
+		version:        "devel",
+		machineVersion: "devel",
+	}
+	cmd.initFlagSet(name)
+	return cmd
+}
+
+// SetVersion sets the command's version.
+// It is divided into a human part and a machine part.
+// For example, Staticcheck 2020.2.1 had the human version "2020.2.1" and the machine version "v0.1.1".
+// If you only use Semver, you can set both parts to the same value.
+//
+// Calling this method is optional. Both versions default to "devel", and we'll attempt to deduce more version information from the Go module.
+func (cmd *Command) SetVersion(human, machine string) {
+	cmd.version = human
+	cmd.machineVersion = machine
+}
+
+// FlagSet returns the command's flag set.
+// This can be used to add additional command line arguments.
+func (cmd *Command) FlagSet() *flag.FlagSet {
+	return cmd.flags.fs
+}
+
+// AddAnalyzers adds analyzers to the command.
+// These are lint.Analyzer analyzers, which wrap analysis.Analyzer analyzers, bundling them with structured documentation.
+//
+// To add analysis.Analyzer analyzers without providing structured documentation, use AddBareAnalyzers.
+func (cmd *Command) AddAnalyzers(as ...*lint.Analyzer) {
+	for _, a := range as {
+		cmd.analyzers[makeCaseFoldedString(a.Analyzer.Name)] = a
+	}
+}
+
+// AddBareAnalyzers adds bare analyzers to the command.
+func (cmd *Command) AddBareAnalyzers(as ...*analysis.Analyzer) {
+	for _, a := range as {
+		var title, text string
+		if idx := strings.Index(a.Doc, "\n\n"); idx > -1 {
+			title = a.Doc[:idx]
+			text = a.Doc[idx+2:]
+		}
+
+		doc := &lint.RawDocumentation{
+			Title:    title,
+			Text:     text,
+			Severity: lint.SeverityWarning,
+		}
+
+		cmd.analyzers[makeCaseFoldedString(a.Name)] = &lint.Analyzer{
+			Doc:      doc,
+			Analyzer: a,
+		}
+	}
+}
+
+func (cmd *Command) initFlagSet(name string) {
+	flags := flag.NewFlagSet("", flag.ExitOnError)
+	cmd.flags.fs = flags
+	flags.Usage = usage(name, flags)
+
+	flags.StringVar(&cmd.flags.tags, "tags", "", "List of `build tags`")
+	flags.BoolVar(&cmd.flags.tests, "tests", true, "Include tests")
+	flags.BoolVar(&cmd.flags.printVersion, "version", false, "Print version and exit")
+	flags.BoolVar(&cmd.flags.showIgnored, "show-ignored", false, "Don't filter ignored diagnostics")
+	flags.StringVar(&cmd.flags.formatter, "f", "text", "Output `format` (valid choices are 'stylish', 'text' and 'json')")
+	flags.StringVar(&cmd.flags.explain, "explain", "", "Print description of `check`")
+	flags.BoolVar(&cmd.flags.listChecks, "list-checks", false, "List all available checks")
+	flags.BoolVar(&cmd.flags.merge, "merge", false, "Merge results of multiple Staticcheck runs")
+	flags.BoolVar(&cmd.flags.matrix, "matrix", false, "Read a build config matrix from stdin")
+
+	flags.StringVar(&cmd.flags.debugCpuprofile, "debug.cpuprofile", "", "Write CPU profile to `file`")
+	flags.StringVar(&cmd.flags.debugMemprofile, "debug.memprofile", "", "Write memory profile to `file`")
+	flags.BoolVar(&cmd.flags.debugVersion, "debug.version", false, "Print detailed version information about this program")
+	flags.BoolVar(&cmd.flags.debugNoCompileErrors, "debug.no-compile-errors", false, "Don't print compile errors")
+	flags.StringVar(&cmd.flags.debugMeasureAnalyzers, "debug.measure-analyzers", "", "Write analysis measurements to `file`. `file` will be opened for appending if it already exists.")
+	flags.StringVar(&cmd.flags.debugTrace, "debug.trace", "", "Write trace to `file`")
+
+	cmd.flags.checks = list{"inherit"}
+	cmd.flags.fail = list{"all"}
+	cmd.flags.goVersion = versionFlag("module")
+	flags.Var(&cmd.flags.checks, "checks", "Comma-separated list of `checks` to enable.")
+	flags.Var(&cmd.flags.fail, "fail", "Comma-separated list of `checks` that can cause a non-zero exit status.")
+	flags.Var(&cmd.flags.goVersion, "go", "Target Go `version` in the format '1.x', or the literal 'module' to use the module's Go version")
+}
+
+type list []string
+
+func (list *list) String() string {
+	return `"` + strings.Join(*list, ",") + `"`
+}
+
+func (list *list) Set(s string) error {
+	if s == "" {
+		*list = nil
+		return nil
+	}
+
+	elems := strings.Split(s, ",")
+	for i, elem := range elems {
+		elems[i] = strings.TrimSpace(elem)
+	}
+	*list = elems
+	return nil
+}
+
+type versionFlag string
+
+func (v *versionFlag) String() string {
+	return fmt.Sprintf("%q", string(*v))
+}
+
+func (v *versionFlag) Set(s string) error {
+	if s == "module" {
+		*v = "module"
+	} else {
+		orig := s
+		if !strings.HasPrefix(s, "go") {
+			s = "go" + s
+		}
+		if stdversion.IsValid(s) {
+			*v = versionFlag(s)
+		} else {
+			return fmt.Errorf("%q is not a valid Go version", orig)
+		}
+	}
+	return nil
+}
+
+// ParseFlags parses command line flags.
+// It must be called before calling Run.
+// After calling ParseFlags, the values of flags can be accessed.
+//
+// Example:
+//
+//	cmd.ParseFlags(os.Args[1:])
+func (cmd *Command) ParseFlags(args []string) {
+	cmd.flags.fs.Parse(args)
+}
+
+// diagnosticDescriptor represents the uniquely identifying information of diagnostics.
+type diagnosticDescriptor struct {
+	Position token.Position
+	End      token.Position
+	Category string
+	Message  string
+}
+
+func (diag diagnostic) descriptor() diagnosticDescriptor {
+	return diagnosticDescriptor{
+		Position: diag.Position,
+		End:      diag.End,
+		Category: diag.Category,
+		Message:  diag.Message,
+	}
+}
+
+type run struct {
+	checkedFiles map[string]struct{}
+	diagnostics  map[diagnosticDescriptor]diagnostic
+}
+
+func runFromLintResult(res lintResult) run {
+	out := run{
+		checkedFiles: map[string]struct{}{},
+		diagnostics:  map[diagnosticDescriptor]diagnostic{},
+	}
+
+	for _, cf := range res.CheckedFiles {
+		out.checkedFiles[cf] = struct{}{}
+	}
+	for _, diag := range res.Diagnostics {
+		out.diagnostics[diag.descriptor()] = diag
+	}
+	return out
+}
+
+func decodeGob(br io.ByteReader) ([]run, error) {
+	var runs []run
+	for {
+		var res lintResult
+		if err := gob.NewDecoder(br.(io.Reader)).Decode(&res); err != nil {
+			if err == io.EOF {
+				break
+			} else {
+				return nil, err
+			}
+		}
+		runs = append(runs, runFromLintResult(res))
+	}
+	return runs, nil
+}
+
+// Execute runs all registered analyzers and reports their findings.
+// The status code returned can be used for os.Exit(cmd.Execute()).
+func (cmd *Command) Execute() int {
+	// Set up profiling and tracing
+	if path := cmd.flags.debugCpuprofile; path != "" {
+		f, err := os.Create(path)
+		if err != nil {
+			log.Fatal(err)
+		}
+		pprof.StartCPUProfile(f)
+	}
+	if path := cmd.flags.debugTrace; path != "" {
+		f, err := os.Create(path)
+		if err != nil {
+			log.Fatal(err)
+		}
+		trace.Start(f)
+	}
+
+	// Update the default config's list of enabled checks
+	defaultChecks := []string{"all"}
+	for _, a := range cmd.analyzers {
+		if a.Doc.NonDefault {
+			defaultChecks = append(defaultChecks, "-"+a.Analyzer.Name)
+		}
+	}
+	config.DefaultConfig.Checks = defaultChecks
+
+	// Run the appropriate mode
+	var exit int
+	switch {
+	case cmd.flags.debugVersion:
+		exit = cmd.printDebugVersion()
+	case cmd.flags.listChecks:
+		exit = cmd.listChecks()
+	case cmd.flags.printVersion:
+		exit = cmd.printVersion()
+	case cmd.flags.explain != "":
+		exit = cmd.explain()
+	case cmd.flags.merge:
+		exit = cmd.merge()
+	default:
+		exit = cmd.lint()
+	}
+
+	// Stop profiling
+	if cmd.flags.debugCpuprofile != "" {
+		pprof.StopCPUProfile()
+	}
+	if path := cmd.flags.debugMemprofile; path != "" {
+		f, err := os.Create(path)
+		if err != nil {
+			panic(err)
+		}
+		runtime.GC()
+		pprof.WriteHeapProfile(f)
+	}
+	if cmd.flags.debugTrace != "" {
+		trace.Stop()
+	}
+
+	return exit
+}
+
+// Run runs all registered analyzers and reports their findings.
+// It always calls os.Exit and does not return.
+func (cmd *Command) Run() {
+	os.Exit(cmd.Execute())
+}
+
+func (cmd *Command) printDebugVersion() int {
+	version.Verbose(cmd.version, cmd.machineVersion)
+	return 0
+}
+
+func (cmd *Command) listChecks() int {
+	cs := slices.Collect(maps.Values(cmd.analyzers))
+	sort.Slice(cs, func(i, j int) bool {
+		return cs[i].Analyzer.Name < cs[j].Analyzer.Name
+	})
+	for _, c := range cs {
+		var title string
+		if c.Doc != nil {
+			title = c.Doc.Compile().Title
+		}
+		fmt.Printf("%s %s\n", c.Analyzer.Name, title)
+	}
+	return 0
+}
+
+func (cmd *Command) printVersion() int {
+	version.Print(cmd.version, cmd.machineVersion)
+	return 0
+}
+
+func (cmd *Command) explain() int {
+	explain := cmd.flags.explain
+	check, ok := cmd.analyzers[makeCaseFoldedString(explain)]
+	if !ok {
+		fmt.Fprintln(os.Stderr, "Couldn't find check", explain)
+		return 1
+	}
+	if check.Analyzer.Doc == "" {
+		fmt.Fprintln(os.Stderr, check.Analyzer.Name, "has no documentation")
+		return 1
+	}
+	fmt.Println(check.Doc.Compile())
+	fmt.Println("Online documentation\n    https://staticcheck.dev/docs/checks#" + check.Analyzer.Name)
+	return 0
+}
+
+func (cmd *Command) merge() int {
+	var runs []run
+	if len(cmd.flags.fs.Args()) == 0 {
+		var err error
+		runs, err = decodeGob(bufio.NewReader(os.Stdin))
+		if err != nil {
+			fmt.Fprintln(os.Stderr, fmt.Errorf("couldn't parse stdin: %s", err))
+			return 1
+		}
+	} else {
+		for _, path := range cmd.flags.fs.Args() {
+			someRuns, err := func(path string) ([]run, error) {
+				f, err := os.Open(path)
+				if err != nil {
+					return nil, err
+				}
+				defer f.Close()
+				br := bufio.NewReader(f)
+				return decodeGob(br)
+			}(path)
+			if err != nil {
+				fmt.Fprintln(os.Stderr, fmt.Errorf("couldn't parse file %s: %s", path, err))
+				return 1
+			}
+			runs = append(runs, someRuns...)
+		}
+	}
+
+	relevantDiagnostics := mergeRuns(runs)
+	cs := slices.Collect(maps.Values(cmd.analyzers))
+	return cmd.printDiagnostics(cs, relevantDiagnostics)
+}
+
+func (cmd *Command) lint() int {
+	switch cmd.flags.formatter {
+	case "text", "stylish", "json", "sarif", "binary", "null":
+	default:
+		fmt.Fprintf(os.Stderr, "unsupported output format %q\n", cmd.flags.formatter)
+		return 2
+	}
+
+	var bconfs []buildConfig
+	if cmd.flags.matrix {
+		if cmd.flags.tags != "" {
+			fmt.Fprintln(os.Stderr, "cannot use -matrix and -tags together")
+			return 2
+		}
+
+		var err error
+		bconfs, err = parseBuildConfigs(os.Stdin)
+		if err != nil {
+			if perr, ok := err.(parseBuildConfigError); ok {
+				fmt.Fprintf(os.Stderr, ":%d couldn't parse build matrix: %s\n", perr.line, perr.err)
+			} else {
+				fmt.Fprintln(os.Stderr, err)
+			}
+			return 2
+		}
+	} else {
+		bc := buildConfig{}
+		if cmd.flags.tags != "" {
+			// Validate that the tags argument is well-formed. go/packages
+			// doesn't detect malformed build flags and returns unhelpful
+			// errors.
+			tf := buildutil.TagsFlag{}
+			if err := tf.Set(cmd.flags.tags); err != nil {
+				fmt.Fprintln(os.Stderr, fmt.Errorf("invalid value %q for flag -tags: %s", cmd.flags.tags, err))
+				return 1
+			}
+
+			bc.Flags = []string{"-tags", cmd.flags.tags}
+		}
+		bconfs = append(bconfs, bc)
+	}
+
+	var measureAnalyzers func(analysis *analysis.Analyzer, pkg *loader.PackageSpec, d time.Duration)
+	if path := cmd.flags.debugMeasureAnalyzers; path != "" {
+		f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		mu := &sync.Mutex{}
+		measureAnalyzers = func(analysis *analysis.Analyzer, pkg *loader.PackageSpec, d time.Duration) {
+			mu.Lock()
+			defer mu.Unlock()
+			// FIXME(dh): print pkg.ID
+			if _, err := fmt.Fprintf(f, "%s\t%s\t%d\n", analysis.Name, pkg, d.Nanoseconds()); err != nil {
+				log.Println("error writing analysis measurements:", err)
+			}
+		}
+	}
+
+	var runs []run
+	cs := slices.Collect(maps.Values(cmd.analyzers))
+	opts := options{
+		analyzers: cs,
+		patterns:  cmd.flags.fs.Args(),
+		lintTests: cmd.flags.tests,
+		goVersion: string(cmd.flags.goVersion),
+		config: config.Config{
+			Checks: cmd.flags.checks,
+		},
+		printAnalyzerMeasurement: measureAnalyzers,
+	}
+	l, err := newLinter(opts)
+	if err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		return 1
+	}
+	for _, bconf := range bconfs {
+		res, err := l.run(bconf)
+		if err != nil {
+			fmt.Fprintln(os.Stderr, err)
+			return 1
+		}
+
+		for _, w := range res.Warnings {
+			fmt.Fprintln(os.Stderr, "warning:", w)
+		}
+
+		cwd, err := os.Getwd()
+		if err != nil {
+			cwd = ""
+		}
+		relPath := func(s string) string {
+			if cwd == "" {
+				return filepath.ToSlash(s)
+			}
+			out, err := filepath.Rel(cwd, s)
+			if err != nil {
+				return filepath.ToSlash(s)
+			}
+			return filepath.ToSlash(out)
+		}
+
+		if cmd.flags.formatter == "binary" {
+			for i, s := range res.CheckedFiles {
+				res.CheckedFiles[i] = relPath(s)
+			}
+			for i := range res.Diagnostics {
+				// We turn all paths into relative, /-separated paths. This is to make -merge work correctly when
+				// merging runs from different OSs, with different absolute paths.
+				//
+				// We zero out Offset, because checkouts of code on different OSs may have different kinds of
+				// newlines and thus different offsets. We don't ever make use of the Offset, anyway. Line and
+				// column numbers are precomputed.
+
+				d := &res.Diagnostics[i]
+				d.Position.Filename = relPath(d.Position.Filename)
+				d.Position.Offset = 0
+				d.End.Filename = relPath(d.End.Filename)
+				d.End.Offset = 0
+				for j := range d.Related {
+					r := &d.Related[j]
+					r.Position.Filename = relPath(r.Position.Filename)
+					r.Position.Offset = 0
+					r.End.Filename = relPath(r.End.Filename)
+					r.End.Offset = 0
+				}
+			}
+			err := gob.NewEncoder(os.Stdout).Encode(res)
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "failed writing output: %s\n", err)
+				return 2
+			}
+		} else {
+			runs = append(runs, runFromLintResult(res))
+		}
+	}
+
+	l.cache.Close()
+
+	if cmd.flags.formatter != "binary" {
+		diags := mergeRuns(runs)
+		return cmd.printDiagnostics(cs, diags)
+	}
+	return 0
+}
+
+func mergeRuns(runs []run) []diagnostic {
+	var relevantDiagnostics []diagnostic
+	for _, r := range runs {
+		for _, diag := range r.diagnostics {
+			switch diag.MergeIf {
+			case lint.MergeIfAny:
+				relevantDiagnostics = append(relevantDiagnostics, diag)
+			case lint.MergeIfAll:
+				doPrint := true
+				for _, r := range runs {
+					if _, ok := r.checkedFiles[diag.Position.Filename]; ok {
+						if _, ok := r.diagnostics[diag.descriptor()]; !ok {
+							doPrint = false
+						}
+					}
+				}
+				if doPrint {
+					relevantDiagnostics = append(relevantDiagnostics, diag)
+				}
+			}
+		}
+	}
+	return relevantDiagnostics
+}
+
+// printDiagnostics prints the diagnostics and exits the process.
+func (cmd *Command) printDiagnostics(cs []*lint.Analyzer, diagnostics []diagnostic) int {
+	if len(diagnostics) > 1 {
+		sort.Slice(diagnostics, func(i, j int) bool {
+			di := diagnostics[i]
+			dj := diagnostics[j]
+			pi := di.Position
+			pj := dj.Position
+
+			if pi.Filename != pj.Filename {
+				return pi.Filename < pj.Filename
+			}
+			if pi.Line != pj.Line {
+				return pi.Line < pj.Line
+			}
+			if pi.Column != pj.Column {
+				return pi.Column < pj.Column
+			}
+			if di.Message != dj.Message {
+				return di.Message < dj.Message
+			}
+			if di.BuildName != dj.BuildName {
+				return di.BuildName < dj.BuildName
+			}
+			return di.Category < dj.Category
+		})
+
+		filtered := []diagnostic{
+			diagnostics[0],
+		}
+		builds := []map[string]struct{}{
+			{diagnostics[0].BuildName: {}},
+		}
+		for _, diag := range diagnostics[1:] {
+			// We may encounter duplicate diagnostics because one file
+			// can be part of many packages, and because multiple
+			// build configurations may check the same files.
+			if !filtered[len(filtered)-1].equal(diag) {
+				if filtered[len(filtered)-1].descriptor() == diag.descriptor() {
+					// Diagnostics only differ in build name, track new name
+					builds[len(filtered)-1][diag.BuildName] = struct{}{}
+				} else {
+					filtered = append(filtered, diag)
+					builds = append(builds, map[string]struct{}{})
+					builds[len(filtered)-1][diag.BuildName] = struct{}{}
+				}
+			}
+		}
+
+		var names []string
+		for i := range filtered {
+			names = names[:0]
+			for k := range builds[i] {
+				names = append(names, k)
+			}
+			sort.Strings(names)
+			filtered[i].BuildName = strings.Join(names, ",")
+		}
+		diagnostics = filtered
+	}
+
+	var f formatter
+	switch cmd.flags.formatter {
+	case "text":
+		f = textFormatter{W: os.Stdout}
+	case "stylish":
+		f = &stylishFormatter{W: os.Stdout}
+	case "json":
+		f = jsonFormatter{W: os.Stdout}
+	case "sarif":
+		f = &sarifFormatter{
+			driverName:    cmd.name,
+			driverVersion: cmd.version,
+		}
+		if cmd.name == "staticcheck" {
+			f.(*sarifFormatter).driverName = "Staticcheck"
+			f.(*sarifFormatter).driverWebsite = "https://staticcheck.dev"
+		}
+	case "binary":
+		fmt.Fprintln(os.Stderr, "'-f binary' not supported in this context")
+		return 2
+	case "null":
+		f = nullFormatter{}
+	default:
+		fmt.Fprintf(os.Stderr, "unsupported output format %q\n", cmd.flags.formatter)
+		return 2
+	}
+
+	fail := makeCaseFoldedStrings(cmd.flags.fail)
+	analyzerNames := make([]caseFoldedString, len(cs))
+	for i, a := range cs {
+		analyzerNames[i] = makeCaseFoldedString(a.Analyzer.Name)
+	}
+	shouldExit := filterAnalyzerNames(analyzerNames, fail)
+	shouldExit[makeCaseFoldedString("staticcheck")] = true
+	shouldExit[makeCaseFoldedString("compile")] = true
+	shouldExit[makeCaseFoldedString("config")] = true
+
+	var (
+		numErrors   int
+		numWarnings int
+		numIgnored  int
+	)
+	notIgnored := make([]diagnostic, 0, len(diagnostics))
+	for _, diag := range diagnostics {
+		if diag.Category == "compile" && cmd.flags.debugNoCompileErrors {
+			continue
+		}
+		if diag.Severity == severityIgnored && !cmd.flags.showIgnored {
+			numIgnored++
+			continue
+		}
+		if shouldExit[makeCaseFoldedString(diag.Category)] {
+			numErrors++
+		} else {
+			diag.Severity = severityWarning
+			numWarnings++
+		}
+		notIgnored = append(notIgnored, diag)
+	}
+
+	f.Format(cs, notIgnored)
+	if f, ok := f.(statter); ok {
+		f.Stats(len(diagnostics), numErrors, numWarnings, numIgnored)
+	}
+
+	if numErrors > 0 {
+		if _, ok := f.(*sarifFormatter); ok {
+			// When emitting SARIF, finding errors is considered success.
+			return 0
+		} else {
+			return 1
+		}
+	}
+	return 0
+}
+
+func usage(name string, fs *flag.FlagSet) func() {
+	return func() {
+		fmt.Fprintf(os.Stderr, "Usage: %s [flags] [packages]\n", name)
+
+		fmt.Fprintln(os.Stderr)
+		fmt.Fprintln(os.Stderr, "Flags:")
+		printDefaults(fs)
+
+		fmt.Fprintln(os.Stderr)
+		fmt.Fprintln(os.Stderr, "For help about specifying packages, see 'go help packages'")
+	}
+}
+
+// isZeroValue determines whether the string represents the zero
+// value for a flag.
+//
+// this function has been copied from the Go standard library's 'flag' package.
+func isZeroValue(f *flag.Flag, value string) bool {
+	// Build a zero value of the flag's Value type, and see if the
+	// result of calling its String method equals the value passed in.
+	// This works unless the Value type is itself an interface type.
+	typ := reflect.TypeOf(f.Value)
+	var z reflect.Value
+	if typ.Kind() == reflect.Pointer {
+		z = reflect.New(typ.Elem())
+	} else {
+		z = reflect.Zero(typ)
+	}
+	return value == z.Interface().(flag.Value).String()
+}
+
+// this function has been copied from the Go standard library's 'flag' package and modified to skip debug flags.
+func printDefaults(fs *flag.FlagSet) {
+	fs.VisitAll(func(f *flag.Flag) {
+		// Don't print debug flags
+		if strings.HasPrefix(f.Name, "debug.") {
+			return
+		}
+
+		var b strings.Builder
+		fmt.Fprintf(&b, "  -%s", f.Name) // Two spaces before -; see next two comments.
+		name, usage := flag.UnquoteUsage(f)
+		if len(name) > 0 {
+			b.WriteString(" ")
+			b.WriteString(name)
+		}
+		// Boolean flags of one ASCII letter are so common we
+		// treat them specially, putting their usage on the same line.
+		if b.Len() <= 4 { // space, space, '-', 'x'.
+			b.WriteString("\t")
+		} else {
+			// Four spaces before the tab triggers good alignment
+			// for both 4- and 8-space tab stops.
+			b.WriteString("\n    \t")
+		}
+		b.WriteString(strings.ReplaceAll(usage, "\n", "\n    \t"))
+
+		if !isZeroValue(f, f.DefValue) {
+			if T := reflect.TypeOf(f.Value); T.Name() == "*stringValue" && T.PkgPath() == "flag" {
+				// put quotes on the value
+				fmt.Fprintf(&b, " (default %q)", f.DefValue)
+			} else {
+				fmt.Fprintf(&b, " (default %v)", f.DefValue)
+			}
+		}
+		fmt.Fprint(fs.Output(), b.String(), "\n")
+	})
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/config.go b/vendor/honnef.co/go/tools/lintcmd/config.go
new file mode 100644
index 0000000..eb38c97
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/config.go
@@ -0,0 +1,105 @@
+package lintcmd
+
+import (
+	"bufio"
+	"errors"
+	"fmt"
+	"io"
+	"strings"
+	"unicode"
+)
+
+type parseBuildConfigError struct {
+	line int
+	err  error
+}
+
+func (err parseBuildConfigError) Error() string { return err.err.Error() }
+
+func parseBuildConfigs(r io.Reader) ([]buildConfig, error) {
+	var builds []buildConfig
+	br := bufio.NewReader(r)
+	i := 0
+	for {
+		line, err := br.ReadString('\n')
+		if err != nil {
+			if err == io.EOF {
+				break
+			} else {
+				return nil, err
+			}
+		}
+		line = strings.TrimSpace(line)
+		if line == "" {
+			continue
+		}
+		name, envs, flags, err := parseBuildConfig(line)
+		if err != nil {
+			return nil, parseBuildConfigError{line: i + 1, err: err}
+		}
+
+		bc := buildConfig{
+			Name:  name,
+			Envs:  envs,
+			Flags: flags,
+		}
+		builds = append(builds, bc)
+
+		i++
+	}
+	return builds, nil
+}
+
+func parseBuildConfig(line string) (name string, envs []string, flags []string, err error) {
+	if line == "" {
+		return "", nil, nil, errors.New("couldn't parse empty build config")
+	}
+	if strings.Index(line, ":") == len(line)-1 {
+		name = line[:len(line)-1]
+	} else {
+		before, after, ok := strings.Cut(line, ": ")
+		if !ok {
+			return name, envs, flags, errors.New("missing build name")
+		}
+		name = before
+
+		var buf []rune
+		var inQuote bool
+		args := &envs
+		for _, r := range strings.TrimSpace(after) {
+			switch r {
+			case ' ':
+				if inQuote {
+					buf = append(buf, r)
+				} else if len(buf) != 0 {
+					if buf[0] == '-' {
+						args = &flags
+					}
+					*args = append(*args, string(buf))
+					buf = buf[:0]
+				}
+			case '"':
+				inQuote = !inQuote
+			default:
+				buf = append(buf, r)
+			}
+		}
+
+		if len(buf) > 0 {
+			if inQuote {
+				return "", nil, nil, errors.New("unterminated quoted string")
+			}
+			if buf[0] == '-' {
+				args = &flags
+			}
+			*args = append(*args, string(buf))
+		}
+	}
+
+	for _, r := range name {
+		if !(r == '_' || unicode.IsLetter(r) || unicode.IsNumber(r)) {
+			return "", nil, nil, fmt.Errorf("invalid build name %q", name)
+		}
+	}
+	return name, envs, flags, nil
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/directives.go b/vendor/honnef.co/go/tools/lintcmd/directives.go
new file mode 100644
index 0000000..d4f54a0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/directives.go
@@ -0,0 +1,55 @@
+package lintcmd
+
+import (
+	"strings"
+
+	"honnef.co/go/tools/lintcmd/runner"
+)
+
+func parseDirectives(dirs []runner.SerializedDirective) ([]ignore, []diagnostic) {
+	var ignores []ignore
+	var diagnostics []diagnostic
+
+	for _, dir := range dirs {
+		cmd := dir.Command
+		args := dir.Arguments
+		switch cmd {
+		case "ignore", "file-ignore":
+			if len(args) < 2 {
+				p := diagnostic{
+					Diagnostic: runner.Diagnostic{
+						Position: dir.NodePosition,
+						Message:  "malformed linter directive; missing the required reason field?",
+						Category: "compile",
+					},
+					Severity: severityError,
+				}
+				diagnostics = append(diagnostics, p)
+				continue
+			}
+		default:
+			// unknown directive, ignore
+			continue
+		}
+		checks := strings.Split(args[0], ",")
+		pos := dir.NodePosition
+		var ig ignore
+		switch cmd {
+		case "ignore":
+			ig = &lineIgnore{
+				File:   pos.Filename,
+				Line:   pos.Line,
+				Checks: makeCaseFoldedStrings(checks),
+				Pos:    dir.DirectivePosition,
+			}
+		case "file-ignore":
+			ig = &fileIgnore{
+				File:   pos.Filename,
+				Checks: makeCaseFoldedStrings(checks),
+			}
+		}
+		ignores = append(ignores, ig)
+	}
+
+	return ignores, diagnostics
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/format.go b/vendor/honnef.co/go/tools/lintcmd/format.go
new file mode 100644
index 0000000..8a23c3c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/format.go
@@ -0,0 +1,161 @@
+package lintcmd
+
+import (
+	"encoding/json"
+	"fmt"
+	"go/token"
+	"io"
+	"os"
+	"path/filepath"
+	"text/tabwriter"
+
+	"honnef.co/go/tools/analysis/lint"
+)
+
+func shortPath(path string) string {
+	cwd, err := os.Getwd()
+	if err != nil {
+		return path
+	}
+	if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
+		return rel
+	}
+	return path
+}
+
+func relativePositionString(pos token.Position) string {
+	s := shortPath(pos.Filename)
+	if pos.IsValid() {
+		if s != "" {
+			s += ":"
+		}
+		s += fmt.Sprintf("%d:%d", pos.Line, pos.Column)
+	}
+	if s == "" {
+		s = "-"
+	}
+	return s
+}
+
+type statter interface {
+	Stats(total, errors, warnings, ignored int)
+}
+
+type formatter interface {
+	Format(checks []*lint.Analyzer, diagnostics []diagnostic)
+}
+
+type textFormatter struct {
+	W io.Writer
+}
+
+func (o textFormatter) Format(_ []*lint.Analyzer, ps []diagnostic) {
+	for _, p := range ps {
+		fmt.Fprintf(o.W, "%s: %s\n", relativePositionString(p.Position), p.String())
+		for _, r := range p.Related {
+			fmt.Fprintf(o.W, "\t%s: %s\n", relativePositionString(r.Position), r.Message)
+		}
+	}
+}
+
+type nullFormatter struct{}
+
+func (nullFormatter) Format([]*lint.Analyzer, []diagnostic) {}
+
+type jsonFormatter struct {
+	W io.Writer
+}
+
+func (o jsonFormatter) Format(_ []*lint.Analyzer, ps []diagnostic) {
+	type location struct {
+		File   string `json:"file"`
+		Line   int    `json:"line"`
+		Column int    `json:"column"`
+	}
+	type related struct {
+		Location location `json:"location"`
+		End      location `json:"end"`
+		Message  string   `json:"message"`
+	}
+
+	enc := json.NewEncoder(o.W)
+	for _, p := range ps {
+		jp := struct {
+			Code     string    `json:"code"`
+			Severity string    `json:"severity,omitempty"`
+			Location location  `json:"location"`
+			End      location  `json:"end"`
+			Message  string    `json:"message"`
+			Related  []related `json:"related,omitempty"`
+		}{
+			Code:     p.Category,
+			Severity: p.Severity.String(),
+			Location: location{
+				File:   p.Position.Filename,
+				Line:   p.Position.Line,
+				Column: p.Position.Column,
+			},
+			End: location{
+				File:   p.End.Filename,
+				Line:   p.End.Line,
+				Column: p.End.Column,
+			},
+			Message: p.Message,
+		}
+		for _, r := range p.Related {
+			jp.Related = append(jp.Related, related{
+				Location: location{
+					File:   r.Position.Filename,
+					Line:   r.Position.Line,
+					Column: r.Position.Column,
+				},
+				End: location{
+					File:   r.End.Filename,
+					Line:   r.End.Line,
+					Column: r.End.Column,
+				},
+				Message: r.Message,
+			})
+		}
+		_ = enc.Encode(jp)
+	}
+}
+
+type stylishFormatter struct {
+	W io.Writer
+
+	prevFile string
+	tw       *tabwriter.Writer
+}
+
+func (o *stylishFormatter) Format(_ []*lint.Analyzer, ps []diagnostic) {
+	for _, p := range ps {
+		pos := p.Position
+		if pos.Filename == "" {
+			pos.Filename = "-"
+		}
+
+		if pos.Filename != o.prevFile {
+			if o.prevFile != "" {
+				o.tw.Flush()
+				fmt.Fprintln(o.W)
+			}
+			fmt.Fprintln(o.W, pos.Filename)
+			o.prevFile = pos.Filename
+			o.tw = tabwriter.NewWriter(o.W, 0, 4, 2, ' ', 0)
+		}
+		fmt.Fprintf(o.tw, "  (%d, %d)\t%s\t%s\n", pos.Line, pos.Column, p.Category, p.Message)
+		for _, r := range p.Related {
+			fmt.Fprintf(o.tw, "    (%d, %d)\t\t  %s\n", r.Position.Line, r.Position.Column, r.Message)
+		}
+	}
+}
+
+func (o *stylishFormatter) Stats(total, errors, warnings, ignored int) {
+	if o.tw != nil {
+		o.tw.Flush()
+		fmt.Fprintln(o.W)
+	}
+	fmt.Fprintf(o.W, " ✖ %d problems (%d errors, %d warnings, %d ignored)\n",
+		total, errors, warnings, ignored)
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/lint.go b/vendor/honnef.co/go/tools/lintcmd/lint.go
new file mode 100644
index 0000000..2147849
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/lint.go
@@ -0,0 +1,571 @@
+package lintcmd
+
+import (
+	"crypto/sha256"
+	"fmt"
+	"go/token"
+	"io"
+	"os"
+	"os/signal"
+	"path/filepath"
+	"regexp"
+	"strconv"
+	"strings"
+	"time"
+	"unicode"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/config"
+	"honnef.co/go/tools/go/buildid"
+	"honnef.co/go/tools/go/loader"
+	"honnef.co/go/tools/lintcmd/cache"
+	"honnef.co/go/tools/lintcmd/runner"
+	"honnef.co/go/tools/unused"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/packages"
+)
+
+// A linter lints Go source code.
+type linter struct {
+	analyzers map[caseFoldedString]*lint.Analyzer
+	cache     cache.Cache
+	opts      options
+}
+
+func computeSalt() ([]byte, error) {
+	p, err := os.Executable()
+	if err != nil {
+		return nil, err
+	}
+
+	if id, err := buildid.ReadFile(p); err == nil {
+		return []byte(id), nil
+	} else {
+		// For some reason we couldn't read the build id from the executable.
+		// Fall back to hashing the entire executable.
+		f, err := os.Open(p)
+		if err != nil {
+			return nil, err
+		}
+		defer f.Close()
+		h := sha256.New()
+		if _, err := io.Copy(h, f); err != nil {
+			return nil, err
+		}
+		return h.Sum(nil), nil
+	}
+}
+
+func newLinter(opts options) (*linter, error) {
+	c, err := cache.Default()
+	if err != nil {
+		return nil, err
+	}
+	salt, err := computeSalt()
+	if err != nil {
+		return nil, fmt.Errorf("could not compute salt for cache: %s", err)
+	}
+	cache.SetSalt(salt)
+
+	analyzers := make(map[caseFoldedString]*lint.Analyzer, len(opts.analyzers))
+	for _, a := range opts.analyzers {
+		analyzers[makeCaseFoldedString(a.Analyzer.Name)] = a
+	}
+
+	return &linter{
+		cache:     c,
+		analyzers: analyzers,
+		opts:      opts,
+	}, nil
+}
+
+type lintResult struct {
+	// These fields are exported so that we can gob encode them.
+
+	CheckedFiles []string
+	Diagnostics  []diagnostic
+	Warnings     []string
+}
+
+type options struct {
+	config                   config.Config
+	analyzers                []*lint.Analyzer
+	patterns                 []string
+	lintTests                bool
+	goVersion                string
+	printAnalyzerMeasurement func(analysis *analysis.Analyzer, pkg *loader.PackageSpec, d time.Duration)
+}
+
+func (l *linter) run(bconf buildConfig) (lintResult, error) {
+	cfg := &packages.Config{}
+	if l.opts.lintTests {
+		cfg.Tests = true
+	}
+
+	cfg.BuildFlags = bconf.Flags
+	cfg.Env = append(os.Environ(), bconf.Envs...)
+
+	r, err := runner.New(l.opts.config, l.cache)
+	if err != nil {
+		return lintResult{}, err
+	}
+	r.GoVersion = l.opts.goVersion
+	r.Stats.PrintAnalyzerMeasurement = l.opts.printAnalyzerMeasurement
+
+	printStats := func() {
+		// Individual stats are read atomically, but overall there
+		// is no synchronisation. For printing rough progress
+		// information, this doesn't matter.
+		switch r.Stats.State() {
+		case runner.StateInitializing:
+			fmt.Fprintln(os.Stderr, "Status: initializing")
+		case runner.StateLoadPackageGraph:
+			fmt.Fprintln(os.Stderr, "Status: loading package graph")
+		case runner.StateBuildActionGraph:
+			fmt.Fprintln(os.Stderr, "Status: building action graph")
+		case runner.StateProcessing:
+			fmt.Fprintf(os.Stderr, "Packages: %d/%d initial, %d/%d total; Workers: %d/%d\n",
+				r.Stats.ProcessedInitialPackages(),
+				r.Stats.InitialPackages(),
+				r.Stats.ProcessedPackages(),
+				r.Stats.TotalPackages(),
+				r.ActiveWorkers(),
+				r.TotalWorkers(),
+			)
+		case runner.StateFinalizing:
+			fmt.Fprintln(os.Stderr, "Status: finalizing")
+		}
+	}
+	if len(infoSignals) > 0 {
+		ch := make(chan os.Signal, 1)
+		signal.Notify(ch, infoSignals...)
+		defer signal.Stop(ch)
+		go func() {
+			for range ch {
+				printStats()
+			}
+		}()
+	}
+	res, err := l.lint(r, cfg, l.opts.patterns)
+	for i := range res.Diagnostics {
+		res.Diagnostics[i].BuildName = bconf.Name
+	}
+	return res, err
+}
+
+func (l *linter) lint(r *runner.Runner, cfg *packages.Config, patterns []string) (lintResult, error) {
+	var out lintResult
+
+	as := make([]*analysis.Analyzer, 0, len(l.analyzers))
+	for _, a := range l.analyzers {
+		as = append(as, a.Analyzer)
+	}
+	results, err := r.Run(cfg, as, patterns)
+	if err != nil {
+		return out, err
+	}
+
+	if len(results) == 0 {
+		// TODO(dh): emulate Go's behavior more closely once we have
+		// access to go list's Match field.
+		for _, pattern := range patterns {
+			fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
+		}
+	}
+
+	analyzerNames := make([]caseFoldedString, 0, len(l.analyzers))
+	for name := range l.analyzers {
+		analyzerNames = append(analyzerNames, name)
+	}
+	used := map[unusedKey]bool{}
+	var unuseds []unusedPair
+	for _, res := range results {
+		if len(res.Errors) > 0 && !res.Failed {
+			panic("package has errors but isn't marked as failed")
+		}
+		if res.Failed {
+			out.Diagnostics = append(out.Diagnostics, failed(res)...)
+		} else {
+			if res.Skipped {
+				out.Warnings = append(out.Warnings, fmt.Sprintf("skipped package %s because it is too large", res.Package))
+				continue
+			}
+
+			if !res.Initial {
+				continue
+			}
+
+			out.CheckedFiles = append(out.CheckedFiles, res.Package.GoFiles...)
+			resChecks := makeCaseFoldedStrings(res.Config.Checks)
+			allowedAnalyzers := filterAnalyzerNames(analyzerNames, resChecks)
+			resd, err := res.Load()
+			if err != nil {
+				return out, err
+			}
+			ps := success(allowedAnalyzers, resd)
+			filtered, err := filterIgnored(ps, resd, allowedAnalyzers)
+			if err != nil {
+				return out, err
+			}
+			// OPT move this code into the 'success' function.
+			for i, diag := range filtered {
+				a := l.analyzers[makeCaseFoldedString(diag.Category)]
+				// Some diag.Category don't map to analyzers, such as "staticcheck"
+				if a != nil {
+					filtered[i].MergeIf = a.Doc.MergeIf
+				}
+			}
+			out.Diagnostics = append(out.Diagnostics, filtered...)
+
+			for _, obj := range resd.Unused.Used {
+				// Note: a side-effect of this code is that fields in instantiated structs are handled correctly. Even
+				// if only an instantiated field is marked as used, we will not flag the generic field, because it has
+				// the same position as the instance. At some point this won't be necessary anymore because we'll be
+				// able to make use of the Go 1.19+ Origin methods.
+
+				// FIXME(dh): pick the object whose filename does not include $GOROOT
+				key := unusedKey{
+					pkgPath: res.Package.PkgPath,
+					base:    filepath.Base(obj.Position.Filename),
+					line:    obj.Position.Line,
+					name:    obj.Name,
+				}
+				used[key] = true
+			}
+
+			if allowedAnalyzers[makeCaseFoldedString("U1000")] {
+				for _, obj := range resd.Unused.Unused {
+					key := unusedKey{
+						pkgPath: res.Package.PkgPath,
+						base:    filepath.Base(obj.Position.Filename),
+						line:    obj.Position.Line,
+						name:    obj.Name,
+					}
+					unuseds = append(unuseds, unusedPair{key, obj})
+					if _, ok := used[key]; !ok {
+						used[key] = false
+					}
+				}
+			}
+		}
+	}
+
+	for _, uo := range unuseds {
+		if used[uo.key] {
+			continue
+		}
+		out.Diagnostics = append(out.Diagnostics, diagnostic{
+			Diagnostic: runner.Diagnostic{
+				Position: uo.obj.DisplayPosition,
+				Message:  fmt.Sprintf("%s %s is unused", uo.obj.Kind, uo.obj.Name),
+				Category: "U1000",
+			},
+			MergeIf: lint.MergeIfAll,
+		})
+	}
+
+	return out, nil
+}
+
+func filterIgnored(
+	diagnostics []diagnostic,
+	res runner.ResultData,
+	allowedAnalyzers map[caseFoldedString]bool,
+) ([]diagnostic, error) {
+	couldHaveMatched := func(ig *lineIgnore) bool {
+		for _, c := range ig.Checks {
+			if c.String() == "u1000" {
+				// We never want to flag ignores for U1000,
+				// because U1000 isn't local to a single
+				// package. For example, an identifier may
+				// only be used by tests, in which case an
+				// ignore would only fire when not analyzing
+				// tests. To avoid spurious "useless ignore"
+				// warnings, just never flag U1000.
+				return false
+			}
+
+			// Even though the runner always runs all analyzers, we
+			// still only flag unmatched ignores for the set of
+			// analyzers the user has expressed interest in. That way,
+			// `staticcheck -checks=SA1000` won't complain about an
+			// unmatched ignore for an unrelated check.
+			if allowedAnalyzers[c] {
+				return true
+			}
+		}
+
+		return false
+	}
+
+	ignores, moreDiagnostics := parseDirectives(res.Directives)
+
+	for _, ig := range ignores {
+		for i := range diagnostics {
+			diag := &diagnostics[i]
+			if ig.match(*diag) {
+				diag.Severity = severityIgnored
+			}
+		}
+
+		if ig, ok := ig.(*lineIgnore); ok && !ig.Matched && couldHaveMatched(ig) {
+			diag := diagnostic{
+				Diagnostic: runner.Diagnostic{
+					Position: ig.Pos,
+					Message:  "this linter directive didn't match anything; should it be removed?",
+					Category: "staticcheck",
+				},
+			}
+			moreDiagnostics = append(moreDiagnostics, diag)
+		}
+	}
+
+	return append(diagnostics, moreDiagnostics...), nil
+}
+
+type ignore interface {
+	match(diag diagnostic) bool
+}
+
+type lineIgnore struct {
+	File    string
+	Line    int
+	Checks  []caseFoldedString
+	Matched bool
+	Pos     token.Position
+}
+
+func (li *lineIgnore) match(p diagnostic) bool {
+	pos := p.Position
+	if pos.Filename != li.File || pos.Line != li.Line {
+		return false
+	}
+	for _, c := range li.Checks {
+		if m, _ := filepath.Match(c.String(), makeCaseFoldedString(p.Category).String()); m {
+			li.Matched = true
+			return true
+		}
+	}
+	return false
+}
+
+type fileIgnore struct {
+	File   string
+	Checks []caseFoldedString
+}
+
+func (fi *fileIgnore) match(p diagnostic) bool {
+	if p.Position.Filename != fi.File {
+		return false
+	}
+	for _, c := range fi.Checks {
+		if m, _ := filepath.Match(c.String(), makeCaseFoldedString(p.Category).String()); m {
+			return true
+		}
+	}
+	return false
+}
+
+type severity uint8
+
+const (
+	severityError severity = iota
+	severityWarning
+	severityIgnored
+)
+
+func (s severity) String() string {
+	switch s {
+	case severityError:
+		return "error"
+	case severityWarning:
+		return "warning"
+	case severityIgnored:
+		return "ignored"
+	default:
+		return fmt.Sprintf("Severity(%d)", s)
+	}
+}
+
+// diagnostic represents a diagnostic in some source code.
+type diagnostic struct {
+	runner.Diagnostic
+
+	// These fields are exported so that we can gob encode them.
+	Severity  severity
+	MergeIf   lint.MergeStrategy
+	BuildName string
+}
+
+func (p diagnostic) equal(o diagnostic) bool {
+	return p.Position == o.Position &&
+		p.End == o.End &&
+		p.Message == o.Message &&
+		makeCaseFoldedString(p.Category) == makeCaseFoldedString(o.Category) &&
+		p.Severity == o.Severity &&
+		p.MergeIf == o.MergeIf &&
+		p.BuildName == o.BuildName
+}
+
+func (p *diagnostic) String() string {
+	if p.BuildName != "" {
+		return fmt.Sprintf("%s [%s] (%s)", p.Message, p.BuildName, p.Category)
+	} else {
+		return fmt.Sprintf("%s (%s)", p.Message, p.Category)
+	}
+}
+
+func failed(res runner.Result) []diagnostic {
+	var diagnostics []diagnostic
+
+	for _, e := range res.Errors {
+		switch e := e.(type) {
+		case packages.Error:
+			msg := e.Msg
+			if len(msg) != 0 && msg[0] == '\n' {
+				// TODO(dh): See https://github.com/golang/go/issues/32363
+				msg = msg[1:]
+			}
+
+			cat := "compile"
+			if e.Kind == packages.ParseError {
+				cat = "config"
+			}
+
+			var posn token.Position
+			if e.Pos == "" {
+				// Under certain conditions (malformed package
+				// declarations, multiple packages in the same
+				// directory), go list emits an error on stderr
+				// instead of JSON. Those errors do not have
+				// associated position information in
+				// go/packages.Error, even though the output on
+				// stderr may contain it.
+				if p, n, err := parsePos(msg); err == nil {
+					if abs, err := filepath.Abs(p.Filename); err == nil {
+						p.Filename = abs
+					}
+					posn = p
+					msg = msg[n+2:]
+				}
+			} else {
+				var err error
+				posn, _, err = parsePos(e.Pos)
+				if err != nil {
+					panic(fmt.Sprintf("internal error: %s", err))
+				}
+			}
+			diag := diagnostic{
+				Diagnostic: runner.Diagnostic{
+					Position: posn,
+					Message:  msg,
+					Category: cat,
+				},
+				Severity: severityError,
+			}
+			diagnostics = append(diagnostics, diag)
+		case error:
+			diag := diagnostic{
+				Diagnostic: runner.Diagnostic{
+					Position: token.Position{},
+					Message:  e.Error(),
+					Category: "compile",
+				},
+				Severity: severityError,
+			}
+			diagnostics = append(diagnostics, diag)
+		}
+	}
+
+	return diagnostics
+}
+
+type unusedKey struct {
+	pkgPath string
+	base    string
+	line    int
+	name    string
+}
+
+type unusedPair struct {
+	key unusedKey
+	obj unused.Object
+}
+
+func success(allowedAnalyzers map[caseFoldedString]bool, res runner.ResultData) []diagnostic {
+	diags := res.Diagnostics
+	var diagnostics []diagnostic
+	for _, diag := range diags {
+		if !allowedAnalyzers[makeCaseFoldedString(diag.Category)] {
+			continue
+		}
+		diagnostics = append(diagnostics, diagnostic{Diagnostic: diag})
+	}
+	return diagnostics
+}
+
+func filterAnalyzerNames(allAnalyzers []caseFoldedString, selection []caseFoldedString) map[caseFoldedString]bool {
+	allowedChecks := map[caseFoldedString]bool{}
+
+	for _, check := range selection {
+		b := true
+		if check.Length() > 1 && check.Index(0) == '-' {
+			b = false
+			check = check.Slice(1, -1)
+		}
+		if check.String() == "*" || check.String() == "all" {
+			// Match all
+			for _, a := range allAnalyzers {
+				allowedChecks[a] = b
+			}
+		} else if strings.HasSuffix(check.String(), "*") {
+			// Glob
+			prefix := check.Slice(0, check.Length()-1)
+			isCat := strings.IndexFunc(prefix.String(), unicode.IsNumber) == -1
+
+			for _, a := range allAnalyzers {
+				idx := strings.IndexFunc(a.String(), unicode.IsNumber)
+				if isCat {
+					// Glob is S*, which should match S1000 but not SA1000
+					cat := a.Slice(0, idx)
+					if prefix == cat {
+						allowedChecks[a] = b
+					}
+				} else {
+					// Glob is S1*
+					if strings.HasPrefix(a.String(), prefix.String()) {
+						allowedChecks[a] = b
+					}
+				}
+			}
+		} else {
+			// Literal check name
+			allowedChecks[check] = b
+		}
+	}
+	return allowedChecks
+}
+
+// Note that the file name is optional and can be empty because of //line
+// directives of the form "//line :1" (but not "//line :1:1"). See
+// https://go.dev/issue/24183 and https://staticcheck.dev/issues/1582.
+var posRe = regexp.MustCompile(`^(?:(.+?):)?(\d+)(?::(\d+)?)?`)
+
+func parsePos(pos string) (token.Position, int, error) {
+	if pos == "-" || pos == "" {
+		return token.Position{}, 0, nil
+	}
+	parts := posRe.FindStringSubmatch(pos)
+	if parts == nil {
+		return token.Position{}, 0, fmt.Errorf("malformed position %q", pos)
+	}
+	file := parts[1]
+	line, _ := strconv.Atoi(parts[2])
+	col, _ := strconv.Atoi(parts[3])
+	return token.Position{
+		Filename: file,
+		Line:     line,
+		Column:   col,
+	}, len(parts[0]), nil
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/runner/runner.go b/vendor/honnef.co/go/tools/lintcmd/runner/runner.go
new file mode 100644
index 0000000..a963cbe
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/runner/runner.go
@@ -0,0 +1,1246 @@
+// Package runner implements a go/analysis runner. It makes heavy use
+// of on-disk caching to reduce overall memory usage and to speed up
+// repeat runs.
+//
+// # Public API
+//
+// A Runner maps a list of analyzers and package patterns to a list of
+// results. Results provide access to diagnostics, directives, errors
+// encountered, and information about packages. Results explicitly do
+// not contain ASTs or type information. All position information is
+// returned in the form of token.Position, not token.Pos. All work
+// that requires access to the loaded representation of a package has
+// to occur inside analyzers.
+//
+// # Planning and execution
+//
+// Analyzing packages is split into two phases: planning and
+// execution.
+//
+// During planning, a directed acyclic graph of package dependencies
+// is computed. We materialize the full graph so that we can execute
+// the graph from the bottom up, without keeping unnecessary data in
+// memory during a DFS and with simplified parallel execution.
+//
+// During execution, leaf nodes (nodes with no outstanding
+// dependencies) get executed in parallel, bounded by a semaphore
+// sized according to the number of CPUs. Conceptually, this happens
+// in a loop, processing new leaf nodes as they appear, until no more
+// nodes are left. In the actual implementation, nodes know their
+// dependents, and the last dependency of a node to be processed is
+// responsible for scheduling its dependent.
+//
+// The graph is rooted at a synthetic root node. Upon execution of the
+// root node, the algorithm terminates.
+//
+// Analyzing a package repeats the same planning + execution steps,
+// but this time on a graph of analyzers for the package. Parallel
+// execution of individual analyzers is bounded by the same semaphore
+// as executing packages.
+//
+// # Parallelism
+//
+// Actions are executed in parallel where the dependency graph allows.
+// Overall parallelism is bounded by a semaphore, sized according to
+// GOMAXPROCS. Each concurrently processed package takes up a
+// token, as does each analyzer – but a package can always execute at
+// least one analyzer, using the package's token.
+//
+// Depending on the overall shape of the graph, there may be GOMAXPROCS
+// packages running a single analyzer each, a single package running
+// GOMAXPROCS analyzers, or anything in between.
+//
+// Total memory consumption grows roughly linearly with the number of
+// CPUs, while total execution time is inversely proportional to the
+// number of CPUs. Overall, parallelism is affected by the shape of
+// the dependency graph. A lot of inter-connected packages will see
+// less parallelism than a lot of independent packages.
+//
+// # Caching
+//
+// The runner caches facts, directives and diagnostics in a
+// content-addressable cache that is designed after Go's own cache.
+// Additionally, it makes use of Go's export data.
+//
+// This cache not only speeds up repeat runs, it also reduces peak
+// memory usage. When we've analyzed a package, we cache the results
+// and drop them from memory. When a dependent needs any of this
+// information, or when analysis is complete and we wish to render the
+// results, the data gets loaded from disk again.
+//
+// Data only exists in memory when it is immediately needed, not
+// retained for possible future uses. This trades increased CPU usage
+// for reduced memory usage. A single dependency may be loaded many
+// times over, but it greatly reduces peak memory usage, as an
+// arbitrary amount of time may pass between analyzing a dependency
+// and its dependent, during which other packages will be processed.
+package runner
+
+// OPT(dh): we could reduce disk storage usage of cached data by
+// compressing it, either directly at the cache layer, or by feeding
+// compressed data to the cache. Of course doing so may negatively
+// affect CPU usage, and there are lower hanging fruit, such as
+// needing to cache less data in the first place.
+
+// OPT(dh): right now, each package is analyzed completely
+// independently. Each package loads all of its dependencies from
+// export data and cached facts. If we have two packages A and B,
+// which both depend on C, and which both get analyzed in parallel,
+// then C will be loaded twice. This wastes CPU time and memory. It
+// would be nice if we could reuse a single C for the analysis of both
+// A and B.
+//
+// We can't reuse the actual types.Package or facts, because each
+// package gets its own token.FileSet. Sharing a global FileSet has
+// several drawbacks, including increased memory usage and running the
+// risk of running out of FileSet address space.
+//
+// We could however avoid loading the same raw export data from disk
+// twice, as well as deserializing gob data twice. One possible
+// solution would be a duplicate-suppressing in-memory cache that
+// caches data for a limited amount of time. When the same package
+// needs to be loaded twice in close succession, we can reuse work,
+// without holding unnecessary data in memory for an extended period
+// of time.
+//
+// We would likely need to do extensive benchmarking to figure out how
+// long to keep data around to find a sweet spot where we reduce CPU
+// load without increasing memory usage.
+//
+// We can probably populate the cache after we've analyzed a package,
+// on the assumption that it will have to be loaded again in the near
+// future.
+
+import (
+	"bytes"
+	"encoding/gob"
+	"fmt"
+	"go/token"
+	"go/types"
+	"io"
+	"maps"
+	"os"
+	"reflect"
+	"runtime"
+	"sort"
+	"strings"
+	"sync/atomic"
+	"time"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/config"
+	"honnef.co/go/tools/go/loader"
+	tsync "honnef.co/go/tools/internal/sync"
+	"honnef.co/go/tools/lintcmd/cache"
+	"honnef.co/go/tools/unused"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/tools/go/types/objectpath"
+)
+
+const sanityCheck = false
+
+// Diagnostic is like go/analysis.Diagnostic, but with all token.Pos resolved to token.Position.
+type Diagnostic struct {
+	Position token.Position
+	End      token.Position
+	Category string
+	Message  string
+
+	SuggestedFixes []SuggestedFix
+	Related        []RelatedInformation
+}
+
+// RelatedInformation provides additional context for a diagnostic.
+type RelatedInformation struct {
+	Position token.Position
+	End      token.Position
+	Message  string
+}
+
+type SuggestedFix struct {
+	Message   string
+	TextEdits []TextEdit
+}
+
+type TextEdit struct {
+	Position token.Position
+	End      token.Position
+	NewText  []byte
+}
+
+// A Result describes the result of analyzing a single package.
+//
+// It holds references to cached diagnostics and directives. They can
+// be loaded on demand with the Load method.
+type Result struct {
+	Package *loader.PackageSpec
+	Config  config.Config
+	Initial bool
+	Skipped bool
+
+	Failed bool
+	Errors []error
+	// Action results, path to file
+	results string
+	// Results relevant to testing, only set when test mode is enabled, path to file
+	testData string
+}
+
+type SerializedDirective struct {
+	Command   string
+	Arguments []string
+	// The position of the comment
+	DirectivePosition token.Position
+	// The position of the node that the comment is attached to
+	NodePosition token.Position
+}
+
+func serializeDirective(dir lint.Directive, fset *token.FileSet) SerializedDirective {
+	return SerializedDirective{
+		Command:           dir.Command,
+		Arguments:         dir.Arguments,
+		DirectivePosition: report.DisplayPosition(fset, dir.Directive.Pos()),
+		NodePosition:      report.DisplayPosition(fset, dir.Node.Pos()),
+	}
+}
+
+type ResultData struct {
+	Directives  []SerializedDirective
+	Diagnostics []Diagnostic
+	Unused      unused.Result
+}
+
+func (r Result) Load() (ResultData, error) {
+	if r.Failed {
+		panic("Load called on failed Result")
+	}
+	if r.results == "" {
+		// this package was only a dependency
+		return ResultData{}, nil
+	}
+	f, err := os.Open(r.results)
+	if err != nil {
+		return ResultData{}, fmt.Errorf("failed loading result: %w", err)
+	}
+	defer f.Close()
+	var out ResultData
+	err = gob.NewDecoder(f).Decode(&out)
+	return out, err
+}
+
+// TestData contains extra information about analysis runs that is only available in test mode.
+type TestData struct {
+	// Facts contains facts produced by analyzers for a package.
+	// Unlike vetx, this list only contains facts specific to this package,
+	// not all facts for the transitive closure of dependencies.
+	Facts []TestFact
+	// List of files that were part of the package.
+	Files []string
+}
+
+// LoadTest returns data relevant to testing.
+// It should only be called if Runner.TestMode was set to true.
+func (r Result) LoadTest() (TestData, error) {
+	if r.Failed {
+		panic("Load called on failed Result")
+	}
+	if r.results == "" {
+		// this package was only a dependency
+		return TestData{}, nil
+	}
+	f, err := os.Open(r.testData)
+	if err != nil {
+		return TestData{}, fmt.Errorf("failed loading test data: %w", err)
+	}
+	defer f.Close()
+	var out TestData
+	err = gob.NewDecoder(f).Decode(&out)
+	return out, err
+}
+
+type action interface {
+	Deps() []action
+	Triggers() []action
+	DecrementPending() bool
+	MarkFailed()
+	IsFailed() bool
+	AddError(error)
+}
+
+type baseAction struct {
+	// Action description
+
+	deps     []action
+	triggers []action
+	pending  uint32
+
+	// Action results
+
+	// failed is set to true if the action couldn't be processed. This
+	// may either be due to an error specific to this action, in
+	// which case the errors field will be populated, or due to a
+	// dependency being marked as failed, in which case errors will be
+	// empty.
+	failed bool
+	errors []error
+}
+
+func (act *baseAction) Deps() []action     { return act.deps }
+func (act *baseAction) Triggers() []action { return act.triggers }
+func (act *baseAction) DecrementPending() bool {
+	return atomic.AddUint32(&act.pending, ^uint32(0)) == 0
+}
+func (act *baseAction) MarkFailed()        { act.failed = true }
+func (act *baseAction) IsFailed() bool     { return act.failed }
+func (act *baseAction) AddError(err error) { act.errors = append(act.errors, err) }
+
+// packageAction describes the act of loading a package, fully
+// analyzing it, and storing the results.
+type packageAction struct {
+	baseAction
+
+	// Action description
+	Package   *loader.PackageSpec
+	factsOnly bool
+	hash      cache.ActionID
+
+	// Action results
+	cfg      config.Config
+	vetx     string
+	results  string
+	testData string
+	skipped  bool
+}
+
+func (act *packageAction) String() string {
+	return fmt.Sprintf("packageAction(%s)", act.Package)
+}
+
+type objectFact struct {
+	fact analysis.Fact
+	// TODO(dh): why do we store the objectpath when producing the
+	// fact? Is it just for the sanity checking, which compares the
+	// stored path with a path recomputed from objectFactKey.Obj?
+	path objectpath.Path
+}
+
+type objectFactKey struct {
+	Obj  types.Object
+	Type reflect.Type
+}
+
+type packageFactKey struct {
+	Pkg  *types.Package
+	Type reflect.Type
+}
+
+type gobFact struct {
+	PkgPath string
+	ObjPath string
+	Fact    analysis.Fact
+}
+
+// TestFact is a serialization of facts that is specific to the test mode.
+type TestFact struct {
+	ObjectName string
+	Position   token.Position
+	FactString string
+	Analyzer   string
+}
+
+// analyzerAction describes the act of analyzing a package with a
+// single analyzer.
+type analyzerAction struct {
+	baseAction
+
+	// Action description
+
+	Analyzer *analysis.Analyzer
+
+	// Action results
+
+	// We can store actual results here without worrying about memory
+	// consumption because analyzer actions get garbage collected once
+	// a package has been fully analyzed.
+	Result       any
+	Diagnostics  []Diagnostic
+	ObjectFacts  map[objectFactKey]objectFact
+	PackageFacts map[packageFactKey]analysis.Fact
+	Pass         *analysis.Pass
+}
+
+func (act *analyzerAction) String() string {
+	return fmt.Sprintf("analyzerAction(%s)", act.Analyzer)
+}
+
+// A Runner executes analyzers on packages.
+type Runner struct {
+	Stats     Stats
+	GoVersion string
+
+	// If set to true, Runner will populate results with data relevant to testing analyzers
+	TestMode bool
+
+	// Config that gets merged with per-package configs
+	cfg       config.Config
+	cache     cache.Cache
+	semaphore tsync.Semaphore
+}
+
+type subrunner struct {
+	*Runner
+	analyzers     []*analysis.Analyzer
+	factAnalyzers []*analysis.Analyzer
+	analyzerNames string
+	cache         cache.Cache
+}
+
+// New returns a new Runner.
+func New(cfg config.Config, c cache.Cache) (*Runner, error) {
+	return &Runner{
+		cfg:       cfg,
+		cache:     c,
+		semaphore: tsync.NewSemaphore(runtime.GOMAXPROCS(0)),
+	}, nil
+}
+
+func newSubrunner(r *Runner, analyzers []*analysis.Analyzer) *subrunner {
+	analyzerNames := make([]string, len(analyzers))
+	for i, a := range analyzers {
+		analyzerNames[i] = a.Name
+	}
+	sort.Strings(analyzerNames)
+
+	var factAnalyzers []*analysis.Analyzer
+	for _, a := range analyzers {
+		if len(a.FactTypes) > 0 {
+			factAnalyzers = append(factAnalyzers, a)
+		}
+	}
+	return &subrunner{
+		Runner:        r,
+		analyzers:     analyzers,
+		factAnalyzers: factAnalyzers,
+		analyzerNames: strings.Join(analyzerNames, ","),
+		cache:         r.cache,
+	}
+}
+
+func newPackageActionRoot(pkg *loader.PackageSpec, cache map[*loader.PackageSpec]*packageAction) *packageAction {
+	a := newPackageAction(pkg, cache)
+	a.factsOnly = false
+	return a
+}
+
+func newPackageAction(pkg *loader.PackageSpec, cache map[*loader.PackageSpec]*packageAction) *packageAction {
+	if a, ok := cache[pkg]; ok {
+		return a
+	}
+
+	a := &packageAction{
+		Package:   pkg,
+		factsOnly: true, // will be overwritten by any call to Action
+	}
+	cache[pkg] = a
+
+	if len(pkg.Errors) > 0 {
+		a.errors = make([]error, len(pkg.Errors))
+		for i, err := range pkg.Errors {
+			a.errors[i] = err
+		}
+		a.failed = true
+
+		// We don't need to process our imports if this package is
+		// already broken.
+		return a
+	}
+
+	a.deps = make([]action, 0, len(pkg.Imports))
+	for _, dep := range pkg.Imports {
+		depa := newPackageAction(dep, cache)
+		depa.triggers = append(depa.triggers, a)
+		a.deps = append(a.deps, depa)
+
+		if depa.failed {
+			a.failed = true
+		}
+	}
+	// sort dependencies because the list of dependencies is part of
+	// the cache key
+	sort.Slice(a.deps, func(i, j int) bool {
+		return a.deps[i].(*packageAction).Package.ID < a.deps[j].(*packageAction).Package.ID
+	})
+
+	a.pending = uint32(len(a.deps))
+
+	return a
+}
+
+func newAnalyzerAction(an *analysis.Analyzer, cache map[*analysis.Analyzer]*analyzerAction) *analyzerAction {
+	if a, ok := cache[an]; ok {
+		return a
+	}
+
+	a := &analyzerAction{
+		Analyzer:     an,
+		ObjectFacts:  map[objectFactKey]objectFact{},
+		PackageFacts: map[packageFactKey]analysis.Fact{},
+	}
+	cache[an] = a
+	for _, dep := range an.Requires {
+		depa := newAnalyzerAction(dep, cache)
+		depa.triggers = append(depa.triggers, a)
+		a.deps = append(a.deps, depa)
+	}
+	a.pending = uint32(len(a.deps))
+	return a
+}
+
+func getCachedFiles(c cache.Cache, ids []cache.ActionID, out []*string) error {
+	for i, id := range ids {
+		var err error
+		*out[i], _, err = cache.GetFile(c, id)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (r *subrunner) do(act action) error {
+	a := act.(*packageAction)
+	defer func() {
+		r.Stats.finishPackage()
+		if !a.factsOnly {
+			r.Stats.finishInitialPackage()
+		}
+	}()
+
+	// compute hash of action
+	a.cfg = a.Package.Config.Merge(r.cfg)
+	h := cache.NewHash("staticcheck " + a.Package.PkgPath)
+
+	// Note that we do not filter the list of analyzers by the
+	// package's configuration. We don't allow configuration to
+	// accidentally break dependencies between analyzers, and it's
+	// easier to always run all checks and filter the output. This
+	// also makes cached data more reusable.
+
+	// OPT(dh): not all changes in configuration invalidate cached
+	// data. specifically, when a.factsOnly == true, we only care
+	// about checks that produce facts, and settings that affect those
+	// checks.
+
+	// Config used for constructing the hash; this config doesn't have
+	// Checks populated, because we always run all checks.
+	//
+	// This even works for users who add custom checks, because we include the binary's hash.
+	hashCfg := a.cfg
+	hashCfg.Checks = nil
+	// note that we don't hash staticcheck's version; it is set as the
+	// salt by a package main.
+	fmt.Fprintf(h, "cfg %#v\n", hashCfg)
+	fmt.Fprintf(h, "pkg %x\n", a.Package.Hash)
+	fmt.Fprintf(h, "analyzers %s\n", r.analyzerNames)
+	fmt.Fprintf(h, "go %s\n", r.GoVersion)
+	fmt.Fprintf(h, "env godebug %q\n", os.Getenv("GODEBUG"))
+
+	// OPT(dh): do we actually need to hash vetx? can we not assume
+	// that for identical inputs, staticcheck will produce identical
+	// vetx?
+	for _, dep := range a.deps {
+		dep := dep.(*packageAction)
+		vetxHash, err := cache.FileHash(dep.vetx)
+		if err != nil {
+			return fmt.Errorf("failed computing hash: %w", err)
+		}
+		fmt.Fprintf(h, "vetout %q %x\n", dep.Package.PkgPath, vetxHash)
+	}
+	a.hash = cache.ActionID(h.Sum())
+
+	// try to fetch hashed data
+	ids := make([]cache.ActionID, 0, 2)
+	ids = append(ids, cache.Subkey(a.hash, "vetx"))
+	if !a.factsOnly {
+		ids = append(ids, cache.Subkey(a.hash, "results"))
+		if r.TestMode {
+			ids = append(ids, cache.Subkey(a.hash, "testdata"))
+		}
+	}
+	if err := getCachedFiles(r.cache, ids, []*string{&a.vetx, &a.results, &a.testData}); err != nil {
+		result, err := r.doUncached(a)
+		if err != nil {
+			return err
+		}
+		if a.failed {
+			return nil
+		}
+
+		a.skipped = result.skipped
+
+		// OPT(dh) instead of collecting all object facts and encoding
+		// them after analysis finishes, we could encode them as we
+		// go. however, that would require some locking.
+		//
+		// OPT(dh): We could sort gobFacts for more consistent output,
+		// but it doesn't matter. The hash of a package includes all
+		// of its files, so whether the vetx hash changes or not, a
+		// change to a package requires re-analyzing all dependents,
+		// even if the vetx data stayed the same. See also the note at
+		// the top of loader/hash.go.
+
+		tf := &bytes.Buffer{}
+		enc := gob.NewEncoder(tf)
+		for _, gf := range result.facts {
+			if err := enc.Encode(gf); err != nil {
+				return fmt.Errorf("failed gob encoding data: %w", err)
+			}
+		}
+
+		a.vetx, err = r.writeCacheReader(a, "vetx", bytes.NewReader(tf.Bytes()))
+		if err != nil {
+			return err
+		}
+
+		if a.factsOnly {
+			return nil
+		}
+
+		var out ResultData
+		out.Directives = make([]SerializedDirective, len(result.dirs))
+		for i, dir := range result.dirs {
+			out.Directives[i] = serializeDirective(dir, result.lpkg.Fset)
+		}
+
+		out.Diagnostics = result.diags
+		out.Unused = result.unused
+		a.results, err = r.writeCacheGob(a, "results", out)
+		if err != nil {
+			return err
+		}
+
+		if r.TestMode {
+			out := TestData{
+				Facts: result.testFacts,
+				Files: result.lpkg.GoFiles,
+			}
+			a.testData, err = r.writeCacheGob(a, "testdata", out)
+			if err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+// ActiveWorkers returns the number of currently running workers.
+func (r *Runner) ActiveWorkers() int {
+	return r.semaphore.Len()
+}
+
+// TotalWorkers returns the maximum number of possible workers.
+func (r *Runner) TotalWorkers() int {
+	return r.semaphore.Cap()
+}
+
+func (r *Runner) writeCacheReader(a *packageAction, kind string, rs io.ReadSeeker) (string, error) {
+	h := cache.Subkey(a.hash, kind)
+	out, _, err := r.cache.Put(h, rs)
+	if err != nil {
+		return "", fmt.Errorf("failed caching data: %w", err)
+	}
+	return r.cache.OutputFile(out), nil
+}
+
+func (r *Runner) writeCacheGob(a *packageAction, kind string, data any) (string, error) {
+	f, err := os.CreateTemp("", "staticcheck")
+	if err != nil {
+		return "", err
+	}
+	defer f.Close()
+	os.Remove(f.Name())
+	if err := gob.NewEncoder(f).Encode(data); err != nil {
+		return "", fmt.Errorf("failed gob encoding data: %w", err)
+	}
+	if _, err := f.Seek(0, io.SeekStart); err != nil {
+		return "", err
+	}
+	return r.writeCacheReader(a, kind, f)
+}
+
+type packageActionResult struct {
+	facts   []gobFact
+	diags   []Diagnostic
+	unused  unused.Result
+	dirs    []lint.Directive
+	lpkg    *loader.Package
+	skipped bool
+
+	// Only set when using test mode
+	testFacts []TestFact
+}
+
+func (r *subrunner) doUncached(a *packageAction) (packageActionResult, error) {
+	// OPT(dh): for a -> b; c -> b; if both a and b are being
+	// processed concurrently, we shouldn't load b's export data
+	// twice.
+
+	pkg, _, err := loader.Load(a.Package, &loader.Options{GoVersion: r.GoVersion})
+	if err != nil {
+		return packageActionResult{}, err
+	}
+
+	if len(pkg.Errors) > 0 {
+		// this handles errors that occurred during type-checking the
+		// package in loader.Load
+		for _, err := range pkg.Errors {
+			a.errors = append(a.errors, err)
+		}
+		a.failed = true
+		return packageActionResult{}, nil
+	}
+
+	if len(pkg.Syntax) == 0 && pkg.PkgPath != "unsafe" {
+		return packageActionResult{lpkg: pkg, skipped: true}, nil
+	}
+
+	// OPT(dh): instead of parsing directives twice (twice because
+	// U1000 depends on the facts.Directives analyzer), reuse the
+	// existing result
+	var dirs []lint.Directive
+	if !a.factsOnly {
+		dirs = lint.ParseDirectives(pkg.Syntax, pkg.Fset)
+	}
+	res, err := r.runAnalyzers(a, pkg)
+
+	return packageActionResult{
+		facts:     res.facts,
+		testFacts: res.testFacts,
+		diags:     res.diagnostics,
+		unused:    res.unused,
+		dirs:      dirs,
+		lpkg:      pkg,
+	}, err
+}
+
+func pkgPaths(root *types.Package) map[string]*types.Package {
+	out := map[string]*types.Package{}
+	var dfs func(*types.Package)
+	dfs = func(pkg *types.Package) {
+		if _, ok := out[pkg.Path()]; ok {
+			return
+		}
+		out[pkg.Path()] = pkg
+		for _, imp := range pkg.Imports() {
+			dfs(imp)
+		}
+	}
+	dfs(root)
+	return out
+}
+
+func (r *Runner) loadFacts(root *types.Package, dep *packageAction, objFacts map[objectFactKey]objectFact, pkgFacts map[packageFactKey]analysis.Fact) error {
+	// Load facts of all imported packages
+	vetx, err := os.Open(dep.vetx)
+	if err != nil {
+		return fmt.Errorf("failed loading cached facts: %w", err)
+	}
+	defer vetx.Close()
+
+	pathToPkg := pkgPaths(root)
+	dec := gob.NewDecoder(vetx)
+	for {
+		var gf gobFact
+		err := dec.Decode(&gf)
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			return fmt.Errorf("failed loading cached facts: %w", err)
+		}
+
+		pkg, ok := pathToPkg[gf.PkgPath]
+		if !ok {
+			continue
+		}
+		if gf.ObjPath == "" {
+			pkgFacts[packageFactKey{
+				Pkg:  pkg,
+				Type: reflect.TypeOf(gf.Fact),
+			}] = gf.Fact
+		} else {
+			obj, err := objectpath.Object(pkg, objectpath.Path(gf.ObjPath))
+			if err != nil {
+				continue
+			}
+			objFacts[objectFactKey{
+				Obj:  obj,
+				Type: reflect.TypeOf(gf.Fact),
+			}] = objectFact{gf.Fact, objectpath.Path(gf.ObjPath)}
+		}
+	}
+	return nil
+}
+
+func genericHandle(a action, root action, queue chan action, sem *tsync.Semaphore, exec func(a action) error) {
+	if a == root {
+		close(queue)
+		if sem != nil {
+			sem.Release()
+		}
+		return
+	}
+	if !a.IsFailed() {
+		// the action may have already been marked as failed during
+		// construction of the action graph, for example because of
+		// unresolved imports.
+
+		for _, dep := range a.Deps() {
+			if dep.IsFailed() {
+				// One of our dependencies failed, so mark this package as
+				// failed and bail. We don't need to record an error for
+				// this package, the relevant error will have been
+				// reported by the first package in the chain that failed.
+				a.MarkFailed()
+				break
+			}
+		}
+	}
+
+	if !a.IsFailed() {
+		if err := exec(a); err != nil {
+			a.MarkFailed()
+			a.AddError(err)
+		}
+	}
+	if sem != nil {
+		sem.Release()
+	}
+
+	for _, t := range a.Triggers() {
+		if t.DecrementPending() {
+			queue <- t
+		}
+	}
+}
+
+type analyzerRunner struct {
+	pkg *loader.Package
+	// object facts of our dependencies; may contain facts of
+	// analyzers other than the current one
+	depObjFacts map[objectFactKey]objectFact
+	// package facts of our dependencies; may contain facts of
+	// analyzers other than the current one
+	depPkgFacts map[packageFactKey]analysis.Fact
+	factsOnly   bool
+
+	stats *Stats
+}
+
+func (ar *analyzerRunner) do(act action) error {
+	a := act.(*analyzerAction)
+	results := map[*analysis.Analyzer]any{}
+	// TODO(dh): does this have to be recursive?
+	for _, dep := range a.deps {
+		dep := dep.(*analyzerAction)
+		results[dep.Analyzer] = dep.Result
+	}
+	// OPT(dh): cache factTypes, it is the same for all packages for a given analyzer
+	//
+	// OPT(dh): do we need the factTypes map? most analyzers have 0-1
+	// fact types. iterating over the slice is probably faster than
+	// indexing a map.
+	factTypes := map[reflect.Type]struct{}{}
+	for _, typ := range a.Analyzer.FactTypes {
+		factTypes[reflect.TypeOf(typ)] = struct{}{}
+	}
+	filterFactType := func(typ reflect.Type) bool {
+		_, ok := factTypes[typ]
+		return ok
+	}
+	a.Pass = &analysis.Pass{
+		Analyzer:   a.Analyzer,
+		Fset:       ar.pkg.Fset,
+		Files:      ar.pkg.Syntax,
+		OtherFiles: ar.pkg.OtherFiles,
+		Pkg:        ar.pkg.Types,
+		TypesInfo:  ar.pkg.TypesInfo,
+		TypesSizes: ar.pkg.TypesSizes,
+		Report: func(diag analysis.Diagnostic) {
+			if !ar.factsOnly {
+				if diag.Category == "" {
+					diag.Category = a.Analyzer.Name
+				}
+				d := Diagnostic{
+					Position: report.DisplayPosition(ar.pkg.Fset, diag.Pos),
+					End:      report.DisplayPosition(ar.pkg.Fset, diag.End),
+					Category: diag.Category,
+					Message:  diag.Message,
+				}
+				for _, sugg := range diag.SuggestedFixes {
+					s := SuggestedFix{
+						Message: sugg.Message,
+					}
+					for _, edit := range sugg.TextEdits {
+						s.TextEdits = append(s.TextEdits, TextEdit{
+							Position: report.DisplayPosition(ar.pkg.Fset, edit.Pos),
+							End:      report.DisplayPosition(ar.pkg.Fset, edit.End),
+							NewText:  edit.NewText,
+						})
+					}
+					d.SuggestedFixes = append(d.SuggestedFixes, s)
+				}
+				for _, rel := range diag.Related {
+					d.Related = append(d.Related, RelatedInformation{
+						Position: report.DisplayPosition(ar.pkg.Fset, rel.Pos),
+						End:      report.DisplayPosition(ar.pkg.Fset, rel.End),
+						Message:  rel.Message,
+					})
+				}
+				a.Diagnostics = append(a.Diagnostics, d)
+			}
+		},
+		ResultOf: results,
+		ImportObjectFact: func(obj types.Object, fact analysis.Fact) bool {
+			key := objectFactKey{
+				Obj:  obj,
+				Type: reflect.TypeOf(fact),
+			}
+			if f, ok := ar.depObjFacts[key]; ok {
+				reflect.ValueOf(fact).Elem().Set(reflect.ValueOf(f.fact).Elem())
+				return true
+			} else if f, ok := a.ObjectFacts[key]; ok {
+				reflect.ValueOf(fact).Elem().Set(reflect.ValueOf(f.fact).Elem())
+				return true
+			}
+			return false
+		},
+		ImportPackageFact: func(pkg *types.Package, fact analysis.Fact) bool {
+			key := packageFactKey{
+				Pkg:  pkg,
+				Type: reflect.TypeOf(fact),
+			}
+			if f, ok := ar.depPkgFacts[key]; ok {
+				reflect.ValueOf(fact).Elem().Set(reflect.ValueOf(f).Elem())
+				return true
+			} else if f, ok := a.PackageFacts[key]; ok {
+				reflect.ValueOf(fact).Elem().Set(reflect.ValueOf(f).Elem())
+				return true
+			}
+			return false
+		},
+		ExportObjectFact: func(obj types.Object, fact analysis.Fact) {
+			key := objectFactKey{
+				Obj:  obj,
+				Type: reflect.TypeOf(fact),
+			}
+			path, _ := objectpath.For(obj)
+			a.ObjectFacts[key] = objectFact{fact, path}
+		},
+		ExportPackageFact: func(fact analysis.Fact) {
+			key := packageFactKey{
+				Pkg:  ar.pkg.Types,
+				Type: reflect.TypeOf(fact),
+			}
+			a.PackageFacts[key] = fact
+		},
+		AllPackageFacts: func() []analysis.PackageFact {
+			out := make([]analysis.PackageFact, 0, len(ar.depPkgFacts)+len(a.PackageFacts))
+			for key, fact := range ar.depPkgFacts {
+				out = append(out, analysis.PackageFact{
+					Package: key.Pkg,
+					Fact:    fact,
+				})
+			}
+			for key, fact := range a.PackageFacts {
+				out = append(out, analysis.PackageFact{
+					Package: key.Pkg,
+					Fact:    fact,
+				})
+			}
+			return out
+		},
+		AllObjectFacts: func() []analysis.ObjectFact {
+			out := make([]analysis.ObjectFact, 0, len(ar.depObjFacts)+len(a.ObjectFacts))
+			for key, fact := range ar.depObjFacts {
+				if filterFactType(key.Type) {
+					out = append(out, analysis.ObjectFact{
+						Object: key.Obj,
+						Fact:   fact.fact,
+					})
+				}
+			}
+			for key, fact := range a.ObjectFacts {
+				if filterFactType(key.Type) {
+					out = append(out, analysis.ObjectFact{
+						Object: key.Obj,
+						Fact:   fact.fact,
+					})
+				}
+			}
+			return out
+		},
+	}
+
+	t := time.Now()
+	res, err := a.Analyzer.Run(a.Pass)
+	ar.stats.measureAnalyzer(a.Analyzer, ar.pkg.PackageSpec, time.Since(t))
+	if err != nil {
+		return err
+	}
+	a.Result = res
+	return nil
+}
+
+type analysisResult struct {
+	facts       []gobFact
+	diagnostics []Diagnostic
+	unused      unused.Result
+
+	// Only set when using test mode
+	testFacts []TestFact
+}
+
+func (r *subrunner) runAnalyzers(pkgAct *packageAction, pkg *loader.Package) (analysisResult, error) {
+	depObjFacts := map[objectFactKey]objectFact{}
+	depPkgFacts := map[packageFactKey]analysis.Fact{}
+
+	for _, dep := range pkgAct.deps {
+		if err := r.loadFacts(pkg.Types, dep.(*packageAction), depObjFacts, depPkgFacts); err != nil {
+			return analysisResult{}, err
+		}
+	}
+
+	root := &analyzerAction{}
+	var analyzers []*analysis.Analyzer
+	if pkgAct.factsOnly {
+		// When analyzing non-initial packages, we only care about
+		// analyzers that produce facts.
+		analyzers = r.factAnalyzers
+	} else {
+		analyzers = r.analyzers
+	}
+
+	all := map[*analysis.Analyzer]*analyzerAction{}
+	for _, a := range analyzers {
+		a := newAnalyzerAction(a, all)
+		root.deps = append(root.deps, a)
+		a.triggers = append(a.triggers, root)
+	}
+	root.pending = uint32(len(root.deps))
+
+	ar := &analyzerRunner{
+		pkg:         pkg,
+		factsOnly:   pkgAct.factsOnly,
+		depObjFacts: depObjFacts,
+		depPkgFacts: depPkgFacts,
+		stats:       &r.Stats,
+	}
+	queue := make(chan action, len(all))
+	for _, a := range all {
+		if len(a.Deps()) == 0 {
+			queue <- a
+		}
+	}
+
+	// Don't hang if there are no analyzers to run; for example
+	// because we are analyzing a dependency but have no analyzers
+	// that produce facts.
+	if len(all) == 0 {
+		close(queue)
+	}
+	for item := range queue {
+		b := r.semaphore.AcquireMaybe()
+		if b {
+			go genericHandle(item, root, queue, &r.semaphore, ar.do)
+		} else {
+			// the semaphore is exhausted; run the analysis under the
+			// token we've acquired for analyzing the package.
+			genericHandle(item, root, queue, nil, ar.do)
+		}
+	}
+
+	var unusedResult unused.Result
+	for _, a := range all {
+		if a != root && a.Analyzer.Name == "U1000" && !a.failed {
+			// TODO(dh): figure out a clean abstraction, instead of
+			// special-casing U1000.
+			unusedResult = a.Result.(unused.Result)
+		}
+
+		maps.Copy(depObjFacts, a.ObjectFacts)
+		maps.Copy(depPkgFacts, a.PackageFacts)
+	}
+
+	// OPT(dh): cull objects not reachable via the exported closure
+	var testFacts []TestFact
+	gobFacts := make([]gobFact, 0, len(depObjFacts)+len(depPkgFacts))
+	for key, fact := range depObjFacts {
+		if fact.path == "" {
+			continue
+		}
+		if sanityCheck {
+			p, _ := objectpath.For(key.Obj)
+			if p != fact.path {
+				panic(fmt.Sprintf("got different object paths for %v. old: %q new: %q", key.Obj, fact.path, p))
+			}
+		}
+		gf := gobFact{
+			PkgPath: key.Obj.Pkg().Path(),
+			ObjPath: string(fact.path),
+			Fact:    fact.fact,
+		}
+		gobFacts = append(gobFacts, gf)
+	}
+
+	for key, fact := range depPkgFacts {
+		gf := gobFact{
+			PkgPath: key.Pkg.Path(),
+			Fact:    fact,
+		}
+		gobFacts = append(gobFacts, gf)
+	}
+
+	if r.TestMode {
+		for _, a := range all {
+			for key, fact := range a.ObjectFacts {
+				tgf := TestFact{
+					ObjectName: key.Obj.Name(),
+					Position:   pkg.Fset.Position(key.Obj.Pos()),
+					FactString: fmt.Sprint(fact.fact),
+					Analyzer:   a.Analyzer.Name,
+				}
+				testFacts = append(testFacts, tgf)
+			}
+
+			for _, fact := range a.PackageFacts {
+				tgf := TestFact{
+					ObjectName: "",
+					Position:   pkg.Fset.Position(pkg.Syntax[0].Pos()),
+					FactString: fmt.Sprint(fact),
+					Analyzer:   a.Analyzer.Name,
+				}
+				testFacts = append(testFacts, tgf)
+			}
+		}
+	}
+
+	var diags []Diagnostic
+	for _, a := range root.deps {
+		a := a.(*analyzerAction)
+		diags = append(diags, a.Diagnostics...)
+	}
+	return analysisResult{
+		facts:       gobFacts,
+		testFacts:   testFacts,
+		diagnostics: diags,
+		unused:      unusedResult,
+	}, nil
+}
+
+func registerGobTypes(analyzers []*analysis.Analyzer) {
+	for _, a := range analyzers {
+		for _, typ := range a.FactTypes {
+			// FIXME(dh): use RegisterName so we can work around collisions
+			// in names. For pointer-types, gob incorrectly qualifies
+			// type names with the package name, not the import path.
+			gob.Register(typ)
+		}
+	}
+}
+
+func allAnalyzers(analyzers []*analysis.Analyzer) []*analysis.Analyzer {
+	seen := map[*analysis.Analyzer]struct{}{}
+	out := make([]*analysis.Analyzer, 0, len(analyzers))
+	var dfs func(*analysis.Analyzer)
+	dfs = func(a *analysis.Analyzer) {
+		if _, ok := seen[a]; ok {
+			return
+		}
+		seen[a] = struct{}{}
+		out = append(out, a)
+		for _, dep := range a.Requires {
+			dfs(dep)
+		}
+	}
+	for _, a := range analyzers {
+		dfs(a)
+	}
+	return out
+}
+
+// Run loads the packages specified by patterns, runs analyzers on
+// them and returns the results. Each result corresponds to a single
+// package. Results will be returned for all packages, including
+// dependencies. Errors specific to packages will be reported in the
+// respective results.
+//
+// If cfg is nil, a default config will be used. Otherwise, cfg will
+// be used, with the exception of the Mode field.
+func (r *Runner) Run(cfg *packages.Config, analyzers []*analysis.Analyzer, patterns []string) ([]Result, error) {
+	analyzers = allAnalyzers(analyzers)
+	registerGobTypes(analyzers)
+
+	r.Stats.setState(StateLoadPackageGraph)
+	lpkgs, err := loader.Graph(cfg, patterns...)
+	if err != nil {
+		return nil, err
+	}
+	r.Stats.setInitialPackages(len(lpkgs))
+
+	if len(lpkgs) == 0 {
+		return nil, nil
+	}
+
+	r.Stats.setState(StateBuildActionGraph)
+	all := map[*loader.PackageSpec]*packageAction{}
+	root := &packageAction{}
+	for _, lpkg := range lpkgs {
+		a := newPackageActionRoot(lpkg, all)
+		root.deps = append(root.deps, a)
+		a.triggers = append(a.triggers, root)
+	}
+	root.pending = uint32(len(root.deps))
+
+	queue := make(chan action)
+	r.Stats.setTotalPackages(len(all) - 1)
+
+	r.Stats.setState(StateProcessing)
+	go func() {
+		for _, a := range all {
+			if len(a.Deps()) == 0 {
+				queue <- a
+			}
+		}
+	}()
+
+	sr := newSubrunner(r, analyzers)
+	for item := range queue {
+		r.semaphore.Acquire()
+		go genericHandle(item, root, queue, &r.semaphore, func(act action) error {
+			return sr.do(act)
+		})
+	}
+
+	r.Stats.setState(StateFinalizing)
+	out := make([]Result, 0, len(all))
+	for _, item := range all {
+		if item.Package == nil {
+			continue
+		}
+		out = append(out, Result{
+			Package:  item.Package,
+			Config:   item.cfg,
+			Initial:  !item.factsOnly,
+			Skipped:  item.skipped,
+			Failed:   item.failed,
+			Errors:   item.errors,
+			results:  item.results,
+			testData: item.testData,
+		})
+	}
+	return out, nil
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/runner/stats.go b/vendor/honnef.co/go/tools/lintcmd/runner/stats.go
new file mode 100644
index 0000000..fd7da2f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/runner/stats.go
@@ -0,0 +1,49 @@
+package runner
+
+import (
+	"sync/atomic"
+	"time"
+
+	"honnef.co/go/tools/go/loader"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+const (
+	StateInitializing = iota
+	StateLoadPackageGraph
+	StateBuildActionGraph
+	StateProcessing
+	StateFinalizing
+)
+
+type Stats struct {
+	state                    uint32
+	initialPackages          uint32
+	totalPackages            uint32
+	processedPackages        uint32
+	processedInitialPackages uint32
+
+	// optional function to call every time an analyzer has finished analyzing a package.
+	PrintAnalyzerMeasurement func(*analysis.Analyzer, *loader.PackageSpec, time.Duration)
+}
+
+func (s *Stats) setState(state uint32)    { atomic.StoreUint32(&s.state, state) }
+func (s *Stats) State() int               { return int(atomic.LoadUint32(&s.state)) }
+func (s *Stats) setInitialPackages(n int) { atomic.StoreUint32(&s.initialPackages, uint32(n)) }
+func (s *Stats) InitialPackages() int     { return int(atomic.LoadUint32(&s.initialPackages)) }
+func (s *Stats) setTotalPackages(n int)   { atomic.StoreUint32(&s.totalPackages, uint32(n)) }
+func (s *Stats) TotalPackages() int       { return int(atomic.LoadUint32(&s.totalPackages)) }
+
+func (s *Stats) finishPackage()         { atomic.AddUint32(&s.processedPackages, 1) }
+func (s *Stats) finishInitialPackage()  { atomic.AddUint32(&s.processedInitialPackages, 1) }
+func (s *Stats) ProcessedPackages() int { return int(atomic.LoadUint32(&s.processedPackages)) }
+func (s *Stats) ProcessedInitialPackages() int {
+	return int(atomic.LoadUint32(&s.processedInitialPackages))
+}
+
+func (s *Stats) measureAnalyzer(analysis *analysis.Analyzer, pkg *loader.PackageSpec, d time.Duration) {
+	if s.PrintAnalyzerMeasurement != nil {
+		s.PrintAnalyzerMeasurement(analysis, pkg, d)
+	}
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/sarif.go b/vendor/honnef.co/go/tools/lintcmd/sarif.go
new file mode 100644
index 0000000..4e575aa
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/sarif.go
@@ -0,0 +1,371 @@
+package lintcmd
+
+// Notes on GitHub-specific restrictions:
+//
+// Result.Message needs to either have ID or Text set. Markdown
+// gets ignored. Text isn't treated verbatim however: Markdown
+// formatting gets stripped, except for links.
+//
+// GitHub does not display RelatedLocations. The only way to make
+// use of them is to link to them (via their ID) in the
+// Result.Message. And even then, it will only show the referred
+// line of code, not the message. We can duplicate the messages in
+// the Result.Message, but we can't even indent them, because
+// leading whitespace gets stripped.
+//
+// GitHub does use the Markdown version of rule help, but it
+// renders it the way it renders comments on issues – that is, it
+// turns line breaks into hard line breaks, even though it
+// shouldn't.
+//
+// GitHub doesn't make use of the tool's URI or version, nor of
+// the help URIs of rules.
+//
+// There does not seem to be a way of using SARIF for "normal" CI,
+// without results showing up as code scanning alerts. Also, a
+// SARIF file containing only warnings, no errors, will not fail
+// CI by default, but this is configurable.
+// GitHub does display some parts of SARIF results in PRs, but
+// most of the useful parts of SARIF, such as help text of rules,
+// is only accessible via the code scanning alerts, which are only
+// accessible by users with write permissions.
+//
+// Result.Suppressions is being ignored.
+//
+//
+// Notes on other tools
+//
+// VS Code Sarif viewer
+//
+// The Sarif viewer in VS Code displays the full message in the
+// tabular view, removing newlines. That makes our multi-line
+// messages (which we use as a workaround for missing related
+// information) very ugly.
+//
+// Much like GitHub, the Sarif viewer does not make related
+// information visible unless we explicitly refer to it in the
+// message.
+//
+// Suggested fixes are not exposed in any way.
+//
+// It only shows the shortDescription or fullDescription of a
+// rule, not its help. We can't put the help in fullDescription,
+// because the fullDescription isn't meant to be that long. For
+// example, GitHub displays it in a single line, under the
+// shortDescription.
+//
+// VS Code can filter based on Result.Suppressions, but it doesn't
+// display our suppression message. Also, by default, suppressed
+// results get shown, and the column indicating that a result is
+// suppressed is hidden, which makes for a confusing experience.
+//
+// When a rule has only an ID, no name, VS Code displays a
+// prominent dash in place of the name. When the name and ID are
+// identical, it prints both. However, we can't make them
+// identical, as SARIF requires that either the ID and name are
+// different, or that the name is omitted.
+
+// FIXME(dh): we're currently reporting column information using UTF-8
+// byte offsets, not using Unicode code points or UTF-16, which are
+// the only two ways allowed by SARIF.
+
+// TODO(dh) set properties.tags – we can use different tags for the
+// staticcheck, simple, stylecheck and unused checks, so users can
+// filter their results
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/url"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strings"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/sarif"
+)
+
+type sarifFormatter struct {
+	driverName    string
+	driverVersion string
+	driverWebsite string
+}
+
+func sarifLevel(severity lint.Severity) string {
+	switch severity {
+	case lint.SeverityNone:
+		// no configured severity, default to warning
+		return "warning"
+	case lint.SeverityError:
+		return "error"
+	case lint.SeverityDeprecated:
+		return "warning"
+	case lint.SeverityWarning:
+		return "warning"
+	case lint.SeverityInfo:
+		return "note"
+	case lint.SeverityHint:
+		return "note"
+	default:
+		// unreachable
+		return "none"
+	}
+}
+
+func encodePath(path string) string {
+	return (&url.URL{Path: path}).EscapedPath()
+}
+
+func sarifURI(path string) string {
+	u := url.URL{
+		Scheme: "file",
+		Path:   path,
+	}
+	return u.String()
+}
+
+func sarifArtifactLocation(name string) sarif.ArtifactLocation {
+	// Ideally we use relative paths so that GitHub can resolve them
+	name = shortPath(name)
+	if filepath.IsAbs(name) {
+		return sarif.ArtifactLocation{
+			URI: sarifURI(name),
+		}
+	} else {
+		return sarif.ArtifactLocation{
+			URI:       encodePath(name),
+			URIBaseID: "%SRCROOT%", // This is specific to GitHub,
+		}
+	}
+}
+
+func sarifFormatText(s string) string {
+	// GitHub doesn't ignore line breaks, even though it should, so we remove them.
+
+	var out strings.Builder
+	lines := strings.Split(s, "\n")
+	for i, line := range lines[:len(lines)-1] {
+		out.WriteString(line)
+		if line == "" {
+			out.WriteString("\n")
+		} else {
+			nextLine := lines[i+1]
+			if nextLine == "" || strings.HasPrefix(line, "> ") || strings.HasPrefix(line, "    ") {
+				out.WriteString("\n")
+			} else {
+				out.WriteString(" ")
+			}
+		}
+	}
+	out.WriteString(lines[len(lines)-1])
+	return convertCodeBlocks(out.String())
+}
+
+func moreCodeFollows(lines []string) bool {
+	for _, line := range lines {
+		if line == "" {
+			continue
+		}
+		if strings.HasPrefix(line, "    ") {
+			return true
+		} else {
+			return false
+		}
+	}
+	return false
+}
+
+var alpha = regexp.MustCompile(`^[a-zA-Z ]+$`)
+
+func convertCodeBlocks(text string) string {
+	var buf strings.Builder
+	lines := strings.Split(text, "\n")
+
+	inCode := false
+	empties := 0
+	for i, line := range lines {
+		if inCode {
+			if !moreCodeFollows(lines[i:]) {
+				if inCode {
+					fmt.Fprintln(&buf, "```")
+					inCode = false
+				}
+			}
+		}
+
+		prevEmpties := empties
+		if line == "" && !inCode {
+			empties++
+		} else {
+			empties = 0
+		}
+
+		if line == "" {
+			fmt.Fprintln(&buf)
+			continue
+		}
+
+		if strings.HasPrefix(line, "    ") {
+			line = line[4:]
+			if !inCode {
+				fmt.Fprintln(&buf, "```go")
+				inCode = true
+			}
+		}
+
+		onlyAlpha := alpha.MatchString(line)
+		out := line
+		if !inCode && prevEmpties >= 2 && onlyAlpha {
+			fmt.Fprintf(&buf, "## %s\n", out)
+		} else {
+			fmt.Fprint(&buf, out)
+			fmt.Fprintln(&buf)
+		}
+	}
+	if inCode {
+		fmt.Fprintln(&buf, "```")
+	}
+
+	return buf.String()
+}
+
+func (o *sarifFormatter) Format(checks []*lint.Analyzer, diagnostics []diagnostic) {
+	// TODO(dh): some diagnostics shouldn't be reported as results. For example, when the user specifies a package on the command line that doesn't exist.
+
+	cwd, _ := os.Getwd()
+	run := sarif.Run{
+		Tool: sarif.Tool{
+			Driver: sarif.ToolComponent{
+				Name:           o.driverName,
+				Version:        o.driverVersion,
+				InformationURI: o.driverWebsite,
+			},
+		},
+		Invocations: []sarif.Invocation{{
+			Arguments: os.Args[1:],
+			WorkingDirectory: sarif.ArtifactLocation{
+				URI: sarifURI(cwd),
+			},
+			ExecutionSuccessful: true,
+		}},
+	}
+	for _, c := range checks {
+		doc := c.Doc.Compile()
+		run.Tool.Driver.Rules = append(run.Tool.Driver.Rules,
+			sarif.ReportingDescriptor{
+				// We don't set Name, as Name and ID mustn't be identical.
+				ID: c.Analyzer.Name,
+				ShortDescription: sarif.Message{
+					Text:     doc.Title,
+					Markdown: doc.TitleMarkdown,
+				},
+				HelpURI: "https://staticcheck.dev/docs/checks#" + c.Analyzer.Name,
+				// We use our markdown as the plain text version, too. We
+				// use very little markdown, primarily quotations,
+				// indented code blocks and backticks. All of these are
+				// fine as plain text, too.
+				Help: sarif.Message{
+					Text:     sarifFormatText(doc.Format(false)),
+					Markdown: sarifFormatText(doc.FormatMarkdown(false)),
+				},
+				DefaultConfiguration: sarif.ReportingConfiguration{
+					// TODO(dh): we could figure out which checks were disabled globally
+					Enabled: true,
+					Level:   sarifLevel(doc.Severity),
+				},
+			})
+	}
+
+	for _, p := range diagnostics {
+		r := sarif.Result{
+			RuleID: p.Category,
+			Kind:   sarif.Fail,
+			Message: sarif.Message{
+				Text: p.Message,
+			},
+		}
+		r.Locations = []sarif.Location{{
+			PhysicalLocation: sarif.PhysicalLocation{
+				ArtifactLocation: sarifArtifactLocation(p.Position.Filename),
+				Region: sarif.Region{
+					StartLine:   p.Position.Line,
+					StartColumn: p.Position.Column,
+					EndLine:     p.End.Line,
+					EndColumn:   p.End.Column,
+				},
+			},
+		}}
+		for _, fix := range p.SuggestedFixes {
+			sfix := sarif.Fix{
+				Description: sarif.Message{
+					Text: fix.Message,
+				},
+			}
+			// file name -> replacements
+			changes := map[string][]sarif.Replacement{}
+			for _, edit := range fix.TextEdits {
+				changes[edit.Position.Filename] = append(changes[edit.Position.Filename], sarif.Replacement{
+					DeletedRegion: sarif.Region{
+						StartLine:   edit.Position.Line,
+						StartColumn: edit.Position.Column,
+						EndLine:     edit.End.Line,
+						EndColumn:   edit.End.Column,
+					},
+					InsertedContent: sarif.ArtifactContent{
+						Text: string(edit.NewText),
+					},
+				})
+			}
+			for path, replacements := range changes {
+				sfix.ArtifactChanges = append(sfix.ArtifactChanges, sarif.ArtifactChange{
+					ArtifactLocation: sarifArtifactLocation(path),
+					Replacements:     replacements,
+				})
+			}
+			r.Fixes = append(r.Fixes, sfix)
+		}
+		for i, related := range p.Related {
+			r.Message.Text += fmt.Sprintf("\n\t[%s](%d)", related.Message, i+1)
+
+			r.RelatedLocations = append(r.RelatedLocations,
+				sarif.Location{
+					ID: i + 1,
+					Message: &sarif.Message{
+						Text: related.Message,
+					},
+					PhysicalLocation: sarif.PhysicalLocation{
+						ArtifactLocation: sarifArtifactLocation(related.Position.Filename),
+						Region: sarif.Region{
+							StartLine:   related.Position.Line,
+							StartColumn: related.Position.Column,
+							EndLine:     related.End.Line,
+							EndColumn:   related.End.Column,
+						},
+					},
+				})
+		}
+
+		if p.Severity == severityIgnored {
+			// Note that GitHub does not support suppressions, which is why Staticcheck still requires the -show-ignored flag to be set for us to emit ignored diagnostics.
+
+			r.Suppressions = []sarif.Suppression{{
+				Kind: "inSource",
+				// TODO(dh): populate the Justification field
+			}}
+		} else {
+			// We want an empty slice, not nil. SARIF differentiates
+			// between the two. An empty slice means that the diagnostic
+			// wasn't suppressed, while nil means that we don't have the
+			// information available.
+			r.Suppressions = []sarif.Suppression{}
+		}
+		run.Results = append(run.Results, r)
+	}
+
+	json.NewEncoder(os.Stdout).Encode(sarif.Log{
+		Version: sarif.Version,
+		Schema:  sarif.Schema,
+		Runs:    []sarif.Run{run},
+	})
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/stats.go b/vendor/honnef.co/go/tools/lintcmd/stats.go
new file mode 100644
index 0000000..fa9613b
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/stats.go
@@ -0,0 +1,7 @@
+//go:build !aix && !android && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris
+
+package lintcmd
+
+import "os"
+
+var infoSignals = []os.Signal{}
diff --git a/vendor/honnef.co/go/tools/lintcmd/stats_bsd.go b/vendor/honnef.co/go/tools/lintcmd/stats_bsd.go
new file mode 100644
index 0000000..8704e64
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/stats_bsd.go
@@ -0,0 +1,10 @@
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
+
+package lintcmd
+
+import (
+	"os"
+	"syscall"
+)
+
+var infoSignals = []os.Signal{syscall.SIGINFO}
diff --git a/vendor/honnef.co/go/tools/lintcmd/stats_posix.go b/vendor/honnef.co/go/tools/lintcmd/stats_posix.go
new file mode 100644
index 0000000..2fdb3b7
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/stats_posix.go
@@ -0,0 +1,10 @@
+//go:build aix || android || linux || solaris
+
+package lintcmd
+
+import (
+	"os"
+	"syscall"
+)
+
+var infoSignals = []os.Signal{syscall.SIGUSR1}
diff --git a/vendor/honnef.co/go/tools/lintcmd/version/buildinfo.go b/vendor/honnef.co/go/tools/lintcmd/version/buildinfo.go
new file mode 100644
index 0000000..ecf50a1
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/version/buildinfo.go
@@ -0,0 +1,44 @@
+package version
+
+import (
+	"fmt"
+	"runtime/debug"
+)
+
+func printBuildInfo() {
+	if info, ok := debug.ReadBuildInfo(); ok {
+		fmt.Println("Main module:")
+		printModule(&info.Main)
+		fmt.Println("Dependencies:")
+		for _, dep := range info.Deps {
+			printModule(dep)
+		}
+	} else {
+		fmt.Println("Built without Go modules")
+	}
+}
+
+func buildInfoVersion() (string, bool) {
+	info, ok := debug.ReadBuildInfo()
+	if !ok {
+		return "", false
+	}
+	if info.Main.Version == "(devel)" {
+		return "", false
+	}
+	return info.Main.Version, true
+}
+
+func printModule(m *debug.Module) {
+	fmt.Printf("\t%s", m.Path)
+	if m.Version != "(devel)" {
+		fmt.Printf("@%s", m.Version)
+	}
+	if m.Sum != "" {
+		fmt.Printf(" (sum: %s)", m.Sum)
+	}
+	if m.Replace != nil {
+		fmt.Printf(" (replace: %s)", m.Replace.Path)
+	}
+	fmt.Println()
+}
diff --git a/vendor/honnef.co/go/tools/lintcmd/version/version.go b/vendor/honnef.co/go/tools/lintcmd/version/version.go
new file mode 100644
index 0000000..19a5b7e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/lintcmd/version/version.go
@@ -0,0 +1,43 @@
+package version
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"runtime"
+)
+
+const Version = "2026.2.2"
+const MachineVersion = "0.8.2"
+
+// version returns a version descriptor and reports whether the
+// version is a known release.
+func version(human, machine string) (human_, machine_ string, known bool) {
+	if human != "devel" {
+		return human, machine, true
+	}
+	v, ok := buildInfoVersion()
+	if ok {
+		return v, "", false
+	}
+	return "devel", "", false
+}
+
+func Print(human, machine string) {
+	human, machine, release := version(human, machine)
+
+	if release {
+		fmt.Printf("%s %s (%s)\n", filepath.Base(os.Args[0]), human, machine)
+	} else if human == "devel" {
+		fmt.Printf("%s (no version)\n", filepath.Base(os.Args[0]))
+	} else {
+		fmt.Printf("%s (devel, %s)\n", filepath.Base(os.Args[0]), human)
+	}
+}
+
+func Verbose(human, machine string) {
+	Print(human, machine)
+	fmt.Println()
+	fmt.Println("Compiled with Go version:", runtime.Version())
+	printBuildInfo()
+}
diff --git a/vendor/honnef.co/go/tools/pattern/convert.go b/vendor/honnef.co/go/tools/pattern/convert.go
new file mode 100644
index 0000000..ae9a0a5
--- /dev/null
+++ b/vendor/honnef.co/go/tools/pattern/convert.go
@@ -0,0 +1,243 @@
+package pattern
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"reflect"
+)
+
+var astTypes = map[string]reflect.Type{
+	"Ellipsis":       reflect.TypeFor[ast.Ellipsis](),
+	"RangeStmt":      reflect.TypeFor[ast.RangeStmt](),
+	"AssignStmt":     reflect.TypeFor[ast.AssignStmt](),
+	"IndexExpr":      reflect.TypeFor[ast.IndexExpr](),
+	"IndexListExpr":  reflect.TypeFor[ast.IndexListExpr](),
+	"Ident":          reflect.TypeFor[ast.Ident](),
+	"ValueSpec":      reflect.TypeFor[ast.ValueSpec](),
+	"GenDecl":        reflect.TypeFor[ast.GenDecl](),
+	"BinaryExpr":     reflect.TypeFor[ast.BinaryExpr](),
+	"ForStmt":        reflect.TypeFor[ast.ForStmt](),
+	"ArrayType":      reflect.TypeFor[ast.ArrayType](),
+	"DeferStmt":      reflect.TypeFor[ast.DeferStmt](),
+	"MapType":        reflect.TypeFor[ast.MapType](),
+	"ReturnStmt":     reflect.TypeFor[ast.ReturnStmt](),
+	"SliceExpr":      reflect.TypeFor[ast.SliceExpr](),
+	"StarExpr":       reflect.TypeFor[ast.StarExpr](),
+	"UnaryExpr":      reflect.TypeFor[ast.UnaryExpr](),
+	"SendStmt":       reflect.TypeFor[ast.SendStmt](),
+	"SelectStmt":     reflect.TypeFor[ast.SelectStmt](),
+	"ImportSpec":     reflect.TypeFor[ast.ImportSpec](),
+	"IfStmt":         reflect.TypeFor[ast.IfStmt](),
+	"GoStmt":         reflect.TypeFor[ast.GoStmt](),
+	"Field":          reflect.TypeFor[ast.Field](),
+	"SelectorExpr":   reflect.TypeFor[ast.SelectorExpr](),
+	"StructType":     reflect.TypeFor[ast.StructType](),
+	"KeyValueExpr":   reflect.TypeFor[ast.KeyValueExpr](),
+	"FuncType":       reflect.TypeFor[ast.FuncType](),
+	"FuncLit":        reflect.TypeFor[ast.FuncLit](),
+	"FuncDecl":       reflect.TypeFor[ast.FuncDecl](),
+	"ChanType":       reflect.TypeFor[ast.ChanType](),
+	"CallExpr":       reflect.TypeFor[ast.CallExpr](),
+	"CaseClause":     reflect.TypeFor[ast.CaseClause](),
+	"CommClause":     reflect.TypeFor[ast.CommClause](),
+	"CompositeLit":   reflect.TypeFor[ast.CompositeLit](),
+	"EmptyStmt":      reflect.TypeFor[ast.EmptyStmt](),
+	"SwitchStmt":     reflect.TypeFor[ast.SwitchStmt](),
+	"TypeSwitchStmt": reflect.TypeFor[ast.TypeSwitchStmt](),
+	"TypeAssertExpr": reflect.TypeFor[ast.TypeAssertExpr](),
+	"TypeSpec":       reflect.TypeFor[ast.TypeSpec](),
+	"InterfaceType":  reflect.TypeFor[ast.InterfaceType](),
+	"BranchStmt":     reflect.TypeFor[ast.BranchStmt](),
+	"IncDecStmt":     reflect.TypeFor[ast.IncDecStmt](),
+	"BasicLit":       reflect.TypeFor[ast.BasicLit](),
+}
+
+func ASTToNode(node any) Node {
+	switch node := node.(type) {
+	case *ast.File:
+		panic("cannot convert *ast.File to Node")
+	case nil:
+		return Nil{}
+	case string:
+		return String(node)
+	case token.Token:
+		return Token(node)
+	case *ast.ExprStmt:
+		return ASTToNode(node.X)
+	case *ast.BlockStmt:
+		if node == nil {
+			return Nil{}
+		}
+		return ASTToNode(node.List)
+	case *ast.FieldList:
+		if node == nil {
+			return Nil{}
+		}
+		return ASTToNode(node.List)
+	case *ast.BasicLit:
+		if node == nil {
+			return Nil{}
+		}
+	case *ast.ParenExpr:
+		return ASTToNode(node.X)
+	}
+
+	if node, ok := node.(ast.Node); ok {
+		name := reflect.TypeOf(node).Elem().Name()
+		T, ok := structNodes[name]
+		if !ok {
+			panic(fmt.Sprintf("internal error: unhandled type %T", node))
+		}
+
+		if reflect.ValueOf(node).IsNil() {
+			return Nil{}
+		}
+		v := reflect.ValueOf(node).Elem()
+		objs := make([]Node, T.NumField())
+		for i := 0; i < T.NumField(); i++ {
+			f := v.FieldByName(T.Field(i).Name)
+			objs[i] = ASTToNode(f.Interface())
+		}
+
+		n, err := populateNode(name, objs, false)
+		if err != nil {
+			panic(fmt.Sprintf("internal error: %s", err))
+		}
+		return n
+	}
+
+	s := reflect.ValueOf(node)
+	if s.Kind() == reflect.Slice {
+		if s.Len() == 0 {
+			return List{}
+		}
+		if s.Len() == 1 {
+			return ASTToNode(s.Index(0).Interface())
+		}
+
+		tail := List{}
+		for i := s.Len() - 1; i >= 0; i-- {
+			head := ASTToNode(s.Index(i).Interface())
+			l := List{
+				Head: head,
+				Tail: tail,
+			}
+			tail = l
+		}
+		return tail
+	}
+
+	panic(fmt.Sprintf("internal error: unhandled type %T", node))
+}
+
+func NodeToAST(node Node, state State) any {
+	switch node := node.(type) {
+	case Binding:
+		v, ok := state[node.Name]
+		if !ok {
+			// really we want to return an error here
+			panic("XXX")
+		}
+		switch v := v.(type) {
+		case types.Object:
+			return &ast.Ident{Name: v.Name()}
+		default:
+			return v
+		}
+	case Builtin, Any, Object, Symbol, Not, Or:
+		panic("XXX")
+	case List:
+		if (node == List{}) {
+			return []ast.Node{}
+		}
+		x := []ast.Node{NodeToAST(node.Head, state).(ast.Node)}
+		x = append(x, NodeToAST(node.Tail, state).([]ast.Node)...)
+		return x
+	case Token:
+		return token.Token(node)
+	case String:
+		return string(node)
+	case Nil:
+		return nil
+	}
+
+	name := reflect.TypeOf(node).Name()
+	T, ok := astTypes[name]
+	if !ok {
+		panic(fmt.Sprintf("internal error: unhandled type %T", node))
+	}
+	v := reflect.ValueOf(node)
+	out := reflect.New(T)
+	for i := 0; i < T.NumField(); i++ {
+		fNode := v.FieldByName(T.Field(i).Name)
+		if (fNode == reflect.Value{}) {
+			continue
+		}
+		fAST := out.Elem().FieldByName(T.Field(i).Name)
+		switch fAST.Type().Kind() {
+		case reflect.Slice:
+			c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state))
+			if c.Kind() != reflect.Slice {
+				// it's a single node in the pattern, we have to wrap
+				// it in a slice
+				slice := reflect.MakeSlice(fAST.Type(), 1, 1)
+				slice.Index(0).Set(c)
+				c = slice
+			}
+			switch fAST.Interface().(type) {
+			case []ast.Node:
+				switch cc := c.Interface().(type) {
+				case []ast.Node:
+					fAST.Set(c)
+				case []ast.Expr:
+					var slice []ast.Node
+					for _, el := range cc {
+						slice = append(slice, el)
+					}
+					fAST.Set(reflect.ValueOf(slice))
+				default:
+					panic("XXX")
+				}
+			case []ast.Expr:
+				switch cc := c.Interface().(type) {
+				case []ast.Node:
+					var slice []ast.Expr
+					for _, el := range cc {
+						slice = append(slice, el.(ast.Expr))
+					}
+					fAST.Set(reflect.ValueOf(slice))
+				case []ast.Expr:
+					fAST.Set(c)
+				default:
+					panic("XXX")
+				}
+			default:
+				panic("XXX")
+			}
+		case reflect.Int:
+			c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state))
+			switch c.Kind() {
+			case reflect.String:
+				tok, ok := tokensByString[c.Interface().(string)]
+				if !ok {
+					// really we want to return an error here
+					panic("XXX")
+				}
+				fAST.SetInt(int64(tok))
+			case reflect.Int:
+				fAST.Set(c)
+			default:
+				panic(fmt.Sprintf("internal error: unexpected kind %s", c.Kind()))
+			}
+		default:
+			r := NodeToAST(fNode.Interface().(Node), state)
+			if r != nil {
+				fAST.Set(reflect.ValueOf(r))
+			}
+		}
+	}
+
+	return out.Interface().(ast.Node)
+}
diff --git a/vendor/honnef.co/go/tools/pattern/doc.go b/vendor/honnef.co/go/tools/pattern/doc.go
new file mode 100644
index 0000000..22fe2cf
--- /dev/null
+++ b/vendor/honnef.co/go/tools/pattern/doc.go
@@ -0,0 +1,272 @@
+/*
+Package pattern implements a simple language for pattern matching Go ASTs.
+
+# Design decisions and trade-offs
+
+The language is designed specifically for the task of filtering ASTs
+to simplify the implementation of analyses in staticcheck.
+It is also intended to be trivial to parse and execute.
+
+To that end, we make certain decisions that make the language more
+suited to its task, while making certain queries infeasible.
+
+Furthermore, it is fully expected that the majority of analyses will still require ordinary Go code
+to further process the filtered AST, to make use of type information and to enforce complex invariants.
+It is not our goal to design a scripting language for writing entire checks in.
+
+# The language
+
+At its core, patterns are a representation of Go ASTs, allowing for the use of placeholders to enable pattern matching.
+Their syntax is inspired by LISP and Haskell, but unlike LISP, the core unit of patterns isn't the list, but the node.
+There is a fixed set of nodes, identified by name, and with the exception of the Or node, all nodes have a fixed number of arguments.
+In addition to nodes, there are atoms, which represent basic units such as strings or the nil value.
+
+Pattern matching is implemented via bindings, represented by the Binding node.
+A Binding can match nodes and associate them with names, to later recall the nodes.
+This allows for expressing "this node must be equal to that node" constraints.
+
+To simplify writing and reading patterns, a small amount of additional syntax exists on top of nodes and atoms.
+This additional syntax doesn't add any new features of its own, it simply provides shortcuts to creating nodes and atoms.
+
+To show an example of a pattern, first consider this snippet of Go code:
+
+	if x := fn(); x != nil {
+		for _, v := range x {
+			println(v, x)
+		}
+	}
+
+The corresponding AST expressed as an idiomatic pattern would look as follows:
+
+	(IfStmt
+		(AssignStmt (Ident "x") ":=" (CallExpr (Ident "fn") []))
+		(BinaryExpr (Ident "x") "!=" (Ident "nil"))
+		(RangeStmt
+			(Ident "_") (Ident "v") ":=" (Ident "x")
+			(CallExpr (Ident "println") [(Ident "v") (Ident "x")]))
+		nil)
+
+Two things are worth noting about this representation.
+First, the [el1 el2 ...] syntax is a short-hand for creating lists.
+It is a short-hand for el1:el2:[], which itself is a short-hand for (List el1 (List el2 (List nil nil)).
+Second, note the absence of a lot of lists in places that normally accept lists.
+For example, assignment assigns a number of right-hands to a number of left-hands, yet our AssignStmt is lacking any form of list.
+This is due to the fact that a single node can match a list of exactly one element.
+Thus, the two following forms have identical matching behavior:
+
+	(AssignStmt (Ident "x") ":=" (CallExpr (Ident "fn") []))
+	(AssignStmt [(Ident "x")] ":=" [(CallExpr (Ident "fn") [])])
+
+This section serves as an overview of the language's syntax.
+More in-depth explanations of the matching behavior as well as an exhaustive list of node types follows in the coming sections.
+
+# Pattern matching
+
+# TODO write about pattern matching
+
+- inspired by haskell syntax, but much, much simpler and naive
+
+# Node types
+
+The language contains two kinds of nodes: those that map to nodes in the AST, and those that implement additional logic.
+
+Nodes that map directly to AST nodes are named identically to the types in the go/ast package.
+What follows is an exhaustive list of these nodes:
+
+	(ArrayType len elt)
+	(AssignStmt lhs tok rhs)
+	(BasicLit kind value)
+	(BinaryExpr x op y)
+	(BranchStmt tok label)
+	(CallExpr fun args)
+	(CaseClause list body)
+	(ChanType dir value)
+	(CommClause comm body)
+	(CompositeLit type elts)
+	(DeferStmt call)
+	(Ellipsis elt)
+	(EmptyStmt)
+	(Field names type tag)
+	(ForStmt init cond post body)
+	(FuncDecl recv name type body)
+	(FuncLit type body)
+	(FuncType params results)
+	(GenDecl specs)
+	(GoStmt call)
+	(Ident name)
+	(IfStmt init cond body else)
+	(ImportSpec name path)
+	(IncDecStmt x tok)
+	(IndexExpr x index)
+	(InterfaceType methods)
+	(KeyValueExpr key value)
+	(MapType key value)
+	(RangeStmt key value tok x body)
+	(ReturnStmt results)
+	(SelectStmt body)
+	(SelectorExpr x sel)
+	(SendStmt chan value)
+	(SliceExpr x low high max)
+	(StarExpr x)
+	(StructType fields)
+	(SwitchStmt init tag body)
+	(TypeAssertExpr)
+	(TypeSpec name type)
+	(TypeSwitchStmt init assign body)
+	(UnaryExpr op x)
+	(ValueSpec names type values)
+
+Additionally, there are the String, Token and nil atoms.
+Strings are double-quoted string literals, as in (Ident "someName").
+Tokens are also represented as double-quoted string literals, but are converted to token.Token values in contexts that require tokens,
+such as in (BinaryExpr x "<" y), where "<" is transparently converted to token.LSS during matching.
+The keyword 'nil' denotes the nil value, which represents the absence of any value.
+
+We also define the (List head tail) node, which is used to represent sequences of elements as a singly linked list.
+The head is a single element, and the tail is the remainder of the list.
+For example,
+
+	(List "foo" (List "bar" (List "baz" (List nil nil))))
+
+represents a list of three elements, "foo", "bar" and "baz". There is dedicated syntax for writing lists, which looks as follows:
+
+	["foo" "bar" "baz"]
+
+This syntax is itself syntactic sugar for the following form:
+
+	"foo":"bar":"baz":[]
+
+This form is of particular interest for pattern matching, as it allows matching on the head and tail. For example,
+
+	"foo":"bar":_
+
+would match any list with at least two elements, where the first two elements are "foo" and "bar". This is equivalent to writing
+
+	(List "foo" (List "bar" _))
+
+Note that it is not possible to match from the end of the list.
+That is, there is no way to express a query such as "a list of any length where the last element is foo".
+
+Note that unlike in LISP, nil and empty lists are distinct from one another.
+In patterns, with respect to lists, nil is akin to Go's untyped nil.
+It will match a nil ast.Node, but it will not match a nil []ast.Expr. Nil will, however, match pointers to named types such as *ast.Ident.
+Similarly, lists are akin to Go's
+slices. An empty list will match both a nil and an empty []ast.Expr, but it will not match a nil ast.Node.
+
+Due to the difference between nil and empty lists, an empty list is represented as (List nil nil), i.e. a list with no head or tail.
+Similarly, a list of one element is represented as (List el (List nil nil)). Unlike in LISP, it cannot be represented by (List el nil).
+
+Finally, there are nodes that implement special logic or matching behavior.
+
+(Any) matches any value. The underscore (_) maps to this node, making the following two forms equivalent:
+
+	(Ident _)
+	(Ident (Any))
+
+(Builtin name) matches a built-in identifier or function by name.
+This is a type-aware variant of (Ident name).
+Instead of only comparing the name, it resolves the object behind the name and makes sure it's a pre-declared identifier.
+
+For example, in the following piece of code
+
+	func fn() {
+		println(true)
+		true := false
+		println(true)
+	}
+
+the pattern
+
+	(Builtin "true")
+
+will match exactly once, on the first use of 'true' in the function.
+Subsequent occurrences of 'true' no longer refer to the pre-declared identifier.
+
+(Object name) matches an identifier by name, but yields the
+types.Object it refers to.
+
+(Symbol name) matches ast.Idents and ast.SelectorExprs that refer to a symbol with a given fully qualified name.
+For example, "net/url.PathEscape" matches the PathEscape function in the net/url package,
+and "(net/url.EscapeError).Error" refers to the Error method on the net/url.EscapeError type,
+either on an instance of the type, or on the type itself.
+
+For example, the following patterns match the following lines of code:
+
+	(CallExpr (Symbol "fmt.Println") _) // pattern 1
+	(CallExpr (Symbol "(net/url.EscapeError).Error") _) // pattern 2
+
+	fmt.Println("hello, world") // matches pattern 1
+	var x url.EscapeError
+	x.Error() // matches pattern 2
+	(url.EscapeError).Error(x) // also matches pattern 2
+
+(Binding name node) creates or uses a binding.
+Bindings work like variable assignments, allowing referring to already matched nodes.
+As an example, bindings are necessary to match self-assignment of the form "x = x",
+since we need to express that the right-hand side is identical to the left-hand side.
+
+If a binding's node is not nil, the matcher will attempt to match a node according to the pattern.
+If a binding's node is nil, the binding will either recall an existing value, or match the Any node.
+It is an error to provide a non-nil node to a binding that has already been bound.
+
+Referring back to the earlier example, the following pattern will match self-assignment of idents:
+
+	(AssignStmt (Binding "lhs" (Ident _)) "=" (Binding "lhs" nil))
+
+Because bindings are a crucial component of pattern matching, there is special syntax for creating and recalling bindings.
+Lower-case names refer to bindings. If standing on its own, the name "foo" will be equivalent to (Binding "foo" nil).
+If a name is followed by an at-sign (@) then it will create a binding for the node that follows.
+Together, this allows us to rewrite the earlier example as follows:
+
+	(AssignStmt lhs@(Ident _) "=" lhs)
+
+(Or nodes...) is a variadic node that tries matching each node until one succeeds. For example, the following pattern matches all idents of name "foo" or "bar":
+
+	(Ident (Or "foo" "bar"))
+
+We could also have written
+
+	(Or (Ident "foo") (Ident "bar"))
+
+and achieved the same result. We can also mix different kinds of nodes:
+
+	(Or (Ident "foo") (CallExpr (Ident "bar") _))
+
+When using bindings inside of nodes used inside Or, all or none of the bindings will be bound.
+That is, partially matched nodes that ultimately failed to match will not produce any bindings observable outside of the matching attempt.
+We can thus write
+
+	(Or (Ident name) (CallExpr name))
+
+and 'name' will either be a String if the first option matched, or an Ident or SelectorExpr if the second option matched.
+
+(Not node)
+
+The Not node negates a match. For example, (Not (Ident _)) will match all nodes that aren't identifiers.
+
+ChanDir(0)
+
+# Automatic unnesting of AST nodes
+
+The Go AST has several types of nodes that wrap other nodes.
+To simplify matching, we automatically unwrap some of these nodes.
+
+These nodes are ExprStmt (for using expressions in a statement context),
+ParenExpr (for parenthesized expressions),
+DeclStmt (for declarations in a statement context),
+and LabeledStmt (for labeled statements).
+
+Thus, the query
+
+	(FuncLit _ [(CallExpr _ _)]
+
+will match a function literal containing a single function call,
+even though in the actual Go AST, the CallExpr is nested inside an ExprStmt,
+as function bodies are made up of sequences of statements.
+
+On the flip-side, there is no way to specifically match these wrapper nodes.
+For example, there is no way of searching for unnecessary parentheses, like in the following piece of Go code:
+
+	((x)) += 2
+*/
+package pattern
diff --git a/vendor/honnef.co/go/tools/pattern/lexer.go b/vendor/honnef.co/go/tools/pattern/lexer.go
new file mode 100644
index 0000000..8ab8f56
--- /dev/null
+++ b/vendor/honnef.co/go/tools/pattern/lexer.go
@@ -0,0 +1,257 @@
+package pattern
+
+import (
+	"fmt"
+	"go/token"
+	"iter"
+	"unicode"
+	"unicode/utf8"
+)
+
+// lex returns the sequence of tokens in the input.
+func lex(f *token.File, input string) iter.Seq[item] {
+	return func(yield func(item) bool) {
+		lex := &lexer{
+			f:     f,
+			input: input,
+			yield: yield,
+		}
+		lex.run()
+	}
+}
+
+// lexer holds the state of a single [lex] iteration.
+type lexer struct {
+	f *token.File
+
+	input string
+	start int
+	pos   int
+	width int
+
+	yield func(item) bool
+}
+
+type itemType int
+
+const eof = -1
+
+const (
+	itemError itemType = iota
+	itemLeftParen
+	itemRightParen
+	itemLeftBracket
+	itemRightBracket
+	itemTypeName
+	itemVariable
+	itemAt
+	itemColon
+	itemBlank
+	itemString
+	itemEOF
+)
+
+func (typ itemType) String() string {
+	switch typ {
+	case itemError:
+		return "ERROR"
+	case itemLeftParen:
+		return "("
+	case itemRightParen:
+		return ")"
+	case itemLeftBracket:
+		return "["
+	case itemRightBracket:
+		return "]"
+	case itemTypeName:
+		return "TYPE"
+	case itemVariable:
+		return "VAR"
+	case itemAt:
+		return "@"
+	case itemColon:
+		return ":"
+	case itemBlank:
+		return "_"
+	case itemString:
+		return "STRING"
+	case itemEOF:
+		return "EOF"
+	default:
+		return fmt.Sprintf("itemType(%d)", typ)
+	}
+}
+
+type item struct {
+	typ itemType
+	val string
+	pos int
+}
+
+type stateFn func(*lexer) stateFn
+
+func (l *lexer) run() {
+	for state := lexStart; state != nil; {
+		state = state(l)
+	}
+}
+
+func (l *lexer) emitValue(t itemType, value string) bool {
+	ok := l.yield(item{t, value, l.start})
+	l.start = l.pos
+	return ok
+}
+
+func (l *lexer) emit(t itemType) bool {
+	ok := l.yield(item{t, l.input[l.start:l.pos], l.start})
+	l.start = l.pos
+	return ok
+}
+
+func lexStart(l *lexer) stateFn {
+	switch r := l.next(); {
+	case r == eof:
+		_ = l.emit(itemEOF)
+		return nil
+	case unicode.IsSpace(r):
+		l.ignore()
+	case r == '(':
+		if !l.emit(itemLeftParen) {
+			return nil
+		}
+	case r == ')':
+		if !l.emit(itemRightParen) {
+			return nil
+		}
+	case r == '[':
+		if !l.emit(itemLeftBracket) {
+			return nil
+		}
+	case r == ']':
+		if !l.emit(itemRightBracket) {
+			return nil
+		}
+	case r == '@':
+		if !l.emit(itemAt) {
+			return nil
+		}
+	case r == ':':
+		if !l.emit(itemColon) {
+			return nil
+		}
+	case r == '_':
+		if !l.emit(itemBlank) {
+			return nil
+		}
+	case r == '"':
+		l.backup()
+		return lexString
+	case unicode.IsUpper(r):
+		l.backup()
+		return lexType
+	case unicode.IsLower(r):
+		l.backup()
+		return lexVariable
+	default:
+		return l.errorf("unexpected character %c", r)
+	}
+	return lexStart
+}
+
+func (l *lexer) next() (r rune) {
+	if l.pos >= len(l.input) {
+		l.width = 0
+		return eof
+	}
+	r, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
+
+	if r == '\n' {
+		l.f.AddLine(l.pos)
+	}
+
+	l.pos += l.width
+
+	return r
+}
+
+func (l *lexer) ignore() {
+	l.start = l.pos
+}
+
+func (l *lexer) backup() {
+	l.pos -= l.width
+}
+
+func (l *lexer) errorf(format string, args ...any) stateFn {
+	// TODO(dh): emit position information in errors
+	_ = l.yield(item{
+		itemError,
+		fmt.Sprintf(format, args...),
+		l.start,
+	})
+	return nil
+}
+
+func isAlphaNumeric(r rune) bool {
+	return r >= '0' && r <= '9' ||
+		r >= 'a' && r <= 'z' ||
+		r >= 'A' && r <= 'Z'
+}
+
+func lexString(l *lexer) stateFn {
+	l.next() // skip quote
+	escape := false
+
+	var runes []rune
+	for {
+		switch r := l.next(); r {
+		case eof:
+			return l.errorf("unterminated string")
+		case '"':
+			if !escape {
+				if !l.emitValue(itemString, string(runes)) {
+					return nil
+				}
+				return lexStart
+			} else {
+				runes = append(runes, '"')
+				escape = false
+			}
+		case '\\':
+			if escape {
+				runes = append(runes, '\\')
+				escape = false
+			} else {
+				escape = true
+			}
+		default:
+			runes = append(runes, r)
+		}
+	}
+}
+
+func lexType(l *lexer) stateFn {
+	l.next()
+	for {
+		if !isAlphaNumeric(l.next()) {
+			l.backup()
+			if !l.emit(itemTypeName) {
+				return nil
+			}
+			return lexStart
+		}
+	}
+}
+
+func lexVariable(l *lexer) stateFn {
+	l.next()
+	for {
+		if !isAlphaNumeric(l.next()) {
+			l.backup()
+			if !l.emit(itemVariable) {
+				return nil
+			}
+			return lexStart
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/pattern/match.go b/vendor/honnef.co/go/tools/pattern/match.go
new file mode 100644
index 0000000..1d3eaae
--- /dev/null
+++ b/vendor/honnef.co/go/tools/pattern/match.go
@@ -0,0 +1,712 @@
+package pattern
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"reflect"
+)
+
+var tokensByString = map[string]Token{
+	"INT":         Token(token.INT),
+	"FLOAT":       Token(token.FLOAT),
+	"IMAG":        Token(token.IMAG),
+	"CHAR":        Token(token.CHAR),
+	"STRING":      Token(token.STRING),
+	"+":           Token(token.ADD),
+	"-":           Token(token.SUB),
+	"*":           Token(token.MUL),
+	"/":           Token(token.QUO),
+	"%":           Token(token.REM),
+	"&":           Token(token.AND),
+	"|":           Token(token.OR),
+	"^":           Token(token.XOR),
+	"<<":          Token(token.SHL),
+	">>":          Token(token.SHR),
+	"&^":          Token(token.AND_NOT),
+	"+=":          Token(token.ADD_ASSIGN),
+	"-=":          Token(token.SUB_ASSIGN),
+	"*=":          Token(token.MUL_ASSIGN),
+	"/=":          Token(token.QUO_ASSIGN),
+	"%=":          Token(token.REM_ASSIGN),
+	"&=":          Token(token.AND_ASSIGN),
+	"|=":          Token(token.OR_ASSIGN),
+	"^=":          Token(token.XOR_ASSIGN),
+	"<<=":         Token(token.SHL_ASSIGN),
+	">>=":         Token(token.SHR_ASSIGN),
+	"&^=":         Token(token.AND_NOT_ASSIGN),
+	"&&":          Token(token.LAND),
+	"||":          Token(token.LOR),
+	"<-":          Token(token.ARROW),
+	"++":          Token(token.INC),
+	"--":          Token(token.DEC),
+	"==":          Token(token.EQL),
+	"<":           Token(token.LSS),
+	">":           Token(token.GTR),
+	"=":           Token(token.ASSIGN),
+	"!":           Token(token.NOT),
+	"!=":          Token(token.NEQ),
+	"<=":          Token(token.LEQ),
+	">=":          Token(token.GEQ),
+	":=":          Token(token.DEFINE),
+	"...":         Token(token.ELLIPSIS),
+	"IMPORT":      Token(token.IMPORT),
+	"VAR":         Token(token.VAR),
+	"TYPE":        Token(token.TYPE),
+	"CONST":       Token(token.CONST),
+	"BREAK":       Token(token.BREAK),
+	"CONTINUE":    Token(token.CONTINUE),
+	"GOTO":        Token(token.GOTO),
+	"FALLTHROUGH": Token(token.FALLTHROUGH),
+}
+
+func maybeToken(node Node) (Node, bool) {
+	if node, ok := node.(String); ok {
+		if tok, ok := tokensByString[string(node)]; ok {
+			return tok, true
+		}
+		return node, false
+	}
+	return node, false
+}
+
+func isNil(v any) bool {
+	if v == nil {
+		return true
+	}
+	if _, ok := v.(Nil); ok {
+		return true
+	}
+	return false
+}
+
+type matcher interface {
+	Match(*Matcher, any) (any, bool)
+}
+
+type State = map[string]any
+
+type Matcher struct {
+	TypesInfo *types.Info
+	State     State
+
+	bindingsMapping []string
+
+	setBindings []uint64
+}
+
+func (m *Matcher) set(b Binding, value any) {
+	m.State[b.Name] = value
+	m.setBindings[len(m.setBindings)-1] |= 1 << b.idx
+}
+
+func (m *Matcher) push() {
+	m.setBindings = append(m.setBindings, 0)
+}
+
+func (m *Matcher) pop() {
+	set := m.setBindings[len(m.setBindings)-1]
+	if set != 0 {
+		for i := 0; i < len(m.bindingsMapping); i++ {
+			if (set & (1 << i)) != 0 {
+				key := m.bindingsMapping[i]
+				delete(m.State, key)
+			}
+		}
+	}
+	m.setBindings = m.setBindings[:len(m.setBindings)-1]
+}
+
+func (m *Matcher) merge() {
+	m.setBindings = m.setBindings[:len(m.setBindings)-1]
+}
+
+func (m *Matcher) Match(a Pattern, b ast.Node) bool {
+	m.bindingsMapping = a.Bindings
+	m.State = State{}
+	m.push()
+	_, ok := match(m, a.Root, b)
+	m.merge()
+	if len(m.setBindings) != 0 {
+		panic(fmt.Sprintf("%d entries left on the stack, expected none", len(m.setBindings)))
+	}
+	return ok
+}
+
+func Match(a Pattern, b ast.Node) (*Matcher, bool) {
+	m := &Matcher{}
+	ret := m.Match(a, b)
+	return m, ret
+}
+
+// Match two items, which may be (Node, AST) or (AST, AST)
+func match(m *Matcher, l, r any) (any, bool) {
+	if _, ok := r.(Node); ok {
+		panic("Node mustn't be on right side of match")
+	}
+
+	switch l := l.(type) {
+	case *ast.ParenExpr:
+		return match(m, l.X, r)
+	case *ast.ExprStmt:
+		return match(m, l.X, r)
+	case *ast.DeclStmt:
+		return match(m, l.Decl, r)
+	case *ast.LabeledStmt:
+		return match(m, l.Stmt, r)
+	case *ast.BlockStmt:
+		return match(m, l.List, r)
+	case *ast.FieldList:
+		if l == nil {
+			return match(m, nil, r)
+		} else {
+			return match(m, l.List, r)
+		}
+	}
+
+	switch r := r.(type) {
+	case *ast.ParenExpr:
+		return match(m, l, r.X)
+	case *ast.ExprStmt:
+		return match(m, l, r.X)
+	case *ast.DeclStmt:
+		return match(m, l, r.Decl)
+	case *ast.LabeledStmt:
+		return match(m, l, r.Stmt)
+	case *ast.BlockStmt:
+		if r == nil {
+			return match(m, l, nil)
+		}
+		return match(m, l, r.List)
+	case *ast.FieldList:
+		if r == nil {
+			return match(m, l, nil)
+		}
+		return match(m, l, r.List)
+	case *ast.BasicLit:
+		if r == nil {
+			return match(m, l, nil)
+		}
+	}
+
+	if l, ok := l.(matcher); ok {
+		return l.Match(m, r)
+	}
+
+	if l, ok := l.(Node); ok {
+		// Matching of pattern with concrete value
+		return matchNodeAST(m, l, r)
+	}
+
+	if l == nil || r == nil {
+		return nil, l == r
+	}
+
+	{
+		ln, ok1 := l.(ast.Node)
+		rn, ok2 := r.(ast.Node)
+		if ok1 && ok2 {
+			return matchAST(m, ln, rn)
+		}
+	}
+
+	{
+		obj, ok := l.(types.Object)
+		if ok {
+			switch r := r.(type) {
+			case *ast.Ident:
+				return obj, obj == m.TypesInfo.ObjectOf(r)
+			case *ast.SelectorExpr:
+				return obj, obj == m.TypesInfo.ObjectOf(r.Sel)
+			default:
+				return obj, false
+			}
+		}
+	}
+
+	// TODO(dh): the three blocks handling slices can be combined into a single block if we use reflection
+
+	{
+		ln, ok1 := l.([]ast.Expr)
+		rn, ok2 := r.([]ast.Expr)
+		if ok1 || ok2 {
+			if ok1 && !ok2 {
+				cast, ok := r.(ast.Expr)
+				if !ok {
+					return nil, false
+				}
+				rn = []ast.Expr{cast}
+			} else if !ok1 && ok2 {
+				cast, ok := l.(ast.Expr)
+				if !ok {
+					return nil, false
+				}
+				ln = []ast.Expr{cast}
+			}
+
+			if len(ln) != len(rn) {
+				return nil, false
+			}
+			for i, ll := range ln {
+				if _, ok := match(m, ll, rn[i]); !ok {
+					return nil, false
+				}
+			}
+			return r, true
+		}
+	}
+
+	{
+		ln, ok1 := l.([]ast.Stmt)
+		rn, ok2 := r.([]ast.Stmt)
+		if ok1 || ok2 {
+			if ok1 && !ok2 {
+				cast, ok := r.(ast.Stmt)
+				if !ok {
+					return nil, false
+				}
+				rn = []ast.Stmt{cast}
+			} else if !ok1 && ok2 {
+				cast, ok := l.(ast.Stmt)
+				if !ok {
+					return nil, false
+				}
+				ln = []ast.Stmt{cast}
+			}
+
+			if len(ln) != len(rn) {
+				return nil, false
+			}
+			for i, ll := range ln {
+				if _, ok := match(m, ll, rn[i]); !ok {
+					return nil, false
+				}
+			}
+			return r, true
+		}
+	}
+
+	{
+		ln, ok1 := l.([]*ast.Field)
+		rn, ok2 := r.([]*ast.Field)
+		if ok1 || ok2 {
+			if ok1 && !ok2 {
+				cast, ok := r.(*ast.Field)
+				if !ok {
+					return nil, false
+				}
+				rn = []*ast.Field{cast}
+			} else if !ok1 && ok2 {
+				cast, ok := l.(*ast.Field)
+				if !ok {
+					return nil, false
+				}
+				ln = []*ast.Field{cast}
+			}
+
+			if len(ln) != len(rn) {
+				return nil, false
+			}
+			for i, ll := range ln {
+				if _, ok := match(m, ll, rn[i]); !ok {
+					return nil, false
+				}
+			}
+			return r, true
+		}
+	}
+
+	return nil, false
+}
+
+// Match a Node with an AST node
+func matchNodeAST(m *Matcher, a Node, b any) (any, bool) {
+	switch b := b.(type) {
+	case []ast.Stmt:
+		// 'a' is not a List or we'd be using its Match
+		// implementation.
+
+		if len(b) != 1 {
+			return nil, false
+		}
+		return match(m, a, b[0])
+	case []ast.Expr:
+		// 'a' is not a List or we'd be using its Match
+		// implementation.
+
+		if len(b) != 1 {
+			return nil, false
+		}
+		return match(m, a, b[0])
+	case []*ast.Field:
+		// 'a' is not a List or we'd be using its Match
+		// implementation
+		if len(b) != 1 {
+			return nil, false
+		}
+		return match(m, a, b[0])
+	case ast.Node:
+		ra := reflect.ValueOf(a)
+		rb := reflect.ValueOf(b).Elem()
+
+		if ra.Type().Name() != rb.Type().Name() {
+			return nil, false
+		}
+
+		for i := 0; i < ra.NumField(); i++ {
+			af := ra.Field(i)
+			fieldName := ra.Type().Field(i).Name
+			bf := rb.FieldByName(fieldName)
+			if (bf == reflect.Value{}) {
+				panic(fmt.Sprintf("internal error: could not find field %s in type %t when comparing with %T", fieldName, b, a))
+			}
+			ai := af.Interface()
+			bi := bf.Interface()
+			if ai == nil {
+				return b, bi == nil
+			}
+			if _, ok := match(m, ai.(Node), bi); !ok {
+				return b, false
+			}
+		}
+		return b, true
+	case nil:
+		return nil, a == Nil{}
+	case string, token.Token:
+		// 'a' can't be a String, Token, or Binding or we'd be using their Match implementations.
+		return nil, false
+	default:
+		panic(fmt.Sprintf("unhandled type %T", b))
+	}
+}
+
+// Match two AST nodes
+func matchAST(m *Matcher, a, b ast.Node) (any, bool) {
+	ra := reflect.ValueOf(a)
+	rb := reflect.ValueOf(b)
+
+	if ra.Type() != rb.Type() {
+		return nil, false
+	}
+	if ra.IsNil() || rb.IsNil() {
+		return rb, ra.IsNil() == rb.IsNil()
+	}
+
+	ra = ra.Elem()
+	rb = rb.Elem()
+	for i := 0; i < ra.NumField(); i++ {
+		af := ra.Field(i)
+		bf := rb.Field(i)
+		if af.Type() == rtTokPos || af.Type() == rtObject || af.Type() == rtCommentGroup {
+			continue
+		}
+
+		switch af.Kind() {
+		case reflect.Slice:
+			if af.Len() != bf.Len() {
+				return nil, false
+			}
+			for j := 0; j < af.Len(); j++ {
+				if _, ok := match(m, af.Index(j).Interface().(ast.Node), bf.Index(j).Interface().(ast.Node)); !ok {
+					return nil, false
+				}
+			}
+		case reflect.String:
+			if af.String() != bf.String() {
+				return nil, false
+			}
+		case reflect.Int:
+			if af.Int() != bf.Int() {
+				return nil, false
+			}
+		case reflect.Bool:
+			if af.Bool() != bf.Bool() {
+				return nil, false
+			}
+		case reflect.Pointer, reflect.Interface:
+			if _, ok := match(m, af.Interface(), bf.Interface()); !ok {
+				return nil, false
+			}
+		default:
+			panic(fmt.Sprintf("internal error: unhandled kind %s (%T)", af.Kind(), af.Interface()))
+		}
+	}
+	return b, true
+}
+
+func (b Binding) Match(m *Matcher, node any) (any, bool) {
+	if isNil(b.Node) {
+		v, ok := m.State[b.Name]
+		if ok {
+			// Recall value
+			return match(m, v, node)
+		}
+		// Matching anything
+		b.Node = Any{}
+	}
+
+	// Store value
+	if _, ok := m.State[b.Name]; ok {
+		panic(fmt.Sprintf("binding already created: %s", b.Name))
+	}
+	new, ret := match(m, b.Node, node)
+	if ret {
+		m.set(b, new)
+	}
+	return new, ret
+}
+
+func (Any) Match(m *Matcher, node any) (any, bool) {
+	return node, true
+}
+
+func (l List) Match(m *Matcher, node any) (any, bool) {
+	v := reflect.ValueOf(node)
+	if v.Kind() == reflect.Slice {
+		if isNil(l.Head) {
+			return node, v.Len() == 0
+		}
+		if v.Len() == 0 {
+			return nil, false
+		}
+		// OPT(dh): don't check the entire tail if head didn't match
+		_, ok1 := match(m, l.Head, v.Index(0).Interface())
+		_, ok2 := match(m, l.Tail, v.Slice(1, v.Len()).Interface())
+		return node, ok1 && ok2
+	}
+	// Our empty list does not equal an untyped Go nil. This way, we can
+	// tell apart an if with no else and an if with an empty else.
+	return nil, false
+}
+
+func (s String) Match(m *Matcher, node any) (any, bool) {
+	switch o := node.(type) {
+	case token.Token:
+		if tok, ok := maybeToken(s); ok {
+			return match(m, tok, node)
+		}
+		return nil, false
+	case string:
+		return o, string(s) == o
+	case types.TypeAndValue:
+		return o, o.Value != nil && o.Value.String() == string(s)
+	default:
+		return nil, false
+	}
+}
+
+func (tok Token) Match(m *Matcher, node any) (any, bool) {
+	o, ok := node.(token.Token)
+	if !ok {
+		return nil, false
+	}
+	return o, token.Token(tok) == o
+}
+
+func (Nil) Match(m *Matcher, node any) (any, bool) {
+	if isNil(node) {
+		return nil, true
+	}
+	v := reflect.ValueOf(node)
+	switch v.Kind() {
+	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice:
+		return nil, v.IsNil()
+	default:
+		return nil, false
+	}
+}
+
+func (builtin Builtin) Match(m *Matcher, node any) (any, bool) {
+	r, ok := match(m, Ident(builtin), node)
+	if !ok {
+		return nil, false
+	}
+	ident := r.(*ast.Ident)
+	obj := m.TypesInfo.ObjectOf(ident)
+	if obj != types.Universe.Lookup(ident.Name) {
+		return nil, false
+	}
+	return ident, true
+}
+
+func (obj Object) Match(m *Matcher, node any) (any, bool) {
+	r, ok := match(m, Ident(obj), node)
+	if !ok {
+		return nil, false
+	}
+	ident := r.(*ast.Ident)
+
+	id := m.TypesInfo.ObjectOf(ident)
+	_, ok = match(m, obj.Name, ident.Name)
+	return id, ok
+}
+
+func (fn Symbol) Match(m *Matcher, node any) (any, bool) {
+	var name string
+	var obj types.Object
+
+	base := []Node{
+		Ident{Any{}},
+		SelectorExpr{Any{}, Any{}},
+	}
+	p := Or{
+		Nodes: append(base,
+			IndexExpr{Or{Nodes: base}, Any{}},
+			IndexListExpr{Or{Nodes: base}, Any{}})}
+
+	r, ok := match(m, p, node)
+	if !ok {
+		return nil, false
+	}
+
+	fun := r.(ast.Expr)
+	switch idx := fun.(type) {
+	case *ast.IndexExpr:
+		fun = idx.X
+	case *ast.IndexListExpr:
+		fun = idx.X
+	}
+
+	switch fun := ast.Unparen(fun).(type) {
+	case *ast.Ident:
+		obj = m.TypesInfo.ObjectOf(fun)
+	case *ast.SelectorExpr:
+		obj = m.TypesInfo.ObjectOf(fun.Sel)
+	default:
+		panic("unreachable")
+	}
+	switch obj := obj.(type) {
+	case *types.Func:
+		// OPT(dh): optimize this similar to code.FuncName
+		name = obj.FullName()
+	case *types.Builtin:
+		name = obj.Name()
+	case *types.TypeName:
+		origObj := obj
+		for {
+			if obj.Parent() != obj.Pkg().Scope() {
+				return nil, false
+			}
+			name = types.TypeString(obj.Type(), nil)
+			_, ok = match(m, fn.Name, name)
+			if ok || !obj.IsAlias() {
+				return origObj, ok
+			} else {
+				// FIXME(dh): we should peel away one layer of alias at a time; this is blocked on
+				// github.com/golang/go/issues/66559
+				switch typ := types.Unalias(obj.Type()).(type) {
+				case interface{ Obj() *types.TypeName }:
+					obj = typ.Obj()
+				case *types.Basic:
+					return match(m, fn.Name, typ.Name())
+				default:
+					return nil, false
+				}
+			}
+		}
+	case *types.Const, *types.Var:
+		if obj.Pkg() == nil {
+			return nil, false
+		}
+		if obj.Parent() != obj.Pkg().Scope() {
+			return nil, false
+		}
+		name = fmt.Sprintf("%s.%s", obj.Pkg().Path(), obj.Name())
+	default:
+		return nil, false
+	}
+
+	_, ok = match(m, fn.Name, name)
+	return obj, ok
+}
+
+func (or Or) Match(m *Matcher, node any) (any, bool) {
+	for _, opt := range or.Nodes {
+		m.push()
+		if ret, ok := match(m, opt, node); ok {
+			m.merge()
+			return ret, true
+		} else {
+			m.pop()
+		}
+	}
+	return nil, false
+}
+
+func (not Not) Match(m *Matcher, node any) (any, bool) {
+	_, ok := match(m, not.Node, node)
+	if ok {
+		return nil, false
+	}
+	return node, true
+}
+
+var integerLiteralQ = MustParse(`(Or (BasicLit "INT" _) (UnaryExpr (Or "+" "-") (IntegerLiteral _)))`)
+
+func (lit IntegerLiteral) Match(m *Matcher, node any) (any, bool) {
+	matched, ok := match(m, integerLiteralQ.Root, node)
+	if !ok {
+		return nil, false
+	}
+	tv, ok := m.TypesInfo.Types[matched.(ast.Expr)]
+	if !ok {
+		return nil, false
+	}
+	if tv.Value == nil {
+		return nil, false
+	}
+	_, ok = match(m, lit.Value, tv)
+	return matched, ok
+}
+
+func (texpr TrulyConstantExpression) Match(m *Matcher, node any) (any, bool) {
+	expr, ok := node.(ast.Expr)
+	if !ok {
+		return nil, false
+	}
+	tv, ok := m.TypesInfo.Types[expr]
+	if !ok {
+		return nil, false
+	}
+	if tv.Value == nil {
+		return nil, false
+	}
+	truly := true
+	ast.Inspect(expr, func(node ast.Node) bool {
+		if _, ok := node.(*ast.Ident); ok {
+			truly = false
+			return false
+		}
+		return true
+	})
+	if !truly {
+		return nil, false
+	}
+	_, ok = match(m, texpr.Value, tv)
+	return expr, ok
+}
+
+var (
+	// Types of fields in go/ast structs that we want to skip
+	rtTokPos = reflect.TypeFor[token.Pos]()
+	//lint:ignore SA1019 It's deprecated, but we still want to skip the field.
+	rtObject       = reflect.TypeFor[*ast.Object]()
+	rtCommentGroup = reflect.TypeFor[*ast.CommentGroup]()
+)
+
+var (
+	_ matcher = Binding{}
+	_ matcher = Any{}
+	_ matcher = List{}
+	_ matcher = String("")
+	_ matcher = Token(0)
+	_ matcher = Nil{}
+	_ matcher = Builtin{}
+	_ matcher = Object{}
+	_ matcher = Symbol{}
+	_ matcher = Or{}
+	_ matcher = Not{}
+	_ matcher = IntegerLiteral{}
+	_ matcher = TrulyConstantExpression{}
+)
diff --git a/vendor/honnef.co/go/tools/pattern/parser.go b/vendor/honnef.co/go/tools/pattern/parser.go
new file mode 100644
index 0000000..e9af702
--- /dev/null
+++ b/vendor/honnef.co/go/tools/pattern/parser.go
@@ -0,0 +1,714 @@
+package pattern
+
+import (
+	"errors"
+	"fmt"
+	"go/ast"
+	"go/token"
+	"iter"
+	"reflect"
+	"strings"
+)
+
+type Pattern struct {
+	Root Node
+	// EntryNodes contains instances of ast.Node that could potentially
+	// initiate a successful match of the pattern.
+	EntryNodes []ast.Node
+
+	// SymbolsPattern is a pattern consisting or Any, Or, And, and IndexSymbol,
+	// that can be used to implement fast rejection of whole packages using
+	// typeindex.
+	SymbolsPattern Node
+
+	// If non-empty, all possible candidate nodes for this pattern can be found
+	// by finding all call expressions for this list of symbols.
+	RootCallSymbols []IndexSymbol
+
+	// Mapping from binding index to binding name
+	Bindings []string
+}
+
+func MustParse(s string) Pattern {
+	p := &Parser{AllowTypeInfo: true}
+	pat, err := p.Parse(s)
+	if err != nil {
+		panic(err)
+	}
+	return pat
+}
+
+func symbolToIndexSymbol(name string) IndexSymbol {
+	if len(name) == 0 {
+		return IndexSymbol{}
+	}
+	if name[0] == '(' {
+		end := strings.IndexAny(name, ")")
+		// Ensure there's a ), and also that there are at least two more
+		// characters after it, for a dot and an identifier.
+		if end == -1 || end > len(name)-2 {
+			return IndexSymbol{}
+		}
+		pathAndType := strings.TrimPrefix(name[1:end], "*")
+		dot := strings.LastIndex(pathAndType, ".")
+		if dot == -1 {
+			return IndexSymbol{}
+		}
+		path := pathAndType[:dot]
+		typ := pathAndType[dot+1:]
+		ident := name[end+2:]
+		return IndexSymbol{path, typ, ident}
+	} else {
+		dot := strings.LastIndex(name, ".")
+		if dot == -1 {
+			return IndexSymbol{"", "", name}
+		}
+		path := name[:dot]
+		ident := name[dot+1:]
+		return IndexSymbol{path, "", ident}
+	}
+}
+
+func collectSymbols(node Node, inSymbol bool) Node {
+	and := func(c Node, out *And) {
+		switch cc := c.(type) {
+		case And:
+			out.Nodes = append(out.Nodes, cc.Nodes...)
+		case Any:
+		case nil:
+		default:
+			out.Nodes = append(out.Nodes, c)
+		}
+	}
+
+	switch node := node.(type) {
+	case Or:
+		s := Or{}
+		for _, el := range node.Nodes {
+			c := collectSymbols(el, inSymbol)
+			switch cc := c.(type) {
+			case Or:
+				s.Nodes = append(s.Nodes, cc.Nodes...)
+			case Any:
+				return Any{}
+			case nil:
+			default:
+				s.Nodes = append(s.Nodes, c)
+			}
+		}
+		switch len(s.Nodes) {
+		case 0:
+			return nil
+		case 1:
+			return s.Nodes[0]
+		default:
+			return s
+		}
+	case Not, Token, nil:
+		return Any{}
+	case Symbol:
+		return collectSymbols(node.Name, true)
+	case String:
+		if !inSymbol {
+			return Any{}
+		}
+		// In logically correct patterns, all Strings that are children of
+		// Symbols describe the names of symbols.
+		return symbolToIndexSymbol(string(node))
+	case Binding:
+		return collectSymbols(node.Node, inSymbol)
+	case Any:
+		return Any{}
+	case List:
+		var out And
+		and(collectSymbols(node.Head, inSymbol), &out)
+		and(collectSymbols(node.Tail, inSymbol), &out)
+		switch len(out.Nodes) {
+		case 0:
+			return Any{}
+		case 1:
+			return out.Nodes[0]
+		default:
+			return out
+		}
+	default:
+		var out And
+		rv := reflect.ValueOf(node)
+		for i := range rv.NumField() {
+			c := collectSymbols(rv.Field(i).Interface().(Node), inSymbol)
+			and(c, &out)
+		}
+		switch len(out.Nodes) {
+		case 0:
+			return Any{}
+		case 1:
+			return out.Nodes[0]
+		default:
+			return out
+		}
+	}
+}
+
+func collectRootCallSymbols(node Node) []IndexSymbol {
+	root, ok := node.(CallExpr)
+	if !ok {
+		return nil
+	}
+
+	var names []String
+	var handleSymName func(name Node) bool
+	handleSymName = func(name Node) bool {
+		switch name := name.(type) {
+		case String:
+			names = append(names, name)
+		case Or:
+			for _, node := range name.Nodes {
+				if name, ok := node.(String); ok {
+					names = append(names, name)
+				} else {
+					return false
+				}
+			}
+		case Binding:
+			return handleSymName(name.Node)
+		default:
+			return false
+		}
+		return true
+	}
+	var handleRootFun func(node Node) bool
+	handleRootFun = func(node Node) bool {
+		switch fun := node.(type) {
+		case Binding:
+			return handleRootFun(fun.Node)
+		case Symbol:
+			return handleSymName(fun.Name)
+		case Or:
+			for _, node := range fun.Nodes {
+				if sym, ok := node.(Symbol); !ok || !handleSymName(sym.Name) {
+					return false
+				}
+			}
+			return true
+		default:
+			return false
+		}
+	}
+	if !handleRootFun(root.Fun) {
+		return nil
+	}
+
+	out := make([]IndexSymbol, len(names))
+	for i, name := range names {
+		out[i] = symbolToIndexSymbol(string(name))
+	}
+	return out
+}
+
+func collectEntryNodes(node Node, m map[reflect.Type]struct{}) {
+	switch node := node.(type) {
+	case Or:
+		for _, el := range node.Nodes {
+			collectEntryNodes(el, m)
+		}
+	case Not:
+		collectEntryNodes(node.Node, m)
+	case Binding:
+		collectEntryNodes(node.Node, m)
+	case Nil, nil:
+		// this branch is reached via bindings
+		for _, T := range allTypes {
+			m[T] = struct{}{}
+		}
+	default:
+		Ts, ok := nodeToASTTypes[reflect.TypeOf(node)]
+		if !ok {
+			panic(fmt.Sprintf("internal error: unhandled type %T", node))
+		}
+		for _, T := range Ts {
+			m[T] = struct{}{}
+		}
+	}
+}
+
+var allTypes = []reflect.Type{
+	reflect.TypeFor[*ast.RangeStmt](),
+	reflect.TypeFor[*ast.AssignStmt](),
+	reflect.TypeFor[*ast.IndexExpr](),
+	reflect.TypeFor[*ast.Ident](),
+	reflect.TypeFor[*ast.ValueSpec](),
+	reflect.TypeFor[*ast.GenDecl](),
+	reflect.TypeFor[*ast.BinaryExpr](),
+	reflect.TypeFor[*ast.ForStmt](),
+	reflect.TypeFor[*ast.ArrayType](),
+	reflect.TypeFor[*ast.DeferStmt](),
+	reflect.TypeFor[*ast.MapType](),
+	reflect.TypeFor[*ast.ReturnStmt](),
+	reflect.TypeFor[*ast.SliceExpr](),
+	reflect.TypeFor[*ast.StarExpr](),
+	reflect.TypeFor[*ast.UnaryExpr](),
+	reflect.TypeFor[*ast.SendStmt](),
+	reflect.TypeFor[*ast.SelectStmt](),
+	reflect.TypeFor[*ast.ImportSpec](),
+	reflect.TypeFor[*ast.IfStmt](),
+	reflect.TypeFor[*ast.GoStmt](),
+	reflect.TypeFor[*ast.Field](),
+	reflect.TypeFor[*ast.SelectorExpr](),
+	reflect.TypeFor[*ast.StructType](),
+	reflect.TypeFor[*ast.KeyValueExpr](),
+	reflect.TypeFor[*ast.FuncType](),
+	reflect.TypeFor[*ast.FuncLit](),
+	reflect.TypeFor[*ast.FuncDecl](),
+	reflect.TypeFor[*ast.ChanType](),
+	reflect.TypeFor[*ast.CallExpr](),
+	reflect.TypeFor[*ast.CaseClause](),
+	reflect.TypeFor[*ast.CommClause](),
+	reflect.TypeFor[*ast.CompositeLit](),
+	reflect.TypeFor[*ast.EmptyStmt](),
+	reflect.TypeFor[*ast.SwitchStmt](),
+	reflect.TypeFor[*ast.TypeSwitchStmt](),
+	reflect.TypeFor[*ast.TypeAssertExpr](),
+	reflect.TypeFor[*ast.TypeSpec](),
+	reflect.TypeFor[*ast.InterfaceType](),
+	reflect.TypeFor[*ast.BranchStmt](),
+	reflect.TypeFor[*ast.IncDecStmt](),
+	reflect.TypeFor[*ast.BasicLit](),
+}
+
+var nodeToASTTypes = map[reflect.Type][]reflect.Type{
+	reflect.TypeFor[String]():                  nil,
+	reflect.TypeFor[Token]():                   nil,
+	reflect.TypeFor[List]():                    {reflect.TypeFor[*ast.BlockStmt](), reflect.TypeFor[*ast.FieldList]()},
+	reflect.TypeFor[Builtin]():                 {reflect.TypeFor[*ast.Ident]()},
+	reflect.TypeFor[Object]():                  {reflect.TypeFor[*ast.Ident]()},
+	reflect.TypeFor[Symbol]():                  {reflect.TypeFor[*ast.Ident](), reflect.TypeFor[*ast.SelectorExpr]()},
+	reflect.TypeFor[Any]():                     allTypes,
+	reflect.TypeFor[RangeStmt]():               {reflect.TypeFor[*ast.RangeStmt]()},
+	reflect.TypeFor[AssignStmt]():              {reflect.TypeFor[*ast.AssignStmt]()},
+	reflect.TypeFor[IndexExpr]():               {reflect.TypeFor[*ast.IndexExpr]()},
+	reflect.TypeFor[Ident]():                   {reflect.TypeFor[*ast.Ident]()},
+	reflect.TypeFor[ValueSpec]():               {reflect.TypeFor[*ast.ValueSpec]()},
+	reflect.TypeFor[GenDecl]():                 {reflect.TypeFor[*ast.GenDecl]()},
+	reflect.TypeFor[BinaryExpr]():              {reflect.TypeFor[*ast.BinaryExpr]()},
+	reflect.TypeFor[ForStmt]():                 {reflect.TypeFor[*ast.ForStmt]()},
+	reflect.TypeFor[ArrayType]():               {reflect.TypeFor[*ast.ArrayType]()},
+	reflect.TypeFor[DeferStmt]():               {reflect.TypeFor[*ast.DeferStmt]()},
+	reflect.TypeFor[MapType]():                 {reflect.TypeFor[*ast.MapType]()},
+	reflect.TypeFor[ReturnStmt]():              {reflect.TypeFor[*ast.ReturnStmt]()},
+	reflect.TypeFor[SliceExpr]():               {reflect.TypeFor[*ast.SliceExpr]()},
+	reflect.TypeFor[StarExpr]():                {reflect.TypeFor[*ast.StarExpr]()},
+	reflect.TypeFor[UnaryExpr]():               {reflect.TypeFor[*ast.UnaryExpr]()},
+	reflect.TypeFor[SendStmt]():                {reflect.TypeFor[*ast.SendStmt]()},
+	reflect.TypeFor[SelectStmt]():              {reflect.TypeFor[*ast.SelectStmt]()},
+	reflect.TypeFor[ImportSpec]():              {reflect.TypeFor[*ast.ImportSpec]()},
+	reflect.TypeFor[IfStmt]():                  {reflect.TypeFor[*ast.IfStmt]()},
+	reflect.TypeFor[GoStmt]():                  {reflect.TypeFor[*ast.GoStmt]()},
+	reflect.TypeFor[Field]():                   {reflect.TypeFor[*ast.Field]()},
+	reflect.TypeFor[SelectorExpr]():            {reflect.TypeFor[*ast.SelectorExpr]()},
+	reflect.TypeFor[StructType]():              {reflect.TypeFor[*ast.StructType]()},
+	reflect.TypeFor[KeyValueExpr]():            {reflect.TypeFor[*ast.KeyValueExpr]()},
+	reflect.TypeFor[FuncType]():                {reflect.TypeFor[*ast.FuncType]()},
+	reflect.TypeFor[FuncLit]():                 {reflect.TypeFor[*ast.FuncLit]()},
+	reflect.TypeFor[FuncDecl]():                {reflect.TypeFor[*ast.FuncDecl]()},
+	reflect.TypeFor[ChanType]():                {reflect.TypeFor[*ast.ChanType]()},
+	reflect.TypeFor[CallExpr]():                {reflect.TypeFor[*ast.CallExpr]()},
+	reflect.TypeFor[CaseClause]():              {reflect.TypeFor[*ast.CaseClause]()},
+	reflect.TypeFor[CommClause]():              {reflect.TypeFor[*ast.CommClause]()},
+	reflect.TypeFor[CompositeLit]():            {reflect.TypeFor[*ast.CompositeLit]()},
+	reflect.TypeFor[EmptyStmt]():               {reflect.TypeFor[*ast.EmptyStmt]()},
+	reflect.TypeFor[SwitchStmt]():              {reflect.TypeFor[*ast.SwitchStmt]()},
+	reflect.TypeFor[TypeSwitchStmt]():          {reflect.TypeFor[*ast.TypeSwitchStmt]()},
+	reflect.TypeFor[TypeAssertExpr]():          {reflect.TypeFor[*ast.TypeAssertExpr]()},
+	reflect.TypeFor[TypeSpec]():                {reflect.TypeFor[*ast.TypeSpec]()},
+	reflect.TypeFor[InterfaceType]():           {reflect.TypeFor[*ast.InterfaceType]()},
+	reflect.TypeFor[BranchStmt]():              {reflect.TypeFor[*ast.BranchStmt]()},
+	reflect.TypeFor[IncDecStmt]():              {reflect.TypeFor[*ast.IncDecStmt]()},
+	reflect.TypeFor[BasicLit]():                {reflect.TypeFor[*ast.BasicLit]()},
+	reflect.TypeFor[IntegerLiteral]():          {reflect.TypeFor[*ast.BasicLit](), reflect.TypeFor[*ast.UnaryExpr]()},
+	reflect.TypeFor[TrulyConstantExpression](): allTypes, // this is an over-approximation, which is fine
+}
+
+var requiresTypeInfo = map[string]bool{
+	"Symbol":                  true,
+	"Builtin":                 true,
+	"Object":                  true,
+	"IntegerLiteral":          true,
+	"TrulyConstantExpression": true,
+}
+
+type Parser struct {
+	// Allow nodes that rely on type information
+	AllowTypeInfo bool
+
+	f        *token.File
+	cur      item
+	last     *item
+	nextItem func() (item, bool)
+
+	bindings map[string]int
+}
+
+func (p *Parser) bindingIndex(name string) int {
+	if p.bindings == nil {
+		p.bindings = map[string]int{}
+	}
+	if idx, ok := p.bindings[name]; ok {
+		return idx
+	}
+	idx := len(p.bindings)
+	p.bindings[name] = idx
+	return idx
+}
+
+func (p *Parser) Parse(s string) (Pattern, error) {
+	f := token.NewFileSet().AddFile("", -1, len(s))
+
+	// Run the lexer iterator as a coroutine.
+	// The parser will call 'next' to consume each item.
+	// After the parser returns, we must call 'stop' to
+	// terminate the coroutine.
+	next, stop := iter.Pull(lex(f, s))
+	defer stop()
+
+	p.cur = item{}
+	p.last = nil
+	p.f = f
+	p.nextItem = next
+
+	// Parse.
+	root, err := p.node()
+	if err != nil {
+		return Pattern{}, err
+	}
+	// Consume final EOF token.
+	if item, ok := next(); !ok || item.typ != itemEOF {
+		return Pattern{}, fmt.Errorf("unexpected token %s after end of pattern", item.typ)
+	}
+
+	if len(p.bindings) > 64 {
+		return Pattern{}, errors.New("encountered more than 64 bindings")
+	}
+
+	bindings := make([]string, len(p.bindings))
+	for name, idx := range p.bindings {
+		bindings[idx] = name
+	}
+
+	_, isSymbol := root.(Symbol)
+	sym := collectSymbols(root, isSymbol)
+	rootSyms := collectRootCallSymbols(root)
+	relevantMap := map[reflect.Type]struct{}{}
+	collectEntryNodes(root, relevantMap)
+	relevantNodes := make([]ast.Node, 0, len(relevantMap))
+	for k := range relevantMap {
+		relevantNodes = append(relevantNodes, reflect.Zero(k).Interface().(ast.Node))
+	}
+	return Pattern{
+		Root:            root,
+		EntryNodes:      relevantNodes,
+		SymbolsPattern:  sym,
+		RootCallSymbols: rootSyms,
+		Bindings:        bindings,
+	}, nil
+}
+
+func (p *Parser) next() item {
+	if p.last != nil {
+		n := *p.last
+		p.last = nil
+		return n
+	}
+	var ok bool
+	p.cur, ok = p.nextItem()
+	if !ok {
+		p.cur = item{typ: eof}
+	}
+	return p.cur
+}
+
+func (p *Parser) rewind() {
+	p.last = &p.cur
+}
+
+func (p *Parser) peek() item {
+	n := p.next()
+	p.rewind()
+	return n
+}
+
+func (p *Parser) accept(typ itemType) (item, bool) {
+	n := p.next()
+	if n.typ == typ {
+		return n, true
+	}
+	p.rewind()
+	return item{}, false
+}
+
+func (p *Parser) unexpectedToken(valid string) error {
+	if p.cur.typ == itemError {
+		return fmt.Errorf("error lexing input: %s", p.cur.val)
+	}
+	var got string
+	switch p.cur.typ {
+	case itemTypeName, itemVariable, itemString:
+		got = p.cur.val
+	default:
+		got = "'" + p.cur.typ.String() + "'"
+	}
+
+	pos := p.f.Position(token.Pos(p.cur.pos))
+	return fmt.Errorf("%s: expected %s, found %s", pos, valid, got)
+}
+
+func (p *Parser) node() (Node, error) {
+	if _, ok := p.accept(itemLeftParen); !ok {
+		return nil, p.unexpectedToken("'('")
+	}
+	typ, ok := p.accept(itemTypeName)
+	if !ok {
+		return nil, p.unexpectedToken("Node type")
+	}
+
+	var objs []Node
+	for {
+		if _, ok := p.accept(itemRightParen); ok {
+			break
+		} else {
+			p.rewind()
+			obj, err := p.object()
+			if err != nil {
+				return nil, err
+			}
+			objs = append(objs, obj)
+		}
+	}
+
+	node, err := p.populateNode(typ.val, objs)
+	if err != nil {
+		return nil, err
+	}
+	if node, ok := node.(Binding); ok {
+		node.idx = p.bindingIndex(node.Name)
+	}
+	return node, nil
+}
+
+func populateNode(typ string, objs []Node, allowTypeInfo bool) (Node, error) {
+	T, ok := structNodes[typ]
+	if !ok {
+		return nil, fmt.Errorf("unknown node %s", typ)
+	}
+
+	if !allowTypeInfo && requiresTypeInfo[typ] {
+		return nil, fmt.Errorf("Node %s requires type information", typ)
+	}
+
+	pv := reflect.New(T)
+	v := pv.Elem()
+
+	if v.NumField() == 1 {
+		f := v.Field(0)
+		if f.Type().Kind() == reflect.Slice {
+			// Variadic node
+			f.Set(reflect.AppendSlice(f, reflect.ValueOf(objs)))
+			return v.Interface().(Node), nil
+		}
+	}
+
+	n := -1
+	for i := 0; i < T.NumField(); i++ {
+		if !T.Field(i).IsExported() {
+			break
+		}
+		n = i
+	}
+
+	if len(objs) != n+1 {
+		return nil, fmt.Errorf("tried to initialize node %s with %d values, expected %d", typ, len(objs), n+1)
+	}
+
+	for i := 0; i < v.NumField(); i++ {
+		if !T.Field(i).IsExported() {
+			break
+		}
+		f := v.Field(i)
+		if f.Kind() == reflect.String {
+			if obj, ok := objs[i].(String); ok {
+				f.Set(reflect.ValueOf(string(obj)))
+			} else {
+				return nil, fmt.Errorf("first argument of (Binding name node) must be string, but got %s", objs[i])
+			}
+		} else {
+			f.Set(reflect.ValueOf(objs[i]))
+		}
+	}
+	return v.Interface().(Node), nil
+}
+
+func (p *Parser) populateNode(typ string, objs []Node) (Node, error) {
+	return populateNode(typ, objs, p.AllowTypeInfo)
+}
+
+var structNodes = map[string]reflect.Type{
+	"Any":                     reflect.TypeFor[Any](),
+	"Ellipsis":                reflect.TypeFor[Ellipsis](),
+	"List":                    reflect.TypeFor[List](),
+	"Binding":                 reflect.TypeFor[Binding](),
+	"RangeStmt":               reflect.TypeFor[RangeStmt](),
+	"AssignStmt":              reflect.TypeFor[AssignStmt](),
+	"IndexExpr":               reflect.TypeFor[IndexExpr](),
+	"Ident":                   reflect.TypeFor[Ident](),
+	"Builtin":                 reflect.TypeFor[Builtin](),
+	"ValueSpec":               reflect.TypeFor[ValueSpec](),
+	"GenDecl":                 reflect.TypeFor[GenDecl](),
+	"BinaryExpr":              reflect.TypeFor[BinaryExpr](),
+	"ForStmt":                 reflect.TypeFor[ForStmt](),
+	"ArrayType":               reflect.TypeFor[ArrayType](),
+	"DeferStmt":               reflect.TypeFor[DeferStmt](),
+	"MapType":                 reflect.TypeFor[MapType](),
+	"ReturnStmt":              reflect.TypeFor[ReturnStmt](),
+	"SliceExpr":               reflect.TypeFor[SliceExpr](),
+	"StarExpr":                reflect.TypeFor[StarExpr](),
+	"UnaryExpr":               reflect.TypeFor[UnaryExpr](),
+	"SendStmt":                reflect.TypeFor[SendStmt](),
+	"SelectStmt":              reflect.TypeFor[SelectStmt](),
+	"ImportSpec":              reflect.TypeFor[ImportSpec](),
+	"IfStmt":                  reflect.TypeFor[IfStmt](),
+	"GoStmt":                  reflect.TypeFor[GoStmt](),
+	"Field":                   reflect.TypeFor[Field](),
+	"SelectorExpr":            reflect.TypeFor[SelectorExpr](),
+	"StructType":              reflect.TypeFor[StructType](),
+	"KeyValueExpr":            reflect.TypeFor[KeyValueExpr](),
+	"FuncType":                reflect.TypeFor[FuncType](),
+	"FuncLit":                 reflect.TypeFor[FuncLit](),
+	"FuncDecl":                reflect.TypeFor[FuncDecl](),
+	"ChanType":                reflect.TypeFor[ChanType](),
+	"CallExpr":                reflect.TypeFor[CallExpr](),
+	"CaseClause":              reflect.TypeFor[CaseClause](),
+	"CommClause":              reflect.TypeFor[CommClause](),
+	"CompositeLit":            reflect.TypeFor[CompositeLit](),
+	"EmptyStmt":               reflect.TypeFor[EmptyStmt](),
+	"SwitchStmt":              reflect.TypeFor[SwitchStmt](),
+	"TypeSwitchStmt":          reflect.TypeFor[TypeSwitchStmt](),
+	"TypeAssertExpr":          reflect.TypeFor[TypeAssertExpr](),
+	"TypeSpec":                reflect.TypeFor[TypeSpec](),
+	"InterfaceType":           reflect.TypeFor[InterfaceType](),
+	"BranchStmt":              reflect.TypeFor[BranchStmt](),
+	"IncDecStmt":              reflect.TypeFor[IncDecStmt](),
+	"BasicLit":                reflect.TypeFor[BasicLit](),
+	"Object":                  reflect.TypeFor[Object](),
+	"Symbol":                  reflect.TypeFor[Symbol](),
+	"Or":                      reflect.TypeFor[Or](),
+	"Not":                     reflect.TypeFor[Not](),
+	"IntegerLiteral":          reflect.TypeFor[IntegerLiteral](),
+	"TrulyConstantExpression": reflect.TypeFor[TrulyConstantExpression](),
+}
+
+func (p *Parser) object() (Node, error) {
+	n := p.next()
+	switch n.typ {
+	case itemLeftParen:
+		p.rewind()
+		node, err := p.node()
+		if err != nil {
+			return node, err
+		}
+		if p.peek().typ == itemColon {
+			p.next()
+			tail, err := p.object()
+			if err != nil {
+				return node, err
+			}
+			return List{Head: node, Tail: tail}, nil
+		}
+		return node, nil
+	case itemLeftBracket:
+		p.rewind()
+		return p.array()
+	case itemVariable:
+		v := n
+		if v.val == "nil" {
+			return Nil{}, nil
+		}
+		var b Binding
+		if _, ok := p.accept(itemAt); ok {
+			o, err := p.node()
+			if err != nil {
+				return nil, err
+			}
+			b = Binding{
+				Name: v.val,
+				Node: o,
+				idx:  p.bindingIndex(v.val),
+			}
+		} else {
+			p.rewind()
+			b = Binding{
+				Name: v.val,
+				idx:  p.bindingIndex(v.val),
+			}
+		}
+		if p.peek().typ == itemColon {
+			p.next()
+			tail, err := p.object()
+			if err != nil {
+				return b, err
+			}
+			return List{Head: b, Tail: tail}, nil
+		}
+		return b, nil
+	case itemBlank:
+		if p.peek().typ == itemColon {
+			p.next()
+			tail, err := p.object()
+			if err != nil {
+				return Any{}, err
+			}
+			return List{Head: Any{}, Tail: tail}, nil
+		}
+		return Any{}, nil
+	case itemString:
+		return String(n.val), nil
+	default:
+		return nil, p.unexpectedToken("object")
+	}
+}
+
+func (p *Parser) array() (Node, error) {
+	if _, ok := p.accept(itemLeftBracket); !ok {
+		return nil, p.unexpectedToken("'['")
+	}
+
+	var objs []Node
+	for {
+		if _, ok := p.accept(itemRightBracket); ok {
+			break
+		} else {
+			p.rewind()
+			obj, err := p.object()
+			if err != nil {
+				return nil, err
+			}
+			objs = append(objs, obj)
+		}
+	}
+
+	tail := List{}
+	for i := len(objs) - 1; i >= 0; i-- {
+		l := List{
+			Head: objs[i],
+			Tail: tail,
+		}
+		tail = l
+	}
+	return tail, nil
+}
+
+/*
+Node ::= itemLeftParen itemTypeName Object* itemRightParen
+Object ::= Node | Array | Binding | itemVariable | itemBlank | itemString
+Array := itemLeftBracket Object* itemRightBracket
+Array := Object itemColon Object
+Binding ::= itemVariable itemAt Node
+*/
diff --git a/vendor/honnef.co/go/tools/pattern/pattern.go b/vendor/honnef.co/go/tools/pattern/pattern.go
new file mode 100644
index 0000000..107f95b
--- /dev/null
+++ b/vendor/honnef.co/go/tools/pattern/pattern.go
@@ -0,0 +1,551 @@
+package pattern
+
+import (
+	"fmt"
+	"go/token"
+	"reflect"
+	"strings"
+)
+
+var (
+	_ Node = Ellipsis{}
+	_ Node = Binding{}
+	_ Node = RangeStmt{}
+	_ Node = AssignStmt{}
+	_ Node = IndexExpr{}
+	_ Node = IndexListExpr{}
+	_ Node = Ident{}
+	_ Node = Builtin{}
+	_ Node = String("")
+	_ Node = Any{}
+	_ Node = ValueSpec{}
+	_ Node = List{}
+	_ Node = GenDecl{}
+	_ Node = BinaryExpr{}
+	_ Node = ForStmt{}
+	_ Node = ArrayType{}
+	_ Node = DeferStmt{}
+	_ Node = MapType{}
+	_ Node = ReturnStmt{}
+	_ Node = SliceExpr{}
+	_ Node = StarExpr{}
+	_ Node = UnaryExpr{}
+	_ Node = SendStmt{}
+	_ Node = SelectStmt{}
+	_ Node = ImportSpec{}
+	_ Node = IfStmt{}
+	_ Node = GoStmt{}
+	_ Node = Field{}
+	_ Node = SelectorExpr{}
+	_ Node = StructType{}
+	_ Node = KeyValueExpr{}
+	_ Node = FuncType{}
+	_ Node = FuncLit{}
+	_ Node = FuncDecl{}
+	_ Node = Token(0)
+	_ Node = ChanType{}
+	_ Node = CallExpr{}
+	_ Node = CaseClause{}
+	_ Node = CommClause{}
+	_ Node = CompositeLit{}
+	_ Node = EmptyStmt{}
+	_ Node = SwitchStmt{}
+	_ Node = TypeSwitchStmt{}
+	_ Node = TypeAssertExpr{}
+	_ Node = TypeSpec{}
+	_ Node = InterfaceType{}
+	_ Node = BranchStmt{}
+	_ Node = IncDecStmt{}
+	_ Node = BasicLit{}
+	_ Node = Nil{}
+	_ Node = Object{}
+	_ Node = Symbol{}
+	_ Node = Not{}
+	_ Node = Or{}
+	_ Node = IntegerLiteral{}
+	_ Node = TrulyConstantExpression{}
+)
+
+type Symbol struct {
+	Name Node
+}
+
+type Token token.Token
+
+type Nil struct {
+}
+
+type Ellipsis struct {
+	Elt Node
+}
+
+type IncDecStmt struct {
+	X   Node
+	Tok Node
+}
+
+type BranchStmt struct {
+	Tok   Node
+	Label Node
+}
+
+type InterfaceType struct {
+	Methods Node
+}
+
+type TypeSpec struct {
+	Name Node
+	Type Node
+}
+
+type TypeAssertExpr struct {
+	X    Node
+	Type Node
+}
+
+type TypeSwitchStmt struct {
+	Init   Node
+	Assign Node
+	Body   Node
+}
+
+type SwitchStmt struct {
+	Init Node
+	Tag  Node
+	Body Node
+}
+
+type EmptyStmt struct {
+}
+
+type CompositeLit struct {
+	Type Node
+	Elts Node
+}
+
+type CommClause struct {
+	Comm Node
+	Body Node
+}
+
+type CaseClause struct {
+	List Node
+	Body Node
+}
+
+type CallExpr struct {
+	Fun  Node
+	Args Node
+	// XXX handle ellipsis
+}
+
+// TODO(dh): add a ChanDir node, and a way of instantiating it.
+
+type ChanType struct {
+	Dir   Node
+	Value Node
+}
+
+type FuncDecl struct {
+	Recv Node
+	Name Node
+	Type Node
+	Body Node
+}
+
+type FuncLit struct {
+	Type Node
+	Body Node
+}
+
+type FuncType struct {
+	Params  Node
+	Results Node
+}
+
+type KeyValueExpr struct {
+	Key   Node
+	Value Node
+}
+
+type StructType struct {
+	Fields Node
+}
+
+type SelectorExpr struct {
+	X   Node
+	Sel Node
+}
+
+type Field struct {
+	Names Node
+	Type  Node
+	Tag   Node
+}
+
+type GoStmt struct {
+	Call Node
+}
+
+type IfStmt struct {
+	Init Node
+	Cond Node
+	Body Node
+	Else Node
+}
+
+type ImportSpec struct {
+	Name Node
+	Path Node
+}
+
+type SelectStmt struct {
+	Body Node
+}
+
+type ArrayType struct {
+	Len Node
+	Elt Node
+}
+
+type DeferStmt struct {
+	Call Node
+}
+
+type MapType struct {
+	Key   Node
+	Value Node
+}
+
+type ReturnStmt struct {
+	Results Node
+}
+
+type SliceExpr struct {
+	X    Node
+	Low  Node
+	High Node
+	Max  Node
+}
+
+type StarExpr struct {
+	X Node
+}
+
+type UnaryExpr struct {
+	Op Node
+	X  Node
+}
+
+type SendStmt struct {
+	Chan  Node
+	Value Node
+}
+
+type Binding struct {
+	Name string
+	Node Node
+
+	idx int
+}
+
+type RangeStmt struct {
+	Key   Node
+	Value Node
+	Tok   Node
+	X     Node
+	Body  Node
+}
+
+type AssignStmt struct {
+	Lhs Node
+	Tok Node
+	Rhs Node
+}
+
+type IndexExpr struct {
+	X     Node
+	Index Node
+}
+
+type IndexListExpr struct {
+	X       Node
+	Indices Node
+}
+
+type Node interface {
+	String() string
+	isNode()
+}
+
+type Ident struct {
+	Name Node
+}
+
+type Object struct {
+	Name Node
+}
+
+type Builtin struct {
+	Name Node
+}
+
+type String string
+
+type Any struct{}
+
+type ValueSpec struct {
+	Names  Node
+	Type   Node
+	Values Node
+}
+
+type List struct {
+	Head Node
+	Tail Node
+}
+
+type GenDecl struct {
+	Tok   Node
+	Specs Node
+}
+
+type BasicLit struct {
+	Kind  Node
+	Value Node
+}
+
+// An IntegerLiteral is a constant expression made up of only integer basic literals and the "+" and "-" unary operators.
+// That is, 0, -4, -+42 are all integer literals, but 1 + 2 is not.
+type IntegerLiteral struct {
+	Value Node
+}
+
+type BinaryExpr struct {
+	X  Node
+	Op Node
+	Y  Node
+}
+
+type ForStmt struct {
+	Init Node
+	Cond Node
+	Post Node
+	Body Node
+}
+
+type Or struct {
+	Nodes []Node
+}
+
+type And struct {
+	Nodes []Node
+}
+
+type Not struct {
+	Node Node
+}
+
+// A TrulyConstantExpression is a constant expression that does not make use of any identifiers.
+// It is constant even under varying build tags.
+type TrulyConstantExpression struct {
+	Value Node
+}
+
+type IndexSymbol struct {
+	Path  string
+	Type  string
+	Ident string
+}
+
+func stringify(n Node) string {
+	v := reflect.ValueOf(n)
+	var parts []string
+	parts = append(parts, v.Type().Name())
+	for i := 0; i < v.NumField(); i++ {
+		parts = append(parts, fmt.Sprintf("%s", v.Field(i)))
+	}
+	return "(" + strings.Join(parts, " ") + ")"
+}
+
+func (stmt AssignStmt) String() string              { return stringify(stmt) }
+func (expr IndexExpr) String() string               { return stringify(expr) }
+func (expr IndexListExpr) String() string           { return stringify(expr) }
+func (id Ident) String() string                     { return stringify(id) }
+func (spec ValueSpec) String() string               { return stringify(spec) }
+func (decl GenDecl) String() string                 { return stringify(decl) }
+func (lit BasicLit) String() string                 { return stringify(lit) }
+func (expr BinaryExpr) String() string              { return stringify(expr) }
+func (stmt ForStmt) String() string                 { return stringify(stmt) }
+func (stmt RangeStmt) String() string               { return stringify(stmt) }
+func (typ ArrayType) String() string                { return stringify(typ) }
+func (stmt DeferStmt) String() string               { return stringify(stmt) }
+func (typ MapType) String() string                  { return stringify(typ) }
+func (stmt ReturnStmt) String() string              { return stringify(stmt) }
+func (expr SliceExpr) String() string               { return stringify(expr) }
+func (expr StarExpr) String() string                { return stringify(expr) }
+func (expr UnaryExpr) String() string               { return stringify(expr) }
+func (stmt SendStmt) String() string                { return stringify(stmt) }
+func (spec ImportSpec) String() string              { return stringify(spec) }
+func (stmt SelectStmt) String() string              { return stringify(stmt) }
+func (stmt IfStmt) String() string                  { return stringify(stmt) }
+func (stmt IncDecStmt) String() string              { return stringify(stmt) }
+func (stmt GoStmt) String() string                  { return stringify(stmt) }
+func (field Field) String() string                  { return stringify(field) }
+func (expr SelectorExpr) String() string            { return stringify(expr) }
+func (typ StructType) String() string               { return stringify(typ) }
+func (expr KeyValueExpr) String() string            { return stringify(expr) }
+func (typ FuncType) String() string                 { return stringify(typ) }
+func (lit FuncLit) String() string                  { return stringify(lit) }
+func (decl FuncDecl) String() string                { return stringify(decl) }
+func (stmt BranchStmt) String() string              { return stringify(stmt) }
+func (expr CallExpr) String() string                { return stringify(expr) }
+func (clause CaseClause) String() string            { return stringify(clause) }
+func (typ ChanType) String() string                 { return stringify(typ) }
+func (clause CommClause) String() string            { return stringify(clause) }
+func (lit CompositeLit) String() string             { return stringify(lit) }
+func (stmt EmptyStmt) String() string               { return stringify(stmt) }
+func (typ InterfaceType) String() string            { return stringify(typ) }
+func (stmt SwitchStmt) String() string              { return stringify(stmt) }
+func (expr TypeAssertExpr) String() string          { return stringify(expr) }
+func (spec TypeSpec) String() string                { return stringify(spec) }
+func (stmt TypeSwitchStmt) String() string          { return stringify(stmt) }
+func (nil Nil) String() string                      { return "nil" }
+func (builtin Builtin) String() string              { return stringify(builtin) }
+func (obj Object) String() string                   { return stringify(obj) }
+func (fn Symbol) String() string                    { return stringify(fn) }
+func (el Ellipsis) String() string                  { return stringify(el) }
+func (not Not) String() string                      { return stringify(not) }
+func (lit IntegerLiteral) String() string           { return stringify(lit) }
+func (expr TrulyConstantExpression) String() string { return stringify(expr) }
+func (sym IndexSymbol) String() string {
+	return fmt.Sprintf("(IndexSymbol %q %q %q)", sym.Path, sym.Type, sym.Ident)
+}
+
+func (or Or) String() string {
+	var s strings.Builder
+	s.WriteString("(Or")
+	for _, node := range or.Nodes {
+		s.WriteString(" ")
+		s.WriteString(node.String())
+	}
+	s.WriteString(")")
+	return s.String()
+}
+
+func (and And) String() string {
+	var s strings.Builder
+	s.WriteString("(And")
+	for _, node := range and.Nodes {
+		s.WriteString(" ")
+		s.WriteString(node.String())
+	}
+	s.WriteString(")")
+	return s.String()
+}
+
+func isProperList(l List) bool {
+	if l.Head == nil && l.Tail == nil {
+		return true
+	}
+	switch tail := l.Tail.(type) {
+	case nil:
+		return false
+	case List:
+		return isProperList(tail)
+	default:
+		return false
+	}
+}
+
+func (l List) String() string {
+	if l.Head == nil && l.Tail == nil {
+		return "[]"
+	}
+
+	if isProperList(l) {
+		// pretty-print the list
+		var objs []string
+		for l.Head != nil {
+			objs = append(objs, l.Head.String())
+			l = l.Tail.(List)
+		}
+		return fmt.Sprintf("[%s]", strings.Join(objs, " "))
+	}
+
+	return fmt.Sprintf("%s:%s", l.Head, l.Tail)
+}
+
+func (bind Binding) String() string {
+	if bind.Node == nil {
+		return bind.Name
+	}
+	return fmt.Sprintf("%s@%s", bind.Name, bind.Node)
+}
+
+func (s String) String() string { return fmt.Sprintf("%q", string(s)) }
+
+func (tok Token) String() string {
+	return fmt.Sprintf("%q", strings.ToUpper(token.Token(tok).String()))
+}
+
+func (Any) String() string { return "_" }
+
+func (AssignStmt) isNode()              {}
+func (IndexExpr) isNode()               {}
+func (IndexListExpr) isNode()           {}
+func (Ident) isNode()                   {}
+func (ValueSpec) isNode()               {}
+func (GenDecl) isNode()                 {}
+func (BasicLit) isNode()                {}
+func (BinaryExpr) isNode()              {}
+func (ForStmt) isNode()                 {}
+func (RangeStmt) isNode()               {}
+func (ArrayType) isNode()               {}
+func (DeferStmt) isNode()               {}
+func (MapType) isNode()                 {}
+func (ReturnStmt) isNode()              {}
+func (SliceExpr) isNode()               {}
+func (StarExpr) isNode()                {}
+func (UnaryExpr) isNode()               {}
+func (SendStmt) isNode()                {}
+func (ImportSpec) isNode()              {}
+func (SelectStmt) isNode()              {}
+func (IfStmt) isNode()                  {}
+func (IncDecStmt) isNode()              {}
+func (GoStmt) isNode()                  {}
+func (Field) isNode()                   {}
+func (SelectorExpr) isNode()            {}
+func (StructType) isNode()              {}
+func (KeyValueExpr) isNode()            {}
+func (FuncType) isNode()                {}
+func (FuncLit) isNode()                 {}
+func (FuncDecl) isNode()                {}
+func (BranchStmt) isNode()              {}
+func (CallExpr) isNode()                {}
+func (CaseClause) isNode()              {}
+func (ChanType) isNode()                {}
+func (CommClause) isNode()              {}
+func (CompositeLit) isNode()            {}
+func (EmptyStmt) isNode()               {}
+func (InterfaceType) isNode()           {}
+func (SwitchStmt) isNode()              {}
+func (TypeAssertExpr) isNode()          {}
+func (TypeSpec) isNode()                {}
+func (TypeSwitchStmt) isNode()          {}
+func (Nil) isNode()                     {}
+func (Builtin) isNode()                 {}
+func (Object) isNode()                  {}
+func (Symbol) isNode()                  {}
+func (Ellipsis) isNode()                {}
+func (Or) isNode()                      {}
+func (And) isNode()                     {}
+func (List) isNode()                    {}
+func (String) isNode()                  {}
+func (Token) isNode()                   {}
+func (Any) isNode()                     {}
+func (Binding) isNode()                 {}
+func (Not) isNode()                     {}
+func (IntegerLiteral) isNode()          {}
+func (TrulyConstantExpression) isNode() {}
+func (IndexSymbol) isNode()             {}
diff --git a/vendor/honnef.co/go/tools/printf/fuzz.go b/vendor/honnef.co/go/tools/printf/fuzz.go
new file mode 100644
index 0000000..cf6310a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/printf/fuzz.go
@@ -0,0 +1,11 @@
+//go:build gofuzz
+
+package printf
+
+func Fuzz(data []byte) int {
+	_, err := Parse(string(data))
+	if err == nil {
+		return 1
+	}
+	return 0
+}
diff --git a/vendor/honnef.co/go/tools/printf/printf.go b/vendor/honnef.co/go/tools/printf/printf.go
new file mode 100644
index 0000000..b4d4bac
--- /dev/null
+++ b/vendor/honnef.co/go/tools/printf/printf.go
@@ -0,0 +1,198 @@
+// Package printf implements a parser for fmt.Printf-style format
+// strings.
+//
+// It parses verbs according to the following syntax:
+//
+//	Numeric -> '0'-'9'
+//	Letter -> 'a'-'z' | 'A'-'Z'
+//	Index -> '[' Numeric+ ']'
+//	Star -> '*'
+//	Star -> Index '*'
+//
+//	Precision -> Numeric+ | Star
+//	Width -> Numeric+ | Star
+//
+//	WidthAndPrecision -> Width '.' Precision
+//	WidthAndPrecision -> Width '.'
+//	WidthAndPrecision -> Width
+//	WidthAndPrecision -> '.' Precision
+//	WidthAndPrecision -> '.'
+//
+//	Flag -> '+' | '-' | '#' | ' ' | '0'
+//	Verb -> Letter | '%'
+//
+//	Input -> '%' [ Flag+ ] [ WidthAndPrecision ] [ Index ] Verb
+package printf
+
+import (
+	"errors"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+// ErrInvalid is returned for invalid format strings or verbs.
+var ErrInvalid = errors.New("invalid format string")
+
+type Verb struct {
+	Letter rune
+	Flags  string
+
+	Width     Argument
+	Precision Argument
+	// Which value in the argument list the verb uses.
+	// -1 denotes the next argument,
+	// values > 0 denote explicit arguments.
+	// The value 0 denotes that no argument is consumed. This is the case for %%.
+	Value int
+
+	Raw string
+}
+
+// Argument is an implicit or explicit width or precision.
+type Argument interface {
+	isArgument()
+}
+
+// The Default value, when no width or precision is provided.
+type Default struct{}
+
+// Zero is the implicit zero value.
+// This value may only appear for precisions in format strings like %6.f
+type Zero struct{}
+
+// Star is a * value, which may either refer to the next argument (Index == -1) or an explicit argument.
+type Star struct{ Index int }
+
+// A Literal value, such as 6 in %6d.
+type Literal int
+
+func (Default) isArgument() {}
+func (Zero) isArgument()    {}
+func (Star) isArgument()    {}
+func (Literal) isArgument() {}
+
+// Parse parses f and returns a list of actions.
+// An action may either be a literal string, or a Verb.
+func Parse(f string) ([]any, error) {
+	var out []any
+	for len(f) > 0 {
+		if f[0] == '%' {
+			v, n, err := ParseVerb(f)
+			if err != nil {
+				return nil, err
+			}
+			f = f[n:]
+			out = append(out, v)
+		} else {
+			n := strings.IndexByte(f, '%')
+			if n > -1 {
+				out = append(out, f[:n])
+				f = f[n:]
+			} else {
+				out = append(out, f)
+				f = ""
+			}
+		}
+	}
+
+	return out, nil
+}
+
+func atoi(s string) int {
+	n, _ := strconv.Atoi(s)
+	return n
+}
+
+// ParseVerb parses the verb at the beginning of f.
+// It returns the verb, how much of the input was consumed, and an error, if any.
+func ParseVerb(f string) (Verb, int, error) {
+	if len(f) < 2 {
+		return Verb{}, 0, ErrInvalid
+	}
+	const (
+		flags = 1
+
+		width      = 2
+		widthStar  = 3
+		widthIndex = 5
+
+		dot       = 6
+		prec      = 7
+		precStar  = 8
+		precIndex = 10
+
+		verbIndex = 11
+		verb      = 12
+	)
+
+	m := re.FindStringSubmatch(f)
+	if m == nil {
+		return Verb{}, 0, ErrInvalid
+	}
+
+	v := Verb{
+		Letter: []rune(m[verb])[0],
+		Flags:  m[flags],
+		Raw:    m[0],
+	}
+
+	if m[width] != "" {
+		// Literal width
+		v.Width = Literal(atoi(m[width]))
+	} else if m[widthStar] != "" {
+		// Star width
+		if m[widthIndex] != "" {
+			v.Width = Star{atoi(m[widthIndex])}
+		} else {
+			v.Width = Star{-1}
+		}
+	} else {
+		// Default width
+		v.Width = Default{}
+	}
+
+	if m[dot] == "" {
+		// default precision
+		v.Precision = Default{}
+	} else {
+		if m[prec] != "" {
+			// Literal precision
+			v.Precision = Literal(atoi(m[prec]))
+		} else if m[precStar] != "" {
+			// Star precision
+			if m[precIndex] != "" {
+				v.Precision = Star{atoi(m[precIndex])}
+			} else {
+				v.Precision = Star{-1}
+			}
+		} else {
+			// Zero precision
+			v.Precision = Zero{}
+		}
+	}
+
+	if m[verb] == "%" {
+		v.Value = 0
+	} else if m[verbIndex] != "" {
+		v.Value = atoi(m[verbIndex])
+	} else {
+		v.Value = -1
+	}
+
+	return v, len(m[0]), nil
+}
+
+const (
+	flags             = `([+#0 -]*)`
+	verb              = `([a-zA-Z%])`
+	index             = `(?:\[([0-9]+)\])`
+	star              = `((` + index + `)?\*)`
+	width1            = `([0-9]+)`
+	width2            = star
+	width             = `(?:` + width1 + `|` + width2 + `)`
+	precision         = width
+	widthAndPrecision = `(?:(?:` + width + `)?(?:(\.)(?:` + precision + `)?)?)`
+)
+
+var re = regexp.MustCompile(`^%` + flags + widthAndPrecision + `?` + index + `?` + verb)
diff --git a/vendor/honnef.co/go/tools/quickfix/analysis.go b/vendor/honnef.co/go/tools/quickfix/analysis.go
new file mode 100644
index 0000000..b877a91
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/analysis.go
@@ -0,0 +1,34 @@
+// Code generated by generate.go. DO NOT EDIT.
+
+package quickfix
+
+import (
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/quickfix/qf1001"
+	"honnef.co/go/tools/quickfix/qf1002"
+	"honnef.co/go/tools/quickfix/qf1003"
+	"honnef.co/go/tools/quickfix/qf1004"
+	"honnef.co/go/tools/quickfix/qf1005"
+	"honnef.co/go/tools/quickfix/qf1006"
+	"honnef.co/go/tools/quickfix/qf1007"
+	"honnef.co/go/tools/quickfix/qf1008"
+	"honnef.co/go/tools/quickfix/qf1009"
+	"honnef.co/go/tools/quickfix/qf1010"
+	"honnef.co/go/tools/quickfix/qf1011"
+	"honnef.co/go/tools/quickfix/qf1012"
+)
+
+var Analyzers = []*lint.Analyzer{
+	qf1001.SCAnalyzer,
+	qf1002.SCAnalyzer,
+	qf1003.SCAnalyzer,
+	qf1004.SCAnalyzer,
+	qf1005.SCAnalyzer,
+	qf1006.SCAnalyzer,
+	qf1007.SCAnalyzer,
+	qf1008.SCAnalyzer,
+	qf1009.SCAnalyzer,
+	qf1010.SCAnalyzer,
+	qf1011.SCAnalyzer,
+	qf1012.SCAnalyzer,
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/doc.go b/vendor/honnef.co/go/tools/quickfix/doc.go
new file mode 100644
index 0000000..16d67b3
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/doc.go
@@ -0,0 +1,9 @@
+//go:generate go run ../generate.go
+
+// Package quickfix contains analyzes that implement code refactorings.
+// None of these analyzers produce diagnostics that have to be followed.
+// Most of the time, they only provide alternative ways of doing things,
+// requiring users to make informed decisions.
+//
+// None of these analyzes should fail a build, and they are likely useless in CI as a whole.
+package quickfix
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1001/qf1001.go b/vendor/honnef.co/go/tools/quickfix/qf1001/qf1001.go
new file mode 100644
index 0000000..b338dba
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1001/qf1001.go
@@ -0,0 +1,123 @@
+package qf1001
+
+import (
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "QF1001",
+		Run:      CheckDeMorgan,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    "Apply De Morgan's law",
+		Since:    "2021.1",
+		Severity: lint.SeverityHint,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var demorganQ = pattern.MustParse(`(UnaryExpr "!" expr@(BinaryExpr _ _ _))`)
+
+func CheckDeMorgan(pass *analysis.Pass) (any, error) {
+	// TODO(dh): support going in the other direction, e.g. turning `!a && !b && !c` into `!(a || b || c)`
+
+	// hasFloats reports whether any subexpression is of type float.
+	hasFloats := func(expr ast.Expr) bool {
+		found := false
+		ast.Inspect(expr, func(node ast.Node) bool {
+			if expr, ok := node.(ast.Expr); ok {
+				if typ := pass.TypesInfo.TypeOf(expr); typ != nil {
+					if basic, ok := typ.Underlying().(*types.Basic); ok {
+						if (basic.Info() & types.IsFloat) != 0 {
+							found = true
+							return false
+						}
+					}
+				}
+			}
+			return true
+		})
+		return found
+	}
+
+	for c := range code.Cursor(pass).Preorder((*ast.UnaryExpr)(nil)) {
+		node := c.Node()
+		matcher, ok := code.Match(pass, demorganQ, node)
+		if !ok {
+			continue
+		}
+
+		expr := matcher.State["expr"].(ast.Expr)
+
+		// be extremely conservative when it comes to floats
+		if hasFloats(expr) {
+			continue
+		}
+
+		n := astutil.NegateDeMorgan(expr, false)
+		nr := astutil.NegateDeMorgan(expr, true)
+		nc, ok := astutil.CopyExpr(n)
+		if !ok {
+			continue
+		}
+		ns := astutil.SimplifyParentheses(nc)
+		nrc, ok := astutil.CopyExpr(nr)
+		if !ok {
+			continue
+		}
+		nrs := astutil.SimplifyParentheses(nrc)
+
+		var bn, bnr, bns, bnrs string
+		switch c.Parent().Node().(type) {
+		case *ast.BinaryExpr, *ast.IfStmt, *ast.ForStmt, *ast.SwitchStmt:
+			// Always add parentheses for if, for and switch. If
+			// they're unnecessary, go/printer will strip them when
+			// the whole file gets formatted.
+
+			bn = report.Render(pass, &ast.ParenExpr{X: n})
+			bnr = report.Render(pass, &ast.ParenExpr{X: nr})
+			bns = report.Render(pass, &ast.ParenExpr{X: ns})
+			bnrs = report.Render(pass, &ast.ParenExpr{X: nrs})
+
+		default:
+			// TODO are there other types where we don't want to strip parentheses?
+			bn = report.Render(pass, n)
+			bnr = report.Render(pass, nr)
+			bns = report.Render(pass, ns)
+			bnrs = report.Render(pass, nrs)
+		}
+
+		// Note: we cannot compare the ASTs directly, because
+		// simplifyParentheses might have rebalanced trees without
+		// affecting the rendered form.
+		var fixes []analysis.SuggestedFix
+		fixes = append(fixes, edit.Fix("Apply De Morgan's law", edit.ReplaceWithString(node, bn)))
+		if bn != bns {
+			fixes = append(fixes, edit.Fix("Apply De Morgan's law & simplify", edit.ReplaceWithString(node, bns)))
+		}
+		if bn != bnr {
+			fixes = append(fixes, edit.Fix("Apply De Morgan's law recursively", edit.ReplaceWithString(node, bnr)))
+			if bnr != bnrs {
+				fixes = append(fixes, edit.Fix("Apply De Morgan's law recursively & simplify", edit.ReplaceWithString(node, bnrs)))
+			}
+		}
+
+		report.Report(pass, node, "could apply De Morgan's law", report.Fixes(fixes...))
+	}
+
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1002/qf1002.go b/vendor/honnef.co/go/tools/quickfix/qf1002/qf1002.go
new file mode 100644
index 0000000..dd52216
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1002/qf1002.go
@@ -0,0 +1,146 @@
+package qf1002
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "QF1002",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "Convert untagged switch to tagged switch",
+		Text: `
+An untagged switch that compares a single variable against a series of
+values can be replaced with a tagged switch.`,
+		Before: `
+switch {
+case x == 1 || x == 2, x == 3:
+    ...
+case x == 4:
+    ...
+default:
+    ...
+}`,
+
+		After: `
+switch x {
+case 1, 2, 3:
+    ...
+case 4:
+    ...
+default:
+    ...
+}`,
+		Since:    "2021.1",
+		Severity: lint.SeverityHint,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		swtch := node.(*ast.SwitchStmt)
+		if swtch.Tag != nil || len(swtch.Body.List) == 0 {
+			return
+		}
+
+		pairs := make([][]*ast.BinaryExpr, len(swtch.Body.List))
+		for i, stmt := range swtch.Body.List {
+			stmt := stmt.(*ast.CaseClause)
+			for _, cond := range stmt.List {
+				if !findSwitchPairs(pass, cond, &pairs[i]) {
+					return
+				}
+			}
+		}
+
+		var x ast.Expr
+		for _, pair := range pairs {
+			if len(pair) == 0 {
+				continue
+			}
+			if x == nil {
+				x = pair[0].X
+			} else {
+				if !astutil.Equal(x, pair[0].X) {
+					return
+				}
+			}
+		}
+		if x == nil {
+			// the switch only has a default case
+			if len(pairs) > 1 {
+				panic("found more than one case clause with no pairs")
+			}
+			return
+		}
+
+		edits := make([]analysis.TextEdit, 0, len(swtch.Body.List)+1)
+		for i, stmt := range swtch.Body.List {
+			stmt := stmt.(*ast.CaseClause)
+			if stmt.List == nil {
+				continue
+			}
+
+			var values []string
+			for _, binexpr := range pairs[i] {
+				y := binexpr.Y
+				if p, ok := y.(*ast.ParenExpr); ok {
+					y = p.X
+				}
+				values = append(values, report.Render(pass, y))
+			}
+
+			edits = append(edits, edit.ReplaceWithString(edit.Range{stmt.List[0].Pos(), stmt.Colon}, strings.Join(values, ", ")))
+		}
+		pos := swtch.Body.Lbrace
+		edits = append(edits, edit.ReplaceWithString(edit.Range{pos, pos}, " "+report.Render(pass, x)))
+		report.Report(pass, swtch, fmt.Sprintf("could use tagged switch on %s", report.Render(pass, x)),
+			report.Fixes(edit.Fix("Replace with tagged switch", edits...)),
+			report.ShortRange())
+	}
+
+	code.Preorder(pass, fn, (*ast.SwitchStmt)(nil))
+	return nil, nil
+}
+
+func findSwitchPairs(pass *analysis.Pass, expr ast.Expr, pairs *[]*ast.BinaryExpr) bool {
+	binexpr, ok := ast.Unparen(expr).(*ast.BinaryExpr)
+	if !ok {
+		return false
+	}
+	switch binexpr.Op {
+	case token.EQL:
+		if code.MayHaveSideEffects(pass, binexpr.X, nil) || code.MayHaveSideEffects(pass, binexpr.Y, nil) {
+			return false
+		}
+		// syntactic identity should suffice. we do not allow side
+		// effects in the case clauses, so there should be no way for
+		// values to change.
+		if len(*pairs) > 0 && !astutil.Equal(binexpr.X, (*pairs)[0].X) {
+			return false
+		}
+		*pairs = append(*pairs, binexpr)
+		return true
+	case token.LOR:
+		return findSwitchPairs(pass, binexpr.X, pairs) && findSwitchPairs(pass, binexpr.Y, pairs)
+	default:
+		return false
+	}
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1003/qf1003.go b/vendor/honnef.co/go/tools/quickfix/qf1003/qf1003.go
new file mode 100644
index 0000000..7958795
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1003/qf1003.go
@@ -0,0 +1,205 @@
+package qf1003
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "QF1003",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "Convert if/else-if chain to tagged switch",
+		Text: `
+A series of if/else-if checks comparing the same variable against
+values can be replaced with a tagged switch.`,
+		Before: `
+if x == 1 || x == 2 {
+    ...
+} else if x == 3 {
+    ...
+} else {
+    ...
+}`,
+
+		After: `
+switch x {
+case 1, 2:
+    ...
+case 3:
+    ...
+default:
+    ...
+}`,
+		Since:    "2021.1",
+		Severity: lint.SeverityInfo,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+nodeLoop:
+	for c := range code.Cursor(pass).Preorder((*ast.IfStmt)(nil)) {
+		node := c.Node()
+		if _, ok := c.Parent().Node().(*ast.IfStmt); ok {
+			// this if statement is part of an if-else chain
+			continue
+		}
+		ifstmt := node.(*ast.IfStmt)
+
+		m := map[ast.Expr][]*ast.BinaryExpr{}
+		for item := ifstmt; item != nil; {
+			if item.Init != nil {
+				continue nodeLoop
+			}
+			if item.Body == nil {
+				continue nodeLoop
+			}
+
+			skip := false
+			ast.Inspect(item.Body, func(node ast.Node) bool {
+				if branch, ok := node.(*ast.BranchStmt); ok && branch.Tok != token.GOTO {
+					skip = true
+					return false
+				}
+				return true
+			})
+			if skip {
+				continue nodeLoop
+			}
+
+			var pairs []*ast.BinaryExpr
+			if !findSwitchPairs(pass, item.Cond, &pairs) {
+				continue nodeLoop
+			}
+			m[item.Cond] = pairs
+			switch els := item.Else.(type) {
+			case *ast.IfStmt:
+				item = els
+			case *ast.BlockStmt, nil:
+				item = nil
+			default:
+				panic(fmt.Sprintf("unreachable: %T", els))
+			}
+		}
+
+		var x ast.Expr
+		for _, pair := range m {
+			if len(pair) == 0 {
+				continue
+			}
+			if x == nil {
+				x = pair[0].X
+			} else {
+				if !astutil.Equal(x, pair[0].X) {
+					continue nodeLoop
+				}
+			}
+		}
+		if x == nil {
+			// shouldn't happen
+			continue nodeLoop
+		}
+
+		// We require at least two 'if' to make this suggestion, to
+		// avoid clutter in the editor.
+		if len(m) < 2 {
+			continue nodeLoop
+		}
+
+		// Note that we insert the switch statement as the first text edit instead of the last one so that gopls has an
+		// easier time converting it to an LSP-conforming edit.
+		//
+		// Specifically:
+		// > Text edits ranges must never overlap, that means no part of the original
+		// > document must be manipulated by more than one edit. However, it is
+		// > possible that multiple edits have the same start position: multiple
+		// > inserts, or any number of inserts followed by a single remove or replace
+		// > edit. If multiple inserts have the same position, the order in the array
+		// > defines the order in which the inserted strings appear in the resulting
+		// > text.
+		//
+		// See https://go.dev/issue/63930
+		//
+		// FIXME this edit forces the first case to begin in column 0 because we ignore indentation. try to fix that.
+		edits := []analysis.TextEdit{edit.ReplaceWithString(edit.Range{ifstmt.If, ifstmt.If}, fmt.Sprintf("switch %s {\n", report.Render(pass, x)))}
+		for item := ifstmt; item != nil; {
+			var end token.Pos
+			if item.Else != nil {
+				end = item.Else.Pos()
+			} else {
+				// delete up to but not including the closing brace.
+				end = item.Body.Rbrace
+			}
+
+			var conds []string
+			for _, cond := range m[item.Cond] {
+				y := cond.Y
+				if p, ok := y.(*ast.ParenExpr); ok {
+					y = p.X
+				}
+				conds = append(conds, report.Render(pass, y))
+			}
+			sconds := strings.Join(conds, ", ")
+			edits = append(edits,
+				edit.ReplaceWithString(edit.Range{item.If, item.Body.Lbrace + 1}, "case "+sconds+":"),
+				edit.Delete(edit.Range{item.Body.Rbrace, end}))
+
+			switch els := item.Else.(type) {
+			case *ast.IfStmt:
+				item = els
+			case *ast.BlockStmt:
+				edits = append(edits, edit.ReplaceWithString(edit.Range{els.Lbrace, els.Lbrace + 1}, "default:"))
+				item = nil
+			case nil:
+				item = nil
+			default:
+				panic(fmt.Sprintf("unreachable: %T", els))
+			}
+		}
+		report.Report(pass, ifstmt, fmt.Sprintf("could use tagged switch on %s", report.Render(pass, x)),
+			report.Fixes(edit.Fix("Replace with tagged switch", edits...)),
+			report.ShortRange())
+	}
+	return nil, nil
+}
+
+func findSwitchPairs(pass *analysis.Pass, expr ast.Expr, pairs *[]*ast.BinaryExpr) bool {
+	binexpr, ok := ast.Unparen(expr).(*ast.BinaryExpr)
+	if !ok {
+		return false
+	}
+	switch binexpr.Op {
+	case token.EQL:
+		if code.MayHaveSideEffects(pass, binexpr.X, nil) || code.MayHaveSideEffects(pass, binexpr.Y, nil) {
+			return false
+		}
+		// syntactic identity should suffice. we do not allow side
+		// effects in the case clauses, so there should be no way for
+		// values to change.
+		if len(*pairs) > 0 && !astutil.Equal(binexpr.X, (*pairs)[0].X) {
+			return false
+		}
+		*pairs = append(*pairs, binexpr)
+		return true
+	case token.LOR:
+		return findSwitchPairs(pass, binexpr.X, pairs) && findSwitchPairs(pass, binexpr.Y, pairs)
+	default:
+		return false
+	}
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1004/qf1004.go b/vendor/honnef.co/go/tools/quickfix/qf1004/qf1004.go
new file mode 100644
index 0000000..bde8c67
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1004/qf1004.go
@@ -0,0 +1,65 @@
+package qf1004
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	typeindexanalyzer "honnef.co/go/tools/internal/xtools-internal/analysis/typeindex"
+	"honnef.co/go/tools/internal/xtools-internal/typesinternal/typeindex"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "QF1004",
+		Run:      run,
+		Requires: []*analysis.Analyzer{typeindexanalyzer.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Use \'strings.ReplaceAll\' instead of \'strings.Replace\' with \'n == -1\'`,
+		Since:    "2021.1",
+		Severity: lint.SeverityHint,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var fns = []struct {
+	path        string
+	name        string
+	replacement string
+}{
+	{"strings", "Replace", "strings.ReplaceAll"},
+	{"strings", "SplitN", "strings.Split"},
+	{"strings", "SplitAfterN", "strings.SplitAfter"},
+	{"bytes", "Replace", "bytes.ReplaceAll"},
+	{"bytes", "SplitN", "bytes.Split"},
+	{"bytes", "SplitAfterN", "bytes.SplitAfter"},
+}
+
+func run(pass *analysis.Pass) (any, error) {
+	// XXX respect minimum Go version
+
+	// FIXME(dh): create proper suggested fix for renamed import
+
+	index := pass.ResultOf[typeindexanalyzer.Analyzer].(*typeindex.Index)
+	for _, fn := range fns {
+		for c := range index.Calls(index.Object(fn.path, fn.name)) {
+			call := c.Node().(*ast.CallExpr)
+			if op, ok := call.Args[len(call.Args)-1].(*ast.UnaryExpr); ok && op.Op == token.SUB {
+				if lit, ok := op.X.(*ast.BasicLit); ok && lit.Value == "1" {
+					report.Report(pass, call.Fun, fmt.Sprintf("could use %s instead", fn.replacement),
+						report.Fixes(edit.Fix(fmt.Sprintf("Use %s instead", fn.replacement),
+							edit.ReplaceWithString(call.Fun, fn.replacement),
+							edit.Delete(op))))
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1005/qf1005.go b/vendor/honnef.co/go/tools/quickfix/qf1005/qf1005.go
new file mode 100644
index 0000000..048a1db
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1005/qf1005.go
@@ -0,0 +1,111 @@
+package qf1005
+
+import (
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "QF1005",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Expand call to \'math.Pow\'`,
+		Text:     `Some uses of \'math.Pow\' can be simplified to basic multiplication.`,
+		Before:   `math.Pow(x, 2)`,
+		After:    `x * x`,
+		Since:    "2021.1",
+		Severity: lint.SeverityHint,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var mathPowQ = pattern.MustParse(`(CallExpr (Symbol "math.Pow") [x (IntegerLiteral n)])`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, matcher := range code.Matches(pass, mathPowQ) {
+		x := matcher.State["x"].(ast.Expr)
+		if code.MayHaveSideEffects(pass, x, nil) {
+			continue
+		}
+		n, ok := constant.Int64Val(constant.ToInt(matcher.State["n"].(types.TypeAndValue).Value))
+		if !ok {
+			continue
+		}
+
+		needConversion := false
+		if T, ok := pass.TypesInfo.Types[x]; ok && T.Value != nil {
+			info := types.Info{
+				Types: map[ast.Expr]types.TypeAndValue{},
+			}
+
+			// determine if the constant expression would have type float64 if used on its own
+			if err := types.CheckExpr(pass.Fset, pass.Pkg, x.Pos(), x, &info); err != nil {
+				// This should not happen
+				continue
+			}
+			if T, ok := info.Types[x].Type.(*types.Basic); ok {
+				if T.Kind() != types.UntypedFloat && T.Kind() != types.Float64 {
+					needConversion = true
+				}
+			} else {
+				needConversion = true
+			}
+		}
+
+		var replacement ast.Expr
+		switch n {
+		case 0:
+			replacement = &ast.BasicLit{
+				Kind:  token.FLOAT,
+				Value: "1.0",
+			}
+		case 1:
+			replacement = x
+		case 2, 3:
+			r := &ast.BinaryExpr{
+				X:  x,
+				Op: token.MUL,
+				Y:  x,
+			}
+			for i := 3; i <= int(n); i++ {
+				r = &ast.BinaryExpr{
+					X:  r,
+					Op: token.MUL,
+					Y:  x,
+				}
+			}
+
+			rc, ok := astutil.CopyExpr(r)
+			if !ok {
+				continue
+			}
+			replacement = astutil.SimplifyParentheses(rc)
+		default:
+			continue
+		}
+		if needConversion && n != 0 {
+			replacement = &ast.CallExpr{
+				Fun:  &ast.Ident{Name: "float64"},
+				Args: []ast.Expr{replacement},
+			}
+		}
+		report.Report(pass, node, "could expand call to math.Pow",
+			report.Fixes(edit.Fix("Expand call to math.Pow", edit.ReplaceWithNode(pass.Fset, node, replacement))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1006/qf1006.go b/vendor/honnef.co/go/tools/quickfix/qf1006/qf1006.go
new file mode 100644
index 0000000..66d5fc5
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1006/qf1006.go
@@ -0,0 +1,61 @@
+package qf1006
+
+import (
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "QF1006",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Lift \'if\'+\'break\' into loop condition`,
+		Before: `
+for {
+    if done {
+        break
+    }
+    ...
+}`,
+
+		After: `
+for !done {
+    ...
+}`,
+		Since:    "2021.1",
+		Severity: lint.SeverityHint,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkForLoopIfBreak = pattern.MustParse(`(ForStmt nil nil nil if@(IfStmt nil cond (BranchStmt "BREAK" nil) nil):_)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkForLoopIfBreak) {
+		pos := node.Pos() + token.Pos(len("for"))
+		r := astutil.NegateDeMorgan(m.State["cond"].(ast.Expr), false)
+
+		// FIXME(dh): we're leaving behind an empty line when we
+		// delete the old if statement. However, we can't just delete
+		// an additional character, in case there closing curly brace
+		// is followed by a comment, or Windows newlines.
+		report.Report(pass, m.State["if"].(ast.Node), "could lift into loop condition",
+			report.Fixes(edit.Fix("Lift into loop condition",
+				edit.ReplaceWithString(edit.Range{pos, pos}, " "+report.Render(pass, r)),
+				edit.Delete(m.State["if"].(ast.Node)))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1007/qf1007.go b/vendor/honnef.co/go/tools/quickfix/qf1007/qf1007.go
new file mode 100644
index 0000000..ab3be19
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1007/qf1007.go
@@ -0,0 +1,92 @@
+package qf1007
+
+import (
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "QF1007",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "Merge conditional assignment into variable declaration",
+		Before: `
+x := false
+if someCondition {
+    x = true
+}`,
+		After:    `x := someCondition`,
+		Since:    "2021.1",
+		Severity: lint.SeverityHint,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkConditionalAssignmentQ = pattern.MustParse(`(AssignStmt x@(Object _) ":=" assign@(Builtin b@(Or "true" "false")))`)
+var checkConditionalAssignmentIfQ = pattern.MustParse(`(IfStmt nil cond [(AssignStmt x@(Object _) "=" (Builtin b@(Or "true" "false")))] nil)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		var body *ast.BlockStmt
+		switch node := node.(type) {
+		case *ast.FuncDecl:
+			body = node.Body
+		case *ast.FuncLit:
+			body = node.Body
+		default:
+			panic("unreachable")
+		}
+		if body == nil {
+			return
+		}
+
+		stmts := body.List
+		if len(stmts) < 2 {
+			return
+		}
+		for i, first := range stmts[:len(stmts)-1] {
+			second := stmts[i+1]
+			m1, ok := code.Match(pass, checkConditionalAssignmentQ, first)
+			if !ok {
+				continue
+			}
+			m2, ok := code.Match(pass, checkConditionalAssignmentIfQ, second)
+			if !ok {
+				continue
+			}
+			if m1.State["x"] != m2.State["x"] {
+				continue
+			}
+			if m1.State["b"] == m2.State["b"] {
+				continue
+			}
+
+			v := m2.State["cond"].(ast.Expr)
+			if m1.State["b"] == "true" {
+				v = &ast.UnaryExpr{
+					Op: token.NOT,
+					X:  v,
+				}
+			}
+			report.Report(pass, first, "could merge conditional assignment into variable declaration",
+				report.Fixes(edit.Fix("Merge conditional assignment into variable declaration",
+					edit.ReplaceWithNode(pass.Fset, m1.State["assign"].(ast.Node), v),
+					edit.Delete(second))))
+		}
+	}
+	code.Preorder(pass, fn, (*ast.FuncDecl)(nil), (*ast.FuncLit)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1008/qf1008.go b/vendor/honnef.co/go/tools/quickfix/qf1008/qf1008.go
new file mode 100644
index 0000000..e71d637
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1008/qf1008.go
@@ -0,0 +1,147 @@
+package qf1008
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "QF1008",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    "Omit embedded fields from selector expression",
+		Since:    "2021.1",
+		Severity: lint.SeverityHint,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	type Selector struct {
+		Node   *ast.SelectorExpr
+		X      ast.Expr
+		Fields []*ast.Ident
+	}
+
+	// extractSelectors extracts uninterrupted sequences of selector expressions.
+	// For example, for a.b.c().d.e[0].f.g three sequences will be returned: (X=a, X.b.c), (X=a.b.c(), X.d.e), and (X=a.b.c().d.e[0], X.f.g)
+	//
+	// It returns nil if the provided selector expression is not the root of a set of sequences.
+	// For example, for a.b.c, if node is b.c, no selectors will be returned.
+	extractSelectors := func(expr *ast.SelectorExpr) []Selector {
+		path, _ := astutil.PathEnclosingInterval(code.File(pass, expr), expr.Pos(), expr.Pos())
+		for i := len(path) - 1; i >= 0; i-- {
+			if el, ok := path[i].(*ast.SelectorExpr); ok {
+				if el != expr {
+					// this expression is a subset of the entire chain, don't look at it.
+					return nil
+				}
+				break
+			}
+		}
+
+		inChain := false
+		var out []Selector
+		for _, el := range path {
+			if expr, ok := el.(*ast.SelectorExpr); ok {
+				if !inChain {
+					inChain = true
+					out = append(out, Selector{X: expr.X})
+				}
+				sel := &out[len(out)-1]
+				sel.Fields = append(sel.Fields, expr.Sel)
+				sel.Node = expr
+			} else if inChain {
+				inChain = false
+			}
+		}
+		return out
+	}
+
+	fn := func(node ast.Node) {
+		expr := node.(*ast.SelectorExpr)
+
+		if _, ok := expr.X.(*ast.SelectorExpr); !ok {
+			// Avoid the expensive call to PathEnclosingInterval for the common 1-level deep selector, which cannot be shortened.
+			return
+		}
+
+		sels := extractSelectors(expr)
+		if len(sels) == 0 {
+			return
+		}
+
+		for _, sel := range sels {
+		fieldLoop:
+			for base, fields := pass.TypesInfo.TypeOf(sel.X), sel.Fields; len(fields) >= 2; base, fields = pass.TypesInfo.ObjectOf(fields[0]).Type(), fields[1:] {
+				hop1 := fields[0]
+				hop2 := fields[1]
+
+				// the selector expression might be a qualified identifier, which cannot be simplified
+				if base == types.Typ[types.Invalid] {
+					continue fieldLoop
+				}
+
+				// Check if we can skip a field in the chain of selectors.
+				// We can skip a field 'b' if a.b.c and a.c resolve to the same object and take the same path.
+				//
+				// We set addressable to true unconditionally because we've already successfully type-checked the program,
+				// which means either the selector doesn't need addressability, or it is addressable.
+				leftObj, leftLeg, _ := types.LookupFieldOrMethod(base, true, pass.Pkg, hop1.Name)
+
+				// We can't skip fields that aren't embedded
+				if !leftObj.(*types.Var).Embedded() {
+					continue fieldLoop
+				}
+
+				directObj, directPath, _ := types.LookupFieldOrMethod(base, true, pass.Pkg, hop2.Name)
+
+				// Fail fast if omitting the embedded field leads to a different object
+				if directObj != pass.TypesInfo.ObjectOf(hop2) {
+					continue fieldLoop
+				}
+
+				_, rightLeg, _ := types.LookupFieldOrMethod(leftObj.Type(), true, pass.Pkg, hop2.Name)
+
+				// Fail fast if the paths are obviously different
+				if len(directPath) != len(leftLeg)+len(rightLeg) {
+					continue fieldLoop
+				}
+
+				// Make sure that omitting the embedded field will take the same path to the final object.
+				// Multiple paths involving different fields may lead to the same type-checker object, causing different runtime behavior.
+				for i := range directPath {
+					if i < len(leftLeg) {
+						if leftLeg[i] != directPath[i] {
+							continue fieldLoop
+						}
+					} else {
+						if rightLeg[i-len(leftLeg)] != directPath[i] {
+							continue fieldLoop
+						}
+					}
+				}
+
+				e := edit.Delete(edit.Range{hop1.Pos(), hop2.Pos()})
+				report.Report(pass, hop1, fmt.Sprintf("could remove embedded field %q from selector", hop1.Name),
+					report.Fixes(edit.Fix(fmt.Sprintf("Remove embedded field %q from selector", hop1.Name), e)))
+			}
+		}
+	}
+	code.Preorder(pass, fn, (*ast.SelectorExpr)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1009/qf1009.go b/vendor/honnef.co/go/tools/quickfix/qf1009/qf1009.go
new file mode 100644
index 0000000..d16e67c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1009/qf1009.go
@@ -0,0 +1,51 @@
+package qf1009
+
+import (
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "QF1009",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Use \'time.Time.Equal\' instead of \'==\' operator`,
+		Since:    "2021.1",
+		Severity: lint.SeverityInfo,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var timeEqualR = pattern.MustParse(`(CallExpr (SelectorExpr lhs (Ident "Equal")) rhs)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	// FIXME(dh): create proper suggested fix for renamed import
+
+	fn := func(node ast.Node) {
+		expr := node.(*ast.BinaryExpr)
+		if expr.Op != token.EQL {
+			return
+		}
+		if !code.IsOfTypeWithName(pass, expr.X, "time.Time") || !code.IsOfTypeWithName(pass, expr.Y, "time.Time") {
+			return
+		}
+		report.Report(pass, node, "probably want to use time.Time.Equal instead",
+			report.Fixes(edit.Fix("Use time.Time.Equal method",
+				edit.ReplaceWithPattern(pass.Fset, node, timeEqualR, pattern.State{"lhs": expr.X, "rhs": expr.Y}))))
+	}
+	code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1010/qf1010.go b/vendor/honnef.co/go/tools/quickfix/qf1010/qf1010.go
new file mode 100644
index 0000000..1942bc0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1010/qf1010.go
@@ -0,0 +1,75 @@
+package qf1010
+
+import (
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/knowledge"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "QF1010",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    "Convert slice of bytes to string when printing it",
+		Since:    "2021.1",
+		Severity: lint.SeverityHint,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var byteSlicePrintingQ = pattern.MustParse(`
+	(Or
+		(CallExpr
+			(Symbol (Or
+				"fmt.Print"
+				"fmt.Println"
+				"fmt.Sprint"
+				"fmt.Sprintln"
+				"log.Fatal"
+				"log.Fatalln"
+				"log.Panic"
+				"log.Panicln"
+				"log.Print"
+				"log.Println"
+				"(*log.Logger).Fatal"
+				"(*log.Logger).Fatalln"
+				"(*log.Logger).Panic"
+				"(*log.Logger).Panicln"
+				"(*log.Logger).Print"
+				"(*log.Logger).Println")) args)
+
+		(CallExpr (Symbol (Or
+			"fmt.Fprint"
+			"fmt.Fprintln")) _:args))`)
+
+var byteSlicePrintingR = pattern.MustParse(`(CallExpr (Ident "string") [arg])`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, m := range code.Matches(pass, byteSlicePrintingQ) {
+		args := m.State["args"].([]ast.Expr)
+		for _, arg := range args {
+			if !code.IsOfStringConvertibleByteSlice(pass, arg) {
+				continue
+			}
+			if types.Implements(pass.TypesInfo.TypeOf(arg), knowledge.Interfaces["fmt.Stringer"]) {
+				continue
+			}
+
+			fix := edit.Fix("Convert argument to string", edit.ReplaceWithPattern(pass.Fset, arg, byteSlicePrintingR, pattern.State{"arg": arg}))
+			report.Report(pass, arg, "could convert argument to string", report.Fixes(fix))
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1011/qf1011.go b/vendor/honnef.co/go/tools/quickfix/qf1011/qf1011.go
new file mode 100644
index 0000000..f77fdb9
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1011/qf1011.go
@@ -0,0 +1,21 @@
+package qf1011
+
+import (
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/sharedcheck"
+)
+
+func init() {
+	SCAnalyzer.Analyzer.Name = "QF1011"
+}
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: sharedcheck.RedundantTypeInDeclarationChecker("could", true),
+	Doc: &lint.RawDocumentation{
+		Title:    "Omit redundant type from variable declaration",
+		Since:    "2021.1",
+		Severity: lint.SeverityHint,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1012/qf1012.go b/vendor/honnef.co/go/tools/quickfix/qf1012/qf1012.go
new file mode 100644
index 0000000..45784d9
--- /dev/null
+++ b/vendor/honnef.co/go/tools/quickfix/qf1012/qf1012.go
@@ -0,0 +1,128 @@
+package qf1012
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/knowledge"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "QF1012",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Use \'fmt.Fprintf(x, ...)\' instead of \'x.Write(fmt.Sprintf(...))\'`,
+		Since:    "2022.1",
+		Severity: lint.SeverityHint,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkWriteBytesSprintfQ = pattern.MustParse(`
+	(CallExpr
+		(SelectorExpr recv (Ident "Write"))
+		(CallExpr (ArrayType nil (Ident "byte"))
+			(CallExpr
+				fn@(Or
+					(Symbol "fmt.Sprint")
+					(Symbol "fmt.Sprintf")
+					(Symbol "fmt.Sprintln"))
+				args)
+	))`)
+
+	checkWriteStringSprintfQ = pattern.MustParse(`
+	(CallExpr
+		(SelectorExpr recv (Ident "WriteString"))
+		(CallExpr
+			fn@(Or
+				(Symbol "fmt.Sprint")
+				(Symbol "fmt.Sprintf")
+				(Symbol "fmt.Sprintln"))
+			args))`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		getRecv := func(m *pattern.Matcher) (ast.Expr, types.Type) {
+			recv := m.State["recv"].(ast.Expr)
+			recvT := pass.TypesInfo.TypeOf(recv)
+
+			// Use *N, not N, for the interface check if N
+			// is a named non-interface type, since the pointer
+			// has a larger method set (https://staticcheck.dev/issues/1097).
+			// We assume the receiver expression is addressable
+			// since otherwise the code wouldn't compile.
+			if _, ok := types.Unalias(recvT).(*types.Named); ok && !types.IsInterface(recvT) {
+				recvT = types.NewPointer(recvT)
+				recv = &ast.UnaryExpr{Op: token.AND, X: recv}
+
+			}
+			return recv, recvT
+		}
+
+		if m, ok := code.Match(pass, checkWriteBytesSprintfQ, node); ok {
+			recv, recvT := getRecv(m)
+			if !types.Implements(recvT, knowledge.Interfaces["io.Writer"]) {
+				return
+			}
+
+			name := m.State["fn"].(*types.Func).Name()
+			newName := "F" + strings.TrimPrefix(name, "S")
+			msg := fmt.Sprintf("Use fmt.%s(...) instead of Write([]byte(fmt.%s(...)))", newName, name)
+
+			args := m.State["args"].([]ast.Expr)
+			fix := edit.Fix(msg, edit.ReplaceWithNode(pass.Fset, node, &ast.CallExpr{
+				Fun: &ast.SelectorExpr{
+					X:   ast.NewIdent("fmt"),
+					Sel: ast.NewIdent(newName),
+				},
+				Args: append([]ast.Expr{recv}, args...),
+			}))
+			report.Report(pass, node, msg, report.Fixes(fix))
+		} else if m, ok := code.Match(pass, checkWriteStringSprintfQ, node); ok {
+			recv, recvT := getRecv(m)
+			if !types.Implements(recvT, knowledge.Interfaces["io.StringWriter"]) {
+				return
+			}
+			// The type needs to implement both StringWriter and Writer.
+			// If it doesn't implement Writer, then we cannot pass it to fmt.Fprint.
+			if !types.Implements(recvT, knowledge.Interfaces["io.Writer"]) {
+				return
+			}
+
+			name := m.State["fn"].(*types.Func).Name()
+			newName := "F" + strings.TrimPrefix(name, "S")
+			msg := fmt.Sprintf("Use fmt.%s(...) instead of WriteString(fmt.%s(...))", newName, name)
+
+			args := m.State["args"].([]ast.Expr)
+			fix := edit.Fix(msg, edit.ReplaceWithNode(pass.Fset, node, &ast.CallExpr{
+				Fun: &ast.SelectorExpr{
+					X:   ast.NewIdent("fmt"),
+					Sel: ast.NewIdent(newName),
+				},
+				Args: append([]ast.Expr{recv}, args...),
+			}))
+			report.Report(pass, node, msg, report.Fixes(fix))
+		}
+	}
+	if !code.CouldMatchAny(pass, checkWriteBytesSprintfQ, checkWriteStringSprintfQ) {
+		return nil, nil
+	}
+	code.Preorder(pass, fn, (*ast.CallExpr)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/sarif/sarif.go b/vendor/honnef.co/go/tools/sarif/sarif.go
new file mode 100644
index 0000000..1c7b1d4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/sarif/sarif.go
@@ -0,0 +1,138 @@
+package sarif
+
+const Version = "2.1.0"
+const Schema = "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
+
+type Log struct {
+	Version string `json:"version"`
+	Schema  string `json:"$schema"`
+	Runs    []Run  `json:"runs"`
+}
+
+type Run struct {
+	Tool        Tool         `json:"tool"`
+	Results     []Result     `json:"results,omitempty"`
+	Invocations []Invocation `json:"invocations,omitempty"`
+	Artifacts   []Artifact   `json:"artifacts,omitempty"`
+}
+
+type Artifact struct {
+	Location       ArtifactLocation `json:"location"`
+	Length         int              `json:"length"`
+	SourceLanguage string           `json:"sourceLanguage"`
+	Roles          []string         `json:"roles"`
+	Encoding       string           `json:"encoding"`
+}
+
+const (
+	AnalysisTarget = "analysisTarget"
+	UTF8           = "UTF-8"
+	Fail           = "fail"
+	Warning        = "warning"
+	Error          = "error"
+	Note           = "note"
+	None           = "none"
+)
+
+type Hash struct {
+	Sha256 string `json:"sha-256"`
+}
+
+type Tool struct {
+	Driver ToolComponent `json:"driver"`
+}
+
+type Invocation struct {
+	CommandLine         string           `json:"commandLine,omitempty"`
+	Arguments           []string         `json:"arguments,omitempty"`
+	WorkingDirectory    ArtifactLocation `json:"workingDirectory,omitzero"`
+	ExecutionSuccessful bool             `json:"executionSuccessful"`
+}
+
+type ToolComponent struct {
+	Name            string                `json:"name,omitempty"`
+	Version         string                `json:"version,omitempty"`
+	SemanticVersion string                `json:"semanticVersion,omitempty"`
+	InformationURI  string                `json:"informationUri,omitempty"`
+	Rules           []ReportingDescriptor `json:"rules,omitempty"`
+}
+
+type ReportingDescriptor struct {
+	ID               string  `json:"id"`
+	ShortDescription Message `json:"shortDescription"`
+	// FullDescription  Message `json:"fullDescription"`
+	Help                 Message                `json:"help"`
+	HelpURI              string                 `json:"helpUri,omitempty"`
+	DefaultConfiguration ReportingConfiguration `json:"defaultConfiguration"`
+}
+
+type ReportingConfiguration struct {
+	Enabled    bool           `json:"enabled"`
+	Level      string         `json:"level,omitempty"`
+	Parameters map[string]any `json:"parameters,omitempty"`
+}
+
+type Result struct {
+	RuleID string `json:"ruleId"`
+	// RuleIndex        int        `json:"ruleIndex"`
+	Kind             string        `json:"kind"`
+	Level            string        `json:"level,omitempty"`
+	Message          Message       `json:"message"`
+	Locations        []Location    `json:"locations,omitempty"`
+	RelatedLocations []Location    `json:"relatedLocations,omitempty"`
+	Fixes            []Fix         `json:"fixes,omitempty"`
+	Suppressions     []Suppression `json:"suppressions"`
+}
+
+type Suppression struct {
+	Kind          string `json:"kind"`
+	Justification string `json:"justification"`
+}
+
+type Fix struct {
+	Description     Message          `json:"description"`
+	ArtifactChanges []ArtifactChange `json:"artifactChanges"`
+}
+
+type ArtifactChange struct {
+	ArtifactLocation ArtifactLocation `json:"artifactLocation"`
+	Replacements     []Replacement    `json:"replacements"`
+}
+
+type Replacement struct {
+	DeletedRegion   Region          `json:"deletedRegion"`
+	InsertedContent ArtifactContent `json:"insertedContent"`
+}
+
+type ArtifactContent struct {
+	Text string `json:"text"`
+}
+
+type Message struct {
+	Text     string `json:"text,omitempty"`
+	Markdown string `json:"markdown,omitempty"`
+}
+
+type Location struct {
+	ID               int              `json:"id,omitempty"`
+	Message          *Message         `json:"message,omitempty"`
+	PhysicalLocation PhysicalLocation `json:"physicalLocation"`
+}
+
+type PhysicalLocation struct {
+	ArtifactLocation ArtifactLocation `json:"artifactLocation"`
+	Region           Region           `json:"region"`
+}
+
+type ArtifactLocation struct {
+	URI       string `json:"uri,omitempty"`
+	Index     int    `json:"index,omitempty"`
+	URIBaseID string `json:"uriBaseId,omitempty"`
+}
+
+type Region struct {
+	StartLine   int `json:"startLine"`
+	StartColumn int `json:"startColumn"`
+	EndLine     int `json:"endLine,omitempty"`
+	EndColumn   int `json:"endColumn,omitempty"`
+}
diff --git a/vendor/honnef.co/go/tools/simple/analysis.go b/vendor/honnef.co/go/tools/simple/analysis.go
new file mode 100644
index 0000000..9512d2a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/analysis.go
@@ -0,0 +1,80 @@
+// Code generated by generate.go. DO NOT EDIT.
+
+package simple
+
+import (
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/simple/s1000"
+	"honnef.co/go/tools/simple/s1001"
+	"honnef.co/go/tools/simple/s1002"
+	"honnef.co/go/tools/simple/s1003"
+	"honnef.co/go/tools/simple/s1004"
+	"honnef.co/go/tools/simple/s1005"
+	"honnef.co/go/tools/simple/s1006"
+	"honnef.co/go/tools/simple/s1007"
+	"honnef.co/go/tools/simple/s1008"
+	"honnef.co/go/tools/simple/s1009"
+	"honnef.co/go/tools/simple/s1010"
+	"honnef.co/go/tools/simple/s1011"
+	"honnef.co/go/tools/simple/s1012"
+	"honnef.co/go/tools/simple/s1016"
+	"honnef.co/go/tools/simple/s1017"
+	"honnef.co/go/tools/simple/s1018"
+	"honnef.co/go/tools/simple/s1019"
+	"honnef.co/go/tools/simple/s1020"
+	"honnef.co/go/tools/simple/s1021"
+	"honnef.co/go/tools/simple/s1023"
+	"honnef.co/go/tools/simple/s1024"
+	"honnef.co/go/tools/simple/s1025"
+	"honnef.co/go/tools/simple/s1028"
+	"honnef.co/go/tools/simple/s1029"
+	"honnef.co/go/tools/simple/s1030"
+	"honnef.co/go/tools/simple/s1031"
+	"honnef.co/go/tools/simple/s1032"
+	"honnef.co/go/tools/simple/s1033"
+	"honnef.co/go/tools/simple/s1034"
+	"honnef.co/go/tools/simple/s1035"
+	"honnef.co/go/tools/simple/s1036"
+	"honnef.co/go/tools/simple/s1037"
+	"honnef.co/go/tools/simple/s1038"
+	"honnef.co/go/tools/simple/s1039"
+	"honnef.co/go/tools/simple/s1040"
+)
+
+var Analyzers = []*lint.Analyzer{
+	s1000.SCAnalyzer,
+	s1001.SCAnalyzer,
+	s1002.SCAnalyzer,
+	s1003.SCAnalyzer,
+	s1004.SCAnalyzer,
+	s1005.SCAnalyzer,
+	s1006.SCAnalyzer,
+	s1007.SCAnalyzer,
+	s1008.SCAnalyzer,
+	s1009.SCAnalyzer,
+	s1010.SCAnalyzer,
+	s1011.SCAnalyzer,
+	s1012.SCAnalyzer,
+	s1016.SCAnalyzer,
+	s1017.SCAnalyzer,
+	s1018.SCAnalyzer,
+	s1019.SCAnalyzer,
+	s1020.SCAnalyzer,
+	s1021.SCAnalyzer,
+	s1023.SCAnalyzer,
+	s1024.SCAnalyzer,
+	s1025.SCAnalyzer,
+	s1028.SCAnalyzer,
+	s1029.SCAnalyzer,
+	s1030.SCAnalyzer,
+	s1031.SCAnalyzer,
+	s1032.SCAnalyzer,
+	s1033.SCAnalyzer,
+	s1034.SCAnalyzer,
+	s1035.SCAnalyzer,
+	s1036.SCAnalyzer,
+	s1037.SCAnalyzer,
+	s1038.SCAnalyzer,
+	s1039.SCAnalyzer,
+	s1040.SCAnalyzer,
+}
diff --git a/vendor/honnef.co/go/tools/simple/doc.go b/vendor/honnef.co/go/tools/simple/doc.go
new file mode 100644
index 0000000..c04bc24
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/doc.go
@@ -0,0 +1,6 @@
+//go:generate go run ../generate.go
+
+// Package simple contains analyzes that simplify code.
+// All suggestions made by these analyzes are intended to result in objectively simpler code,
+// and following their advice is recommended.
+package simple
diff --git a/vendor/honnef.co/go/tools/simple/s1000/s1000.go b/vendor/honnef.co/go/tools/simple/s1000/s1000.go
new file mode 100644
index 0000000..3e4adf9
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1000/s1000.go
@@ -0,0 +1,71 @@
+package s1000
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1000",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Use plain channel send or receive instead of single-case select`,
+		Text: `Select statements with a single case can be replaced with a simple
+send or receive.`,
+		Before: `
+select {
+case x := <-ch:
+    fmt.Println(x)
+}`,
+		After: `
+x := <-ch
+fmt.Println(x)
+`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkSingleCaseSelectQ1 = pattern.MustParse(`
+		(ForStmt
+			nil nil nil
+			select@(SelectStmt
+				(CommClause
+					(Or
+						(UnaryExpr "<-" _)
+						(AssignStmt _ _ (UnaryExpr "<-" _)))
+					_)))`)
+	checkSingleCaseSelectQ2 = pattern.MustParse(`(SelectStmt (CommClause _ _))`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	seen := map[ast.Node]struct{}{}
+	fn := func(node ast.Node) {
+		if m, ok := code.Match(pass, checkSingleCaseSelectQ1, node); ok {
+			seen[m.State["select"].(ast.Node)] = struct{}{}
+			report.Report(pass, node, "should use for range instead of for { select {} }", report.FilterGenerated())
+		} else if _, ok := code.Match(pass, checkSingleCaseSelectQ2, node); ok {
+			if _, ok := seen[node]; !ok {
+				report.Report(pass, node, "should use a simple channel send/receive instead of select with a single case",
+					report.ShortRange(),
+					report.FilterGenerated())
+			}
+		}
+	}
+	code.Preorder(pass, fn, (*ast.ForStmt)(nil), (*ast.SelectStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1001/s1001.go b/vendor/honnef.co/go/tools/simple/s1001/s1001.go
new file mode 100644
index 0000000..ae026e2
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1001/s1001.go
@@ -0,0 +1,190 @@
+package s1001
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1001",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Replace for loop with call to copy`,
+		Text: `
+Use \'copy()\' for copying elements from one slice to another. For
+arrays of identical size, you can use simple assignment.`,
+		Before: `
+for i, x := range src {
+    dst[i] = x
+}`,
+		After: `copy(dst, src)`,
+		Since: "2017.1",
+		// MergeIfAll because the types of src and dst might be different under different build tags.
+		// You shouldn't write code like that…
+		MergeIf: lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkLoopCopyQ = pattern.MustParse(`
+		(Or
+			(RangeStmt
+				key@(Ident _) value@(Ident _) ":=" src
+				[(AssignStmt (IndexExpr dst key) "=" value)])
+			(RangeStmt
+				key@(Ident _) nil ":=" src
+				[(AssignStmt (IndexExpr dst key) "=" (IndexExpr src key))])
+			(ForStmt
+				(AssignStmt key@(Ident _) ":=" (IntegerLiteral "0"))
+				(BinaryExpr key "<" (CallExpr (Symbol "len") [src]))
+				(IncDecStmt key "++")
+				[(AssignStmt (IndexExpr dst key) "=" (IndexExpr src key))]))`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	// TODO revisit once range doesn't require a structural type
+
+	isInvariant := func(k, v types.Object, node ast.Expr) bool {
+		if code.MayHaveSideEffects(pass, node, nil) {
+			return false
+		}
+		invariant := true
+		ast.Inspect(node, func(node ast.Node) bool {
+			if node, ok := node.(*ast.Ident); ok {
+				obj := pass.TypesInfo.ObjectOf(node)
+				if obj == k || obj == v {
+					// don't allow loop bodies like 'a[i][i] = v'
+					invariant = false
+					return false
+				}
+			}
+			return true
+		})
+		return invariant
+	}
+
+	var elType func(T types.Type) (el types.Type, isArray bool, isArrayPointer bool, ok bool)
+	elType = func(T types.Type) (el types.Type, isArray bool, isArrayPointer bool, ok bool) {
+		switch typ := T.Underlying().(type) {
+		case *types.Slice:
+			return typ.Elem(), false, false, true
+		case *types.Array:
+			return typ.Elem(), true, false, true
+		case *types.Pointer:
+			el, isArray, _, ok = elType(typ.Elem())
+			return el, isArray, true, ok
+		default:
+			return nil, false, false, false
+		}
+	}
+
+	for node, m := range code.Matches(pass, checkLoopCopyQ) {
+		src := m.State["src"].(ast.Expr)
+		dst := m.State["dst"].(ast.Expr)
+
+		k := pass.TypesInfo.ObjectOf(m.State["key"].(*ast.Ident))
+		var v types.Object
+		if value, ok := m.State["value"]; ok {
+			v = pass.TypesInfo.ObjectOf(value.(*ast.Ident))
+		}
+		if !isInvariant(k, v, dst) {
+			continue
+		}
+		if !isInvariant(k, v, src) {
+			// For example: 'for i := range foo()'
+			continue
+		}
+
+		Tsrc := pass.TypesInfo.TypeOf(src)
+		Tdst := pass.TypesInfo.TypeOf(dst)
+		TsrcElem, TsrcArray, TsrcPointer, ok := elType(Tsrc)
+		if !ok {
+			continue
+		}
+		if TsrcPointer {
+			Tsrc = Tsrc.Underlying().(*types.Pointer).Elem()
+		}
+		TdstElem, TdstArray, TdstPointer, ok := elType(Tdst)
+		if !ok {
+			continue
+		}
+		if TdstPointer {
+			Tdst = Tdst.Underlying().(*types.Pointer).Elem()
+		}
+
+		if !types.Identical(TsrcElem, TdstElem) {
+			continue
+		}
+
+		if TsrcArray && TdstArray && types.Identical(Tsrc, Tdst) {
+			if TsrcPointer {
+				src = &ast.StarExpr{
+					X: src,
+				}
+			}
+			if TdstPointer {
+				dst = &ast.StarExpr{
+					X: dst,
+				}
+			}
+			r := &ast.AssignStmt{
+				Lhs: []ast.Expr{dst},
+				Rhs: []ast.Expr{src},
+				Tok: token.ASSIGN,
+			}
+
+			report.Report(pass, node, "should copy arrays using assignment instead of using a loop",
+				report.FilterGenerated(),
+				report.ShortRange(),
+				report.Fixes(edit.Fix("Replace loop with assignment", edit.ReplaceWithNode(pass.Fset, node, r))))
+		} else {
+			tv, err := types.Eval(pass.Fset, pass.Pkg, node.Pos(), "copy")
+			if err == nil && tv.IsBuiltin() {
+				to := "to"
+				from := "from"
+				src := m.State["src"].(ast.Expr)
+				if TsrcArray {
+					from = "from[:]"
+					src = &ast.SliceExpr{
+						X: src,
+					}
+				}
+				dst := m.State["dst"].(ast.Expr)
+				if TdstArray {
+					to = "to[:]"
+					dst = &ast.SliceExpr{
+						X: dst,
+					}
+				}
+
+				r := &ast.CallExpr{
+					Fun:  &ast.Ident{Name: "copy"},
+					Args: []ast.Expr{dst, src},
+				}
+				opts := []report.Option{
+					report.ShortRange(),
+					report.FilterGenerated(),
+					report.Fixes(edit.Fix("Replace loop with call to copy()", edit.ReplaceWithNode(pass.Fset, node, r))),
+				}
+				report.Report(pass, node, fmt.Sprintf("should use copy(%s, %s) instead of a loop", to, from), opts...)
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1002/s1002.go b/vendor/honnef.co/go/tools/simple/s1002/s1002.go
new file mode 100644
index 0000000..7d7d8b8
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1002/s1002.go
@@ -0,0 +1,88 @@
+package s1002
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1002",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:  `Omit comparison with boolean constant`,
+		Before: `if x == true {}`,
+		After:  `if x {}`,
+		Since:  "2017.1",
+		// MergeIfAll because 'true' might not be the builtin constant under all build tags.
+		// You shouldn't write code like that…
+		MergeIf: lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		if code.IsInTest(pass, node) {
+			return
+		}
+
+		expr := node.(*ast.BinaryExpr)
+		if expr.Op != token.EQL && expr.Op != token.NEQ {
+			return
+		}
+		x := code.IsBoolConst(pass, expr.X)
+		y := code.IsBoolConst(pass, expr.Y)
+		if !x && !y {
+			return
+		}
+		var other ast.Expr
+		var val bool
+		if x {
+			val = code.BoolConst(pass, expr.X)
+			other = expr.Y
+		} else {
+			val = code.BoolConst(pass, expr.Y)
+			other = expr.X
+		}
+
+		ok := typeutil.All(pass.TypesInfo.TypeOf(other), func(term *types.Term) bool {
+			basic, ok := term.Type().Underlying().(*types.Basic)
+			return ok && basic.Kind() == types.Bool
+		})
+		if !ok {
+			return
+		}
+		op := ""
+		if (expr.Op == token.EQL && !val) || (expr.Op == token.NEQ && val) {
+			op = "!"
+		}
+		r := op + report.Render(pass, other)
+		l1 := len(r)
+		r = strings.TrimLeft(r, "!")
+		if (l1-len(r))%2 == 1 {
+			r = "!" + r
+		}
+		report.Report(pass, expr, fmt.Sprintf("should omit comparison to bool constant, can be simplified to %s", r),
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix("Simplify bool comparison", edit.ReplaceWithString(expr, r))))
+	}
+	code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1003/s1003.go b/vendor/honnef.co/go/tools/simple/s1003/s1003.go
new file mode 100644
index 0000000..0bd1e02
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1003/s1003.go
@@ -0,0 +1,118 @@
+package s1003
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1003",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:   `Replace call to \'strings.Index\' with \'strings.Contains\'`,
+		Before:  `if strings.Index(x, y) != -1 {}`,
+		After:   `if strings.Contains(x, y) {}`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	// map of value to token to bool value
+	allowed := map[int64]map[token.Token]bool{
+		-1: {token.GTR: true, token.NEQ: true, token.EQL: false},
+		0:  {token.GEQ: true, token.LSS: false},
+	}
+	fn := func(node ast.Node) {
+		expr := node.(*ast.BinaryExpr)
+		switch expr.Op {
+		case token.GEQ, token.GTR, token.NEQ, token.LSS, token.EQL:
+		default:
+			return
+		}
+
+		value, ok := code.ExprToInt(pass, expr.Y)
+		if !ok {
+			return
+		}
+
+		allowedOps, ok := allowed[value]
+		if !ok {
+			return
+		}
+		b, ok := allowedOps[expr.Op]
+		if !ok {
+			return
+		}
+
+		call, ok := expr.X.(*ast.CallExpr)
+		if !ok {
+			return
+		}
+		sel, ok := call.Fun.(*ast.SelectorExpr)
+		if !ok {
+			return
+		}
+		pkgIdent, ok := sel.X.(*ast.Ident)
+		if !ok {
+			return
+		}
+		funIdent := sel.Sel
+		if pkgIdent.Name != "strings" && pkgIdent.Name != "bytes" {
+			return
+		}
+
+		var r ast.Expr
+		switch funIdent.Name {
+		case "IndexRune":
+			r = &ast.SelectorExpr{
+				X:   pkgIdent,
+				Sel: &ast.Ident{Name: "ContainsRune"},
+			}
+		case "IndexAny":
+			r = &ast.SelectorExpr{
+				X:   pkgIdent,
+				Sel: &ast.Ident{Name: "ContainsAny"},
+			}
+		case "Index":
+			r = &ast.SelectorExpr{
+				X:   pkgIdent,
+				Sel: &ast.Ident{Name: "Contains"},
+			}
+		default:
+			return
+		}
+
+		r = &ast.CallExpr{
+			Fun:  r,
+			Args: call.Args,
+		}
+		if !b {
+			r = &ast.UnaryExpr{
+				Op: token.NOT,
+				X:  r,
+			}
+		}
+
+		report.Report(pass, node, fmt.Sprintf("should use %s instead", report.Render(pass, r)),
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix(fmt.Sprintf("Simplify use of %s", report.Render(pass, call.Fun)), edit.ReplaceWithNode(pass.Fset, node, r))))
+	}
+	code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1004/s1004.go b/vendor/honnef.co/go/tools/simple/s1004/s1004.go
new file mode 100644
index 0000000..1299683
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1004/s1004.go
@@ -0,0 +1,65 @@
+package s1004
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1004",
+		Run:      CheckBytesCompare,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:   `Replace call to \'bytes.Compare\' with \'bytes.Equal\'`,
+		Before:  `if bytes.Compare(x, y) == 0 {}`,
+		After:   `if bytes.Equal(x, y) {}`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkBytesCompareQ  = pattern.MustParse(`(BinaryExpr (CallExpr (Symbol "bytes.Compare") args) op@(Or "==" "!=") (IntegerLiteral "0"))`)
+	checkBytesCompareRe = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "bytes") (Ident "Equal")) args)`)
+	checkBytesCompareRn = pattern.MustParse(`(UnaryExpr "!" (CallExpr (SelectorExpr (Ident "bytes") (Ident "Equal")) args))`)
+)
+
+func CheckBytesCompare(pass *analysis.Pass) (any, error) {
+	if pass.Pkg.Path() == "bytes" || pass.Pkg.Path() == "bytes_test" {
+		// the bytes package is free to use bytes.Compare as it sees fit
+		return nil, nil
+	}
+	for node, m := range code.Matches(pass, checkBytesCompareQ) {
+		args := report.RenderArgs(pass, m.State["args"].([]ast.Expr))
+		prefix := ""
+		if m.State["op"].(token.Token) == token.NEQ {
+			prefix = "!"
+		}
+
+		var fix analysis.SuggestedFix
+		switch tok := m.State["op"].(token.Token); tok {
+		case token.EQL:
+			fix = edit.Fix("Simplify use of bytes.Compare", edit.ReplaceWithPattern(pass.Fset, node, checkBytesCompareRe, m.State))
+		case token.NEQ:
+			fix = edit.Fix("Simplify use of bytes.Compare", edit.ReplaceWithPattern(pass.Fset, node, checkBytesCompareRn, m.State))
+		default:
+			panic(fmt.Sprintf("unexpected token %v", tok))
+		}
+		report.Report(pass, node, fmt.Sprintf("should use %sbytes.Equal(%s) instead", prefix, args), report.FilterGenerated(), report.Fixes(fix))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1005/s1005.go b/vendor/honnef.co/go/tools/simple/s1005/s1005.go
new file mode 100644
index 0000000..bd3dcbd
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1005/s1005.go
@@ -0,0 +1,108 @@
+package s1005
+
+import (
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1005",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Drop unnecessary use of the blank identifier`,
+		Text:  `In many cases, assigning to the blank identifier is unnecessary.`,
+		Before: `
+for _ = range s {}
+_ = <-ch`,
+		After: `
+for range s{}
+<-ch`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkUnnecessaryBlankQ1 = pattern.MustParse(`
+		(AssignStmt
+			[_ (Ident "_")]
+			_
+			(UnaryExpr "<-" _)) `)
+	checkUnnecessaryBlankQ2 = pattern.MustParse(`
+		(AssignStmt
+			(Ident "_") _ recv@(UnaryExpr "<-" _))`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	fn1 := func(node ast.Node) {
+		// We don't check for 'x, _ = m[k]', which might be used to indicate
+		// that one knows that there might be no entry and that one doesn't
+		// care.
+
+		if _, ok := code.Match(pass, checkUnnecessaryBlankQ1, node); ok {
+			r := *node.(*ast.AssignStmt)
+			r.Lhs = r.Lhs[0:1]
+			report.Report(pass, node, "unnecessary assignment to the blank identifier",
+				report.FilterGenerated(),
+				report.Fixes(edit.Fix("Remove assignment to blank identifier", edit.ReplaceWithNode(pass.Fset, node, &r))))
+		} else if m, ok := code.Match(pass, checkUnnecessaryBlankQ2, node); ok {
+			report.Report(pass, node, "unnecessary assignment to the blank identifier",
+				report.FilterGenerated(),
+				report.Fixes(edit.Fix("Simplify channel receive operation", edit.ReplaceWithNode(pass.Fset, node, m.State["recv"].(ast.Node)))))
+		}
+	}
+
+	fn3 := func(node ast.Node) {
+		rs := node.(*ast.RangeStmt)
+
+		if _, ok := pass.TypesInfo.TypeOf(rs.X).Underlying().(*types.Signature); ok {
+			// iteration variables are not optional with rangefunc
+			return
+		}
+
+		// for _
+		if rs.Value == nil && astutil.IsBlank(rs.Key) {
+			report.Report(pass, rs.Key, "unnecessary assignment to the blank identifier",
+				report.FilterGenerated(),
+				report.MinimumLanguageVersion("go1.4"),
+				report.Fixes(edit.Fix("Remove assignment to blank identifier", edit.Delete(edit.Range{rs.Key.Pos(), rs.TokPos + 1}))))
+		}
+
+		// for _, _
+		if astutil.IsBlank(rs.Key) && astutil.IsBlank(rs.Value) {
+			// FIXME we should mark both key and value
+			report.Report(pass, rs.Key, "unnecessary assignment to the blank identifier",
+				report.FilterGenerated(),
+				report.MinimumLanguageVersion("go1.4"),
+				report.Fixes(edit.Fix("Remove assignment to blank identifier", edit.Delete(edit.Range{rs.Key.Pos(), rs.TokPos + 1}))))
+		}
+
+		// for x, _
+		if !astutil.IsBlank(rs.Key) && astutil.IsBlank(rs.Value) {
+			report.Report(pass, rs.Value, "unnecessary assignment to the blank identifier",
+				report.FilterGenerated(),
+				report.MinimumLanguageVersion("go1.4"),
+				report.Fixes(edit.Fix("Remove assignment to blank identifier", edit.Delete(edit.Range{rs.Key.End(), rs.Value.End()}))))
+		}
+	}
+
+	code.Preorder(pass, fn1, (*ast.AssignStmt)(nil))
+	code.Preorder(pass, fn3, (*ast.RangeStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1006/s1006.go b/vendor/honnef.co/go/tools/simple/s1006/s1006.go
new file mode 100644
index 0000000..faa58a6
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1006/s1006.go
@@ -0,0 +1,46 @@
+package s1006
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1006",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:   `Use \"for { ... }\" for infinite loops`,
+		Text:    `For infinite loops, using \'for { ... }\' is the most idiomatic choice.`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		loop := node.(*ast.ForStmt)
+		if loop.Init != nil || loop.Post != nil {
+			return
+		}
+		if !code.IsBoolConst(pass, loop.Cond) || !code.BoolConst(pass, loop.Cond) {
+			return
+		}
+		report.Report(pass, loop, "should use for {} instead of for true {}",
+			report.ShortRange(),
+			report.FilterGenerated())
+	}
+	code.Preorder(pass, fn, (*ast.ForStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1007/s1007.go b/vendor/honnef.co/go/tools/simple/s1007/s1007.go
new file mode 100644
index 0000000..a92a2bd
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1007/s1007.go
@@ -0,0 +1,78 @@
+package s1007
+
+import (
+	"fmt"
+	"go/ast"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1007",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Simplify regular expression by using raw string literal`,
+		Text: `Raw string literals use backticks instead of quotation marks and do not support
+any escape sequences. This means that the backslash can be used
+freely, without the need of escaping.
+
+Since regular expressions have their own escape sequences, raw strings
+can improve their readability.`,
+		Before:  `regexp.Compile("\\A(\\w+) profile: total \\d+\\n\\z")`,
+		After:   "regexp.Compile(`\\A(\\w+) profile: total \\d+\\n\\z`)",
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+// TODO(dominikh): support string concat, maybe support constants
+var query = pattern.MustParse(`(CallExpr (Symbol fn@(Or "regexp.MustCompile" "regexp.Compile")) [lit@(BasicLit "STRING" _)])`)
+
+func run(pass *analysis.Pass) (any, error) {
+outer:
+	for _, m := range code.Matches(pass, query) {
+		lit := m.State["lit"].(*ast.BasicLit)
+		val := lit.Value
+		if lit.Value[0] != '"' {
+			// already a raw string
+			continue
+		}
+		if !strings.Contains(val, `\\`) {
+			continue
+		}
+		if strings.Contains(val, "`") {
+			continue
+		}
+
+		bs := false
+		for _, c := range val {
+			if !bs && c == '\\' {
+				bs = true
+				continue
+			}
+			if bs && c == '\\' {
+				bs = false
+				continue
+			}
+			if bs {
+				// backslash followed by non-backslash -> escape sequence
+				continue outer
+			}
+		}
+
+		report.Report(pass, lit, fmt.Sprintf("should use raw string (`...`) with %s to avoid having to escape twice", m.State["fn"]), report.FilterGenerated())
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1008/s1008.go b/vendor/honnef.co/go/tools/simple/s1008/s1008.go
new file mode 100644
index 0000000..e945e3f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1008/s1008.go
@@ -0,0 +1,177 @@
+package s1008
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1008",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Simplify returning boolean expression`,
+		Before: `
+if  {
+    return true
+}
+return false`,
+		After:   `return `,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkIfReturnQIf  = pattern.MustParse(`(IfStmt nil cond [(ReturnStmt [ret@(Builtin (Or "true" "false"))])] nil)`)
+	checkIfReturnQRet = pattern.MustParse(`(ReturnStmt [ret@(Builtin (Or "true" "false"))])`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	var cm ast.CommentMap
+	fn := func(node ast.Node) {
+		if f, ok := node.(*ast.File); ok {
+			cm = ast.NewCommentMap(pass.Fset, f, f.Comments)
+			return
+		}
+
+		block := node.(*ast.BlockStmt)
+		l := len(block.List)
+		if l < 2 {
+			return
+		}
+		n1, n2 := block.List[l-2], block.List[l-1]
+
+		if len(block.List) >= 3 {
+			if _, ok := block.List[l-3].(*ast.IfStmt); ok {
+				// Do not flag a series of if statements
+				return
+			}
+		}
+		m1, ok := code.Match(pass, checkIfReturnQIf, n1)
+		if !ok {
+			return
+		}
+		m2, ok := code.Match(pass, checkIfReturnQRet, n2)
+		if !ok {
+			return
+		}
+
+		if op, ok := m1.State["cond"].(*ast.BinaryExpr); ok {
+			switch op.Op {
+			case token.EQL, token.LSS, token.GTR, token.NEQ, token.LEQ, token.GEQ:
+			default:
+				return
+			}
+		}
+
+		ret1 := m1.State["ret"].(*ast.Ident)
+		ret2 := m2.State["ret"].(*ast.Ident)
+		if ret1.Name == ret2.Name {
+			// we want the function to return true and false, not the
+			// same value both times.
+			return
+		}
+
+		hasComments := func(n ast.Node) bool {
+			cmf := cm.Filter(n)
+			for _, groups := range cmf {
+				for _, group := range groups {
+					for _, cmt := range group.List {
+						if strings.HasPrefix(cmt.Text, "//@ diag") {
+							// Staticcheck test cases use comments to mark
+							// expected diagnostics. Ignore these comments so we
+							// can test this check.
+							continue
+						}
+						return true
+					}
+				}
+			}
+			return false
+		}
+
+		// Don't flag if either branch is commented
+		if hasComments(n1) || hasComments(n2) {
+			return
+		}
+
+		cond := m1.State["cond"].(ast.Expr)
+		origCond := cond
+		if ret1.Name == "false" {
+			cond = negate(pass, cond)
+		}
+		report.Report(pass, n1,
+			fmt.Sprintf("should use 'return %s' instead of 'if %s { return %s }; return %s'",
+				report.Render(pass, cond),
+				report.Render(pass, origCond), report.Render(pass, ret1), report.Render(pass, ret2)),
+			report.FilterGenerated())
+	}
+	code.Preorder(pass, fn, (*ast.File)(nil), (*ast.BlockStmt)(nil))
+	return nil, nil
+}
+
+func negate(pass *analysis.Pass, expr ast.Expr) ast.Expr {
+	switch expr := expr.(type) {
+	case *ast.BinaryExpr:
+		out := *expr
+		switch expr.Op {
+		case token.EQL:
+			out.Op = token.NEQ
+		case token.LSS:
+			out.Op = token.GEQ
+		case token.GTR:
+			// Some builtins never return negative ints; "len(x) <= 0" should be "len(x) == 0".
+			if call, ok := expr.X.(*ast.CallExpr); ok &&
+				code.IsCallToAny(pass, call, "len", "cap", "copy") &&
+				code.IsIntegerLiteral(pass, expr.Y, constant.MakeInt64(0)) {
+				out.Op = token.EQL
+			} else {
+				out.Op = token.LEQ
+			}
+		case token.NEQ:
+			out.Op = token.EQL
+		case token.LEQ:
+			out.Op = token.GTR
+		case token.GEQ:
+			out.Op = token.LSS
+		}
+		return &out
+	case *ast.Ident, *ast.CallExpr, *ast.IndexExpr, *ast.StarExpr:
+		return &ast.UnaryExpr{
+			Op: token.NOT,
+			X:  expr,
+		}
+	case *ast.UnaryExpr:
+		if expr.Op == token.NOT {
+			return expr.X
+		}
+		return &ast.UnaryExpr{
+			Op: token.NOT,
+			X:  expr,
+		}
+	default:
+		return &ast.UnaryExpr{
+			Op: token.NOT,
+			X: &ast.ParenExpr{
+				X: expr,
+			},
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1009/s1009.go b/vendor/honnef.co/go/tools/simple/s1009/s1009.go
new file mode 100644
index 0000000..fda7ec0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1009/s1009.go
@@ -0,0 +1,180 @@
+package s1009
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1009",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Omit redundant nil check on slices, maps, and channels`,
+		Text: `The \'len\' function is defined for all slices, maps, and
+channels, even nil ones, which have a length of zero. It is not necessary to
+check for nil before checking that their length is not zero.`,
+		Before:  `if x != nil && len(x) != 0 {}`,
+		After:   `if len(x) != 0 {}`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var query = pattern.MustParse(`
+	(BinaryExpr
+		(BinaryExpr
+			x
+			lhsOp@(Or "==" "!=")
+			nilly)
+		outerOp@(Or "&&" "||")
+		(BinaryExpr
+			(CallExpr (Builtin "len") [x])
+			rhsOp
+			k))`)
+
+// run checks for the following redundant nil-checks:
+//
+//	if x == nil || len(x) == 0 {}
+//	if x == nil || len(x) < N {} (where N != 0)
+//	if x == nil || len(x) <= N {}
+//	if x != nil && len(x) != 0 {}
+//	if x != nil && len(x) == N {} (where N != 0)
+//	if x != nil && len(x) > N {}
+//	if x != nil && len(x) >= N {} (where N != 0)
+func run(pass *analysis.Pass) (any, error) {
+	isConstZero := func(expr ast.Expr) (isConst bool, isZero bool) {
+		_, ok := expr.(*ast.BasicLit)
+		if ok {
+			return true, code.IsIntegerLiteral(pass, expr, constant.MakeInt64(0))
+		}
+		id, ok := expr.(*ast.Ident)
+		if !ok {
+			return false, false
+		}
+		c, ok := pass.TypesInfo.ObjectOf(id).(*types.Const)
+		if !ok {
+			return false, false
+		}
+		return true, c.Val().Kind() == constant.Int && c.Val().String() == "0"
+	}
+
+	for node, m := range code.Matches(pass, query) {
+		x := m.State["x"].(ast.Expr)
+		outerOp := m.State["outerOp"].(token.Token)
+		lhsOp := m.State["lhsOp"].(token.Token)
+		rhsOp := m.State["rhsOp"].(token.Token)
+		nilly := m.State["nilly"].(ast.Expr)
+		k := m.State["k"].(ast.Expr)
+		eqNil := outerOp == token.LOR
+
+		if code.MayHaveSideEffects(pass, x, nil) {
+			continue
+		}
+
+		if eqNil && lhsOp != token.EQL {
+			continue
+		}
+		if !eqNil && lhsOp != token.NEQ {
+			continue
+		}
+		if !code.IsNil(pass, nilly) {
+			continue
+		}
+		isConst, isZero := isConstZero(k)
+		if !isConst {
+			continue
+		}
+
+		if eqNil {
+			switch rhsOp {
+			case token.EQL:
+				// avoid false positive for "xx == nil || len(xx) == "
+				if !isZero {
+					continue
+				}
+			case token.LEQ:
+				// ok
+			case token.LSS:
+				// avoid false positive for "xx == nil || len(xx) < 0"
+				if isZero {
+					continue
+				}
+			default:
+				continue
+			}
+		} else {
+			switch rhsOp {
+			case token.EQL:
+				// avoid false positive for "xx != nil && len(xx) == 0"
+				if isZero {
+					continue
+				}
+			case token.GEQ:
+				// avoid false positive for "xx != nil && len(xx) >= 0"
+				if isZero {
+					continue
+				}
+			case token.NEQ:
+				// avoid false positive for "xx != nil && len(xx) != "
+				if !isZero {
+					continue
+				}
+			case token.GTR:
+				// ok
+			default:
+				continue
+			}
+		}
+
+		// finally check that xx type is one of array, slice, map or chan
+		// this is to prevent false positive in case if xx is a pointer to an array
+		typ := pass.TypesInfo.TypeOf(x)
+		var nilType string
+		ok := typeutil.All(typ, func(term *types.Term) bool {
+			switch term.Type().Underlying().(type) {
+			case *types.Slice:
+				nilType = "nil slices"
+				return true
+			case *types.Map:
+				nilType = "nil maps"
+				return true
+			case *types.Chan:
+				nilType = "nil channels"
+				return true
+			case *types.Pointer:
+				return false
+			case *types.TypeParam:
+				return false
+			default:
+				lint.ExhaustiveTypeSwitch(term.Type().Underlying())
+				return false
+			}
+		})
+		if !ok {
+			continue
+		}
+
+		report.Report(pass, node,
+			fmt.Sprintf("should omit nil check; len() for %s is defined as zero", nilType),
+			report.FilterGenerated())
+	}
+
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1010/s1010.go b/vendor/honnef.co/go/tools/simple/s1010/s1010.go
new file mode 100644
index 0000000..899a654
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1010/s1010.go
@@ -0,0 +1,44 @@
+package s1010
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1010",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Omit default slice index`,
+		Text: `When slicing, the second index defaults to the length of the value,
+making \'s[n:len(s)]\' and \'s[n:]\' equivalent.`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkSlicingQ = pattern.MustParse(`(SliceExpr x@(Object _) low (CallExpr (Builtin "len") [x]) nil)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node := range code.Matches(pass, checkSlicingQ) {
+		expr := node.(*ast.SliceExpr)
+		report.Report(pass, expr.High,
+			"should omit second index in slice, s[a:len(s)] is identical to s[a:]",
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix("Simplify slice expression", edit.Delete(expr.High))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1011/s1011.go b/vendor/honnef.co/go/tools/simple/s1011/s1011.go
new file mode 100644
index 0000000..50d2549
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1011/s1011.go
@@ -0,0 +1,137 @@
+package s1011
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/facts/purity"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1011",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer, purity.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Use a single \'append\' to concatenate two slices`,
+		Before: `
+for _, e := range y {
+    x = append(x, e)
+}
+
+for i := range y {
+    x = append(x, y[i])
+}
+
+for i := range y {
+    v := y[i]
+    x = append(x, v)
+}`,
+
+		After: `
+x = append(x, y...)
+x = append(x, y...)
+x = append(x, y...)`,
+		Since: "2017.1",
+		// MergeIfAll because y might not be a slice under all build tags.
+		MergeIf: lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkLoopAppendQ = pattern.MustParse(`
+(Or
+	(RangeStmt
+		(Ident "_")
+		val@(Object _)
+		_
+		x
+		[(AssignStmt [lhs] "=" [(CallExpr (Builtin "append") [lhs val])])])
+	(RangeStmt
+		idx@(Object _)
+		nil
+		_
+		x
+		[(AssignStmt [lhs] "=" [(CallExpr (Builtin "append") [lhs (IndexExpr x idx)])])])
+	(RangeStmt
+		idx@(Object _)
+		nil
+		_
+		x
+		[(AssignStmt val@(Object _) ":=" (IndexExpr x idx))
+		(AssignStmt [lhs] "=" [(CallExpr (Builtin "append") [lhs val])])]))`)
+
+func run(pass *analysis.Pass) (any, error) {
+	pure := pass.ResultOf[purity.Analyzer].(purity.Result)
+
+	for node, m := range code.Matches(pass, checkLoopAppendQ) {
+		if val, ok := m.State["val"].(types.Object); ok && code.RefersTo(pass, m.State["lhs"].(ast.Expr), val) {
+			continue
+		}
+
+		if m.State["idx"] != nil && code.MayHaveSideEffects(pass, m.State["x"].(ast.Expr), pure) {
+			// When using an index-based loop, x gets evaluated repeatedly and thus should be pure.
+			// This doesn't matter for value-based loops, because x only gets evaluated once.
+			continue
+		}
+
+		if idx, ok := m.State["idx"].(types.Object); ok && code.RefersTo(pass, m.State["lhs"].(ast.Expr), idx) {
+			// The lhs mustn't refer to the index loop variable.
+			continue
+		}
+
+		if code.MayHaveSideEffects(pass, m.State["lhs"].(ast.Expr), pure) {
+			// The lhs may be dynamic and return different values on each iteration. For example:
+			//
+			// 	func bar() map[int][]int { /* return one of several maps */ }
+			//
+			// 	func foo(x []int, y [][]int) {
+			// 		for i := range x {
+			// 			bar()[0] = append(bar()[0], x[i])
+			// 		}
+			// 	}
+			//
+			// The dynamic nature of the lhs might also affect the value of the index.
+			continue
+		}
+
+		src := pass.TypesInfo.TypeOf(m.State["x"].(ast.Expr))
+		dst := pass.TypesInfo.TypeOf(m.State["lhs"].(ast.Expr))
+		if !types.Identical(src, dst) {
+			continue
+		}
+
+		r := &ast.AssignStmt{
+			Lhs: []ast.Expr{m.State["lhs"].(ast.Expr)},
+			Tok: token.ASSIGN,
+			Rhs: []ast.Expr{
+				&ast.CallExpr{
+					Fun: &ast.Ident{Name: "append"},
+					Args: []ast.Expr{
+						m.State["lhs"].(ast.Expr),
+						m.State["x"].(ast.Expr),
+					},
+					Ellipsis: 1,
+				},
+			},
+		}
+
+		report.Report(pass, node, fmt.Sprintf("should replace loop with %s", report.Render(pass, r)),
+			report.ShortRange(),
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix("Replace loop with call to append", edit.ReplaceWithNode(pass.Fset, node, r))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1012/s1012.go b/vendor/honnef.co/go/tools/simple/s1012/s1012.go
new file mode 100644
index 0000000..33edd55
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1012/s1012.go
@@ -0,0 +1,46 @@
+package s1012
+
+import (
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1012",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Replace \'time.Now().Sub(x)\' with \'time.Since(x)\'`,
+		Text: `The \'time.Since\' helper has the same effect as using \'time.Now().Sub(x)\'
+but is easier to read.`,
+		Before:  `time.Now().Sub(x)`,
+		After:   `time.Since(x)`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkTimeSinceQ = pattern.MustParse(`(CallExpr (SelectorExpr (CallExpr (Symbol "time.Now") []) (Symbol "(time.Time).Sub")) [arg])`)
+	checkTimeSinceR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "time") (Ident "Since")) [arg])`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkTimeSinceQ) {
+		edits := code.EditMatch(pass, node, m, checkTimeSinceR)
+		report.Report(pass, node, "should use time.Since instead of time.Now().Sub",
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix("Replace with call to time.Since", edits...)))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1016/s1016.go b/vendor/honnef.co/go/tools/simple/s1016/s1016.go
new file mode 100644
index 0000000..9f0ab30
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1016/s1016.go
@@ -0,0 +1,193 @@
+package s1016
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"go/version"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1016",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Use a type conversion instead of manually copying struct fields`,
+		Text: `Two struct types with identical fields can be converted between each
+other. In older versions of Go, the fields had to have identical
+struct tags. Since Go 1.8, however, struct tags are ignored during
+conversions. It is thus not necessary to manually copy every field
+individually.`,
+		Before: `
+var x T1
+y := T2{
+    Field1: x.Field1,
+    Field2: x.Field2,
+}`,
+		After: `
+var x T1
+y := T2(x)`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	// TODO(dh): support conversions between type parameters
+	fn := func(c inspector.Cursor) {
+		node := c.Node()
+		if unary, ok := c.Parent().Node().(*ast.UnaryExpr); ok && unary.Op == token.AND {
+			// Do not suggest type conversion between pointers
+			return
+		}
+
+		lit := node.(*ast.CompositeLit)
+		var typ1 types.Type
+		var named1 *types.Named
+		switch typ := pass.TypesInfo.TypeOf(lit.Type).(type) {
+		case *types.Named:
+			typ1 = typ
+			named1 = typ
+		case *types.Alias:
+			ua := types.Unalias(typ)
+			if n, ok := ua.(*types.Named); ok {
+				typ1 = typ
+				named1 = n
+			}
+		}
+		if typ1 == nil {
+			return
+		}
+		s1, ok := typ1.Underlying().(*types.Struct)
+		if !ok {
+			return
+		}
+
+		var typ2 types.Type
+		var named2 *types.Named
+		var ident *ast.Ident
+		getSelType := func(expr ast.Expr) (types.Type, *ast.Ident, bool) {
+			sel, ok := expr.(*ast.SelectorExpr)
+			if !ok {
+				return nil, nil, false
+			}
+			ident, ok := sel.X.(*ast.Ident)
+			if !ok {
+				return nil, nil, false
+			}
+			typ := pass.TypesInfo.TypeOf(sel.X)
+			return typ, ident, typ != nil
+		}
+		if len(lit.Elts) == 0 {
+			return
+		}
+		if s1.NumFields() != len(lit.Elts) {
+			return
+		}
+		for i, elt := range lit.Elts {
+			var t types.Type
+			var id *ast.Ident
+			var ok bool
+			switch elt := elt.(type) {
+			case *ast.SelectorExpr:
+				t, id, ok = getSelType(elt)
+				if !ok {
+					return
+				}
+				if i >= s1.NumFields() || s1.Field(i).Name() != elt.Sel.Name {
+					return
+				}
+			case *ast.KeyValueExpr:
+				var sel *ast.SelectorExpr
+				sel, ok = elt.Value.(*ast.SelectorExpr)
+				if !ok {
+					return
+				}
+
+				if elt.Key.(*ast.Ident).Name != sel.Sel.Name {
+					return
+				}
+				t, id, ok = getSelType(elt.Value)
+			}
+			if !ok {
+				return
+			}
+			// All fields must be initialized from the same object
+			if ident != nil && pass.TypesInfo.ObjectOf(ident) != pass.TypesInfo.ObjectOf(id) {
+				return
+			}
+			switch t := t.(type) {
+			case *types.Named:
+				typ2 = t
+				named2 = t
+			case *types.Alias:
+				if n, ok := types.Unalias(t).(*types.Named); ok {
+					typ2 = t
+					named2 = n
+				}
+			}
+			if typ2 == nil {
+				return
+			}
+			ident = id
+		}
+
+		if typ2 == nil {
+			return
+		}
+
+		if named1.Obj().Pkg() != named2.Obj().Pkg() {
+			// Do not suggest type conversions between different
+			// packages. Types in different packages might only match
+			// by coincidence. Furthermore, if the dependency ever
+			// adds more fields to its type, it could break the code
+			// that relies on the type conversion to work.
+			return
+		}
+
+		s2, ok := typ2.Underlying().(*types.Struct)
+		if !ok {
+			return
+		}
+		if typ1 == typ2 {
+			return
+		}
+		if version.Compare(code.LanguageVersion(pass, node), "go1.8") >= 0 {
+			if !types.IdenticalIgnoreTags(s1, s2) {
+				return
+			}
+		} else {
+			if !types.Identical(s1, s2) {
+				return
+			}
+		}
+
+		r := &ast.CallExpr{
+			Fun:  lit.Type,
+			Args: []ast.Expr{ident},
+		}
+		report.Report(pass, node,
+			fmt.Sprintf("should convert %s (type %s) to %s instead of using struct literal", ident.Name, types.TypeString(typ2, types.RelativeTo(pass.Pkg)), types.TypeString(typ1, types.RelativeTo(pass.Pkg))),
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix("Use type conversion", edit.ReplaceWithNode(pass.Fset, node, r))))
+	}
+	for c := range code.Cursor(pass).Preorder((*ast.CompositeLit)(nil)) {
+		fn(c)
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1017/s1017.go b/vendor/honnef.co/go/tools/simple/s1017/s1017.go
new file mode 100644
index 0000000..cae41eb
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1017/s1017.go
@@ -0,0 +1,239 @@
+package s1017
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"reflect"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1017",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Replace manual trimming with \'strings.TrimPrefix\'`,
+		Text: `Instead of using \'strings.HasPrefix\' and manual slicing, use the
+\'strings.TrimPrefix\' function. If the string doesn't start with the
+prefix, the original string will be returned. Using \'strings.TrimPrefix\'
+reduces complexity, and avoids common bugs, such as off-by-one
+mistakes.`,
+		Before: `
+if strings.HasPrefix(str, prefix) {
+    str = str[len(prefix):]
+}`,
+		After:   `str = strings.TrimPrefix(str, prefix)`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	sameNonDynamic := func(node1, node2 ast.Node) bool {
+		if reflect.TypeOf(node1) != reflect.TypeOf(node2) {
+			return false
+		}
+
+		switch node1 := node1.(type) {
+		case *ast.Ident:
+			return pass.TypesInfo.ObjectOf(node1) == pass.TypesInfo.ObjectOf(node2.(*ast.Ident))
+		case *ast.SelectorExpr, *ast.IndexExpr:
+			return astutil.Equal(node1, node2)
+		case *ast.BasicLit:
+			return astutil.Equal(node1, node2)
+		}
+		return false
+	}
+
+	isLenOnIdent := func(fn ast.Expr, ident ast.Expr) bool {
+		call, ok := fn.(*ast.CallExpr)
+		if !ok {
+			return false
+		}
+		if !code.IsCallTo(pass, call, "len") {
+			return false
+		}
+		if len(call.Args) != 1 {
+			return false
+		}
+		return sameNonDynamic(call.Args[knowledge.Arg("len.v")], ident)
+	}
+
+	seen := make(map[ast.Node]struct{})
+	fn := func(node ast.Node) {
+		var pkg string
+		var fun string
+
+		ifstmt := node.(*ast.IfStmt)
+		if ifstmt.Init != nil {
+			return
+		}
+		if ifstmt.Else != nil {
+			seen[ifstmt.Else] = struct{}{}
+			return
+		}
+		if _, ok := seen[ifstmt]; ok {
+			return
+		}
+		if len(ifstmt.Body.List) != 1 {
+			return
+		}
+		condCall, ok := ifstmt.Cond.(*ast.CallExpr)
+		if !ok {
+			return
+		}
+
+		condCallName := code.CallName(pass, condCall)
+		switch condCallName {
+		case "strings.HasPrefix":
+			pkg = "strings"
+			fun = "HasPrefix"
+		case "strings.HasSuffix":
+			pkg = "strings"
+			fun = "HasSuffix"
+		case "strings.Contains":
+			pkg = "strings"
+			fun = "Contains"
+		case "bytes.HasPrefix":
+			pkg = "bytes"
+			fun = "HasPrefix"
+		case "bytes.HasSuffix":
+			pkg = "bytes"
+			fun = "HasSuffix"
+		case "bytes.Contains":
+			pkg = "bytes"
+			fun = "Contains"
+		default:
+			return
+		}
+
+		assign, ok := ifstmt.Body.List[0].(*ast.AssignStmt)
+		if !ok {
+			return
+		}
+		if assign.Tok != token.ASSIGN {
+			return
+		}
+		if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 {
+			return
+		}
+		if !sameNonDynamic(condCall.Args[0], assign.Lhs[0]) {
+			return
+		}
+
+		switch rhs := assign.Rhs[0].(type) {
+		case *ast.CallExpr:
+			if len(rhs.Args) < 2 || !sameNonDynamic(condCall.Args[0], rhs.Args[0]) || !sameNonDynamic(condCall.Args[1], rhs.Args[1]) {
+				return
+			}
+
+			rhsName := code.CallName(pass, rhs)
+			if condCallName == "strings.HasPrefix" && rhsName == "strings.TrimPrefix" ||
+				condCallName == "strings.HasSuffix" && rhsName == "strings.TrimSuffix" ||
+				condCallName == "strings.Contains" && rhsName == "strings.Replace" ||
+				condCallName == "bytes.HasPrefix" && rhsName == "bytes.TrimPrefix" ||
+				condCallName == "bytes.HasSuffix" && rhsName == "bytes.TrimSuffix" ||
+				condCallName == "bytes.Contains" && rhsName == "bytes.Replace" {
+				report.Report(pass, ifstmt, fmt.Sprintf("should replace this if statement with an unconditional %s", rhsName), report.FilterGenerated())
+			}
+		case *ast.SliceExpr:
+			slice := rhs
+			if !ok {
+				return
+			}
+			if slice.Slice3 {
+				return
+			}
+			if !sameNonDynamic(slice.X, condCall.Args[0]) {
+				return
+			}
+
+			validateOffset := func(off ast.Expr) bool {
+				switch off := off.(type) {
+				case *ast.CallExpr:
+					return isLenOnIdent(off, condCall.Args[1])
+				case *ast.BasicLit:
+					if pkg != "strings" {
+						return false
+					}
+					if _, ok := condCall.Args[1].(*ast.BasicLit); !ok {
+						// Only allow manual slicing with an integer
+						// literal if the second argument to HasPrefix
+						// was a string literal.
+						return false
+					}
+					s, ok1 := code.ExprToString(pass, condCall.Args[1])
+					n, ok2 := code.ExprToInt(pass, off)
+					if !ok1 || !ok2 || n != int64(len(s)) {
+						return false
+					}
+					return true
+				default:
+					return false
+				}
+			}
+
+			switch fun {
+			case "HasPrefix":
+				// TODO(dh) We could detect a High that is len(s), but another
+				// rule will already flag that, anyway.
+				if slice.High != nil {
+					return
+				}
+				if !validateOffset(slice.Low) {
+					return
+				}
+			case "HasSuffix":
+				if slice.Low != nil {
+					n, ok := code.ExprToInt(pass, slice.Low)
+					if !ok || n != 0 {
+						return
+					}
+				}
+				switch index := slice.High.(type) {
+				case *ast.BinaryExpr:
+					if index.Op != token.SUB {
+						return
+					}
+					if !isLenOnIdent(index.X, condCall.Args[0]) {
+						return
+					}
+					if !validateOffset(index.Y) {
+						return
+					}
+				default:
+					return
+				}
+			default:
+				return
+			}
+
+			var replacement string
+			switch fun {
+			case "HasPrefix":
+				replacement = "TrimPrefix"
+			case "HasSuffix":
+				replacement = "TrimSuffix"
+			}
+			report.Report(pass, ifstmt, fmt.Sprintf("should replace this if statement with an unconditional %s.%s", pkg, replacement),
+				report.ShortRange(),
+				report.FilterGenerated())
+		}
+	}
+	code.Preorder(pass, fn, (*ast.IfStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1018/s1018.go b/vendor/honnef.co/go/tools/simple/s1018/s1018.go
new file mode 100644
index 0000000..98e3975
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1018/s1018.go
@@ -0,0 +1,78 @@
+package s1018
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1018",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Use \"copy\" for sliding elements`,
+		Text: `\'copy()\' permits using the same source and destination slice, even with
+overlapping ranges. This makes it ideal for sliding elements in a
+slice.`,
+
+		Before: `
+for i := 0; i < n; i++ {
+    bs[i] = bs[offset+i]
+}`,
+		After:   `copy(bs[:n], bs[offset:])`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkLoopSlideQ = pattern.MustParse(`
+		(ForStmt
+			(AssignStmt initvar@(Ident _) _ (IntegerLiteral "0"))
+			(BinaryExpr initvar "<" limit@(Ident _))
+			(IncDecStmt initvar "++")
+			[(AssignStmt
+				(IndexExpr slice@(Ident _) initvar)
+				"="
+				(IndexExpr slice (BinaryExpr offset@(Ident _) "+" initvar)))])`)
+	checkLoopSlideR = pattern.MustParse(`
+		(CallExpr
+			(Ident "copy")
+			[(SliceExpr slice nil limit nil)
+				(SliceExpr slice offset nil nil)])`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	// TODO(dh): detect bs[i+offset] in addition to bs[offset+i]
+	// TODO(dh): consider merging this function with LintLoopCopy
+	// TODO(dh): detect length that is an expression, not a variable name
+	// TODO(dh): support sliding to a different offset than the beginning of the slice
+
+	for node, m := range code.Matches(pass, checkLoopSlideQ) {
+		typ := pass.TypesInfo.TypeOf(m.State["slice"].(*ast.Ident))
+		// The pattern probably needs a core type, but All is fine, too. Either way we only accept slices.
+		if !typeutil.All(typ, typeutil.IsSlice) {
+			continue
+		}
+
+		edits := code.EditMatch(pass, node, m, checkLoopSlideR)
+		report.Report(pass, node, "should use copy() instead of loop for sliding slice elements",
+			report.ShortRange(),
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix("Use copy() instead of loop", edits...)))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1019/s1019.go b/vendor/honnef.co/go/tools/simple/s1019/s1019.go
new file mode 100644
index 0000000..03e2b10
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1019/s1019.go
@@ -0,0 +1,71 @@
+package s1019
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+	"path/filepath"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1019",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Simplify \"make\" call by omitting redundant arguments`,
+		Text: `The \"make\" function has default values for the length and capacity
+arguments. For channels, the length defaults to zero, and for slices,
+the capacity defaults to the length.`,
+		Since: "2017.1",
+		// MergeIfAll because the type might be different under different build tags.
+		// You shouldn't write code like that…
+		MergeIf: lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkMakeLenCapQ1 = pattern.MustParse(`(CallExpr (Builtin "make") [typ size@(IntegerLiteral "0")])`)
+	checkMakeLenCapQ2 = pattern.MustParse(`(CallExpr (Builtin "make") [typ size size])`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		if pass.Pkg.Path() == "runtime_test" && filepath.Base(pass.Fset.Position(node.Pos()).Filename) == "map_test.go" {
+			// special case of runtime tests testing map creation
+			return
+		}
+		if m, ok := code.Match(pass, checkMakeLenCapQ1, node); ok {
+			T := m.State["typ"].(ast.Expr)
+			size := m.State["size"].(ast.Node)
+
+			if _, ok := typeutil.CoreType(pass.TypesInfo.TypeOf(T)).Underlying().(*types.Chan); ok {
+				report.Report(pass, size, fmt.Sprintf("should use make(%s) instead", report.Render(pass, T)), report.FilterGenerated())
+			}
+
+		} else if m, ok := code.Match(pass, checkMakeLenCapQ2, node); ok {
+			// TODO(dh): don't consider sizes identical if they're
+			// dynamic. for example: make(T, <-ch, <-ch).
+			T := m.State["typ"].(ast.Expr)
+			size := m.State["size"].(ast.Node)
+			report.Report(pass, size,
+				fmt.Sprintf("should use make(%s, %s) instead", report.Render(pass, T), report.Render(pass, size)),
+				report.FilterGenerated())
+		}
+	}
+	code.Preorder(pass, fn, (*ast.CallExpr)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1020/s1020.go b/vendor/honnef.co/go/tools/simple/s1020/s1020.go
new file mode 100644
index 0000000..1983556
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1020/s1020.go
@@ -0,0 +1,74 @@
+package s1020
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1020",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:   `Omit redundant nil check in type assertion`,
+		Before:  `if _, ok := i.(T); ok && i != nil {}`,
+		After:   `if _, ok := i.(T); ok {}`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkAssertNotNilFn1Q = pattern.MustParse(`
+		(IfStmt
+			(AssignStmt [(Ident "_") ok@(Object _)] _ [(TypeAssertExpr assert@(Object _) _)])
+			(Or
+				(BinaryExpr ok "&&" (BinaryExpr assert "!=" (Builtin "nil")))
+				(BinaryExpr (BinaryExpr assert "!=" (Builtin "nil")) "&&" ok))
+			_
+			_)`)
+	checkAssertNotNilFn2Q = pattern.MustParse(`
+		(IfStmt
+			nil
+			(BinaryExpr lhs@(Object _) "!=" (Builtin "nil"))
+			[
+				ifstmt@(IfStmt
+					(AssignStmt [(Ident "_") ok@(Object _)] _ [(TypeAssertExpr lhs _)])
+					ok
+					_
+					nil)
+			]
+			nil)`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkAssertNotNilFn1Q) {
+		assert := m.State["assert"].(types.Object)
+		assign := m.State["ok"].(types.Object)
+		report.Report(pass, node, fmt.Sprintf("when %s is true, %s can't be nil", assign.Name(), assert.Name()),
+			report.ShortRange(),
+			report.FilterGenerated())
+	}
+	for _, m := range code.Matches(pass, checkAssertNotNilFn2Q) {
+		ifstmt := m.State["ifstmt"].(*ast.IfStmt)
+		lhs := m.State["lhs"].(types.Object)
+		assignIdent := m.State["ok"].(types.Object)
+		report.Report(pass, ifstmt, fmt.Sprintf("when %s is true, %s can't be nil", assignIdent.Name(), lhs.Name()),
+			report.ShortRange(),
+			report.FilterGenerated())
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1021/s1021.go b/vendor/honnef.co/go/tools/simple/s1021/s1021.go
new file mode 100644
index 0000000..14f32f0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1021/s1021.go
@@ -0,0 +1,118 @@
+package s1021
+
+import (
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1021",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Merge variable declaration and assignment`,
+		Before: `
+var x uint
+x = 1`,
+		After:   `var x uint = 1`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	hasMultipleAssignments := func(root ast.Node, ident *ast.Ident) bool {
+		num := 0
+		ast.Inspect(root, func(node ast.Node) bool {
+			if num >= 2 {
+				return false
+			}
+			assign, ok := node.(*ast.AssignStmt)
+			if !ok {
+				return true
+			}
+			for _, lhs := range assign.Lhs {
+				if oident, ok := lhs.(*ast.Ident); ok {
+					if pass.TypesInfo.ObjectOf(oident) == pass.TypesInfo.ObjectOf(ident) {
+						num++
+					}
+				}
+			}
+
+			return true
+		})
+		return num >= 2
+	}
+	fn := func(node ast.Node) {
+		block := node.(*ast.BlockStmt)
+		if len(block.List) < 2 {
+			return
+		}
+		for i, stmt := range block.List[:len(block.List)-1] {
+			_ = i
+			decl, ok := stmt.(*ast.DeclStmt)
+			if !ok {
+				continue
+			}
+			gdecl, ok := decl.Decl.(*ast.GenDecl)
+			if !ok || gdecl.Tok != token.VAR || len(gdecl.Specs) != 1 {
+				continue
+			}
+			vspec, ok := gdecl.Specs[0].(*ast.ValueSpec)
+			if !ok || len(vspec.Names) != 1 || len(vspec.Values) != 0 {
+				continue
+			}
+
+			assign, ok := block.List[i+1].(*ast.AssignStmt)
+			if !ok || assign.Tok != token.ASSIGN {
+				continue
+			}
+			if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 {
+				continue
+			}
+			ident, ok := assign.Lhs[0].(*ast.Ident)
+			if !ok {
+				continue
+			}
+			if pass.TypesInfo.ObjectOf(vspec.Names[0]) != pass.TypesInfo.ObjectOf(ident) {
+				continue
+			}
+
+			if code.RefersTo(pass, assign.Rhs[0], pass.TypesInfo.ObjectOf(ident)) {
+				continue
+			}
+			if hasMultipleAssignments(block, ident) {
+				continue
+			}
+
+			r := &ast.GenDecl{
+				Specs: []ast.Spec{
+					&ast.ValueSpec{
+						Names:  vspec.Names,
+						Values: []ast.Expr{assign.Rhs[0]},
+						Type:   vspec.Type,
+					},
+				},
+				Tok: gdecl.Tok,
+			}
+			report.Report(pass, decl, "should merge variable declaration with assignment on next line",
+				report.FilterGenerated(),
+				report.Fixes(edit.Fix("Merge declaration with assignment", edit.ReplaceWithNode(pass.Fset, edit.Range{decl.Pos(), assign.End()}, r))))
+		}
+	}
+	code.Preorder(pass, fn, (*ast.BlockStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1023/s1023.go b/vendor/honnef.co/go/tools/simple/s1023/s1023.go
new file mode 100644
index 0000000..f106d31
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1023/s1023.go
@@ -0,0 +1,79 @@
+package s1023
+
+import (
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1023",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Omit redundant control flow`,
+		Text: `Functions that have no return value do not need a return statement as
+the final statement of the function.
+
+Switches in Go do not have automatic fallthrough, unlike languages
+like C. It is not necessary to have a break statement as the final
+statement in a case block.`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn1 := func(node ast.Node) {
+		clause := node.(*ast.CaseClause)
+		if len(clause.Body) < 2 {
+			return
+		}
+		branch, ok := clause.Body[len(clause.Body)-1].(*ast.BranchStmt)
+		if !ok || branch.Tok != token.BREAK || branch.Label != nil {
+			return
+		}
+		report.Report(pass, branch, "redundant break statement", report.FilterGenerated())
+	}
+	fn2 := func(node ast.Node) {
+		var ret *ast.FieldList
+		var body *ast.BlockStmt
+		switch x := node.(type) {
+		case *ast.FuncDecl:
+			ret = x.Type.Results
+			body = x.Body
+		case *ast.FuncLit:
+			ret = x.Type.Results
+			body = x.Body
+		default:
+			lint.ExhaustiveTypeSwitch(node)
+		}
+		// if the func has results, a return can't be redundant.
+		// similarly, if there are no statements, there can be
+		// no return.
+		if ret != nil || body == nil || len(body.List) < 1 {
+			return
+		}
+		rst, ok := body.List[len(body.List)-1].(*ast.ReturnStmt)
+		if !ok {
+			return
+		}
+		// we don't need to check rst.Results as we already
+		// checked x.Type.Results to be nil.
+		report.Report(pass, rst, "redundant return statement", report.FilterGenerated())
+	}
+	code.Preorder(pass, fn1, (*ast.CaseClause)(nil))
+	code.Preorder(pass, fn2, (*ast.FuncDecl)(nil), (*ast.FuncLit)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1024/s1024.go b/vendor/honnef.co/go/tools/simple/s1024/s1024.go
new file mode 100644
index 0000000..82d3730
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1024/s1024.go
@@ -0,0 +1,55 @@
+package s1024
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1024",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Replace \'x.Sub(time.Now())\' with \'time.Until(x)\'`,
+		Text: `The \'time.Until\' helper has the same effect as using \'x.Sub(time.Now())\'
+but is easier to read.`,
+		Before:  `x.Sub(time.Now())`,
+		After:   `time.Until(x)`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkTimeUntilQ = pattern.MustParse(`(CallExpr (Symbol "(time.Time).Sub") [(CallExpr (Symbol "time.Now") [])])`)
+	checkTimeUntilR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "time") (Ident "Until")) [arg])`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node := range code.Matches(pass, checkTimeUntilQ) {
+		if sel, ok := node.(*ast.CallExpr).Fun.(*ast.SelectorExpr); ok {
+			r := pattern.NodeToAST(checkTimeUntilR.Root, map[string]any{"arg": sel.X}).(ast.Node)
+			report.Report(pass, node, "should use time.Until instead of t.Sub(time.Now())",
+				report.FilterGenerated(),
+				report.MinimumStdlibVersion("go1.8"),
+				report.Fixes(edit.Fix("Replace with call to time.Until", edit.ReplaceWithNode(pass.Fset, node, r))))
+		} else {
+			report.Report(pass, node, "should use time.Until instead of t.Sub(time.Now())",
+				report.MinimumStdlibVersion("go1.8"),
+				report.FilterGenerated())
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1025/s1025.go b/vendor/honnef.co/go/tools/simple/s1025/s1025.go
new file mode 100644
index 0000000..9260789
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1025/s1025.go
@@ -0,0 +1,154 @@
+package s1025
+
+import (
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/exp/typeparams"
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name: "S1025",
+		Run:  run,
+		Requires: append([]*analysis.Analyzer{
+			buildir.Analyzer,
+			generated.Analyzer,
+		}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Don't use \'fmt.Sprintf("%s", x)\' unnecessarily`,
+		Text: `In many instances, there are easier and more efficient ways of getting
+a value's string representation. Whenever a value's underlying type is
+a string already, or the type has a String method, they should be used
+directly.
+
+Given the following shared definitions
+
+    type T1 string
+    type T2 int
+
+    func (T2) String() string { return "Hello, world" }
+
+    var x string
+    var y T1
+    var z T2
+
+we can simplify
+
+    fmt.Sprintf("%s", x)
+    fmt.Sprintf("%s", y)
+    fmt.Sprintf("%s", z)
+
+to
+
+    x
+    string(y)
+    z.String()
+`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkRedundantSprintfQ = pattern.MustParse(`(CallExpr (Symbol "fmt.Sprintf") [format arg])`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkRedundantSprintfQ) {
+		format := m.State["format"].(ast.Expr)
+		arg := m.State["arg"].(ast.Expr)
+		// TODO(dh): should we really support named constants here?
+		// shouldn't we only look for string literals? to avoid false
+		// positives via build tags?
+		if s, ok := code.ExprToString(pass, format); !ok || s != "%s" {
+			continue
+		}
+		typ := pass.TypesInfo.TypeOf(arg)
+		if typeparams.IsTypeParam(typ) {
+			continue
+		}
+		irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
+
+		if typeutil.IsTypeWithName(typ, "reflect.Value") {
+			// printing with %s produces output different from using
+			// the String method
+			continue
+		}
+
+		if isFormatter(typ, &irpkg.Prog.MethodSets) {
+			// the type may choose to handle %s in arbitrary ways
+			continue
+		}
+
+		if types.Implements(typ, knowledge.Interfaces["fmt.Stringer"]) {
+			replacement := &ast.CallExpr{
+				Fun: &ast.SelectorExpr{
+					X:   arg,
+					Sel: &ast.Ident{Name: "String"},
+				},
+			}
+			report.Report(pass, node, "should use String() instead of fmt.Sprintf",
+				report.Fixes(edit.Fix("Replace with call to String method", edit.ReplaceWithNode(pass.Fset, node, replacement))))
+		} else if types.Unalias(typ) == types.Universe.Lookup("string").Type() {
+			report.Report(pass, node, "the argument is already a string, there's no need to use fmt.Sprintf",
+				report.FilterGenerated(),
+				report.Fixes(edit.Fix("Remove unnecessary call to fmt.Sprintf", edit.ReplaceWithNode(pass.Fset, node, arg))))
+		} else if typ.Underlying() == types.Universe.Lookup("string").Type() {
+			replacement := &ast.CallExpr{
+				Fun:  &ast.Ident{Name: "string"},
+				Args: []ast.Expr{arg},
+			}
+			report.Report(pass, node, "the argument's underlying type is a string, should use a simple conversion instead of fmt.Sprintf",
+				report.FilterGenerated(),
+				report.Fixes(edit.Fix("Replace with conversion to string", edit.ReplaceWithNode(pass.Fset, node, replacement))))
+		} else if code.IsOfStringConvertibleByteSlice(pass, arg) {
+			replacement := &ast.CallExpr{
+				Fun:  &ast.Ident{Name: "string"},
+				Args: []ast.Expr{arg},
+			}
+			report.Report(pass, node, "the argument's underlying type is a slice of bytes, should use a simple conversion instead of fmt.Sprintf",
+				report.FilterGenerated(),
+				report.Fixes(edit.Fix("Replace with conversion to string", edit.ReplaceWithNode(pass.Fset, node, replacement))))
+		}
+
+	}
+	return nil, nil
+}
+
+func isFormatter(T types.Type, msCache *typeutil.MethodSetCache) bool {
+	// TODO(dh): this function also exists in staticcheck/lint.go – deduplicate.
+
+	ms := msCache.MethodSet(T)
+	sel := ms.Lookup(nil, "Format")
+	if sel == nil {
+		return false
+	}
+	fn, ok := sel.Obj().(*types.Func)
+	if !ok {
+		// should be unreachable
+		return false
+	}
+	sig := fn.Type().(*types.Signature)
+	if sig.Params().Len() != 2 {
+		return false
+	}
+	// TODO(dh): check the types of the arguments for more
+	// precision
+	if sig.Results().Len() != 0 {
+		return false
+	}
+	return true
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1028/s1028.go b/vendor/honnef.co/go/tools/simple/s1028/s1028.go
new file mode 100644
index 0000000..45da204
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1028/s1028.go
@@ -0,0 +1,45 @@
+package s1028
+
+import (
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1028",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:   `Simplify error construction with \'fmt.Errorf\'`,
+		Before:  `errors.New(fmt.Sprintf(...))`,
+		After:   `fmt.Errorf(...)`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkErrorsNewSprintfQ = pattern.MustParse(`(CallExpr (Symbol "errors.New") [(CallExpr (Symbol "fmt.Sprintf") args)])`)
+	checkErrorsNewSprintfR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "fmt") (Ident "Errorf")) args)`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkErrorsNewSprintfQ) {
+		edits := code.EditMatch(pass, node, m, checkErrorsNewSprintfR)
+		// TODO(dh): the suggested fix may leave an unused import behind
+		report.Report(pass, node, "should use fmt.Errorf(...) instead of errors.New(fmt.Sprintf(...))",
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix("Use fmt.Errorf", edits...)))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1029/s1029.go b/vendor/honnef.co/go/tools/simple/s1029/s1029.go
new file mode 100644
index 0000000..1bf3f00
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1029/s1029.go
@@ -0,0 +1,31 @@
+package s1029
+
+import (
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/internal/sharedcheck"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1029",
+		Run:      sharedcheck.CheckRangeStringRunes,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Range over the string directly`,
+		Text: `Ranging over a string will yield byte offsets and runes. If the offset
+isn't used, this is functionally equivalent to converting the string
+to a slice of runes and ranging over that. Ranging directly over the
+string will be more performant, however, as it avoids allocating a new
+slice, the size of which depends on the length of the string.`,
+		Before:  `for _, r := range []rune(s) {}`,
+		After:   `for _, r := range s {}`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
diff --git a/vendor/honnef.co/go/tools/simple/s1030/s1030.go b/vendor/honnef.co/go/tools/simple/s1030/s1030.go
new file mode 100644
index 0000000..44c8820
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1030/s1030.go
@@ -0,0 +1,87 @@
+package s1030
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1030",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Use \'bytes.Buffer.String\' or \'bytes.Buffer.Bytes\'`,
+		Text: `\'bytes.Buffer\' has both a \'String\' and a \'Bytes\' method. It is almost never
+necessary to use \'string(buf.Bytes())\' or \'[]byte(buf.String())\' – simply
+use the other method.
+
+The only exception to this are map lookups. Due to a compiler optimization,
+\'m[string(buf.Bytes())]\' is more efficient than \'m[buf.String()]\'.
+`,
+		Since:   "2017.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkBytesBufferConversionsQ  = pattern.MustParse(`(CallExpr _ [(CallExpr sel@(SelectorExpr recv _) [])])`)
+	checkBytesBufferConversionsRs = pattern.MustParse(`(CallExpr (SelectorExpr recv (Ident "String")) [])`)
+	checkBytesBufferConversionsRb = pattern.MustParse(`(CallExpr (SelectorExpr recv (Ident "Bytes")) [])`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	if pass.Pkg.Path() == "bytes" || pass.Pkg.Path() == "bytes_test" {
+		// The bytes package can use itself however it wants
+		return nil, nil
+	}
+	fn := func(c inspector.Cursor) {
+		node := c.Node()
+		m, ok := code.Match(pass, checkBytesBufferConversionsQ, node)
+		if !ok {
+			return
+		}
+		call := node.(*ast.CallExpr)
+		sel := m.State["sel"].(*ast.SelectorExpr)
+
+		typ := pass.TypesInfo.TypeOf(call.Fun)
+		if types.Unalias(typ) == types.Universe.Lookup("string").Type() && code.IsCallTo(pass, call.Args[0], "(*bytes.Buffer).Bytes") {
+			if _, ok := c.Parent().Node().(*ast.IndexExpr); ok {
+				// Don't flag m[string(buf.Bytes())] – thanks to a
+				// compiler optimization, this is actually faster than
+				// m[buf.String()]
+				return
+			}
+
+			report.Report(pass, call, fmt.Sprintf("should use %v.String() instead of %v", report.Render(pass, sel.X), report.Render(pass, call)),
+				report.FilterGenerated(),
+				report.Fixes(edit.Fix("Simplify conversion", edit.ReplaceWithPattern(pass.Fset, node, checkBytesBufferConversionsRs, m.State))))
+		} else if typ, ok := types.Unalias(typ).(*types.Slice); ok &&
+			types.Unalias(typ.Elem()) == types.Universe.Lookup("byte").Type() &&
+			code.IsCallTo(pass, call.Args[0], "(*bytes.Buffer).String") {
+			report.Report(pass, call, fmt.Sprintf("should use %v.Bytes() instead of %v", report.Render(pass, sel.X), report.Render(pass, call)),
+				report.FilterGenerated(),
+				report.Fixes(edit.Fix("Simplify conversion", edit.ReplaceWithPattern(pass.Fset, node, checkBytesBufferConversionsRb, m.State))))
+		}
+
+	}
+	for c := range code.Cursor(pass).Preorder((*ast.CallExpr)(nil)) {
+		fn(c)
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1031/s1031.go b/vendor/honnef.co/go/tools/simple/s1031/s1031.go
new file mode 100644
index 0000000..4be0171
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1031/s1031.go
@@ -0,0 +1,71 @@
+package s1031
+
+import (
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1031",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Omit redundant nil check around loop`,
+		Text: `You can use range on nil slices and maps, the loop will simply never
+execute. This makes an additional nil check around the loop
+unnecessary.`,
+		Before: `
+if s != nil {
+    for _, x := range s {
+        ...
+    }
+}`,
+		After: `
+for _, x := range s {
+    ...
+}`,
+		Since: "2017.1",
+		// MergeIfAll because x might be a channel under some build tags.
+		// you shouldn't write code like that…
+		MergeIf: lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkNilCheckAroundRangeQ = pattern.MustParse(`
+	(IfStmt
+		nil
+		(BinaryExpr x@(Object _) "!=" (Builtin "nil"))
+		[(RangeStmt _ _ _ x _)]
+		nil)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkNilCheckAroundRangeQ) {
+		ok := typeutil.All(m.State["x"].(types.Object).Type(), func(term *types.Term) bool {
+			switch term.Type().Underlying().(type) {
+			case *types.Slice, *types.Map:
+				return true
+			case *types.TypeParam, *types.Chan, *types.Pointer, *types.Signature:
+				return false
+			default:
+				lint.ExhaustiveTypeSwitch(term.Type().Underlying())
+				return false
+			}
+		})
+		if ok {
+			report.Report(pass, node, "unnecessary nil check around range", report.ShortRange(), report.FilterGenerated())
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1032/s1032.go b/vendor/honnef.co/go/tools/simple/s1032/s1032.go
new file mode 100644
index 0000000..6684db8
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1032/s1032.go
@@ -0,0 +1,128 @@
+package s1032
+
+import (
+	"go/ast"
+	"go/token"
+	"sort"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1032",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Use \'sort.Ints(x)\', \'sort.Float64s(x)\', and \'sort.Strings(x)\'`,
+		Text: `The \'sort.Ints\', \'sort.Float64s\' and \'sort.Strings\' functions are easier to
+read than \'sort.Sort(sort.IntSlice(x))\', \'sort.Sort(sort.Float64Slice(x))\'
+and \'sort.Sort(sort.StringSlice(x))\'.`,
+		Before:  `sort.Sort(sort.StringSlice(x))`,
+		After:   `sort.Strings(x)`,
+		Since:   "2019.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func isPermissibleSort(pass *analysis.Pass, node ast.Node) bool {
+	call := node.(*ast.CallExpr)
+	typeconv, ok := call.Args[0].(*ast.CallExpr)
+	if !ok {
+		return true
+	}
+
+	sel, ok := typeconv.Fun.(*ast.SelectorExpr)
+	if !ok {
+		return true
+	}
+	name := code.SelectorName(pass, sel)
+	switch name {
+	case "sort.IntSlice", "sort.Float64Slice", "sort.StringSlice":
+	default:
+		return true
+	}
+
+	return false
+}
+
+func run(pass *analysis.Pass) (any, error) {
+	type Error struct {
+		node ast.Node
+		msg  string
+	}
+	var allErrors []Error
+	fn := func(node ast.Node) {
+		var body *ast.BlockStmt
+		switch node := node.(type) {
+		case *ast.FuncLit:
+			body = node.Body
+		case *ast.FuncDecl:
+			body = node.Body
+		default:
+			lint.ExhaustiveTypeSwitch(node)
+		}
+		if body == nil {
+			return
+		}
+
+		var errors []Error
+		permissible := false
+		fnSorts := func(node ast.Node) bool {
+			if permissible {
+				return false
+			}
+			if !code.IsCallTo(pass, node, "sort.Sort") {
+				return true
+			}
+			if isPermissibleSort(pass, node) {
+				permissible = true
+				return false
+			}
+			call := node.(*ast.CallExpr)
+			// isPermissibleSort guarantees that this type assertion will succeed
+			typeconv := call.Args[knowledge.Arg("sort.Sort.data")].(*ast.CallExpr)
+			sel := typeconv.Fun.(*ast.SelectorExpr)
+			name := code.SelectorName(pass, sel)
+
+			switch name {
+			case "sort.IntSlice":
+				errors = append(errors, Error{node, "should use sort.Ints(...) instead of sort.Sort(sort.IntSlice(...))"})
+			case "sort.Float64Slice":
+				errors = append(errors, Error{node, "should use sort.Float64s(...) instead of sort.Sort(sort.Float64Slice(...))"})
+			case "sort.StringSlice":
+				errors = append(errors, Error{node, "should use sort.Strings(...) instead of sort.Sort(sort.StringSlice(...))"})
+			}
+			return true
+		}
+		ast.Inspect(body, fnSorts)
+
+		if permissible {
+			return
+		}
+		allErrors = append(allErrors, errors...)
+	}
+	code.Preorder(pass, fn, (*ast.FuncLit)(nil), (*ast.FuncDecl)(nil))
+	sort.Slice(allErrors, func(i, j int) bool {
+		return allErrors[i].node.Pos() < allErrors[j].node.Pos()
+	})
+	var prev token.Pos
+	for _, err := range allErrors {
+		if err.node.Pos() == prev {
+			continue
+		}
+		prev = err.node.Pos()
+		report.Report(pass, err.node, err.msg, report.FilterGenerated())
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1033/s1033.go b/vendor/honnef.co/go/tools/simple/s1033/s1033.go
new file mode 100644
index 0000000..f6704f4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1033/s1033.go
@@ -0,0 +1,50 @@
+package s1033
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1033",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:   `Unnecessary guard around call to \"delete\"`,
+		Text:    `Calling \'delete\' on a nil map is a no-op.`,
+		Since:   "2019.2",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkGuardedDeleteQ = pattern.MustParse(`
+	(IfStmt
+		(AssignStmt
+			[(Ident "_") ok@(Ident _)]
+			":="
+			(IndexExpr m key))
+		ok
+		[call@(CallExpr (Builtin "delete") [m key])]
+		nil)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkGuardedDeleteQ) {
+		report.Report(pass, node, "unnecessary guard around call to delete",
+			report.ShortRange(),
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix("Remove guard", edit.ReplaceWithNode(pass.Fset, node, m.State["call"].(ast.Node)))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1034/s1034.go b/vendor/honnef.co/go/tools/simple/s1034/s1034.go
new file mode 100644
index 0000000..9eb9531
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1034/s1034.go
@@ -0,0 +1,113 @@
+package s1034
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1034",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:   `Use result of type assertion to simplify cases`,
+		Since:   "2019.2",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkSimplifyTypeSwitchQ = pattern.MustParse(`
+		(TypeSwitchStmt
+			nil
+			expr@(TypeAssertExpr ident@(Ident _) _)
+			body)`)
+	checkSimplifyTypeSwitchR = pattern.MustParse(`(AssignStmt ident ":=" expr)`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkSimplifyTypeSwitchQ) {
+		stmt := node.(*ast.TypeSwitchStmt)
+		expr := m.State["expr"].(ast.Node)
+		ident := m.State["ident"].(*ast.Ident)
+
+		x := pass.TypesInfo.ObjectOf(ident)
+		var allOffenders []*ast.TypeAssertExpr
+		canSuggestFix := true
+		for _, clause := range stmt.Body.List {
+			clause := clause.(*ast.CaseClause)
+			if len(clause.List) != 1 {
+				continue
+			}
+			hasUnrelatedAssertion := false
+			var offenders []*ast.TypeAssertExpr
+			ast.Inspect(clause, func(node ast.Node) bool {
+				assert2, ok := node.(*ast.TypeAssertExpr)
+				if !ok {
+					return true
+				}
+				ident, ok := assert2.X.(*ast.Ident)
+				if !ok {
+					hasUnrelatedAssertion = true
+					return false
+				}
+				if pass.TypesInfo.ObjectOf(ident) != x {
+					hasUnrelatedAssertion = true
+					return false
+				}
+
+				if !types.Identical(pass.TypesInfo.TypeOf(clause.List[0]), pass.TypesInfo.TypeOf(assert2.Type)) {
+					hasUnrelatedAssertion = true
+					return false
+				}
+				offenders = append(offenders, assert2)
+				return true
+			})
+			if !hasUnrelatedAssertion {
+				// don't flag cases that have other type assertions
+				// unrelated to the one in the case clause. often
+				// times, this is done for symmetry, when two
+				// different values have to be asserted to the same
+				// type.
+				allOffenders = append(allOffenders, offenders...)
+			}
+			canSuggestFix = canSuggestFix && !hasUnrelatedAssertion
+		}
+		if len(allOffenders) != 0 {
+			var opts []report.Option
+			for _, offender := range allOffenders {
+				opts = append(opts, report.Related(offender, "could eliminate this type assertion"))
+			}
+			opts = append(opts, report.FilterGenerated())
+
+			msg := fmt.Sprintf("assigning the result of this type assertion to a variable (switch %s := %s.(type)) could eliminate type assertions in switch cases",
+				report.Render(pass, ident), report.Render(pass, ident))
+			if canSuggestFix {
+				var edits []analysis.TextEdit
+				edits = append(edits, edit.ReplaceWithPattern(pass.Fset, expr, checkSimplifyTypeSwitchR, m.State))
+				for _, offender := range allOffenders {
+					edits = append(edits, edit.ReplaceWithNode(pass.Fset, offender, offender.X))
+				}
+				opts = append(opts, report.Fixes(edit.Fix("Simplify type switch", edits...)))
+				report.Report(pass, expr, msg, opts...)
+			} else {
+				report.Report(pass, expr, msg, opts...)
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1035/s1035.go b/vendor/honnef.co/go/tools/simple/s1035/s1035.go
new file mode 100644
index 0000000..969502a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1035/s1035.go
@@ -0,0 +1,54 @@
+package s1035
+
+import (
+	"fmt"
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1035",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Redundant call to \'net/http.CanonicalHeaderKey\' in method call on \'net/http.Header\'`,
+		Text: `
+The methods on \'net/http.Header\', namely \'Add\', \'Del\', \'Get\'
+and \'Set\', already canonicalize the given header name.`,
+		Since:   "2020.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var query = pattern.MustParse(`
+	(CallExpr
+		(Symbol
+			callName@(Or
+				"(net/http.Header).Add"
+				"(net/http.Header).Del"
+				"(net/http.Header).Get"
+				"(net/http.Header).Set"))
+		arg@(CallExpr (Symbol "net/http.CanonicalHeaderKey") _):_)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, m := range code.Matches(pass, query) {
+		arg := m.State["arg"].(*ast.CallExpr)
+		report.Report(pass, m.State["arg"].(ast.Expr),
+			fmt.Sprintf("calling net/http.CanonicalHeaderKey on the 'key' argument of %s is redundant", m.State["callName"].(string)),
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix("Remove call to CanonicalHeaderKey", edit.ReplaceWithNode(pass.Fset, arg, arg.Args[0]))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1036/s1036.go b/vendor/honnef.co/go/tools/simple/s1036/s1036.go
new file mode 100644
index 0000000..2d07874
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1036/s1036.go
@@ -0,0 +1,88 @@
+package s1036
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1036",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Unnecessary guard around map access`,
+
+		Text: `
+When accessing a map key that doesn't exist yet, one receives a zero
+value. Often, the zero value is a suitable value, for example when
+using append or doing integer math.
+
+The following
+
+    if _, ok := m["foo"]; ok {
+        m["foo"] = append(m["foo"], "bar")
+    } else {
+        m["foo"] = []string{"bar"}
+    }
+
+can be simplified to
+
+    m["foo"] = append(m["foo"], "bar")
+
+and
+
+    if _, ok := m2["k"]; ok {
+        m2["k"] += 4
+    } else {
+        m2["k"] = 4
+    }
+
+can be simplified to
+
+    m["k"] += 4
+`,
+		Since:   "2020.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkUnnecessaryGuardQ = pattern.MustParse(`
+	(Or
+		(IfStmt
+			(AssignStmt [(Ident "_") ok@(Ident _)] ":=" indexexpr@(IndexExpr _ _))
+			ok
+			set@(AssignStmt indexexpr "=" (CallExpr (Builtin "append") indexexpr:values))
+			(AssignStmt indexexpr "=" (CompositeLit _ values)))
+		(IfStmt
+			(AssignStmt [(Ident "_") ok] ":=" indexexpr@(IndexExpr _ _))
+			ok
+			set@(AssignStmt indexexpr "+=" value)
+			(AssignStmt indexexpr "=" value))
+		(IfStmt
+			(AssignStmt [(Ident "_") ok] ":=" indexexpr@(IndexExpr _ _))
+			ok
+			set@(IncDecStmt indexexpr "++")
+			(AssignStmt indexexpr "=" (IntegerLiteral "1"))))`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkUnnecessaryGuardQ) {
+		if code.MayHaveSideEffects(pass, m.State["indexexpr"].(ast.Expr), nil) {
+			continue
+		}
+		report.Report(pass, node, "unnecessary guard around map access",
+			report.ShortRange(),
+			report.Fixes(edit.Fix("Simplify map access", edit.ReplaceWithNode(pass.Fset, node, m.State["set"].(ast.Node)))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1037/s1037.go b/vendor/honnef.co/go/tools/simple/s1037/s1037.go
new file mode 100644
index 0000000..a067c1a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1037/s1037.go
@@ -0,0 +1,55 @@
+package s1037
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1037",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Elaborate way of sleeping`,
+		Text: `Using a select statement with a single case receiving
+from the result of \'time.After\' is a very elaborate way of sleeping that
+can much simpler be expressed with a simple call to time.Sleep.`,
+		Since:   "2020.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkElaborateSleepQ = pattern.MustParse(`(SelectStmt (CommClause (UnaryExpr "<-" (CallExpr (Symbol "time.After") [arg])) body))`)
+	checkElaborateSleepR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "time") (Ident "Sleep")) [arg])`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkElaborateSleepQ) {
+		if body, ok := m.State["body"].([]ast.Stmt); ok && len(body) == 0 {
+			report.Report(pass, node, "should use time.Sleep instead of elaborate way of sleeping",
+				report.ShortRange(),
+				report.FilterGenerated(),
+				report.Fixes(edit.Fix("Use time.Sleep", edit.ReplaceWithPattern(pass.Fset, node, checkElaborateSleepR, m.State))))
+		} else {
+			// TODO(dh): we could make a suggested fix if the body
+			// doesn't declare or shadow any identifiers
+			report.Report(pass, node, "should use time.Sleep instead of elaborate way of sleeping",
+				report.ShortRange(),
+				report.FilterGenerated())
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1038/s1038.go b/vendor/honnef.co/go/tools/simple/s1038/s1038.go
new file mode 100644
index 0000000..7987a56
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1038/s1038.go
@@ -0,0 +1,190 @@
+package s1038
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1038",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:   "Unnecessarily complex way of printing formatted string",
+		Text:    `Instead of using \'fmt.Print(fmt.Sprintf(...))\', one can use \'fmt.Printf(...)\'.`,
+		Since:   "2020.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkPrintSprintQ = pattern.MustParse(`
+		(Or
+			(CallExpr
+				fn@(Or
+					(Symbol "fmt.Print")
+					(Symbol "fmt.Sprint")
+					(Symbol "fmt.Println")
+					(Symbol "fmt.Sprintln"))
+				[(CallExpr (Symbol "fmt.Sprintf") f:_)])
+			(CallExpr
+				fn@(Or
+					(Symbol "fmt.Fprint")
+					(Symbol "fmt.Fprintln"))
+				[_ (CallExpr (Symbol "fmt.Sprintf") f:_)]))`)
+
+	checkTestingErrorSprintfQ = pattern.MustParse(`
+		(CallExpr
+			sel@(SelectorExpr
+				recv
+				(Ident
+					name@(Or
+						"Error"
+						"Fatal"
+						"Fatalln"
+						"Log"
+						"Panic"
+						"Panicln"
+						"Print"
+						"Println"
+						"Skip")))
+			[(CallExpr (Symbol "fmt.Sprintf") args)])`)
+
+	checkLogSprintfQ = pattern.MustParse(`
+		(CallExpr
+			(Symbol
+				(Or
+					"log.Fatal"
+					"log.Fatalln"
+					"log.Panic"
+					"log.Panicln"
+					"log.Print"
+					"log.Println"))
+			[(CallExpr (Symbol "fmt.Sprintf") args)])`)
+
+	checkSprintfMapping = map[string]struct {
+		recv        string
+		alternative string
+	}{
+		"(*testing.common).Error": {"(*testing.common)", "Errorf"},
+		"(testing.TB).Error":      {"(testing.TB)", "Errorf"},
+		"(*testing.common).Fatal": {"(*testing.common)", "Fatalf"},
+		"(testing.TB).Fatal":      {"(testing.TB)", "Fatalf"},
+		"(*testing.common).Log":   {"(*testing.common)", "Logf"},
+		"(testing.TB).Log":        {"(testing.TB)", "Logf"},
+		"(*testing.common).Skip":  {"(*testing.common)", "Skipf"},
+		"(testing.TB).Skip":       {"(testing.TB)", "Skipf"},
+		"(*log.Logger).Fatal":     {"(*log.Logger)", "Fatalf"},
+		"(*log.Logger).Fatalln":   {"(*log.Logger)", "Fatalf"},
+		"(*log.Logger).Panic":     {"(*log.Logger)", "Panicf"},
+		"(*log.Logger).Panicln":   {"(*log.Logger)", "Panicf"},
+		"(*log.Logger).Print":     {"(*log.Logger)", "Printf"},
+		"(*log.Logger).Println":   {"(*log.Logger)", "Printf"},
+		"log.Fatal":               {"", "log.Fatalf"},
+		"log.Fatalln":             {"", "log.Fatalf"},
+		"log.Panic":               {"", "log.Panicf"},
+		"log.Panicln":             {"", "log.Panicf"},
+		"log.Print":               {"", "log.Printf"},
+		"log.Println":             {"", "log.Printf"},
+	}
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	fmtPrintf := func(node ast.Node) {
+		m, ok := code.Match(pass, checkPrintSprintQ, node)
+		if !ok {
+			return
+		}
+
+		name := m.State["fn"].(*types.Func).Name()
+		var msg string
+		switch name {
+		case "Print", "Fprint", "Sprint":
+			newname := name + "f"
+			msg = fmt.Sprintf("should use fmt.%s instead of fmt.%s(fmt.Sprintf(...))", newname, name)
+		case "Println", "Fprintln", "Sprintln":
+			if _, ok := m.State["f"].(*ast.BasicLit); !ok {
+				// This may be an instance of
+				// fmt.Println(fmt.Sprintf(arg, ...)) where arg is an
+				// externally provided format string and the caller
+				// cannot guarantee that the format string ends with a
+				// newline.
+				return
+			}
+			newname := name[:len(name)-2] + "f"
+			msg = fmt.Sprintf("should use fmt.%s instead of fmt.%s(fmt.Sprintf(...)) (but don't forget the newline)", newname, name)
+		}
+		report.Report(pass, node, msg,
+			report.FilterGenerated())
+	}
+
+	methSprintf := func(node ast.Node) {
+		m, ok := code.Match(pass, checkTestingErrorSprintfQ, node)
+		if !ok {
+			return
+		}
+		mapped, ok := checkSprintfMapping[code.CallName(pass, node.(*ast.CallExpr))]
+		if !ok {
+			return
+		}
+
+		// Ensure that Errorf/Fatalf refer to the right method
+		recvTV, ok := pass.TypesInfo.Types[m.State["recv"].(ast.Expr)]
+		if !ok {
+			return
+		}
+		obj, _, _ := types.LookupFieldOrMethod(recvTV.Type, recvTV.Addressable(), nil, mapped.alternative)
+		f, ok := obj.(*types.Func)
+		if !ok {
+			return
+		}
+		if typeutil.FuncName(f) != mapped.recv+"."+mapped.alternative {
+			return
+		}
+
+		alt := &ast.SelectorExpr{
+			X:   m.State["recv"].(ast.Expr),
+			Sel: &ast.Ident{Name: mapped.alternative},
+		}
+		report.Report(pass, node, fmt.Sprintf("should use %s(...) instead of %s(fmt.Sprintf(...))", report.Render(pass, alt), report.Render(pass, m.State["sel"].(*ast.SelectorExpr))))
+	}
+
+	pkgSprintf := func(node ast.Node) {
+		_, ok := code.Match(pass, checkLogSprintfQ, node)
+		if !ok {
+			return
+		}
+		callName := code.CallName(pass, node.(*ast.CallExpr))
+		mapped, ok := checkSprintfMapping[callName]
+		if !ok {
+			return
+		}
+		report.Report(pass, node, fmt.Sprintf("should use %s(...) instead of %s(fmt.Sprintf(...))", mapped.alternative, callName))
+	}
+
+	fn := func(node ast.Node) {
+		fmtPrintf(node)
+		// TODO(dh): add suggested fixes
+		methSprintf(node)
+		pkgSprintf(node)
+	}
+	if !code.CouldMatchAny(pass, checkLogSprintfQ, checkPrintSprintQ, checkTestingErrorSprintfQ) {
+		return nil, nil
+	}
+	code.Preorder(pass, fn, (*ast.CallExpr)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1039/s1039.go b/vendor/honnef.co/go/tools/simple/s1039/s1039.go
new file mode 100644
index 0000000..8167046
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1039/s1039.go
@@ -0,0 +1,66 @@
+package s1039
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1039",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Unnecessary use of \'fmt.Sprint\'`,
+		Text: `
+Calling \'fmt.Sprint\' with a single string argument is unnecessary
+and identical to using the string directly.`,
+		Since: "2020.1",
+		// MergeIfAll because s might not be a string under all build tags.
+		// you shouldn't write code like that…
+		MergeIf: lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkSprintLiteralQ = pattern.MustParse(`
+	(CallExpr
+		fn@(Or
+			(Symbol "fmt.Sprint")
+			(Symbol "fmt.Sprintf"))
+		[lit@(BasicLit "STRING" _)])`)
+
+func run(pass *analysis.Pass) (any, error) {
+	// We only flag calls with string literals, not expressions of
+	// type string, because some people use fmt.Sprint(s) as a pattern
+	// for copying strings, which may be useful when extracting a small
+	// substring from a large string.
+
+	for node, m := range code.Matches(pass, checkSprintLiteralQ) {
+		callee := m.State["fn"].(*types.Func)
+		lit := m.State["lit"].(*ast.BasicLit)
+		if callee.Name() == "Sprintf" {
+			if strings.ContainsRune(lit.Value, '%') {
+				// This might be a format string
+				continue
+			}
+		}
+		report.Report(pass, node, fmt.Sprintf("unnecessary use of fmt.%s", callee.Name()),
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix("Replace with string literal", edit.ReplaceWithNode(pass.Fset, node, lit))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/simple/s1040/s1040.go b/vendor/honnef.co/go/tools/simple/s1040/s1040.go
new file mode 100644
index 0000000..62cc8c7
--- /dev/null
+++ b/vendor/honnef.co/go/tools/simple/s1040/s1040.go
@@ -0,0 +1,73 @@
+package s1040
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "S1040",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "Type assertion to current type",
+		Text: `The type assertion \'x.(SomeInterface)\', when \'x\' already has type
+\'SomeInterface\', can only fail if \'x\' is nil. Usually, this is
+left-over code from when \'x\' had a different type and you can safely
+delete the type assertion. If you want to check that \'x\' is not nil,
+consider being explicit and using an actual \'if x == nil\' comparison
+instead of relying on the type assertion panicking.`,
+		Since: "2021.1",
+		// MergeIfAll because x might have different types under different build tags.
+		// You shouldn't write code like that…
+		MergeIf: lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		expr := node.(*ast.TypeAssertExpr)
+		if expr.Type == nil {
+			// skip type switches
+			//
+			// TODO(dh): we could flag type switches, too, when a case
+			// statement has the same type as expr.X – however,
+			// depending on the location of that case, it might behave
+			// identically to a default branch. we need to think
+			// carefully about the instances we want to flag. We also
+			// have to take nil interface values into consideration.
+			//
+			// It might make more sense to extend SA4020 to handle
+			// this.
+			return
+		}
+		t1 := pass.TypesInfo.TypeOf(expr.Type)
+		t2 := pass.TypesInfo.TypeOf(expr.X)
+		if types.IsInterface(t1) && types.Identical(t1, t2) {
+			report.Report(pass, expr,
+				fmt.Sprintf("type assertion to the same type: %s already has type %s", report.Render(pass, expr.X), report.Render(pass, expr.Type)),
+				report.FilterGenerated())
+		}
+	}
+
+	// TODO(dh): add suggested fixes. we need different fixes depending on the context:
+	// - assignment with 1 or 2 lhs
+	// - assignment to blank identifiers (as the first, second or both lhs)
+	// - initializers in if statements, with the same variations as above
+
+	code.Preorder(pass, fn, (*ast.TypeAssertExpr)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/analysis.go b/vendor/honnef.co/go/tools/staticcheck/analysis.go
new file mode 100644
index 0000000..81ab81c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/analysis.go
@@ -0,0 +1,200 @@
+// Code generated by generate.go. DO NOT EDIT.
+
+package staticcheck
+
+import (
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/staticcheck/sa1000"
+	"honnef.co/go/tools/staticcheck/sa1001"
+	"honnef.co/go/tools/staticcheck/sa1002"
+	"honnef.co/go/tools/staticcheck/sa1003"
+	"honnef.co/go/tools/staticcheck/sa1004"
+	"honnef.co/go/tools/staticcheck/sa1005"
+	"honnef.co/go/tools/staticcheck/sa1006"
+	"honnef.co/go/tools/staticcheck/sa1007"
+	"honnef.co/go/tools/staticcheck/sa1008"
+	"honnef.co/go/tools/staticcheck/sa1010"
+	"honnef.co/go/tools/staticcheck/sa1011"
+	"honnef.co/go/tools/staticcheck/sa1012"
+	"honnef.co/go/tools/staticcheck/sa1013"
+	"honnef.co/go/tools/staticcheck/sa1014"
+	"honnef.co/go/tools/staticcheck/sa1015"
+	"honnef.co/go/tools/staticcheck/sa1016"
+	"honnef.co/go/tools/staticcheck/sa1017"
+	"honnef.co/go/tools/staticcheck/sa1018"
+	"honnef.co/go/tools/staticcheck/sa1019"
+	"honnef.co/go/tools/staticcheck/sa1020"
+	"honnef.co/go/tools/staticcheck/sa1021"
+	"honnef.co/go/tools/staticcheck/sa1023"
+	"honnef.co/go/tools/staticcheck/sa1024"
+	"honnef.co/go/tools/staticcheck/sa1025"
+	"honnef.co/go/tools/staticcheck/sa1026"
+	"honnef.co/go/tools/staticcheck/sa1027"
+	"honnef.co/go/tools/staticcheck/sa1028"
+	"honnef.co/go/tools/staticcheck/sa1029"
+	"honnef.co/go/tools/staticcheck/sa1030"
+	"honnef.co/go/tools/staticcheck/sa1031"
+	"honnef.co/go/tools/staticcheck/sa1032"
+	"honnef.co/go/tools/staticcheck/sa2000"
+	"honnef.co/go/tools/staticcheck/sa2001"
+	"honnef.co/go/tools/staticcheck/sa2002"
+	"honnef.co/go/tools/staticcheck/sa2003"
+	"honnef.co/go/tools/staticcheck/sa3000"
+	"honnef.co/go/tools/staticcheck/sa3001"
+	"honnef.co/go/tools/staticcheck/sa4000"
+	"honnef.co/go/tools/staticcheck/sa4001"
+	"honnef.co/go/tools/staticcheck/sa4003"
+	"honnef.co/go/tools/staticcheck/sa4004"
+	"honnef.co/go/tools/staticcheck/sa4005"
+	"honnef.co/go/tools/staticcheck/sa4006"
+	"honnef.co/go/tools/staticcheck/sa4008"
+	"honnef.co/go/tools/staticcheck/sa4009"
+	"honnef.co/go/tools/staticcheck/sa4010"
+	"honnef.co/go/tools/staticcheck/sa4011"
+	"honnef.co/go/tools/staticcheck/sa4012"
+	"honnef.co/go/tools/staticcheck/sa4013"
+	"honnef.co/go/tools/staticcheck/sa4014"
+	"honnef.co/go/tools/staticcheck/sa4015"
+	"honnef.co/go/tools/staticcheck/sa4016"
+	"honnef.co/go/tools/staticcheck/sa4017"
+	"honnef.co/go/tools/staticcheck/sa4018"
+	"honnef.co/go/tools/staticcheck/sa4019"
+	"honnef.co/go/tools/staticcheck/sa4020"
+	"honnef.co/go/tools/staticcheck/sa4021"
+	"honnef.co/go/tools/staticcheck/sa4022"
+	"honnef.co/go/tools/staticcheck/sa4023"
+	"honnef.co/go/tools/staticcheck/sa4024"
+	"honnef.co/go/tools/staticcheck/sa4025"
+	"honnef.co/go/tools/staticcheck/sa4026"
+	"honnef.co/go/tools/staticcheck/sa4027"
+	"honnef.co/go/tools/staticcheck/sa4028"
+	"honnef.co/go/tools/staticcheck/sa4029"
+	"honnef.co/go/tools/staticcheck/sa4030"
+	"honnef.co/go/tools/staticcheck/sa4031"
+	"honnef.co/go/tools/staticcheck/sa4032"
+	"honnef.co/go/tools/staticcheck/sa5000"
+	"honnef.co/go/tools/staticcheck/sa5001"
+	"honnef.co/go/tools/staticcheck/sa5002"
+	"honnef.co/go/tools/staticcheck/sa5003"
+	"honnef.co/go/tools/staticcheck/sa5004"
+	"honnef.co/go/tools/staticcheck/sa5005"
+	"honnef.co/go/tools/staticcheck/sa5007"
+	"honnef.co/go/tools/staticcheck/sa5008"
+	"honnef.co/go/tools/staticcheck/sa5009"
+	"honnef.co/go/tools/staticcheck/sa5010"
+	"honnef.co/go/tools/staticcheck/sa5012"
+	"honnef.co/go/tools/staticcheck/sa6000"
+	"honnef.co/go/tools/staticcheck/sa6001"
+	"honnef.co/go/tools/staticcheck/sa6002"
+	"honnef.co/go/tools/staticcheck/sa6003"
+	"honnef.co/go/tools/staticcheck/sa6005"
+	"honnef.co/go/tools/staticcheck/sa6006"
+	"honnef.co/go/tools/staticcheck/sa9001"
+	"honnef.co/go/tools/staticcheck/sa9002"
+	"honnef.co/go/tools/staticcheck/sa9003"
+	"honnef.co/go/tools/staticcheck/sa9004"
+	"honnef.co/go/tools/staticcheck/sa9005"
+	"honnef.co/go/tools/staticcheck/sa9006"
+	"honnef.co/go/tools/staticcheck/sa9007"
+	"honnef.co/go/tools/staticcheck/sa9008"
+	"honnef.co/go/tools/staticcheck/sa9009"
+	"honnef.co/go/tools/staticcheck/sa9010"
+)
+
+var Analyzers = []*lint.Analyzer{
+	sa1000.SCAnalyzer,
+	sa1001.SCAnalyzer,
+	sa1002.SCAnalyzer,
+	sa1003.SCAnalyzer,
+	sa1004.SCAnalyzer,
+	sa1005.SCAnalyzer,
+	sa1006.SCAnalyzer,
+	sa1007.SCAnalyzer,
+	sa1008.SCAnalyzer,
+	sa1010.SCAnalyzer,
+	sa1011.SCAnalyzer,
+	sa1012.SCAnalyzer,
+	sa1013.SCAnalyzer,
+	sa1014.SCAnalyzer,
+	sa1015.SCAnalyzer,
+	sa1016.SCAnalyzer,
+	sa1017.SCAnalyzer,
+	sa1018.SCAnalyzer,
+	sa1019.SCAnalyzer,
+	sa1020.SCAnalyzer,
+	sa1021.SCAnalyzer,
+	sa1023.SCAnalyzer,
+	sa1024.SCAnalyzer,
+	sa1025.SCAnalyzer,
+	sa1026.SCAnalyzer,
+	sa1027.SCAnalyzer,
+	sa1028.SCAnalyzer,
+	sa1029.SCAnalyzer,
+	sa1030.SCAnalyzer,
+	sa1031.SCAnalyzer,
+	sa1032.SCAnalyzer,
+	sa2000.SCAnalyzer,
+	sa2001.SCAnalyzer,
+	sa2002.SCAnalyzer,
+	sa2003.SCAnalyzer,
+	sa3000.SCAnalyzer,
+	sa3001.SCAnalyzer,
+	sa4000.SCAnalyzer,
+	sa4001.SCAnalyzer,
+	sa4003.SCAnalyzer,
+	sa4004.SCAnalyzer,
+	sa4005.SCAnalyzer,
+	sa4006.SCAnalyzer,
+	sa4008.SCAnalyzer,
+	sa4009.SCAnalyzer,
+	sa4010.SCAnalyzer,
+	sa4011.SCAnalyzer,
+	sa4012.SCAnalyzer,
+	sa4013.SCAnalyzer,
+	sa4014.SCAnalyzer,
+	sa4015.SCAnalyzer,
+	sa4016.SCAnalyzer,
+	sa4017.SCAnalyzer,
+	sa4018.SCAnalyzer,
+	sa4019.SCAnalyzer,
+	sa4020.SCAnalyzer,
+	sa4021.SCAnalyzer,
+	sa4022.SCAnalyzer,
+	sa4023.SCAnalyzer,
+	sa4024.SCAnalyzer,
+	sa4025.SCAnalyzer,
+	sa4026.SCAnalyzer,
+	sa4027.SCAnalyzer,
+	sa4028.SCAnalyzer,
+	sa4029.SCAnalyzer,
+	sa4030.SCAnalyzer,
+	sa4031.SCAnalyzer,
+	sa4032.SCAnalyzer,
+	sa5000.SCAnalyzer,
+	sa5001.SCAnalyzer,
+	sa5002.SCAnalyzer,
+	sa5003.SCAnalyzer,
+	sa5004.SCAnalyzer,
+	sa5005.SCAnalyzer,
+	sa5007.SCAnalyzer,
+	sa5008.SCAnalyzer,
+	sa5009.SCAnalyzer,
+	sa5010.SCAnalyzer,
+	sa5012.SCAnalyzer,
+	sa6000.SCAnalyzer,
+	sa6001.SCAnalyzer,
+	sa6002.SCAnalyzer,
+	sa6003.SCAnalyzer,
+	sa6005.SCAnalyzer,
+	sa6006.SCAnalyzer,
+	sa9001.SCAnalyzer,
+	sa9002.SCAnalyzer,
+	sa9003.SCAnalyzer,
+	sa9004.SCAnalyzer,
+	sa9005.SCAnalyzer,
+	sa9006.SCAnalyzer,
+	sa9007.SCAnalyzer,
+	sa9008.SCAnalyzer,
+	sa9009.SCAnalyzer,
+	sa9010.SCAnalyzer,
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/doc.go b/vendor/honnef.co/go/tools/staticcheck/doc.go
new file mode 100644
index 0000000..462acee
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/doc.go
@@ -0,0 +1,5 @@
+//go:generate go run ../generate.go
+
+// Package staticcheck contains analyzes that find bugs and performance issues.
+// Barring the rare false positive, any code flagged by these analyzes needs to be fixed.
+package staticcheck
diff --git a/vendor/honnef.co/go/tools/staticcheck/fakejson/encode.go b/vendor/honnef.co/go/tools/staticcheck/fakejson/encode.go
new file mode 100644
index 0000000..13e3182
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/fakejson/encode.go
@@ -0,0 +1,370 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains a modified copy of the encoding/json encoder.
+// All dynamic behavior has been removed, and reflecttion has been replaced with go/types.
+// This allows us to statically find unmarshable types
+// with the same rules for tags, shadowing and addressability as encoding/json.
+// This is used for SA1026.
+
+package fakejson
+
+import (
+	"go/types"
+	"sort"
+	"strings"
+	"unicode"
+
+	"golang.org/x/exp/typeparams"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/knowledge"
+	"honnef.co/go/tools/staticcheck/fakereflect"
+)
+
+// parseTag splits a struct field's json tag into its name and
+// comma-separated options.
+func parseTag(tag string) string {
+	if before, _, ok := strings.Cut(tag, ","); ok {
+		return before
+	}
+	return tag
+}
+
+func Marshal(v types.Type) *UnsupportedTypeError {
+	enc := encoder{}
+	return enc.newTypeEncoder(fakereflect.TypeAndCanAddr{Type: v}, "x")
+}
+
+// An UnsupportedTypeError is returned by Marshal when attempting
+// to encode an unsupported value type.
+type UnsupportedTypeError struct {
+	Type types.Type
+	Path string
+}
+
+type encoder struct {
+	// TODO we track addressable and non-addressable instances separately out of an abundance of caution. We don't know
+	// if this is actually required for correctness.
+	seenCanAddr  typeutil.Map[struct{}]
+	seenCantAddr typeutil.Map[struct{}]
+}
+
+func (enc *encoder) newTypeEncoder(t fakereflect.TypeAndCanAddr, stack string) *UnsupportedTypeError {
+	var m *typeutil.Map[struct{}]
+	if t.CanAddr() {
+		m = &enc.seenCanAddr
+	} else {
+		m = &enc.seenCantAddr
+	}
+	if _, ok := m.At(t.Type); ok {
+		return nil
+	}
+	m.Set(t.Type, struct{}{})
+
+	if t.Implements(knowledge.Interfaces["encoding/json.Marshaler"]) {
+		return nil
+	}
+	if !t.IsPtr() && t.CanAddr() && fakereflect.PtrTo(t).Implements(knowledge.Interfaces["encoding/json.Marshaler"]) {
+		return nil
+	}
+	if t.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
+		return nil
+	}
+	if !t.IsPtr() && t.CanAddr() && fakereflect.PtrTo(t).Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
+		return nil
+	}
+
+	switch t.Type.Underlying().(type) {
+	case *types.Basic, *types.Interface:
+		return nil
+	case *types.Struct:
+		return enc.typeFields(t, stack)
+	case *types.Map:
+		return enc.newMapEncoder(t, stack)
+	case *types.Slice:
+		return enc.newSliceEncoder(t, stack)
+	case *types.Array:
+		return enc.newArrayEncoder(t, stack)
+	case *types.Pointer:
+		// we don't have to express the pointer dereference in the path; x.f is syntactic sugar for (*x).f
+		return enc.newTypeEncoder(t.Elem(), stack)
+	default:
+		return &UnsupportedTypeError{t.Type, stack}
+	}
+}
+
+func (enc *encoder) newMapEncoder(t fakereflect.TypeAndCanAddr, stack string) *UnsupportedTypeError {
+	if typeparams.IsTypeParam(t.Key().Type) {
+		// We don't know enough about the concrete instantiation to say much about the key. The only time we could make
+		// a definite "this key is bad" statement is if the type parameter is constrained by type terms, none of which
+		// are tilde terms, none of which are a basic type. In all other cases, the key might implement TextMarshaler.
+		// It doesn't seem worth checking for that one single case.
+		return enc.newTypeEncoder(t.Elem(), stack+"[k]")
+	}
+
+	switch t.Key().Type.Underlying().(type) {
+	case *types.Basic:
+	default:
+		if !t.Key().Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
+			return &UnsupportedTypeError{
+				Type: t.Type,
+				Path: stack,
+			}
+		}
+	}
+	return enc.newTypeEncoder(t.Elem(), stack+"[k]")
+}
+
+func (enc *encoder) newSliceEncoder(t fakereflect.TypeAndCanAddr, stack string) *UnsupportedTypeError {
+	// Byte slices get special treatment; arrays don't.
+	basic, ok := t.Elem().Type.Underlying().(*types.Basic)
+	if ok && basic.Kind() == types.Uint8 {
+		p := fakereflect.PtrTo(t.Elem())
+		if !p.Implements(knowledge.Interfaces["encoding/json.Marshaler"]) && !p.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
+			return nil
+		}
+	}
+	return enc.newArrayEncoder(t, stack)
+}
+
+func (enc *encoder) newArrayEncoder(t fakereflect.TypeAndCanAddr, stack string) *UnsupportedTypeError {
+	return enc.newTypeEncoder(t.Elem(), stack+"[0]")
+}
+
+func isValidTag(s string) bool {
+	if s == "" {
+		return false
+	}
+	for _, c := range s {
+		switch {
+		case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
+			// Backslash and quote chars are reserved, but
+			// otherwise any punctuation chars are allowed
+			// in a tag name.
+		case !unicode.IsLetter(c) && !unicode.IsDigit(c):
+			return false
+		}
+	}
+	return true
+}
+
+func typeByIndex(t fakereflect.TypeAndCanAddr, index []int) fakereflect.TypeAndCanAddr {
+	for _, i := range index {
+		if t.IsPtr() {
+			t = t.Elem()
+		}
+		t = t.Field(i).Type
+	}
+	return t
+}
+
+func pathByIndex(t fakereflect.TypeAndCanAddr, index []int) string {
+	var path strings.Builder
+	for _, i := range index {
+		if t.IsPtr() {
+			t = t.Elem()
+		}
+		path.WriteString("." + t.Field(i).Name)
+		t = t.Field(i).Type
+	}
+	return path.String()
+}
+
+// A field represents a single field found in a struct.
+type field struct {
+	name string
+
+	tag   bool
+	index []int
+	typ   fakereflect.TypeAndCanAddr
+}
+
+// byIndex sorts field by index sequence.
+type byIndex []field
+
+func (x byIndex) Len() int { return len(x) }
+
+func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+func (x byIndex) Less(i, j int) bool {
+	for k, xik := range x[i].index {
+		if k >= len(x[j].index) {
+			return false
+		}
+		if xik != x[j].index[k] {
+			return xik < x[j].index[k]
+		}
+	}
+	return len(x[i].index) < len(x[j].index)
+}
+
+// typeFields returns a list of fields that JSON should recognize for the given type.
+// The algorithm is breadth-first search over the set of structs to include - the top struct
+// and then any reachable anonymous structs.
+func (enc *encoder) typeFields(t fakereflect.TypeAndCanAddr, stack string) *UnsupportedTypeError {
+	// Anonymous fields to explore at the current level and the next.
+	current := []field{}
+	next := []field{{typ: t}}
+
+	// Count of queued names for current level and the next.
+	var count, nextCount map[fakereflect.TypeAndCanAddr]int
+
+	// Types already visited at an earlier level.
+	visited := map[fakereflect.TypeAndCanAddr]bool{}
+
+	// Fields found.
+	var fields []field
+
+	for len(next) > 0 {
+		current, next = next, current[:0]
+		count, nextCount = nextCount, map[fakereflect.TypeAndCanAddr]int{}
+
+		for _, f := range current {
+			if visited[f.typ] {
+				continue
+			}
+			visited[f.typ] = true
+
+			// Scan f.typ for fields to include.
+			for i := 0; i < f.typ.NumField(); i++ {
+				sf := f.typ.Field(i)
+				if sf.Anonymous {
+					t := sf.Type
+					if t.IsPtr() {
+						t = t.Elem()
+					}
+					if !sf.IsExported() && !t.IsStruct() {
+						// Ignore embedded fields of unexported non-struct types.
+						continue
+					}
+					// Do not ignore embedded fields of unexported struct types
+					// since they may have exported fields.
+				} else if !sf.IsExported() {
+					// Ignore unexported non-embedded fields.
+					continue
+				}
+				tag := sf.Tag.Get("json")
+				if tag == "-" {
+					continue
+				}
+				name := parseTag(tag)
+				if !isValidTag(name) {
+					name = ""
+				}
+				index := make([]int, len(f.index)+1)
+				copy(index, f.index)
+				index[len(f.index)] = i
+
+				ft := sf.Type
+				if ft.Name() == "" && ft.IsPtr() {
+					// Follow pointer.
+					ft = ft.Elem()
+				}
+
+				// Record found field and index sequence.
+				if name != "" || !sf.Anonymous || !ft.IsStruct() {
+					tagged := name != ""
+					if name == "" {
+						name = sf.Name
+					}
+					field := field{
+						name:  name,
+						tag:   tagged,
+						index: index,
+						typ:   ft,
+					}
+
+					fields = append(fields, field)
+					if count[f.typ] > 1 {
+						// If there were multiple instances, add a second,
+						// so that the annihilation code will see a duplicate.
+						// It only cares about the distinction between 1 or 2,
+						// so don't bother generating any more copies.
+						fields = append(fields, fields[len(fields)-1])
+					}
+					continue
+				}
+
+				// Record new anonymous struct to explore in next round.
+				nextCount[ft]++
+				if nextCount[ft] == 1 {
+					next = append(next, field{name: ft.Name(), index: index, typ: ft})
+				}
+			}
+		}
+	}
+
+	sort.Slice(fields, func(i, j int) bool {
+		x := fields
+		// sort field by name, breaking ties with depth, then
+		// breaking ties with "name came from json tag", then
+		// breaking ties with index sequence.
+		if x[i].name != x[j].name {
+			return x[i].name < x[j].name
+		}
+		if len(x[i].index) != len(x[j].index) {
+			return len(x[i].index) < len(x[j].index)
+		}
+		if x[i].tag != x[j].tag {
+			return x[i].tag
+		}
+		return byIndex(x).Less(i, j)
+	})
+
+	// Delete all fields that are hidden by the Go rules for embedded fields,
+	// except that fields with JSON tags are promoted.
+
+	// The fields are sorted in primary order of name, secondary order
+	// of field index length. Loop over names; for each name, delete
+	// hidden fields by choosing the one dominant field that survives.
+	out := fields[:0]
+	for advance, i := 0, 0; i < len(fields); i += advance {
+		// One iteration per name.
+		// Find the sequence of fields with the name of this first field.
+		fi := fields[i]
+		name := fi.name
+		for advance = 1; i+advance < len(fields); advance++ {
+			fj := fields[i+advance]
+			if fj.name != name {
+				break
+			}
+		}
+		if advance == 1 { // Only one field with this name
+			out = append(out, fi)
+			continue
+		}
+		dominant, ok := dominantField(fields[i : i+advance])
+		if ok {
+			out = append(out, dominant)
+		}
+	}
+
+	fields = out
+	sort.Sort(byIndex(fields))
+
+	for i := range fields {
+		f := &fields[i]
+		err := enc.newTypeEncoder(typeByIndex(t, f.index), stack+pathByIndex(t, f.index))
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// dominantField looks through the fields, all of which are known to
+// have the same name, to find the single field that dominates the
+// others using Go's embedding rules, modified by the presence of
+// JSON tags. If there are multiple top-level fields, the boolean
+// will be false: This condition is an error in Go and we skip all
+// the fields.
+func dominantField(fields []field) (field, bool) {
+	// The fields are sorted in increasing index-length order, then by presence of tag.
+	// That means that the first field is the dominant one. We need only check
+	// for error cases: two fields at top level, either both tagged or neither tagged.
+	if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag {
+		return field{}, false
+	}
+	return fields[0], true
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/fakereflect/fakereflect.go b/vendor/honnef.co/go/tools/staticcheck/fakereflect/fakereflect.go
new file mode 100644
index 0000000..5fdf15b
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/fakereflect/fakereflect.go
@@ -0,0 +1,131 @@
+package fakereflect
+
+import (
+	"fmt"
+	"go/types"
+	"reflect"
+)
+
+type TypeAndCanAddr struct {
+	Type    types.Type
+	canAddr bool
+}
+
+type StructField struct {
+	Index     []int
+	Name      string
+	Anonymous bool
+	Tag       reflect.StructTag
+	f         *types.Var
+	Type      TypeAndCanAddr
+}
+
+func (sf StructField) IsExported() bool { return sf.f.Exported() }
+
+func (t TypeAndCanAddr) Field(i int) StructField {
+	st := t.Type.Underlying().(*types.Struct)
+	f := st.Field(i)
+	return StructField{
+		f:         f,
+		Index:     []int{i},
+		Name:      f.Name(),
+		Anonymous: f.Anonymous(),
+		Tag:       reflect.StructTag(st.Tag(i)),
+		Type: TypeAndCanAddr{
+			Type:    f.Type(),
+			canAddr: t.canAddr,
+		},
+	}
+}
+
+func (t TypeAndCanAddr) FieldByIndex(index []int) StructField {
+	f := t.Field(index[0])
+	for _, idx := range index[1:] {
+		f = f.Type.Field(idx)
+	}
+	f.Index = index
+	return f
+}
+
+func PtrTo(t TypeAndCanAddr) TypeAndCanAddr {
+	// Note that we don't care about canAddr here because it's irrelevant to all uses of PtrTo
+	return TypeAndCanAddr{Type: types.NewPointer(t.Type)}
+}
+
+func (t TypeAndCanAddr) CanAddr() bool { return t.canAddr }
+
+func (t TypeAndCanAddr) Implements(ityp *types.Interface) bool {
+	return types.Implements(t.Type, ityp)
+}
+
+func (t TypeAndCanAddr) IsSlice() bool {
+	_, ok := t.Type.Underlying().(*types.Slice)
+	return ok
+}
+
+func (t TypeAndCanAddr) IsArray() bool {
+	_, ok := t.Type.Underlying().(*types.Array)
+	return ok
+}
+
+func (t TypeAndCanAddr) IsPtr() bool {
+	_, ok := t.Type.Underlying().(*types.Pointer)
+	return ok
+}
+
+func (t TypeAndCanAddr) IsInterface() bool {
+	_, ok := t.Type.Underlying().(*types.Interface)
+	return ok
+}
+
+func (t TypeAndCanAddr) IsStruct() bool {
+	_, ok := t.Type.Underlying().(*types.Struct)
+	return ok
+}
+
+func (t TypeAndCanAddr) Name() string {
+	named, ok := types.Unalias(t.Type).(*types.Named)
+	if !ok {
+		return ""
+	}
+	return named.Obj().Name()
+}
+
+func (t TypeAndCanAddr) NumField() int {
+	return t.Type.Underlying().(*types.Struct).NumFields()
+}
+
+func (t TypeAndCanAddr) String() string {
+	return t.Type.String()
+}
+
+func (t TypeAndCanAddr) Key() TypeAndCanAddr {
+	return TypeAndCanAddr{Type: t.Type.Underlying().(*types.Map).Key()}
+}
+
+func (t TypeAndCanAddr) Elem() TypeAndCanAddr {
+	switch typ := t.Type.Underlying().(type) {
+	case *types.Pointer:
+		return TypeAndCanAddr{
+			Type:    typ.Elem(),
+			canAddr: true,
+		}
+	case *types.Slice:
+		return TypeAndCanAddr{
+			Type:    typ.Elem(),
+			canAddr: true,
+		}
+	case *types.Array:
+		return TypeAndCanAddr{
+			Type:    typ.Elem(),
+			canAddr: t.canAddr,
+		}
+	case *types.Map:
+		return TypeAndCanAddr{
+			Type:    typ.Elem(),
+			canAddr: false,
+		}
+	default:
+		panic(fmt.Sprintf("unhandled type %T", typ))
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/fakexml/marshal.go b/vendor/honnef.co/go/tools/staticcheck/fakexml/marshal.go
new file mode 100644
index 0000000..9c71e86
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/fakexml/marshal.go
@@ -0,0 +1,376 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains a modified copy of the encoding/xml encoder.
+// All dynamic behavior has been removed, and reflecttion has been replaced with go/types.
+// This allows us to statically find unmarshable types
+// with the same rules for tags, shadowing and addressability as encoding/xml.
+// This is used for SA1026 and SA5008.
+
+// NOTE(dh): we do not check CanInterface in various places, which means we'll accept more marshaler implementations than encoding/xml does. This will lead to a small amount of false negatives.
+
+package fakexml
+
+import (
+	"fmt"
+	"go/types"
+	"strings"
+
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/knowledge"
+	"honnef.co/go/tools/staticcheck/fakereflect"
+)
+
+func Marshal(v types.Type) error {
+	return NewEncoder().Encode(v)
+}
+
+type Encoder struct {
+	// TODO we track addressable and non-addressable instances separately out of an abundance of caution. We don't know
+	// if this is actually required for correctness.
+	seenCanAddr  typeutil.Map[struct{}]
+	seenCantAddr typeutil.Map[struct{}]
+}
+
+func NewEncoder() *Encoder {
+	e := &Encoder{}
+	return e
+}
+
+func (enc *Encoder) Encode(v types.Type) error {
+	rv := fakereflect.TypeAndCanAddr{Type: v}
+	return enc.marshalValue(rv, nil, nil, "x")
+}
+
+func implementsMarshaler(v fakereflect.TypeAndCanAddr) bool {
+	t := v.Type
+	obj, _, _ := types.LookupFieldOrMethod(t, false, nil, "MarshalXML")
+	if obj == nil {
+		return false
+	}
+	fn, ok := obj.(*types.Func)
+	if !ok {
+		return false
+	}
+	params := fn.Type().(*types.Signature).Params()
+	if params.Len() != 2 {
+		return false
+	}
+	if !typeutil.IsPointerToTypeWithName(params.At(0).Type(), "encoding/xml.Encoder") {
+		return false
+	}
+	if !typeutil.IsTypeWithName(params.At(1).Type(), "encoding/xml.StartElement") {
+		return false
+	}
+	rets := fn.Type().(*types.Signature).Results()
+	if rets.Len() != 1 {
+		return false
+	}
+	if !typeutil.IsTypeWithName(rets.At(0).Type(), "error") {
+		return false
+	}
+	return true
+}
+
+func implementsMarshalerAttr(v fakereflect.TypeAndCanAddr) bool {
+	t := v.Type
+	obj, _, _ := types.LookupFieldOrMethod(t, false, nil, "MarshalXMLAttr")
+	if obj == nil {
+		return false
+	}
+	fn, ok := obj.(*types.Func)
+	if !ok {
+		return false
+	}
+	params := fn.Type().(*types.Signature).Params()
+	if params.Len() != 1 {
+		return false
+	}
+	if !typeutil.IsTypeWithName(params.At(0).Type(), "encoding/xml.Name") {
+		return false
+	}
+	rets := fn.Type().(*types.Signature).Results()
+	if rets.Len() != 2 {
+		return false
+	}
+	if !typeutil.IsTypeWithName(rets.At(0).Type(), "encoding/xml.Attr") {
+		return false
+	}
+	if !typeutil.IsTypeWithName(rets.At(1).Type(), "error") {
+		return false
+	}
+	return true
+}
+
+type CyclicTypeError struct {
+	Type types.Type
+	Path string
+}
+
+func (err *CyclicTypeError) Error() string {
+	return "cyclic type"
+}
+
+// marshalValue writes one or more XML elements representing val.
+// If val was obtained from a struct field, finfo must have its details.
+func (e *Encoder) marshalValue(val fakereflect.TypeAndCanAddr, finfo *fieldInfo, startTemplate *StartElement, stack string) error {
+	var m *typeutil.Map[struct{}]
+	if val.CanAddr() {
+		m = &e.seenCanAddr
+	} else {
+		m = &e.seenCantAddr
+	}
+	if _, ok := m.At(val.Type); ok {
+		return nil
+	}
+	m.Set(val.Type, struct{}{})
+
+	// Drill into interfaces and pointers.
+	seen := map[fakereflect.TypeAndCanAddr]struct{}{}
+	for val.IsInterface() || val.IsPtr() {
+		if val.IsInterface() {
+			return nil
+		}
+		val = val.Elem()
+		if _, ok := seen[val]; ok {
+			// Loop in type graph, e.g. 'type P *P'
+			return &CyclicTypeError{val.Type, stack}
+		}
+		seen[val] = struct{}{}
+	}
+
+	// Check for marshaler.
+	if implementsMarshaler(val) {
+		return nil
+	}
+	if val.CanAddr() {
+		pv := fakereflect.PtrTo(val)
+		if implementsMarshaler(pv) {
+			return nil
+		}
+	}
+
+	// Check for text marshaler.
+	if val.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
+		return nil
+	}
+	if val.CanAddr() {
+		pv := fakereflect.PtrTo(val)
+		if pv.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
+			return nil
+		}
+	}
+
+	// Slices and arrays iterate over the elements. They do not have an enclosing tag.
+	if (val.IsSlice() || val.IsArray()) && !isByteArray(val) && !isByteSlice(val) {
+		if err := e.marshalValue(val.Elem(), finfo, startTemplate, stack+"[0]"); err != nil {
+			return err
+		}
+		return nil
+	}
+
+	tinfo, err := getTypeInfo(val)
+	if err != nil {
+		return err
+	}
+
+	// Create start element.
+	// Precedence for the XML element name is:
+	// 0. startTemplate
+	// 1. XMLName field in underlying struct;
+	// 2. field name/tag in the struct field; and
+	// 3. type name
+	var start StartElement
+
+	if startTemplate != nil {
+		start.Name = startTemplate.Name
+		start.Attr = append(start.Attr, startTemplate.Attr...)
+	} else if tinfo.xmlname != nil {
+		xmlname := tinfo.xmlname
+		if xmlname.name != "" {
+			start.Name.Space, start.Name.Local = xmlname.xmlns, xmlname.name
+		}
+	}
+
+	// Attributes
+	for i := range tinfo.fields {
+		finfo := &tinfo.fields[i]
+		if finfo.flags&fAttr == 0 {
+			continue
+		}
+		fv := finfo.value(val)
+
+		name := Name{Space: finfo.xmlns, Local: finfo.name}
+		if err := e.marshalAttr(&start, name, fv, stack+pathByIndex(val, finfo.idx)); err != nil {
+			return err
+		}
+	}
+
+	if val.IsStruct() {
+		return e.marshalStruct(tinfo, val, stack)
+	} else {
+		return e.marshalSimple(val, stack)
+	}
+}
+
+func isSlice(v fakereflect.TypeAndCanAddr) bool {
+	_, ok := v.Type.Underlying().(*types.Slice)
+	return ok
+}
+
+func isByteSlice(v fakereflect.TypeAndCanAddr) bool {
+	slice, ok := v.Type.Underlying().(*types.Slice)
+	if !ok {
+		return false
+	}
+	basic, ok := slice.Elem().Underlying().(*types.Basic)
+	if !ok {
+		return false
+	}
+	return basic.Kind() == types.Uint8
+}
+
+func isByteArray(v fakereflect.TypeAndCanAddr) bool {
+	slice, ok := v.Type.Underlying().(*types.Array)
+	if !ok {
+		return false
+	}
+	basic, ok := slice.Elem().Underlying().(*types.Basic)
+	if !ok {
+		return false
+	}
+	return basic.Kind() == types.Uint8
+}
+
+// marshalAttr marshals an attribute with the given name and value, adding to start.Attr.
+func (e *Encoder) marshalAttr(start *StartElement, name Name, val fakereflect.TypeAndCanAddr, stack string) error {
+	if implementsMarshalerAttr(val) {
+		return nil
+	}
+
+	if val.CanAddr() {
+		pv := fakereflect.PtrTo(val)
+		if implementsMarshalerAttr(pv) {
+			return nil
+		}
+	}
+
+	if val.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
+		return nil
+	}
+
+	if val.CanAddr() {
+		pv := fakereflect.PtrTo(val)
+		if pv.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
+			return nil
+		}
+	}
+
+	// Dereference or skip nil pointer
+	if val.IsPtr() {
+		val = val.Elem()
+	}
+
+	// Walk slices.
+	if isSlice(val) && !isByteSlice(val) {
+		if err := e.marshalAttr(start, name, val.Elem(), stack+"[0]"); err != nil {
+			return err
+		}
+		return nil
+	}
+
+	if typeutil.IsTypeWithName(val.Type, "encoding/xml.Attr") {
+		return nil
+	}
+
+	return e.marshalSimple(val, stack)
+}
+
+func (e *Encoder) marshalSimple(val fakereflect.TypeAndCanAddr, stack string) error {
+	switch val.Type.Underlying().(type) {
+	case *types.Basic, *types.Interface:
+		return nil
+	case *types.Slice, *types.Array:
+		basic, ok := val.Elem().Type.Underlying().(*types.Basic)
+		if !ok || basic.Kind() != types.Uint8 {
+			return &UnsupportedTypeError{val.Type, stack}
+		}
+		return nil
+	default:
+		return &UnsupportedTypeError{val.Type, stack}
+	}
+}
+
+func indirect(vf fakereflect.TypeAndCanAddr) fakereflect.TypeAndCanAddr {
+	for vf.IsPtr() {
+		vf = vf.Elem()
+	}
+	return vf
+}
+
+func pathByIndex(t fakereflect.TypeAndCanAddr, index []int) string {
+	var path strings.Builder
+	for _, i := range index {
+		if t.IsPtr() {
+			t = t.Elem()
+		}
+		path.WriteString("." + t.Field(i).Name)
+		t = t.Field(i).Type
+	}
+	return path.String()
+}
+
+func (e *Encoder) marshalStruct(tinfo *typeInfo, val fakereflect.TypeAndCanAddr, stack string) error {
+	for i := range tinfo.fields {
+		finfo := &tinfo.fields[i]
+		if finfo.flags&fAttr != 0 {
+			continue
+		}
+		vf := finfo.value(val)
+
+		switch finfo.flags & fMode {
+		case fCDATA, fCharData:
+			if vf.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
+				continue
+			}
+			if vf.CanAddr() {
+				pv := fakereflect.PtrTo(vf)
+				if pv.Implements(knowledge.Interfaces["encoding.TextMarshaler"]) {
+					continue
+				}
+			}
+			continue
+
+		case fComment:
+			vf = indirect(vf)
+			if !(isByteSlice(vf) || isByteArray(vf)) {
+				return fmt.Errorf("xml: bad type for comment field of %s", val)
+			}
+			continue
+
+		case fInnerXML:
+			vf = indirect(vf)
+			if t, ok := vf.Type.(*types.Slice); (ok && types.Identical(t.Elem(), types.Typ[types.Byte])) || types.Identical(vf.Type, types.Typ[types.String]) {
+				continue
+			}
+
+		case fElement, fElement | fAny:
+		}
+		if err := e.marshalValue(vf, finfo, nil, stack+pathByIndex(val, finfo.idx)); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// UnsupportedTypeError is returned when Marshal encounters a type
+// that cannot be converted into XML.
+type UnsupportedTypeError struct {
+	Type types.Type
+	Path string
+}
+
+func (e *UnsupportedTypeError) Error() string {
+	return fmt.Sprintf("xml: unsupported type %s, via %s ", e.Type, e.Path)
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/fakexml/typeinfo.go b/vendor/honnef.co/go/tools/staticcheck/fakexml/typeinfo.go
new file mode 100644
index 0000000..bf5c73b
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/fakexml/typeinfo.go
@@ -0,0 +1,381 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fakexml
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+	"sync"
+
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/staticcheck/fakereflect"
+)
+
+// typeInfo holds details for the xml representation of a type.
+type typeInfo struct {
+	xmlname *fieldInfo
+	fields  []fieldInfo
+}
+
+// fieldInfo holds details for the xml representation of a single field.
+type fieldInfo struct {
+	idx     []int
+	name    string
+	xmlns   string
+	flags   fieldFlags
+	parents []string
+}
+
+type fieldFlags int
+
+const (
+	fElement fieldFlags = 1 << iota
+	fAttr
+	fCDATA
+	fCharData
+	fInnerXML
+	fComment
+	fAny
+
+	fOmitEmpty
+
+	fMode = fElement | fAttr | fCDATA | fCharData | fInnerXML | fComment | fAny
+
+	xmlName = "XMLName"
+)
+
+func (f fieldFlags) String() string {
+	switch f {
+	case fAttr:
+		return "attr"
+	case fCDATA:
+		return "cdata"
+	case fCharData:
+		return "chardata"
+	case fInnerXML:
+		return "innerxml"
+	case fComment:
+		return "comment"
+	case fAny:
+		return "any"
+	case fOmitEmpty:
+		return "omitempty"
+	case fAny | fAttr:
+		return "any,attr"
+	default:
+		return strconv.Itoa(int(f))
+	}
+}
+
+var tinfoMap sync.Map // map[reflect.Type]*typeInfo
+
+// getTypeInfo returns the typeInfo structure with details necessary
+// for marshaling and unmarshaling typ.
+func getTypeInfo(typ fakereflect.TypeAndCanAddr) (*typeInfo, error) {
+	if ti, ok := tinfoMap.Load(typ); ok {
+		return ti.(*typeInfo), nil
+	}
+
+	tinfo := &typeInfo{}
+	if typ.IsStruct() && !typeutil.IsTypeWithName(typ.Type, "encoding/xml.Name") {
+		n := typ.NumField()
+		for i := range n {
+			f := typ.Field(i)
+			if (!f.IsExported() && !f.Anonymous) || f.Tag.Get("xml") == "-" {
+				continue // Private field
+			}
+
+			// For embedded structs, embed its fields.
+			if f.Anonymous {
+				t := f.Type
+				if t.IsPtr() {
+					t = t.Elem()
+				}
+				if t.IsStruct() {
+					inner, err := getTypeInfo(t)
+					if err != nil {
+						return nil, err
+					}
+					if tinfo.xmlname == nil {
+						tinfo.xmlname = inner.xmlname
+					}
+					for _, finfo := range inner.fields {
+						finfo.idx = append([]int{i}, finfo.idx...)
+						if err := addFieldInfo(typ, tinfo, &finfo); err != nil {
+							return nil, err
+						}
+					}
+					continue
+				}
+			}
+
+			finfo, err := StructFieldInfo(f)
+			if err != nil {
+				return nil, err
+			}
+
+			if f.Name == xmlName {
+				tinfo.xmlname = finfo
+				continue
+			}
+
+			// Add the field if it doesn't conflict with other fields.
+			if err := addFieldInfo(typ, tinfo, finfo); err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	ti, _ := tinfoMap.LoadOrStore(typ, tinfo)
+	return ti.(*typeInfo), nil
+}
+
+// StructFieldInfo builds and returns a fieldInfo for f.
+func StructFieldInfo(f fakereflect.StructField) (*fieldInfo, error) {
+	finfo := &fieldInfo{idx: f.Index}
+
+	// Split the tag from the xml namespace if necessary.
+	tag := f.Tag.Get("xml")
+	if i := strings.Index(tag, " "); i >= 0 {
+		finfo.xmlns, tag = tag[:i], tag[i+1:]
+	}
+
+	// Parse flags.
+	tokens := strings.Split(tag, ",")
+	if len(tokens) == 1 {
+		finfo.flags = fElement
+	} else {
+		tag = tokens[0]
+		for _, flag := range tokens[1:] {
+			switch flag {
+			case "attr":
+				finfo.flags |= fAttr
+			case "cdata":
+				finfo.flags |= fCDATA
+			case "chardata":
+				finfo.flags |= fCharData
+			case "innerxml":
+				finfo.flags |= fInnerXML
+			case "comment":
+				finfo.flags |= fComment
+			case "any":
+				finfo.flags |= fAny
+			case "omitempty":
+				finfo.flags |= fOmitEmpty
+			}
+		}
+
+		// Validate the flags used.
+		switch mode := finfo.flags & fMode; mode {
+		case 0:
+			finfo.flags |= fElement
+		case fAttr, fCDATA, fCharData, fInnerXML, fComment, fAny, fAny | fAttr:
+			if f.Name == xmlName {
+				return nil, fmt.Errorf("cannot use option %s on XMLName field", mode)
+			} else if tag != "" && mode != fAttr {
+				return nil, fmt.Errorf("cannot specify name together with option ,%s", mode)
+			}
+		default:
+			// This will also catch multiple modes in a single field.
+			return nil, fmt.Errorf("invalid combination of options: %q", f.Tag.Get("xml"))
+		}
+		if finfo.flags&fMode == fAny {
+			finfo.flags |= fElement
+		}
+		if finfo.flags&fOmitEmpty != 0 && finfo.flags&(fElement|fAttr) == 0 {
+			return nil, fmt.Errorf("can only use omitempty on elements and attributes")
+		}
+	}
+
+	// Use of xmlns without a name is not allowed.
+	if finfo.xmlns != "" && tag == "" {
+		return nil, fmt.Errorf("namespace without name: %q", f.Tag.Get("xml"))
+	}
+
+	if f.Name == xmlName {
+		// The XMLName field records the XML element name. Don't
+		// process it as usual because its name should default to
+		// empty rather than to the field name.
+		finfo.name = tag
+		return finfo, nil
+	}
+
+	if tag == "" {
+		// If the name part of the tag is completely empty, get
+		// default from XMLName of underlying struct if feasible,
+		// or field name otherwise.
+		if xmlname := lookupXMLName(f.Type); xmlname != nil {
+			finfo.xmlns, finfo.name = xmlname.xmlns, xmlname.name
+		} else {
+			finfo.name = f.Name
+		}
+		return finfo, nil
+	}
+
+	// Prepare field name and parents.
+	parents := strings.Split(tag, ">")
+	if parents[0] == "" {
+		parents[0] = f.Name
+	}
+	if parents[len(parents)-1] == "" {
+		return nil, fmt.Errorf("trailing '>'")
+	}
+	finfo.name = parents[len(parents)-1]
+	if len(parents) > 1 {
+		if (finfo.flags & fElement) == 0 {
+			return nil, fmt.Errorf("%s chain not valid with %s flag", tag, strings.Join(tokens[1:], ","))
+		}
+		finfo.parents = parents[:len(parents)-1]
+	}
+
+	// If the field type has an XMLName field, the names must match
+	// so that the behavior of both marshaling and unmarshaling
+	// is straightforward and unambiguous.
+	if finfo.flags&fElement != 0 {
+		ftyp := f.Type
+		xmlname := lookupXMLName(ftyp)
+		if xmlname != nil && xmlname.name != finfo.name {
+			return nil, fmt.Errorf("name %q conflicts with name %q in %s.XMLName", finfo.name, xmlname.name, ftyp)
+		}
+	}
+	return finfo, nil
+}
+
+// lookupXMLName returns the fieldInfo for typ's XMLName field
+// in case it exists and has a valid xml field tag, otherwise
+// it returns nil.
+func lookupXMLName(typ fakereflect.TypeAndCanAddr) (xmlname *fieldInfo) {
+	seen := map[fakereflect.TypeAndCanAddr]struct{}{}
+	for typ.IsPtr() {
+		typ = typ.Elem()
+		if _, ok := seen[typ]; ok {
+			// Loop in type graph, e.g. 'type P *P'
+			return nil
+		}
+		seen[typ] = struct{}{}
+	}
+	if !typ.IsStruct() {
+		return nil
+	}
+	for i, n := 0, typ.NumField(); i < n; i++ {
+		f := typ.Field(i)
+		if f.Name != xmlName {
+			continue
+		}
+		finfo, err := StructFieldInfo(f)
+		if err == nil && finfo.name != "" {
+			return finfo
+		}
+		// Also consider errors as a non-existent field tag
+		// and let getTypeInfo itself report the error.
+		break
+	}
+	return nil
+}
+
+// addFieldInfo adds finfo to tinfo.fields if there are no
+// conflicts, or if conflicts arise from previous fields that were
+// obtained from deeper embedded structures than finfo. In the latter
+// case, the conflicting entries are dropped.
+// A conflict occurs when the path (parent + name) to a field is
+// itself a prefix of another path, or when two paths match exactly.
+// It is okay for field paths to share a common, shorter prefix.
+func addFieldInfo(typ fakereflect.TypeAndCanAddr, tinfo *typeInfo, newf *fieldInfo) error {
+	var conflicts []int
+Loop:
+	// First, figure all conflicts. Most working code will have none.
+	for i := range tinfo.fields {
+		oldf := &tinfo.fields[i]
+		if oldf.flags&fMode != newf.flags&fMode {
+			continue
+		}
+		if oldf.xmlns != "" && newf.xmlns != "" && oldf.xmlns != newf.xmlns {
+			continue
+		}
+		minl := min(len(newf.parents), len(oldf.parents))
+		for p := range minl {
+			if oldf.parents[p] != newf.parents[p] {
+				continue Loop
+			}
+		}
+		if len(oldf.parents) > len(newf.parents) {
+			if oldf.parents[len(newf.parents)] == newf.name {
+				conflicts = append(conflicts, i)
+			}
+		} else if len(oldf.parents) < len(newf.parents) {
+			if newf.parents[len(oldf.parents)] == oldf.name {
+				conflicts = append(conflicts, i)
+			}
+		} else {
+			if newf.name == oldf.name {
+				conflicts = append(conflicts, i)
+			}
+		}
+	}
+	// Without conflicts, add the new field and return.
+	if conflicts == nil {
+		tinfo.fields = append(tinfo.fields, *newf)
+		return nil
+	}
+
+	// If any conflict is shallower, ignore the new field.
+	// This matches the Go field resolution on embedding.
+	for _, i := range conflicts {
+		if len(tinfo.fields[i].idx) < len(newf.idx) {
+			return nil
+		}
+	}
+
+	// Otherwise, if any of them is at the same depth level, it's an error.
+	for _, i := range conflicts {
+		oldf := &tinfo.fields[i]
+		if len(oldf.idx) == len(newf.idx) {
+			f1 := typ.FieldByIndex(oldf.idx)
+			f2 := typ.FieldByIndex(newf.idx)
+			return &TagPathError{typ, f1.Name, f1.Tag.Get("xml"), f2.Name, f2.Tag.Get("xml")}
+		}
+	}
+
+	// Otherwise, the new field is shallower, and thus takes precedence,
+	// so drop the conflicting fields from tinfo and append the new one.
+	for c := len(conflicts) - 1; c >= 0; c-- {
+		i := conflicts[c]
+		copy(tinfo.fields[i:], tinfo.fields[i+1:])
+		tinfo.fields = tinfo.fields[:len(tinfo.fields)-1]
+	}
+	tinfo.fields = append(tinfo.fields, *newf)
+	return nil
+}
+
+// A TagPathError represents an error in the unmarshaling process
+// caused by the use of field tags with conflicting paths.
+type TagPathError struct {
+	Struct       fakereflect.TypeAndCanAddr
+	Field1, Tag1 string
+	Field2, Tag2 string
+}
+
+func (e *TagPathError) Error() string {
+	return fmt.Sprintf("%s field %q with tag %q conflicts with field %q with tag %q", e.Struct, e.Field1, e.Tag1, e.Field2, e.Tag2)
+}
+
+// value returns v's field value corresponding to finfo.
+// It's equivalent to v.FieldByIndex(finfo.idx), but when passed
+// initNilPointers, it initializes and dereferences pointers as necessary.
+// When passed dontInitNilPointers and a nil pointer is reached, the function
+// returns a zero reflect.Value.
+func (finfo *fieldInfo) value(v fakereflect.TypeAndCanAddr) fakereflect.TypeAndCanAddr {
+	for i, x := range finfo.idx {
+		if i > 0 {
+			t := v
+			if t.IsPtr() && t.Elem().IsStruct() {
+				v = v.Elem()
+			}
+		}
+		v = v.Field(x).Type
+	}
+	return v
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/fakexml/xml.go b/vendor/honnef.co/go/tools/staticcheck/fakexml/xml.go
new file mode 100644
index 0000000..0f8fb27
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/fakexml/xml.go
@@ -0,0 +1,33 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fakexml
+
+// References:
+//    Annotated XML spec: https://www.xml.com/axml/testaxml.htm
+//    XML name spaces: https://www.w3.org/TR/REC-xml-names/
+
+// TODO(rsc):
+//	Test error handling.
+
+// A Name represents an XML name (Local) annotated
+// with a name space identifier (Space).
+// In tokens returned by Decoder.Token, the Space identifier
+// is given as a canonical URL, not the short prefix used
+// in the document being parsed.
+type Name struct {
+	Space, Local string
+}
+
+// An Attr represents an attribute in an XML element (Name=Value).
+type Attr struct {
+	Name  Name
+	Value string
+}
+
+// A StartElement represents an XML start element.
+type StartElement struct {
+	Name Name
+	Attr []Attr
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1000/sa1000.go b/vendor/honnef.co/go/tools/staticcheck/sa1000/sa1000.go
new file mode 100644
index 0000000..3a1356a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1000/sa1000.go
@@ -0,0 +1,46 @@
+package sa1000
+
+import (
+	"go/constant"
+	"regexp"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1000",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Invalid regular expression`,
+		Since:    "2017.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"regexp.MustCompile": check,
+	"regexp.Compile":     check,
+	"regexp.Match":       check,
+	"regexp.MatchReader": check,
+	"regexp.MatchString": check,
+}
+
+func check(call *callcheck.Call) {
+	arg := call.Args[0]
+	if c := callcheck.ExtractConstExpectKind(arg.Value, constant.String); c != nil {
+		s := constant.StringVal(c.Value)
+		if _, err := regexp.Compile(s); err != nil {
+			arg.Invalid(err.Error())
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1001/sa1001.go b/vendor/honnef.co/go/tools/staticcheck/sa1001/sa1001.go
new file mode 100644
index 0000000..4e8e4ff
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1001/sa1001.go
@@ -0,0 +1,83 @@
+package sa1001
+
+import (
+	"go/ast"
+	htmltemplate "html/template"
+	"strings"
+	texttemplate "text/template"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/knowledge"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1001",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Invalid template`,
+		Since:    "2017.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var query = pattern.MustParse(`
+	(CallExpr
+		(Symbol
+		name@(Or
+			"(*text/template.Template).Parse"
+			"(*html/template.Template).Parse"))
+		[s])`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, query) {
+		name := m.State["name"].(string)
+		var kind string
+		switch name {
+		case "(*text/template.Template).Parse":
+			kind = "text"
+		case "(*html/template.Template).Parse":
+			kind = "html"
+		}
+
+		call := node.(*ast.CallExpr)
+		sel := call.Fun.(*ast.SelectorExpr)
+		if !code.IsCallToAny(pass, sel.X, "text/template.New", "html/template.New") {
+			// TODO(dh): this is a cheap workaround for templates with
+			// different delims. A better solution with less false
+			// negatives would use data flow analysis to see where the
+			// template comes from and where it has been
+			continue
+		}
+
+		s, ok := code.ExprToString(pass, m.State["s"].(ast.Expr))
+		if !ok {
+			continue
+		}
+		var err error
+		switch kind {
+		case "text":
+			_, err = texttemplate.New("").Parse(s)
+		case "html":
+			_, err = htmltemplate.New("").Parse(s)
+		}
+		if err != nil {
+			// TODO(dominikh): whitelist other parse errors, if any
+			if strings.Contains(err.Error(), "unexpected") ||
+				strings.Contains(err.Error(), "bad character") {
+				report.Report(pass, call.Args[knowledge.Arg("(*text/template.Template).Parse.text")], err.Error())
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1002/sa1002.go b/vendor/honnef.co/go/tools/staticcheck/sa1002/sa1002.go
new file mode 100644
index 0000000..4f7159a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1002/sa1002.go
@@ -0,0 +1,48 @@
+package sa1002
+
+import (
+	"go/constant"
+	"strings"
+	"time"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1002",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Invalid format in \'time.Parse\'`,
+		Text: `\'time.Parse\' requires a layout string that uses Go's reference time:
+\"Mon Jan 2 15:04:05 MST 2006\". The layout must represent this date and time
+exactly. See https://pkg.go.dev/time#pkg-constants for layout examples.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"time.Parse": func(call *callcheck.Call) {
+		arg := call.Args[knowledge.Arg("time.Parse.layout")]
+		if c := callcheck.ExtractConstExpectKind(arg.Value, constant.String); c != nil {
+			s := constant.StringVal(c.Value)
+			s = strings.Replace(s, "_", " ", -1)
+			s = strings.Replace(s, "Z", "-", -1)
+			_, err := time.Parse(s, s)
+			if err != nil {
+				arg.Invalid(err.Error())
+			}
+		}
+	},
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1003/sa1003.go b/vendor/honnef.co/go/tools/staticcheck/sa1003/sa1003.go
new file mode 100644
index 0000000..087f031
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1003/sa1003.go
@@ -0,0 +1,92 @@
+package sa1003
+
+import (
+	"fmt"
+	"go/types"
+	"go/version"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1003",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(checkEncodingBinaryRules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Unsupported argument to functions in \'encoding/binary\'`,
+		Text: `The \'encoding/binary\' package can only serialize types with known sizes.
+This precludes the use of the \'int\' and \'uint\' types, as their sizes
+differ on different architectures. Furthermore, it doesn't support
+serializing maps, channels, strings, or functions.
+
+Before Go 1.8, \'bool\' wasn't supported, either.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkEncodingBinaryRules = map[string]callcheck.Check{
+	"encoding/binary.Write": func(call *callcheck.Call) {
+		arg := call.Args[knowledge.Arg("encoding/binary.Write.data")]
+		if !CanBinaryMarshal(call.Pass, call.Parent, arg.Value) {
+			arg.Invalid(fmt.Sprintf("value of type %s cannot be used with binary.Write", arg.Value.Value.Type()))
+		}
+	},
+}
+
+func CanBinaryMarshal(pass *analysis.Pass, node code.Positioner, v callcheck.Value) bool {
+	typ := v.Value.Type().Underlying()
+	if ttyp, ok := typ.(*types.Pointer); ok {
+		typ = ttyp.Elem().Underlying()
+	}
+	if ttyp, ok := types.Unalias(typ).(interface {
+		Elem() types.Type
+	}); ok {
+		if _, ok := ttyp.(*types.Pointer); !ok {
+			typ = ttyp.Elem()
+		}
+	}
+
+	return validEncodingBinaryType(pass, node, typ)
+}
+
+func validEncodingBinaryType(pass *analysis.Pass, node code.Positioner, typ types.Type) bool {
+	typ = typ.Underlying()
+	switch typ := typ.(type) {
+	case *types.Basic:
+		switch typ.Kind() {
+		case types.Uint8, types.Uint16, types.Uint32, types.Uint64,
+			types.Int8, types.Int16, types.Int32, types.Int64,
+			types.Float32, types.Float64, types.Complex64, types.Complex128, types.Invalid:
+			return true
+		case types.Bool:
+			return version.Compare(code.StdlibVersion(pass, node), "go1.8") >= 0
+		}
+		return false
+	case *types.Struct:
+		n := typ.NumFields()
+		for i := range n {
+			if !validEncodingBinaryType(pass, node, typ.Field(i).Type()) {
+				return false
+			}
+		}
+		return true
+	case *types.Array:
+		return validEncodingBinaryType(pass, node, typ.Elem())
+	case *types.Interface:
+		// we can't determine if it's a valid type or not
+		return true
+	}
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1004/sa1004.go b/vendor/honnef.co/go/tools/staticcheck/sa1004/sa1004.go
new file mode 100644
index 0000000..b3dee16
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1004/sa1004.go
@@ -0,0 +1,72 @@
+package sa1004
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1004",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Suspiciously small untyped constant in \'time.Sleep\'`,
+		Text: `The \'time\'.Sleep function takes a \'time.Duration\' as its only argument.
+Durations are expressed in nanoseconds. Thus, calling \'time.Sleep(1)\'
+will sleep for 1 nanosecond. This is a common source of bugs, as sleep
+functions in other languages often accept seconds or milliseconds.
+
+The \'time\' package provides constants such as \'time.Second\' to express
+large durations. These can be combined with arithmetic to express
+arbitrary durations, for example \'5 * time.Second\' for 5 seconds.
+
+If you truly meant to sleep for a tiny amount of time, use
+\'n * time.Nanosecond\' to signal to Staticcheck that you did mean to sleep
+for some amount of nanoseconds.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkTimeSleepConstantPatternQ   = pattern.MustParse(`(CallExpr (Symbol "time.Sleep") lit@(IntegerLiteral value))`)
+	checkTimeSleepConstantPatternRns = pattern.MustParse(`(BinaryExpr duration "*" (SelectorExpr (Ident "time") (Ident "Nanosecond")))`)
+	checkTimeSleepConstantPatternRs  = pattern.MustParse(`(BinaryExpr duration "*" (SelectorExpr (Ident "time") (Ident "Second")))`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, m := range code.Matches(pass, checkTimeSleepConstantPatternQ) {
+		n, ok := constant.Int64Val(m.State["value"].(types.TypeAndValue).Value)
+		if !ok {
+			continue
+		}
+		if n == 0 || n > 120 {
+			// time.Sleep(0) is a seldom used pattern in concurrency
+			// tests. >120 might be intentional. 120 was chosen
+			// because the user could've meant 2 minutes.
+			continue
+		}
+
+		lit := m.State["lit"].(ast.Node)
+		report.Report(pass, lit,
+			fmt.Sprintf("sleeping for %d nanoseconds is probably a bug; be explicit if it isn't", n), report.Fixes(
+				edit.Fix("Explicitly use nanoseconds", edit.ReplaceWithPattern(pass.Fset, lit, checkTimeSleepConstantPatternRns, pattern.State{"duration": lit})),
+				edit.Fix("Use seconds", edit.ReplaceWithPattern(pass.Fset, lit, checkTimeSleepConstantPatternRs, pattern.State{"duration": lit}))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1005/sa1005.go b/vendor/honnef.co/go/tools/staticcheck/sa1005/sa1005.go
new file mode 100644
index 0000000..65edb51
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1005/sa1005.go
@@ -0,0 +1,65 @@
+package sa1005
+
+import (
+	"go/ast"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1005",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Invalid first argument to \'exec.Command\'`,
+		Text: `\'os/exec\' runs programs directly (using variants of the fork and exec
+system calls on Unix systems). This shouldn't be confused with running
+a command in a shell. The shell will allow for features such as input
+redirection, pipes, and general scripting. The shell is also
+responsible for splitting the user's input into a program name and its
+arguments. For example, the equivalent to
+
+    ls / /tmp
+
+would be
+
+    exec.Command("ls", "/", "/tmp")
+
+If you want to run a command in a shell, consider using something like
+the following – but be aware that not all systems, particularly
+Windows, will have a \'/bin/sh\' program:
+
+    exec.Command("/bin/sh", "-c", "ls | grep Awesome")`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var query = pattern.MustParse(`(CallExpr (Symbol "os/exec.Command") arg1:_)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, m := range code.Matches(pass, query) {
+		arg1 := m.State["arg1"].(ast.Expr)
+		val, ok := code.ExprToString(pass, arg1)
+		if !ok {
+			continue
+		}
+		if !strings.Contains(val, " ") || strings.Contains(val, `\`) || strings.Contains(val, "/") {
+			continue
+		}
+		report.Report(pass, arg1,
+			"first argument to exec.Command looks like a shell command, but a program name or path are expected")
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1006/sa1006.go b/vendor/honnef.co/go/tools/staticcheck/sa1006/sa1006.go
new file mode 100644
index 0000000..c613808
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1006/sa1006.go
@@ -0,0 +1,115 @@
+package sa1006
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1006",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `\'Printf\' with dynamic first argument and no further arguments`,
+		Text: `Using \'fmt.Printf\' with a dynamic first argument can lead to unexpected
+output. The first argument is a format string, where certain character
+combinations have special meaning. If, for example, a user were to
+enter a string such as
+
+    Interest rate: 5%
+
+and you printed it with
+
+    fmt.Printf(s)
+
+it would lead to the following output:
+
+    Interest rate: 5%!(NOVERB).
+
+Similarly, forming the first parameter via string concatenation with
+user input should be avoided for the same reason. When printing user
+input, either use a variant of \'fmt.Print\', or use the \'%s\' Printf verb
+and pass the string as an argument.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var query1 = pattern.MustParse(`
+	(CallExpr
+		(Symbol
+			name@(Or
+				"fmt.Errorf"
+				"fmt.Printf"
+				"fmt.Sprintf"
+				"log.Fatalf"
+				"log.Panicf"
+				"log.Printf"
+				"(*log.Logger).Printf"
+				"(*testing.common).Logf"
+				"(*testing.common).Errorf"
+				"(*testing.common).Fatalf"
+				"(*testing.common).Skipf"
+				"(testing.TB).Logf"
+				"(testing.TB).Errorf"
+				"(testing.TB).Fatalf"
+				"(testing.TB).Skipf"))
+		format:[])
+`)
+
+var query2 = pattern.MustParse(`(CallExpr (Symbol "fmt.Fprintf") _:format:[])`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, query1, query2) {
+		call := node.(*ast.CallExpr)
+		name, ok := m.State["name"].(string)
+		if !ok {
+			name = "fmt.Fprintf"
+		}
+
+		arg := m.State["format"].(ast.Expr)
+		switch arg.(type) {
+		case *ast.CallExpr, *ast.Ident:
+		default:
+			continue
+		}
+
+		if _, ok := pass.TypesInfo.TypeOf(arg).(*types.Tuple); ok {
+			// the called function returns multiple values and got
+			// splatted into the call. for all we know, it is
+			// returning good arguments.
+			continue
+		}
+
+		var alt string
+		if name == "fmt.Errorf" {
+			// The alternative to fmt.Errorf isn't fmt.Error but errors.New
+			alt = "errors.New"
+		} else {
+			// This can be either a function call like log.Printf or a method call with an
+			// arbitrarily complex selector, such as foo.bar[0].Printf. In either case,
+			// all we have to do is remove the final 'f' from the existing call.Fun
+			// expression.
+			alt = report.Render(pass, call.Fun)
+			alt = alt[:len(alt)-1]
+		}
+		report.Report(pass, call,
+			"printf-style function with dynamic format string and no further arguments should use print-style function instead",
+			report.Fixes(edit.Fix(fmt.Sprintf("Use %s instead of %s", alt, name), edit.ReplaceWithString(call.Fun, alt))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1007/sa1007.go b/vendor/honnef.co/go/tools/staticcheck/sa1007/sa1007.go
new file mode 100644
index 0000000..8aa6958
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1007/sa1007.go
@@ -0,0 +1,43 @@
+package sa1007
+
+import (
+	"fmt"
+	"go/constant"
+	"net/url"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1007",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Invalid URL in \'net/url.Parse\'`,
+		Since:    "2017.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"net/url.Parse": func(call *callcheck.Call) {
+		arg := call.Args[knowledge.Arg("net/url.Parse.rawurl")]
+		if c := callcheck.ExtractConstExpectKind(arg.Value, constant.String); c != nil {
+			s := constant.StringVal(c.Value)
+			_, err := url.Parse(s)
+			if err != nil {
+				arg.Invalid(fmt.Sprintf("%q is not a valid URL: %s", s, err))
+			}
+		}
+	},
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1008/sa1008.go b/vendor/honnef.co/go/tools/staticcheck/sa1008/sa1008.go
new file mode 100644
index 0000000..3e0d1bb
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1008/sa1008.go
@@ -0,0 +1,111 @@
+package sa1008
+
+import (
+	"fmt"
+	"go/ast"
+	"net/http"
+	"strconv"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1008",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Non-canonical key in \'http.Header\' map`,
+		Text: `Keys in \'http.Header\' maps are canonical, meaning they follow a specific
+combination of uppercase and lowercase letters. Methods such as
+\'http.Header.Add\' and \'http.Header.Del\' convert inputs into this canonical
+form before manipulating the map.
+
+When manipulating \'http.Header\' maps directly, as opposed to using the
+provided methods, care should be taken to stick to canonical form in
+order to avoid inconsistencies. The following piece of code
+demonstrates one such inconsistency:
+
+    h := http.Header{}
+    h["etag"] = []string{"1234"}
+    h.Add("etag", "5678")
+    fmt.Println(h)
+
+    // Output:
+    // map[Etag:[5678] etag:[1234]]
+
+The easiest way of obtaining the canonical form of a key is to use
+\'http.CanonicalHeaderKey\'.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node, push bool) bool {
+		if !push {
+			return false
+		}
+		if assign, ok := node.(*ast.AssignStmt); ok {
+			// TODO(dh): This risks missing some Header reads, for
+			// example in `h1["foo"] = h2["foo"]` – these edge
+			// cases are probably rare enough to ignore for now.
+			for _, expr := range assign.Lhs {
+				op, ok := expr.(*ast.IndexExpr)
+				if !ok {
+					continue
+				}
+				if code.IsOfTypeWithName(pass, op.X, "net/http.Header") {
+					return false
+				}
+			}
+			return true
+		}
+		op, ok := node.(*ast.IndexExpr)
+		if !ok {
+			return true
+		}
+		if !code.IsOfTypeWithName(pass, op.X, "net/http.Header") {
+			return true
+		}
+		s, ok := code.ExprToString(pass, op.Index)
+		if !ok {
+			return true
+		}
+		canonical := http.CanonicalHeaderKey(s)
+		if s == canonical {
+			return true
+		}
+		var fix analysis.SuggestedFix
+		switch op.Index.(type) {
+		case *ast.BasicLit:
+			fix = edit.Fix("Canonicalize header key", edit.ReplaceWithString(op.Index, strconv.Quote(canonical)))
+		case *ast.Ident:
+			call := &ast.CallExpr{
+				Fun:  edit.Selector("http", "CanonicalHeaderKey"),
+				Args: []ast.Expr{op.Index},
+			}
+			fix = edit.Fix("Wrap in http.CanonicalHeaderKey", edit.ReplaceWithNode(pass.Fset, op.Index, call))
+		}
+		msg := fmt.Sprintf("keys in http.Header are canonicalized, %q is not canonical; fix the constant or use http.CanonicalHeaderKey", s)
+		if fix.Message != "" {
+			report.Report(pass, op, msg, report.Fixes(fix))
+		} else {
+			report.Report(pass, op, msg)
+		}
+		return true
+	}
+	pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes([]ast.Node{(*ast.AssignStmt)(nil), (*ast.IndexExpr)(nil)}, fn)
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1010/sa1010.go b/vendor/honnef.co/go/tools/staticcheck/sa1010/sa1010.go
new file mode 100644
index 0000000..2ad6b1f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1010/sa1010.go
@@ -0,0 +1,53 @@
+package sa1010
+
+import (
+	"fmt"
+	"go/constant"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1010",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(checkRegexpFindAllRules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `\'(*regexp.Regexp).FindAll\' called with \'n == 0\', which will always return zero results`,
+		Text: `If \'n >= 0\', the function returns at most \'n\' matches/submatches. To
+return all results, specify a negative number.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny, // MergeIfAny if we only flag literals, not named constants
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkRegexpFindAllRules = map[string]callcheck.Check{
+	"(*regexp.Regexp).FindAll":                    RepeatZeroTimes("a FindAll method", 1),
+	"(*regexp.Regexp).FindAllIndex":               RepeatZeroTimes("a FindAll method", 1),
+	"(*regexp.Regexp).FindAllString":              RepeatZeroTimes("a FindAll method", 1),
+	"(*regexp.Regexp).FindAllStringIndex":         RepeatZeroTimes("a FindAll method", 1),
+	"(*regexp.Regexp).FindAllStringSubmatch":      RepeatZeroTimes("a FindAll method", 1),
+	"(*regexp.Regexp).FindAllStringSubmatchIndex": RepeatZeroTimes("a FindAll method", 1),
+	"(*regexp.Regexp).FindAllSubmatch":            RepeatZeroTimes("a FindAll method", 1),
+	"(*regexp.Regexp).FindAllSubmatchIndex":       RepeatZeroTimes("a FindAll method", 1),
+}
+
+func RepeatZeroTimes(name string, arg int) callcheck.Check {
+	return func(call *callcheck.Call) {
+		arg := call.Args[arg]
+		if k, ok := arg.Value.Value.(*ir.Const); ok && k.Value.Kind() == constant.Int {
+			if v, ok := constant.Int64Val(k.Value); ok && v == 0 {
+				arg.Invalid(fmt.Sprintf("calling %s with n == 0 will return no results, did you mean -1?", name))
+			}
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1011/sa1011.go b/vendor/honnef.co/go/tools/staticcheck/sa1011/sa1011.go
new file mode 100644
index 0000000..5b86c6d
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1011/sa1011.go
@@ -0,0 +1,47 @@
+package sa1011
+
+import (
+	"go/constant"
+	"unicode/utf8"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1011",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(checkUTF8CutsetRules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Various methods in the \"strings\" package expect valid UTF-8, but invalid input is provided`,
+		Since:    "2017.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkUTF8CutsetRules = map[string]callcheck.Check{
+	"strings.IndexAny":     check,
+	"strings.LastIndexAny": check,
+	"strings.ContainsAny":  check,
+	"strings.Trim":         check,
+	"strings.TrimLeft":     check,
+	"strings.TrimRight":    check,
+}
+
+func check(call *callcheck.Call) {
+	arg := call.Args[1]
+	if c := callcheck.ExtractConstExpectKind(arg.Value, constant.String); c != nil {
+		s := constant.StringVal(c.Value)
+		if !utf8.ValidString(s) {
+			arg.Invalid("argument is not a valid UTF-8 encoded string")
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1012/sa1012.go b/vendor/honnef.co/go/tools/staticcheck/sa1012/sa1012.go
new file mode 100644
index 0000000..b04fd8c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1012/sa1012.go
@@ -0,0 +1,68 @@
+package sa1012
+
+import (
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1012",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `A nil \'context.Context\' is being passed to a function, consider using \'context.TODO\' instead`,
+		Text: `The context package prohibits the use of a \'nil\' context.
+If no parent context is available, a new context should be used,
+e.g. \'context.TODO\' or \'context.Background\'.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkNilContextQ = pattern.MustParse(`(CallExpr fun@(Symbol _) (Builtin "nil"):_)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	todo := &ast.CallExpr{
+		Fun: edit.Selector("context", "TODO"),
+	}
+	bg := &ast.CallExpr{
+		Fun: edit.Selector("context", "Background"),
+	}
+	for node, m := range code.Matches(pass, checkNilContextQ) {
+		call := node.(*ast.CallExpr)
+		fun, ok := m.State["fun"].(*types.Func)
+		if !ok {
+			// it might also be a builtin
+			continue
+		}
+		sig := fun.Type().(*types.Signature)
+		if sig.Params().Len() == 0 {
+			// Our CallExpr might've matched a method expression, like
+			// (*T).Foo(nil) – here, nil isn't the first argument of
+			// the Foo method, but the method receiver.
+			continue
+		}
+		if !typeutil.IsTypeWithName(sig.Params().At(0).Type(), "context.Context") {
+			continue
+		}
+		report.Report(pass, call.Args[0],
+			"do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use", report.Fixes(
+				edit.Fix("Use context.TODO", edit.ReplaceWithNode(pass.Fset, call.Args[0], todo)),
+				edit.Fix("Use context.Background", edit.ReplaceWithNode(pass.Fset, call.Args[0], bg))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1013/sa1013.go b/vendor/honnef.co/go/tools/staticcheck/sa1013/sa1013.go
new file mode 100644
index 0000000..cbcbe4e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1013/sa1013.go
@@ -0,0 +1,47 @@
+package sa1013
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/knowledge"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1013",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `\'io.Seeker.Seek\' is being called with the whence constant as the first argument, but it should be the second`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkSeekerQ = pattern.MustParse(`(CallExpr fun@(SelectorExpr _ (Ident "Seek")) [arg1@(SelectorExpr _ (Symbol (Or "io.SeekStart" "io.SeekCurrent" "io.SeekEnd"))) arg2])`)
+	checkSeekerR = pattern.MustParse(`(CallExpr fun [arg2 arg1])`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkSeekerQ) {
+		if !code.IsMethod(pass, m.State["fun"].(*ast.SelectorExpr), "Seek", knowledge.Signatures["(io.Seeker).Seek"]) {
+			continue
+		}
+		edits := code.EditMatch(pass, node, m, checkSeekerR)
+		report.Report(pass, node, "the first argument of io.Seeker is the offset, but an io.Seek* constant is being used instead",
+			report.Fixes(edit.Fix("Swap arguments", edits...)))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1014/sa1014.go b/vendor/honnef.co/go/tools/staticcheck/sa1014/sa1014.go
new file mode 100644
index 0000000..528aa33
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1014/sa1014.go
@@ -0,0 +1,56 @@
+package sa1014
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1014",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(checkUnmarshalPointerRules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Non-pointer value passed to \'Unmarshal\' or \'Decode\'`,
+		Text: `Functions such as \'encoding/json.Unmarshal\' and
+\'(*encoding/json.Decoder).Decode\' require a pointer to the value that should
+be populated. Passing a non-pointer value results in the function returning an
+error at runtime, as it cannot modify the target value.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkUnmarshalPointerRules = map[string]callcheck.Check{
+	"encoding/xml.Unmarshal":                unmarshalPointer("xml.Unmarshal", 1),
+	"(*encoding/xml.Decoder).Decode":        unmarshalPointer("Decode", 0),
+	"(*encoding/xml.Decoder).DecodeElement": unmarshalPointer("DecodeElement", 0),
+	"encoding/json.Unmarshal":               unmarshalPointer("json.Unmarshal", 1),
+	"(*encoding/json.Decoder).Decode":       unmarshalPointer("Decode", 0),
+}
+
+func unmarshalPointer(name string, arg int) callcheck.Check {
+	return func(call *callcheck.Call) {
+		if !Pointer(call.Args[arg].Value) {
+			call.Args[arg].Invalid(fmt.Sprintf("%s expects to unmarshal into a pointer, but the provided value is not a pointer", name))
+		}
+	}
+}
+
+func Pointer(v callcheck.Value) bool {
+	switch v.Value.Type().Underlying().(type) {
+	case *types.Pointer, *types.Interface:
+		return true
+	}
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1015/sa1015.go b/vendor/honnef.co/go/tools/staticcheck/sa1015/sa1015.go
new file mode 100644
index 0000000..a416c34
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1015/sa1015.go
@@ -0,0 +1,69 @@
+package sa1015
+
+import (
+	"go/token"
+	"go/version"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1015",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Using \'time.Tick\' in a way that will leak. Consider using \'time.NewTicker\', and only use \'time.Tick\' in tests, commands and endless functions`,
+
+		Text: `Before Go 1.23, \'time.Ticker\'s had to be closed to be able to be garbage
+collected. Since \'time.Tick\' doesn't make it possible to close the underlying
+ticker, using it repeatedly would leak memory.
+
+Go 1.23 fixes this by allowing tickers to be collected even if they weren't closed.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		if fn.Pos() == token.NoPos || version.Compare(code.StdlibVersion(pass, fn), "go1.23") >= 0 {
+			// Beginning with Go 1.23, the GC is able to collect unreferenced, unclosed
+			// tickers, which makes time.Tick safe(r) to use.
+			//
+			// When we don't have a valid position, we err on the side of false negatives.
+			// This shouldn't actually lead to any false negatives, as no functions
+			// without valid positions (such as the synthesized init function) should be
+			// able to use time.Tick.
+			continue
+		}
+
+		if code.IsMainLike(pass) || code.IsInTest(pass, fn) {
+			continue
+		}
+		for _, block := range fn.Blocks {
+			for _, ins := range block.Instrs {
+				call, ok := ins.(*ir.Call)
+				if !ok || !irutil.IsCallTo(call.Common(), "time.Tick") {
+					continue
+				}
+				if !irutil.Terminates(call.Parent()) {
+					continue
+				}
+				report.Report(pass, call, "using time.Tick leaks the underlying ticker, consider using it only in endless functions, tests and the main package, and use time.NewTicker here")
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1016/sa1016.go b/vendor/honnef.co/go/tools/staticcheck/sa1016/sa1016.go
new file mode 100644
index 0000000..bf89f6c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1016/sa1016.go
@@ -0,0 +1,115 @@
+package sa1016
+
+import (
+	"fmt"
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1016",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Trapping a signal that cannot be trapped`,
+		Text: `Not all signals can be intercepted by a process. Specifically, on
+UNIX-like systems, the \'syscall.SIGKILL\' and \'syscall.SIGSTOP\' signals are
+never passed to the process, but instead handled directly by the
+kernel. It is therefore pointless to try and handle these signals.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var query = pattern.MustParse(`
+	(CallExpr
+		(Symbol
+			(Or
+				"os/signal.Ignore"
+				"os/signal.Notify"
+				"os/signal.Reset"))
+		_)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	isSignal := func(pass *analysis.Pass, expr ast.Expr, name string) bool {
+		if expr, ok := expr.(*ast.SelectorExpr); ok {
+			return code.SelectorName(pass, expr) == name
+		} else {
+			return false
+		}
+	}
+
+	for node := range code.Matches(pass, query) {
+		call := node.(*ast.CallExpr)
+		hasSigterm := false
+		for _, arg := range call.Args {
+			if conv, ok := arg.(*ast.CallExpr); ok && isSignal(pass, conv.Fun, "os.Signal") {
+				arg = conv.Args[0]
+			}
+
+			if isSignal(pass, arg, "syscall.SIGTERM") {
+				hasSigterm = true
+				break
+			}
+
+		}
+		for i, arg := range call.Args {
+			if conv, ok := arg.(*ast.CallExpr); ok && isSignal(pass, conv.Fun, "os.Signal") {
+				arg = conv.Args[0]
+			}
+
+			if isSignal(pass, arg, "os.Kill") || isSignal(pass, arg, "syscall.SIGKILL") {
+				var fixes []analysis.SuggestedFix
+				if !hasSigterm {
+					nargs := make([]ast.Expr, len(call.Args))
+					for j, a := range call.Args {
+						if i == j {
+							nargs[j] = edit.Selector("syscall", "SIGTERM")
+						} else {
+							nargs[j] = a
+						}
+					}
+					ncall := *call
+					ncall.Args = nargs
+					fixes = append(fixes, edit.Fix(fmt.Sprintf("Use syscall.SIGTERM instead of %s", report.Render(pass, arg)), edit.ReplaceWithNode(pass.Fset, call, &ncall)))
+				}
+				nargs := make([]ast.Expr, 0, len(call.Args))
+				for j, a := range call.Args {
+					if i == j {
+						continue
+					}
+					nargs = append(nargs, a)
+				}
+				ncall := *call
+				ncall.Args = nargs
+				fixes = append(fixes, edit.Fix(fmt.Sprintf("Remove %s from list of arguments", report.Render(pass, arg)), edit.ReplaceWithNode(pass.Fset, call, &ncall)))
+				report.Report(pass, arg, fmt.Sprintf("%s cannot be trapped (did you mean syscall.SIGTERM?)", report.Render(pass, arg)), report.Fixes(fixes...))
+			}
+			if isSignal(pass, arg, "syscall.SIGSTOP") {
+				nargs := make([]ast.Expr, 0, len(call.Args)-1)
+				for j, a := range call.Args {
+					if i == j {
+						continue
+					}
+					nargs = append(nargs, a)
+				}
+				ncall := *call
+				ncall.Args = nargs
+				report.Report(pass, arg, "syscall.SIGSTOP cannot be trapped", report.Fixes(edit.Fix("Remove syscall.SIGSTOP from list of arguments", edit.ReplaceWithNode(pass.Fset, call, &ncall))))
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1017/sa1017.go b/vendor/honnef.co/go/tools/staticcheck/sa1017/sa1017.go
new file mode 100644
index 0000000..f200d99
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1017/sa1017.go
@@ -0,0 +1,64 @@
+package sa1017
+
+import (
+	"go/constant"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1017",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Channels used with \'os/signal.Notify\' should be buffered`,
+		Text: `The \'os/signal\' package uses non-blocking channel sends when delivering
+signals. If the receiving end of the channel isn't ready and the
+channel is either unbuffered or full, the signal will be dropped. To
+avoid missing signals, the channel should be buffered and of the
+appropriate size. For a channel used for notification of just one
+signal value, a buffer of size 1 is sufficient.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"os/signal.Notify": func(call *callcheck.Call) {
+		arg := call.Args[knowledge.Arg("os/signal.Notify.c")]
+		if isUnbufferedChannel(arg.Value) {
+			arg.Invalid("the channel used with signal.Notify should be buffered")
+		}
+	},
+}
+
+func isUnbufferedChannel(v callcheck.Value) bool {
+	// TODO(dh): this check of course misses many cases of unbuffered
+	// channels, such as any in phi or sigma nodes. We'll eventually
+	// replace this function.
+	val := v.Value
+	if ct, ok := val.(*ir.ChangeType); ok {
+		val = ct.X
+	}
+	mk, ok := val.(*ir.MakeChan)
+	if !ok {
+		return false
+	}
+	if k, ok := mk.Size.(*ir.Const); ok && k.Value.Kind() == constant.Int {
+		if v, ok := constant.Int64Val(k.Value); ok && v == 0 {
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1018/sa1018.go b/vendor/honnef.co/go/tools/staticcheck/sa1018/sa1018.go
new file mode 100644
index 0000000..9981910
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1018/sa1018.go
@@ -0,0 +1,47 @@
+package sa1018
+
+import (
+	"fmt"
+	"go/constant"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1018",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `\'strings.Replace\' called with \'n == 0\', which does nothing`,
+		Text: `With \'n == 0\', zero instances will be replaced. To replace all
+instances, use a negative number, or use \'strings.ReplaceAll\'.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny, // MergeIfAny if we only flag literals, not named constants
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"strings.Replace": check("strings.Replace", 3),
+	"bytes.Replace":   check("bytes.Replace", 3),
+}
+
+func check(name string, arg int) callcheck.Check {
+	return func(call *callcheck.Call) {
+		arg := call.Args[arg]
+		if k, ok := arg.Value.Value.(*ir.Const); ok && k.Value.Kind() == constant.Int {
+			if v, ok := constant.Int64Val(k.Value); ok && v == 0 {
+				arg.Invalid(fmt.Sprintf("calling %s with n == 0 will return no results, did you mean -1?", name))
+			}
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1019/sa1019.go b/vendor/honnef.co/go/tools/staticcheck/sa1019/sa1019.go
new file mode 100644
index 0000000..0fb9b30
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1019/sa1019.go
@@ -0,0 +1,246 @@
+package sa1019
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+	"go/version"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/deprecated"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1019",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, deprecated.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Using a deprecated function, variable, constant or field`,
+		Since:    "2017.1",
+		Severity: lint.SeverityDeprecated,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func formatGoVersion(s string) string {
+	return "Go " + strings.TrimPrefix(s, "go")
+}
+
+func run(pass *analysis.Pass) (any, error) {
+	deprs := pass.ResultOf[deprecated.Analyzer].(deprecated.Result)
+
+	// Selectors can appear outside of function literals, e.g. when
+	// declaring package level variables.
+
+	isStdlibPath := func(path string) bool {
+		// Modules with no dot in the first path element are reserved for the standard library and tooling.
+		// This is the best we can currently do.
+		// Nobody tells us which import paths are part of the standard library.
+		//
+		// We check the entire path instead of just the first path element, because the standard library doesn't contain paths with any dots, anyway.
+
+		return !strings.Contains(path, ".")
+	}
+
+	handleDeprecation := func(depr *deprecated.IsDeprecated, node ast.Node, deprecatedObjName string, pkgPath string, tfn types.Object) {
+		std, ok := knowledge.StdlibDeprecations[deprecatedObjName]
+		if !ok && isStdlibPath(pkgPath) {
+			// Deprecated object in the standard library, but we don't know the details of the deprecation.
+			// Don't flag it at all, to avoid flagging an object that was deprecated in 1.N when targeting 1.N-1.
+			// See https://staticcheck.dev/issues/1108 for the background on this.
+			return
+		}
+		if ok {
+			// In the past, we made use of the AlternativeAvailableSince field. If a function was deprecated in Go
+			// 1.6 and an alternative had been available in Go 1.0, then we'd recommend using the alternative even
+			// if targeting Go 1.2. The idea was to suggest writing future-proof code by using already-existing
+			// alternatives. This had a major flaw, however: the user would need to use at least Go 1.6 for
+			// Staticcheck to know that the function had been deprecated. Thus, targeting Go 1.2 and using Go 1.2
+			// would behave differently from targeting Go 1.2 and using Go 1.6. This is especially a problem if the
+			// user tries to ignore the warning. Depending on the Go version in use, the ignore directive may or may
+			// not match, causing a warning of its own.
+			//
+			// To avoid this issue, we no longer try to be smart. We now only compare the targeted version against
+			// the version that deprecated an object.
+			//
+			// Unfortunately, this issue also applies to AlternativeAvailableSince == DeprecatedNeverUse. Even though it
+			// is only applied to seriously flawed API, such as broken cryptography, users may wish to ignore those
+			// warnings.
+			//
+			// See also https://staticcheck.dev/issues/1318.
+			if version.Compare(code.StdlibVersion(pass, node), std.DeprecatedSince) == -1 {
+				return
+			}
+		}
+
+		if tfn != nil {
+			if _, ok := deprs.Objects[tfn]; ok {
+				// functions that are deprecated may use deprecated
+				// symbols
+				return
+			}
+		}
+
+		if ok {
+			switch std.AlternativeAvailableSince {
+			case knowledge.DeprecatedNeverUse:
+				report.Report(pass, node,
+					fmt.Sprintf("%s has been deprecated since %s because it shouldn't be used: %s",
+						deprecatedObjName, formatGoVersion(std.DeprecatedSince), depr.Msg))
+			case std.DeprecatedSince, knowledge.DeprecatedUseNoLonger:
+				report.Report(pass, node,
+					fmt.Sprintf("%s has been deprecated since %s: %s",
+						deprecatedObjName, formatGoVersion(std.DeprecatedSince), depr.Msg))
+			default:
+				report.Report(pass, node,
+					fmt.Sprintf("%s has been deprecated since %s and an alternative has been available since %s: %s",
+						deprecatedObjName, formatGoVersion(std.DeprecatedSince), formatGoVersion(std.AlternativeAvailableSince), depr.Msg))
+			}
+		} else {
+			report.Report(pass, node, fmt.Sprintf("%s is deprecated: %s", deprecatedObjName, depr.Msg))
+		}
+	}
+
+	var tfn types.Object
+	stack := 0
+
+	checkIdentObj := func(sel *ast.SelectorExpr) bool {
+		obj := pass.TypesInfo.ObjectOf(sel.Sel)
+
+		if obj_, ok := obj.(*types.Func); ok {
+			obj = obj_.Origin()
+		}
+		if obj.Pkg() == nil {
+			return true
+		}
+		if obj.Pkg() == pass.Pkg {
+			// A package is allowed to use its own deprecated objects
+			return true
+		}
+
+		// A package "foo" has two related packages "foo_test" and "foo.test", for external tests and the package main
+		// generated by 'go test' respectively. "foo_test" can import and use "foo", "foo.test" imports and uses "foo"
+		// and "foo_test".
+
+		if strings.TrimSuffix(pass.Pkg.Path(), "_test") == obj.Pkg().Path() {
+			// foo_test (the external tests of foo) can use objects from foo.
+			return true
+		}
+		if strings.TrimSuffix(pass.Pkg.Path(), ".test") == obj.Pkg().Path() {
+			// foo.test (the main package of foo's tests) can use objects from foo.
+			return true
+		}
+		if strings.TrimSuffix(pass.Pkg.Path(), ".test") == strings.TrimSuffix(obj.Pkg().Path(), "_test") {
+			// foo.test (the main package of foo's tests) can use objects from foo's external tests.
+			return true
+		}
+
+		node := ast.Node(sel)
+		if pass.TypesInfo.Types[sel.X].IsType() {
+			node = sel.Sel
+		}
+		if depr, ok := deprs.Objects[obj]; ok {
+			handleDeprecation(depr, node, code.SelectorName(pass, sel), obj.Pkg().Path(), tfn)
+		}
+		return true
+	}
+
+	fn := func(node ast.Node, push bool) bool {
+		if !push {
+			stack--
+			return false
+		}
+		stack++
+		if stack == 1 {
+			tfn = nil
+		}
+		if fn, ok := node.(*ast.FuncDecl); ok {
+			tfn = pass.TypesInfo.ObjectOf(fn.Name)
+		}
+
+		switch v := node.(type) {
+		// FIXME(dh): this misses dot-imported objects
+		case *ast.SelectorExpr:
+			return checkIdentObj(v)
+
+		case *ast.CompositeLit:
+			litType := pass.TypesInfo.Types[v.Type]
+			if !litType.IsType() {
+				// This is probably unreachable.
+				return true
+			}
+			if _, ok := litType.Type.Underlying().(*types.Struct); !ok {
+				// We don't want to look at expressions in map initializers, for
+				// example.
+				return true
+			}
+			for _, elt := range v.Elts {
+				kv, ok := elt.(*ast.KeyValueExpr)
+				if !ok {
+					return true
+				}
+				key, ok := kv.Key.(*ast.Ident)
+				if !ok {
+					// This is probably unreachable, since we're looking at keys
+					// in a struct initializer.
+					return true
+				}
+				sel := &ast.SelectorExpr{X: v.Type, Sel: key}
+				checkIdentObj(sel)
+			}
+		}
+		return true
+	}
+
+	fn2 := func(node ast.Node) {
+		spec := node.(*ast.ImportSpec)
+		var imp *types.Package
+		if spec.Name != nil {
+			imp = pass.TypesInfo.ObjectOf(spec.Name).(*types.PkgName).Imported()
+		} else {
+			imp = pass.TypesInfo.Implicits[spec].(*types.PkgName).Imported()
+		}
+
+		p := spec.Path.Value
+		path := p[1 : len(p)-1]
+		if depr, ok := deprs.Packages[imp]; ok {
+			if path == "github.com/golang/protobuf/proto" {
+				gen, ok := code.Generator(pass, spec.Path.Pos())
+				if ok && gen == generated.ProtocGenGo {
+					return
+				}
+			}
+
+			if strings.TrimSuffix(pass.Pkg.Path(), "_test") == path {
+				// foo_test can import foo
+				return
+			}
+			if strings.TrimSuffix(pass.Pkg.Path(), ".test") == path {
+				// foo.test can import foo
+				return
+			}
+			if strings.TrimSuffix(pass.Pkg.Path(), ".test") == strings.TrimSuffix(path, "_test") {
+				// foo.test can import foo_test
+				return
+			}
+
+			handleDeprecation(depr, spec.Path, path, path, nil)
+		}
+	}
+	pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes(nil, fn)
+	code.Preorder(pass, fn2, (*ast.ImportSpec)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1020/sa1020.go b/vendor/honnef.co/go/tools/staticcheck/sa1020/sa1020.go
new file mode 100644
index 0000000..9d6256a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1020/sa1020.go
@@ -0,0 +1,99 @@
+package sa1020
+
+import (
+	"go/constant"
+	"net"
+	"strconv"
+	"strings"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1020",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(checkListenAddressRules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Using an invalid host:port pair with a \'net.Listen\'-related function`,
+		Text: `Functions such as \'net.Listen\', \'net.ListenTCP\', and similar,
+expect a valid network address in the form of host:port. The host, the port,
+or both, can be omitted, e.g. \'localhost:8080\', \':8080\' or \':\' are valid
+host:port pairs.
+See https://pkg.go.dev/net#Listen for the full documentation.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkListenAddressRules = map[string]callcheck.Check{
+	"net/http.ListenAndServe":    checkValidHostPort(0),
+	"net/http.ListenAndServeTLS": checkValidHostPort(0),
+}
+
+func checkValidHostPort(arg int) callcheck.Check {
+	return func(call *callcheck.Call) {
+		if !ValidHostPort(call.Args[arg].Value) {
+			const MsgInvalidHostPort = "invalid port or service name in host:port pair"
+			call.Args[arg].Invalid(MsgInvalidHostPort)
+		}
+	}
+}
+
+func ValidHostPort(v callcheck.Value) bool {
+	if k := callcheck.ExtractConstExpectKind(v, constant.String); k != nil {
+		s := constant.StringVal(k.Value)
+		if s == "" {
+			return true
+		}
+		_, port, err := net.SplitHostPort(s)
+		if err != nil {
+			return false
+		}
+		// TODO(dh): check hostname
+		if !validatePort(port) {
+			return false
+		}
+	}
+	return true
+}
+
+func validateServiceName(s string) bool {
+	if len(s) < 1 || len(s) > 15 {
+		return false
+	}
+	if s[0] == '-' || s[len(s)-1] == '-' {
+		return false
+	}
+	if strings.Contains(s, "--") {
+		return false
+	}
+	hasLetter := false
+	for _, r := range s {
+		if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') {
+			hasLetter = true
+			continue
+		}
+		if r >= '0' && r <= '9' {
+			continue
+		}
+		return false
+	}
+	return hasLetter
+}
+
+func validatePort(s string) bool {
+	n, err := strconv.ParseInt(s, 10, 64)
+	if err != nil {
+		return validateServiceName(s)
+	}
+	return n >= 0 && n <= 65535
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1021/sa1021.go b/vendor/honnef.co/go/tools/staticcheck/sa1021/sa1021.go
new file mode 100644
index 0000000..95fc960
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1021/sa1021.go
@@ -0,0 +1,49 @@
+package sa1021
+
+import (
+	"go/types"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1021",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Using \'bytes.Equal\' to compare two \'net.IP\'`,
+		Text: `A \'net.IP\' stores an IPv4 or IPv6 address as a slice of bytes. The
+length of the slice for an IPv4 address, however, can be either 4 or
+16 bytes long, using different ways of representing IPv4 addresses. In
+order to correctly compare two \'net.IP\'s, the \'net.IP.Equal\' method should
+be used, as it takes both representations into account.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"bytes.Equal": func(call *callcheck.Call) {
+		if isConvertedFrom(call.Args[knowledge.Arg("bytes.Equal.a")].Value, "net.IP") &&
+			isConvertedFrom(call.Args[knowledge.Arg("bytes.Equal.b")].Value, "net.IP") {
+			call.Invalid("use net.IP.Equal to compare net.IPs, not bytes.Equal")
+		}
+	},
+}
+
+// ConvertedFrom reports whether value v was converted from type typ.
+func isConvertedFrom(v callcheck.Value, typ string) bool {
+	change, ok := v.Value.(*ir.ChangeType)
+	return ok && types.TypeString(types.Unalias(change.X.Type()), nil) == typ
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1023/sa1023.go b/vendor/honnef.co/go/tools/staticcheck/sa1023/sa1023.go
new file mode 100644
index 0000000..22d21e2
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1023/sa1023.go
@@ -0,0 +1,72 @@
+package sa1023
+
+import (
+	"go/types"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1023",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Modifying the buffer in an \'io.Writer\' implementation`,
+		Text:     `\'Write\' must not modify the slice data, even temporarily.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	// TODO(dh): this might be a good candidate for taint analysis.
+	// Taint the argument as MUST_NOT_MODIFY, then propagate that
+	// through functions like bytes.Split
+
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		sig := fn.Signature
+		if fn.Name() != "Write" || sig.Recv() == nil {
+			continue
+		}
+		if !types.Identical(sig, knowledge.Signatures["(io.Writer).Write"]) {
+			continue
+		}
+
+		for _, block := range fn.Blocks {
+			for _, ins := range block.Instrs {
+				switch ins := ins.(type) {
+				case *ir.Store:
+					addr, ok := ins.Addr.(*ir.IndexAddr)
+					if !ok {
+						continue
+					}
+					if addr.X != fn.Params[1] {
+						continue
+					}
+					report.Report(pass, ins, "io.Writer.Write must not modify the provided buffer, not even temporarily")
+				case *ir.Call:
+					if !irutil.IsCallTo(ins.Common(), "append") {
+						continue
+					}
+					if ins.Common().Args[0] != fn.Params[1] {
+						continue
+					}
+					report.Report(pass, ins, "io.Writer.Write must not modify the provided buffer, not even temporarily")
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1024/sa1024.go b/vendor/honnef.co/go/tools/staticcheck/sa1024/sa1024.go
new file mode 100644
index 0000000..2ff4896
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1024/sa1024.go
@@ -0,0 +1,75 @@
+package sa1024
+
+import (
+	"go/constant"
+	"sort"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1024",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `A string cutset contains duplicate characters`,
+		Text: `The \'strings.TrimLeft\' and \'strings.TrimRight\' functions take cutsets, not
+prefixes. A cutset is treated as a set of characters to remove from a
+string. For example,
+
+    strings.TrimLeft("42133word", "1234")
+
+will result in the string \'"word"\' – any characters that are 1, 2, 3 or
+4 are cut from the left of the string.
+
+In order to remove one string from another, use \'strings.TrimPrefix\' instead.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"strings.Trim":      check,
+	"strings.TrimLeft":  check,
+	"strings.TrimRight": check,
+}
+
+func check(call *callcheck.Call) {
+	arg := call.Args[1]
+	if !isUniqueStringCutset(arg.Value) {
+		const MsgNonUniqueCutset = "cutset contains duplicate characters"
+		arg.Invalid(MsgNonUniqueCutset)
+	}
+}
+
+func isUniqueStringCutset(v callcheck.Value) bool {
+	if c := callcheck.ExtractConstExpectKind(v, constant.String); c != nil {
+		s := constant.StringVal(c.Value)
+		rs := runeSlice(s)
+		if len(rs) < 2 {
+			return true
+		}
+		sort.Sort(rs)
+		for i, r := range rs[1:] {
+			if rs[i] == r {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+type runeSlice []rune
+
+func (rs runeSlice) Len() int               { return len(rs) }
+func (rs runeSlice) Less(i int, j int) bool { return rs[i] < rs[j] }
+func (rs runeSlice) Swap(i int, j int)      { rs[i], rs[j] = rs[j], rs[i] }
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1025/sa1025.go b/vendor/honnef.co/go/tools/staticcheck/sa1025/sa1025.go
new file mode 100644
index 0000000..2ac361a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1025/sa1025.go
@@ -0,0 +1,92 @@
+package sa1025
+
+import (
+	"go/types"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1025",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `It is not possible to use \'(*time.Timer).Reset\''s return value correctly`,
+		Since:    "2019.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		for _, block := range fn.Blocks {
+			for _, ins := range block.Instrs {
+				call, ok := ins.(*ir.Call)
+				if !ok {
+					continue
+				}
+				if !irutil.IsCallTo(call.Common(), "(*time.Timer).Reset") {
+					continue
+				}
+				refs := call.Referrers()
+				if refs == nil {
+					continue
+				}
+				for _, ref := range *refs {
+					ifstmt, ok := ref.(*ir.If)
+					if !ok {
+						continue
+					}
+
+					found := false
+					for _, succ := range ifstmt.Block().Succs {
+						if len(succ.Preds) != 1 {
+							// Merge point, not a branch in the
+							// syntactical sense.
+
+							// FIXME(dh): this is broken for if
+							// statements a la "if x || y"
+							continue
+						}
+						irutil.Walk(succ, func(b *ir.BasicBlock) bool {
+							if !succ.Dominates(b) {
+								// We've reached the end of the branch
+								return false
+							}
+							for _, ins := range b.Instrs {
+								// TODO(dh): we should check that we're receiving from the
+								// channel of a time.Timer to further reduce false
+								// positives. Not a key priority, considering the rarity
+								// of Reset and the tiny likeliness of a false positive
+								//
+								// We intentionally don't handle aliases here, because
+								// we're only interested in time.Timer.C.
+								if ins, ok := ins.(*ir.Recv); ok && types.TypeString(ins.Chan.Type(), nil) == "<-chan time.Time" {
+									found = true
+									return false
+								}
+							}
+							return true
+						})
+					}
+
+					if found {
+						report.Report(pass, call, "it is not possible to use Reset's return value correctly, as there is a race condition between draining the channel and the new timer expiring")
+					}
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1026/sa1026.go b/vendor/honnef.co/go/tools/staticcheck/sa1026/sa1026.go
new file mode 100644
index 0000000..0aa99fc
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1026/sa1026.go
@@ -0,0 +1,79 @@
+package sa1026
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/staticcheck/fakejson"
+	"honnef.co/go/tools/staticcheck/fakexml"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1026",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Cannot marshal channels or functions`,
+		Since:    "2019.2",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"encoding/json.Marshal":           checkJSON,
+	"encoding/json.MarshalIndent":     checkJSON,
+	"encoding/xml.Marshal":            checkXML,
+	"encoding/xml.MarshalIndent":      checkXML,
+	"(*encoding/json.Encoder).Encode": checkJSON,
+	"(*encoding/xml.Encoder).Encode":  checkXML,
+}
+
+func checkJSON(call *callcheck.Call) {
+	arg := call.Args[0]
+	T := arg.Value.Value.Type()
+	if err := fakejson.Marshal(T); err != nil {
+		typ := types.TypeString(err.Type, types.RelativeTo(call.Parent.Pkg.Pkg))
+		if err.Path == "x" {
+			arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s", typ))
+		} else {
+			arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s, via %s", typ, err.Path))
+		}
+	}
+}
+
+func checkXML(call *callcheck.Call) {
+	arg := call.Args[0]
+	T := arg.Value.Value.Type()
+	if err := fakexml.Marshal(T); err != nil {
+		switch err := err.(type) {
+		case *fakexml.UnsupportedTypeError:
+			typ := types.TypeString(err.Type, types.RelativeTo(call.Parent.Pkg.Pkg))
+			if err.Path == "x" {
+				arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s", typ))
+			} else {
+				arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s, via %s", typ, err.Path))
+			}
+		case *fakexml.CyclicTypeError:
+			typ := types.TypeString(err.Type, types.RelativeTo(call.Parent.Pkg.Pkg))
+			if err.Path == "x" {
+				arg.Invalid(fmt.Sprintf("trying to marshal cyclic type %s", typ))
+			} else {
+				arg.Invalid(fmt.Sprintf("trying to marshal cyclic type %s, via %s", typ, err.Path))
+			}
+		case *fakexml.TagPathError:
+			// Vet does a better job at reporting this error, because it can flag the actual struct tags, not just the call to Marshal
+		default:
+			// These errors get reported by SA5008 instead, which can flag the actual fields, independently of calls to xml.Marshal
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1027/sa1027.go b/vendor/honnef.co/go/tools/staticcheck/sa1027/sa1027.go
new file mode 100644
index 0000000..95633c4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1027/sa1027.go
@@ -0,0 +1,76 @@
+package sa1027
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1027",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(checkAtomicAlignment),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Atomic access to 64-bit variable must be 64-bit aligned`,
+		Text: `On ARM, x86-32, and 32-bit MIPS, it is the caller's responsibility to
+arrange for 64-bit alignment of 64-bit words accessed atomically. The
+first word in a variable or in an allocated struct, array, or slice
+can be relied upon to be 64-bit aligned.
+
+You can use the structlayout tool to inspect the alignment of fields
+in a struct.`,
+		Since:    "2019.2",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkAtomicAlignment = map[string]callcheck.Check{
+	"sync/atomic.AddInt64":             checkAtomicAlignmentImpl,
+	"sync/atomic.AddUint64":            checkAtomicAlignmentImpl,
+	"sync/atomic.CompareAndSwapInt64":  checkAtomicAlignmentImpl,
+	"sync/atomic.CompareAndSwapUint64": checkAtomicAlignmentImpl,
+	"sync/atomic.LoadInt64":            checkAtomicAlignmentImpl,
+	"sync/atomic.LoadUint64":           checkAtomicAlignmentImpl,
+	"sync/atomic.StoreInt64":           checkAtomicAlignmentImpl,
+	"sync/atomic.StoreUint64":          checkAtomicAlignmentImpl,
+	"sync/atomic.SwapInt64":            checkAtomicAlignmentImpl,
+	"sync/atomic.SwapUint64":           checkAtomicAlignmentImpl,
+}
+
+func checkAtomicAlignmentImpl(call *callcheck.Call) {
+	sizes := call.Pass.TypesSizes
+	if sizes.Sizeof(types.Typ[types.Uintptr]) != 4 {
+		// Not running on a 32-bit platform
+		return
+	}
+	v, ok := irutil.Flatten(call.Args[0].Value.Value).(*ir.FieldAddr)
+	if !ok {
+		// TODO(dh): also check indexing into arrays and slices
+		return
+	}
+	T := v.X.Type().Underlying().(*types.Pointer).Elem().Underlying().(*types.Struct)
+	fields := make([]*types.Var, 0, T.NumFields())
+	for i := 0; i < T.NumFields() && i <= v.Field; i++ {
+		fields = append(fields, T.Field(i))
+	}
+
+	off := sizes.Offsetsof(fields)[v.Field]
+	if off%8 != 0 {
+		msg := fmt.Sprintf("address of non 64-bit aligned field %s passed to %s",
+			T.Field(v.Field).Name(),
+			irutil.CallName(call.Instr.Common()))
+		call.Invalid(msg)
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1028/sa1028.go b/vendor/honnef.co/go/tools/staticcheck/sa1028/sa1028.go
new file mode 100644
index 0000000..5ac1216
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1028/sa1028.go
@@ -0,0 +1,57 @@
+package sa1028
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1028",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `\'sort.Slice\' can only be used on slices`,
+		Text:     `The first argument of \'sort.Slice\' must be a slice.`,
+		Since:    "2020.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"sort.Slice":         check,
+	"sort.SliceIsSorted": check,
+	"sort.SliceStable":   check,
+}
+
+func check(call *callcheck.Call) {
+	c := call.Instr.Common().StaticCallee()
+	arg := call.Args[0]
+
+	T := arg.Value.Value.Type().Underlying()
+	switch T.(type) {
+	case *types.Interface:
+		// we don't know.
+		// TODO(dh): if the value is a phi node we can look at its edges
+		if k, ok := arg.Value.Value.(*ir.Const); ok && k.Value == nil {
+			// literal nil, e.g. sort.Sort(nil, ...)
+			arg.Invalid(fmt.Sprintf("cannot call %s on nil literal", c))
+		}
+	case *types.Slice:
+		// this is fine
+	default:
+		// this is not fine
+		arg.Invalid(fmt.Sprintf("%s must only be called on slices, was called on %s", c, T))
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1029/sa1029.go b/vendor/honnef.co/go/tools/staticcheck/sa1029/sa1029.go
new file mode 100644
index 0000000..c981baa
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1029/sa1029.go
@@ -0,0 +1,61 @@
+package sa1029
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1029",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(checkWithValueKeyRules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Inappropriate key in call to \'context.WithValue\'`,
+		Text: `The provided key must be comparable and should not be
+of type \'string\' or any other built-in type to avoid collisions between
+packages using context. Users of \'WithValue\' should define their own
+types for keys.
+
+To avoid allocating when assigning to an \'interface{}\',
+context keys often have concrete type \'struct{}\'. Alternatively,
+exported context key variables' static type should be a pointer or
+interface.`,
+		Since:    "2020.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkWithValueKeyRules = map[string]callcheck.Check{
+	"context.WithValue": checkWithValueKey,
+}
+
+func checkWithValueKey(call *callcheck.Call) {
+	arg := call.Args[1]
+	T := arg.Value.Value.Type()
+	if typ, ok := types.Unalias(T).(*types.Basic); ok {
+		if _, ok := T.(*types.Alias); ok {
+			arg.Invalid(
+				fmt.Sprintf("should not use built-in type %s (via alias %s) as key for value; define your own type to avoid collisions", typ, types.TypeString(T, types.RelativeTo(call.Pass.Pkg))))
+		} else {
+			arg.Invalid(
+				fmt.Sprintf("should not use built-in type %s as key for value; define your own type to avoid collisions", typ))
+		}
+	}
+	// TODO(dh): we should probably flag all anonymous structs, as they all risk collisions
+	if s, ok := T.(*types.Struct); ok && s.NumFields() == 0 {
+		arg.Invalid("should not use empty anonymous struct as key for value; define your own type to avoid collisions")
+	} else if !types.Comparable(T) {
+		arg.Invalid(fmt.Sprintf("keys used with context.WithValue must be comparable, but type %s is not comparable", T))
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1030/sa1030.go b/vendor/honnef.co/go/tools/staticcheck/sa1030/sa1030.go
new file mode 100644
index 0000000..0506938
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1030/sa1030.go
@@ -0,0 +1,134 @@
+package sa1030
+
+import (
+	"fmt"
+	"go/constant"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1030",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Invalid argument in call to a \'strconv\' function`,
+		Text: `This check validates the format, number base and bit size arguments of
+the various parsing and formatting functions in \'strconv\'.`,
+		Since:    "2021.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"strconv.ParseComplex": func(call *callcheck.Call) {
+		validateComplexBitSize(call.Args[knowledge.Arg("strconv.ParseComplex.bitSize")])
+	},
+	"strconv.ParseFloat": func(call *callcheck.Call) {
+		validateFloatBitSize(call.Args[knowledge.Arg("strconv.ParseFloat.bitSize")])
+	},
+	"strconv.ParseInt": func(call *callcheck.Call) {
+		validateContinuousBitSize(call.Args[knowledge.Arg("strconv.ParseInt.bitSize")], 0, 64)
+		validateIntBaseAllowZero(call.Args[knowledge.Arg("strconv.ParseInt.base")])
+	},
+	"strconv.ParseUint": func(call *callcheck.Call) {
+		validateContinuousBitSize(call.Args[knowledge.Arg("strconv.ParseUint.bitSize")], 0, 64)
+		validateIntBaseAllowZero(call.Args[knowledge.Arg("strconv.ParseUint.base")])
+	},
+
+	"strconv.FormatComplex": func(call *callcheck.Call) {
+		validateComplexFormat(call.Args[knowledge.Arg("strconv.FormatComplex.fmt")])
+		validateComplexBitSize(call.Args[knowledge.Arg("strconv.FormatComplex.bitSize")])
+	},
+	"strconv.FormatFloat": func(call *callcheck.Call) {
+		validateFloatFormat(call.Args[knowledge.Arg("strconv.FormatFloat.fmt")])
+		validateFloatBitSize(call.Args[knowledge.Arg("strconv.FormatFloat.bitSize")])
+	},
+	"strconv.FormatInt": func(call *callcheck.Call) {
+		validateIntBase(call.Args[knowledge.Arg("strconv.FormatInt.base")])
+	},
+	"strconv.FormatUint": func(call *callcheck.Call) {
+		validateIntBase(call.Args[knowledge.Arg("strconv.FormatUint.base")])
+	},
+
+	"strconv.AppendFloat": func(call *callcheck.Call) {
+		validateFloatFormat(call.Args[knowledge.Arg("strconv.AppendFloat.fmt")])
+		validateFloatBitSize(call.Args[knowledge.Arg("strconv.AppendFloat.bitSize")])
+	},
+	"strconv.AppendInt": func(call *callcheck.Call) {
+		validateIntBase(call.Args[knowledge.Arg("strconv.AppendInt.base")])
+	},
+	"strconv.AppendUint": func(call *callcheck.Call) {
+		validateIntBase(call.Args[knowledge.Arg("strconv.AppendUint.base")])
+	},
+}
+
+func validateDiscreetBitSize(arg *callcheck.Argument, size1 int, size2 int) {
+	if c := callcheck.ExtractConstExpectKind(arg.Value, constant.Int); c != nil {
+		val, _ := constant.Int64Val(c.Value)
+		if val != int64(size1) && val != int64(size2) {
+			arg.Invalid(fmt.Sprintf("'bitSize' argument is invalid, must be either %d or %d", size1, size2))
+		}
+	}
+}
+
+func validateComplexBitSize(arg *callcheck.Argument) { validateDiscreetBitSize(arg, 64, 128) }
+func validateFloatBitSize(arg *callcheck.Argument)   { validateDiscreetBitSize(arg, 32, 64) }
+
+func validateContinuousBitSize(arg *callcheck.Argument, min int, max int) {
+	if c := callcheck.ExtractConstExpectKind(arg.Value, constant.Int); c != nil {
+		val, _ := constant.Int64Val(c.Value)
+		if val < int64(min) || val > int64(max) {
+			arg.Invalid(fmt.Sprintf("'bitSize' argument is invalid, must be within %d and %d", min, max))
+		}
+	}
+}
+
+func validateIntBase(arg *callcheck.Argument) {
+	if c := callcheck.ExtractConstExpectKind(arg.Value, constant.Int); c != nil {
+		val, _ := constant.Int64Val(c.Value)
+		if val < 2 {
+			arg.Invalid("'base' must not be smaller than 2")
+		}
+		if val > 36 {
+			arg.Invalid("'base' must not be larger than 36")
+		}
+	}
+}
+
+func validateIntBaseAllowZero(arg *callcheck.Argument) {
+	if c := callcheck.ExtractConstExpectKind(arg.Value, constant.Int); c != nil {
+		val, _ := constant.Int64Val(c.Value)
+		if val < 2 && val != 0 {
+			arg.Invalid("'base' must not be smaller than 2, unless it is 0")
+		}
+		if val > 36 {
+			arg.Invalid("'base' must not be larger than 36")
+		}
+	}
+}
+
+func validateComplexFormat(arg *callcheck.Argument) {
+	validateFloatFormat(arg)
+}
+
+func validateFloatFormat(arg *callcheck.Argument) {
+	if c := callcheck.ExtractConstExpectKind(arg.Value, constant.Int); c != nil {
+		val, _ := constant.Int64Val(c.Value)
+		switch val {
+		case 'b', 'e', 'E', 'f', 'g', 'G', 'x', 'X':
+		default:
+			arg.Invalid(fmt.Sprintf("'fmt' argument is invalid: unknown format %q", rune(val)))
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1031/sa1031.go b/vendor/honnef.co/go/tools/staticcheck/sa1031/sa1031.go
new file mode 100644
index 0000000..52ba4dc
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1031/sa1031.go
@@ -0,0 +1,81 @@
+package sa1031
+
+import (
+	"go/constant"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1031",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(checkEncodeRules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Overlapping byte slices passed to an encoder`,
+		Text: `In an encoding function of the form \'Encode(dst, src)\', \'dst\' and
+\'src\' were found to reference the same memory. This can result in
+\'src\' bytes being overwritten before they are read, when the encoder
+writes more than one byte per \'src\' byte.`,
+		Since:    "2024.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkEncodeRules = map[string]callcheck.Check{
+	"encoding/ascii85.Encode":            checkNonOverlappingDstSrc(knowledge.Arg("encoding/ascii85.Encode.dst"), knowledge.Arg("encoding/ascii85.Encode.src")),
+	"(*encoding/base32.Encoding).Encode": checkNonOverlappingDstSrc(knowledge.Arg("(*encoding/base32.Encoding).Encode.dst"), knowledge.Arg("(*encoding/base32.Encoding).Encode.src")),
+	"(*encoding/base64.Encoding).Encode": checkNonOverlappingDstSrc(knowledge.Arg("(*encoding/base64.Encoding).Encode.dst"), knowledge.Arg("(*encoding/base64.Encoding).Encode.src")),
+	"encoding/hex.Encode":                checkNonOverlappingDstSrc(knowledge.Arg("encoding/hex.Encode.dst"), knowledge.Arg("encoding/hex.Encode.src")),
+}
+
+func checkNonOverlappingDstSrc(dstArg, srcArg int) callcheck.Check {
+	return func(call *callcheck.Call) {
+		dst := call.Args[dstArg]
+		src := call.Args[srcArg]
+		_, dstConst := irutil.Flatten(dst.Value.Value).(*ir.Const)
+		_, srcConst := irutil.Flatten(src.Value.Value).(*ir.Const)
+		if dstConst || srcConst {
+			// one of the arguments is nil, therefore overlap is not possible
+			return
+		}
+		if dst.Value == src.Value {
+			// simple case of f(b, b)
+			dst.Invalid("overlapping dst and src")
+			return
+		}
+		dstSlice, ok := irutil.Flatten(dst.Value.Value).(*ir.Slice)
+		if !ok {
+			return
+		}
+		srcSlice, ok := irutil.Flatten(src.Value.Value).(*ir.Slice)
+		if !ok {
+			return
+		}
+		if irutil.Flatten(dstSlice.X) != irutil.Flatten(srcSlice.X) {
+			// differing underlying arrays, all is well
+			return
+		}
+		l1 := irutil.Flatten(dstSlice.Low)
+		l2 := irutil.Flatten(srcSlice.Low)
+		c1, ok1 := l1.(*ir.Const)
+		c2, ok2 := l2.(*ir.Const)
+		if l1 == l2 || (ok1 && ok2 && constant.Compare(c1.Value, token.EQL, c2.Value)) {
+			// dst and src are the same slice, and have the same lower bound
+			dst.Invalid("overlapping dst and src")
+			return
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1032/sa1032.go b/vendor/honnef.co/go/tools/staticcheck/sa1032/sa1032.go
new file mode 100644
index 0000000..2ea6038
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1032/sa1032.go
@@ -0,0 +1,79 @@
+package sa1032
+
+import (
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA1032",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Wrong order of arguments to \'errors.Is\'`,
+		Text: `
+The first argument of the function \'errors.Is\' is the error
+that we have and the second argument is the error we're trying to match against.
+For example:
+
+	if errors.Is(err, io.EOF) { ... }
+
+This check detects some cases where the two arguments have been swapped. It
+flags any calls where the first argument is referring to a package-level error
+variable, such as
+
+	if errors.Is(io.EOF, err) { /* this is wrong */ }`,
+		Since:    "2024.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"errors.Is": validateIs,
+}
+
+func validateIs(call *callcheck.Call) {
+	if len(call.Args) != 2 {
+		return
+	}
+
+	global := func(arg *callcheck.Argument) *ir.Global {
+		v, ok := arg.Value.Value.(*ir.Load)
+		if !ok {
+			return nil
+		}
+		g, _ := v.X.(*ir.Global)
+		return g
+	}
+
+	x, y := call.Args[0], call.Args[1]
+	gx := global(x)
+	if gx == nil {
+		return
+	}
+
+	if pkgx := gx.Package().Pkg; pkgx != nil && pkgx.Path() != call.Pass.Pkg.Path() {
+		// x is a global that's not in this package
+
+		if gy := global(y); gy != nil {
+			if pkgy := gy.Package().Pkg; pkgy != nil && pkgy.Path() != call.Pass.Pkg.Path() {
+				// Both arguments refer to globals that aren't in this package. This can
+				// genuinely happen for external tests that check that one error "is"
+				// another one. net/http's external tests, for example, do
+				// `errors.Is(http.ErrNotSupported, errors.ErrUnsupported)`.
+				return
+			}
+		}
+
+		call.Invalid("arguments have the wrong order")
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa2000/sa2000.go b/vendor/honnef.co/go/tools/staticcheck/sa2000/sa2000.go
new file mode 100644
index 0000000..721f269
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa2000/sa2000.go
@@ -0,0 +1,47 @@
+package sa2000
+
+import (
+	"fmt"
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA2000",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `\'(*sync.WaitGroup).Add\' called inside the goroutine, leading to a race condition`,
+		Text: `\'(*sync.WaitGroup).Add\' must be called before starting the goroutine
+it is meant to wait for. Calling \'Add\' inside the goroutine creates a race
+condition between the call to \'Add\' and the call to \'Wait\'.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkWaitgroupAddQ = pattern.MustParse(`
+	(GoStmt
+		(CallExpr
+			(FuncLit
+				_
+				call@(CallExpr (Symbol "(*sync.WaitGroup).Add") _):_) _))`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, m := range code.Matches(pass, checkWaitgroupAddQ) {
+		call := m.State["call"].(ast.Node)
+		report.Report(pass, call, fmt.Sprintf("should call %s before starting the goroutine to avoid a race", report.Render(pass, call)))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa2001/sa2001.go b/vendor/honnef.co/go/tools/staticcheck/sa2001/sa2001.go
new file mode 100644
index 0000000..5e3f83e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa2001/sa2001.go
@@ -0,0 +1,110 @@
+package sa2001
+
+import (
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA2001",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Empty critical section, did you mean to defer the unlock?`,
+		Text: `Empty critical sections of the kind
+
+    mu.Lock()
+    mu.Unlock()
+
+are very often a typo, and the following was intended instead:
+
+    mu.Lock()
+    defer mu.Unlock()
+
+Do note that sometimes empty critical sections can be useful, as a
+form of signaling to wait on another goroutine. Many times, there are
+simpler ways of achieving the same effect. When that isn't the case,
+the code should be amply commented to avoid confusion. Combining such
+comments with a \'//lint:ignore\' directive can be used to suppress this
+rare false positive.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	if pass.Pkg.Path() == "sync_test" {
+		// exception for the sync package's tests
+		return nil, nil
+	}
+
+	// Initially it might seem like this check would be easier to
+	// implement using IR. After all, we're only checking for two
+	// consecutive method calls. In reality, however, there may be any
+	// number of other instructions between the lock and unlock, while
+	// still constituting an empty critical section. For example,
+	// given `m.x().Lock(); m.x().Unlock()`, there will be a call to
+	// x(). In the AST-based approach, this has a tiny potential for a
+	// false positive (the second call to x might be doing work that
+	// is protected by the mutex). In an IR-based approach, however,
+	// it would miss a lot of real bugs.
+
+	mutexParams := func(s ast.Stmt) (x ast.Expr, funcName string, ok bool) {
+		expr, ok := s.(*ast.ExprStmt)
+		if !ok {
+			return nil, "", false
+		}
+		call, ok := ast.Unparen(expr.X).(*ast.CallExpr)
+		if !ok {
+			return nil, "", false
+		}
+		sel, ok := call.Fun.(*ast.SelectorExpr)
+		if !ok {
+			return nil, "", false
+		}
+
+		fn, ok := pass.TypesInfo.ObjectOf(sel.Sel).(*types.Func)
+		if !ok {
+			return nil, "", false
+		}
+		sig := fn.Type().(*types.Signature)
+		if sig.Params().Len() != 0 || sig.Results().Len() != 0 {
+			return nil, "", false
+		}
+
+		return sel.X, fn.Name(), true
+	}
+
+	fn := func(node ast.Node) {
+		block := node.(*ast.BlockStmt)
+		if len(block.List) < 2 {
+			return
+		}
+		for i := range block.List[:len(block.List)-1] {
+			sel1, method1, ok1 := mutexParams(block.List[i])
+			sel2, method2, ok2 := mutexParams(block.List[i+1])
+
+			if !ok1 || !ok2 || report.Render(pass, sel1) != report.Render(pass, sel2) {
+				continue
+			}
+			if (method1 == "Lock" && method2 == "Unlock") ||
+				(method1 == "RLock" && method2 == "RUnlock") {
+				report.Report(pass, block.List[i+1], "empty critical section")
+			}
+		}
+	}
+	code.Preorder(pass, fn, (*ast.BlockStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa2002/sa2002.go b/vendor/honnef.co/go/tools/staticcheck/sa2002/sa2002.go
new file mode 100644
index 0000000..5641dd8
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa2002/sa2002.go
@@ -0,0 +1,93 @@
+package sa2002
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA2002",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Called \'testing.T.FailNow\' or \'SkipNow\' in a goroutine, which isn't allowed`,
+		Since:    "2017.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		for _, block := range fn.Blocks {
+			for _, ins := range block.Instrs {
+				gostmt, ok := ins.(*ir.Go)
+				if !ok {
+					continue
+				}
+				var fn *ir.Function
+				switch val := gostmt.Call.Value.(type) {
+				case *ir.Function:
+					fn = val
+				case *ir.MakeClosure:
+					fn = val.Fn.(*ir.Function)
+				default:
+					continue
+				}
+				if fn.Blocks == nil {
+					continue
+				}
+				for _, block := range fn.Blocks {
+					for _, ins := range block.Instrs {
+						call, ok := ins.(*ir.Call)
+						if !ok {
+							continue
+						}
+						if call.Call.IsInvoke() {
+							continue
+						}
+						callee := call.Call.StaticCallee()
+						if callee == nil {
+							continue
+						}
+						recv := callee.Signature.Recv()
+						if recv == nil {
+							continue
+						}
+						if !typeutil.IsPointerToTypeWithName(recv.Type(), "testing.common") {
+							continue
+						}
+						fn, ok := call.Call.StaticCallee().Object().(*types.Func)
+						if !ok {
+							continue
+						}
+						name := fn.Name()
+						switch name {
+						case "FailNow", "Fatal", "Fatalf", "SkipNow", "Skip", "Skipf":
+						default:
+							continue
+						}
+						// TODO(dh): don't report multiple diagnostics
+						// for multiple calls to T.Fatal, but do
+						// collect all of them as related information
+						report.Report(pass, gostmt, fmt.Sprintf("the goroutine calls T.%s, which must be called in the same goroutine as the test", name),
+							report.Related(call, fmt.Sprintf("call to T.%s", name)))
+					}
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa2003/sa2003.go b/vendor/honnef.co/go/tools/staticcheck/sa2003/sa2003.go
new file mode 100644
index 0000000..c6fb7f0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa2003/sa2003.go
@@ -0,0 +1,99 @@
+package sa2003
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA2003",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Deferred \'Lock\' right after locking, likely meant to defer \'Unlock\' instead`,
+		Text: `Deferring a call to \'Lock\' immediately after locking is almost always
+a typo. For example:
+
+    mu.Lock()
+    defer mu.Lock()
+
+While this does not strictly guarantee a deadlock depending on how the
+surrounding code is structured, it is highly likely to be a mistake.
+The intended code was likely this:
+
+    mu.Lock()
+    defer mu.Unlock()`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		for _, block := range fn.Blocks {
+			instrs := block.Instrs
+			if len(instrs) < 2 {
+				continue
+			}
+			for i, ins := range instrs[:len(instrs)-1] {
+				call, ok := ins.(*ir.Call)
+				if !ok {
+					continue
+				}
+				if !irutil.IsCallToAny(call.Common(), "(*sync.Mutex).Lock", "(*sync.RWMutex).RLock") {
+					continue
+				}
+				nins, ok := instrs[i+1].(*ir.Defer)
+				if !ok {
+					continue
+				}
+				if !irutil.IsCallToAny(&nins.Call, "(*sync.Mutex).Lock", "(*sync.RWMutex).RLock") {
+					continue
+				}
+				if call.Common().Args[0] != nins.Call.Args[0] {
+					continue
+				}
+				name := shortCallName(call.Common())
+				alt := ""
+				switch name {
+				case "Lock":
+					alt = "Unlock"
+				case "RLock":
+					alt = "RUnlock"
+				}
+				report.Report(pass, nins, fmt.Sprintf("deferring %s right after having locked already; did you mean to defer %s?", name, alt))
+			}
+		}
+	}
+	return nil, nil
+}
+
+func shortCallName(call *ir.CallCommon) string {
+	if call.IsInvoke() {
+		return ""
+	}
+	switch v := call.Value.(type) {
+	case *ir.Function:
+		fn, ok := v.Object().(*types.Func)
+		if !ok {
+			return ""
+		}
+		return fn.Name()
+	case *ir.Builtin:
+		return v.Name()
+	}
+	return ""
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa3000/sa3000.go b/vendor/honnef.co/go/tools/staticcheck/sa3000/sa3000.go
new file mode 100644
index 0000000..69d4dc1
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa3000/sa3000.go
@@ -0,0 +1,118 @@
+package sa3000
+
+import (
+	"go/ast"
+	"go/types"
+	"go/version"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA3000",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `\'TestMain\' doesn't call \'os.Exit\', hiding test failures`,
+		Text: `Test executables (and in turn \"go test\") exit with a non-zero status
+code if any tests failed. When specifying your own \'TestMain\' function,
+it is your responsibility to arrange for this, by calling \'os.Exit\' with
+the correct code. The correct code is returned by \'(*testing.M).Run\', so
+the usual way of implementing \'TestMain\' is to end it with
+\'os.Exit(m.Run())\'.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	var (
+		fnmain    ast.Node
+		callsExit bool
+		callsRun  bool
+		arg       types.Object
+	)
+	fn := func(node ast.Node, push bool) bool {
+		if !push {
+			if fnmain != nil && node == fnmain {
+				if !callsExit && callsRun {
+					report.Report(pass, fnmain, "TestMain should call os.Exit to set exit code")
+				}
+				fnmain = nil
+				callsExit = false
+				callsRun = false
+				arg = nil
+			}
+			return true
+		}
+
+		switch node := node.(type) {
+		case *ast.FuncDecl:
+			if fnmain != nil {
+				return true
+			}
+			if !isTestMain(pass, node) {
+				return false
+			}
+			if version.Compare(code.StdlibVersion(pass, node), "go1.15") >= 0 {
+				// Beginning with Go 1.15, the test framework will call
+				// os.Exit for us.
+				return false
+			}
+			fnmain = node
+			arg = pass.TypesInfo.ObjectOf(node.Type.Params.List[0].Names[0])
+			return true
+		case *ast.CallExpr:
+			if code.IsCallTo(pass, node, "os.Exit") {
+				callsExit = true
+				return false
+			}
+			sel, ok := node.Fun.(*ast.SelectorExpr)
+			if !ok {
+				return true
+			}
+			ident, ok := sel.X.(*ast.Ident)
+			if !ok {
+				return true
+			}
+			if arg != pass.TypesInfo.ObjectOf(ident) {
+				return true
+			}
+			if sel.Sel.Name == "Run" {
+				callsRun = true
+				return false
+			}
+			return true
+		default:
+			lint.ExhaustiveTypeSwitch(node)
+			return true
+		}
+	}
+	pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes([]ast.Node{(*ast.FuncDecl)(nil), (*ast.CallExpr)(nil)}, fn)
+	return nil, nil
+}
+
+func isTestMain(pass *analysis.Pass, decl *ast.FuncDecl) bool {
+	if decl.Name.Name != "TestMain" {
+		return false
+	}
+	if len(decl.Type.Params.List) != 1 {
+		return false
+	}
+	arg := decl.Type.Params.List[0]
+	if len(arg.Names) != 1 {
+		return false
+	}
+	return code.IsOfPointerToTypeWithName(pass, arg.Type, "testing.M")
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa3001/sa3001.go b/vendor/honnef.co/go/tools/staticcheck/sa3001/sa3001.go
new file mode 100644
index 0000000..eebd13b
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa3001/sa3001.go
@@ -0,0 +1,47 @@
+package sa3001
+
+import (
+	"fmt"
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA3001",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Assigning to \'b.N\' in benchmarks distorts the results`,
+		Text: `The testing package dynamically sets \'b.N\' to improve the reliability of
+benchmarks and uses it in computations to determine the duration of a
+single operation. Benchmark code must not alter \'b.N\' as this would
+falsify results.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var query = pattern.MustParse(`(AssignStmt sel@(SelectorExpr selX (Ident "N")) "=" [_] )`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, query) {
+		assign := node.(*ast.AssignStmt)
+		if !code.IsOfPointerToTypeWithName(pass, m.State["selX"].(ast.Expr), "testing.B") {
+			continue
+		}
+		report.Report(pass, assign,
+			fmt.Sprintf("should not assign to %s", report.Render(pass, m.State["sel"])))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4000/sa4000.go b/vendor/honnef.co/go/tools/staticcheck/sa4000/sa4000.go
new file mode 100644
index 0000000..bec2afd
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4000/sa4000.go
@@ -0,0 +1,217 @@
+package sa4000
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"reflect"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/edge"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4000",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Binary operator has identical expressions on both sides`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	var isFloat func(T types.Type) bool
+	isFloat = func(T types.Type) bool {
+		tset := typeutil.NewTypeSet(T)
+		if len(tset.Terms) == 0 {
+			// no terms, so floats are a possibility
+			return true
+		}
+		return tset.Any(func(term *types.Term) bool {
+			switch typ := term.Type().Underlying().(type) {
+			case *types.Basic:
+				kind := typ.Kind()
+				return kind == types.Float32 || kind == types.Float64
+			case *types.Array:
+				return isFloat(typ.Elem())
+			case *types.Struct:
+				for field := range typ.Fields() {
+					if isFloat(field.Type()) {
+						return true
+					}
+				}
+				return false
+			default:
+				return false
+			}
+		})
+	}
+
+	// TODO(dh): this check ignores the existence of side-effects and
+	// happily flags fn() == fn() – so far, we've had only two complains
+	// about false positives, and it's caught several bugs in real
+	// code.
+	//
+	// We special case functions from the math/rand package. Someone ran
+	// into the following false positive: "rand.Intn(2) - rand.Intn(2), which I wrote to generate values {-1, 0, 1} with {0.25, 0.5, 0.25} probability."
+
+	skipComparableCheck := func(c inspector.Cursor) bool {
+		op, ok := c.Node().(*ast.BinaryExpr)
+		if !ok {
+			return false
+		}
+		if clit, ok := op.X.(*ast.CompositeLit); !ok || len(clit.Elts) != 0 {
+			return false
+		}
+		if clit, ok := op.Y.(*ast.CompositeLit); !ok || len(clit.Elts) != 0 {
+			return false
+		}
+
+		// TODO(dh): we should probably skip ParenExprs, but users should
+		// probably not use unnecessary ParenExprs.
+		vspec, ok := c.Parent().Node().(*ast.ValueSpec)
+		if !ok {
+			return false
+		}
+		e, i := c.ParentEdge()
+		if e != edge.ValueSpec_Values {
+			return false
+		}
+		if vspec.Names[i].Name == "_" {
+			// `var _ = T{} == T{}` is permitted, as a compile-time
+			// check that T implements comparable.
+			return true
+		}
+		return false
+	}
+
+	for c := range code.Cursor(pass).Preorder((*ast.BinaryExpr)(nil)) {
+		node := c.Node()
+		op := node.(*ast.BinaryExpr)
+		switch op.Op {
+		case token.EQL, token.NEQ:
+			if skipComparableCheck(c) {
+				continue
+			}
+		case token.SUB, token.QUO, token.AND, token.REM, token.OR, token.XOR, token.AND_NOT,
+			token.LAND, token.LOR, token.LSS, token.GTR, token.LEQ, token.GEQ:
+		default:
+			// For some ops, such as + and *, it can make sense to
+			// have identical operands
+			continue
+		}
+
+		if isFloat(pass.TypesInfo.TypeOf(op.X)) {
+			// 'float  float' makes sense for several operators.
+			// We've tried keeping an exact list of operators to allow, but floats keep surprising us. Let's just give up instead.
+			continue
+		}
+
+		if reflect.TypeOf(op.X) != reflect.TypeOf(op.Y) {
+			continue
+		}
+		if report.Render(pass, op.X) != report.Render(pass, op.Y) {
+			continue
+		}
+		l1, ok1 := op.X.(*ast.BasicLit)
+		l2, ok2 := op.Y.(*ast.BasicLit)
+		if ok1 && ok2 && l1.Kind == token.INT && l2.Kind == l1.Kind && l1.Value == "0" && l2.Value == l1.Value && code.IsGenerated(pass, l1.Pos()) {
+			// cgo generates the following function call:
+			// _cgoCheckPointer(_cgoBase0, 0 == 0) – it uses 0 == 0
+			// instead of true in case the user shadowed the
+			// identifier. Ideally we'd restrict this exception to
+			// calls of _cgoCheckPointer, but it's not worth the
+			// hassle of keeping track of the stack.   
+			// are very rare to begin with, and we're mostly checking
+			// for them to catch typos such as 1 == 1 where the user
+			// meant to type i == 1. The odds of a false negative for
+			// 0 == 0 are slim.
+			continue
+		}
+
+		if expr, ok := op.X.(*ast.CallExpr); ok {
+			call := code.CallName(pass, expr)
+			switch call {
+			case "math/rand.Int",
+				"math/rand.Int31",
+				"math/rand.Int31n",
+				"math/rand.Int63",
+				"math/rand.Int63n",
+				"math/rand.Intn",
+				"math/rand.Uint32",
+				"math/rand.Uint64",
+				"math/rand.ExpFloat64",
+				"math/rand.Float32",
+				"math/rand.Float64",
+				"math/rand.NormFloat64",
+				"(*math/rand.Rand).Int",
+				"(*math/rand.Rand).Int31",
+				"(*math/rand.Rand).Int31n",
+				"(*math/rand.Rand).Int63",
+				"(*math/rand.Rand).Int63n",
+				"(*math/rand.Rand).Intn",
+				"(*math/rand.Rand).Uint32",
+				"(*math/rand.Rand).Uint64",
+				"(*math/rand.Rand).ExpFloat64",
+				"(*math/rand.Rand).Float32",
+				"(*math/rand.Rand).Float64",
+				"(*math/rand.Rand).NormFloat64",
+				"math/rand/v2.Int",
+				"math/rand/v2.Int32",
+				"math/rand/v2.Int32N",
+				"math/rand/v2.Int64",
+				"math/rand/v2.Int64N",
+				"math/rand/v2.IntN",
+				"math/rand/v2.N",
+				"math/rand/v2.Uint",
+				"math/rand/v2.Uint32",
+				"math/rand/v2.Uint32N",
+				"math/rand/v2.Uint64",
+				"math/rand/v2.Uint64N",
+				"math/rand/v2.UintN",
+				"math/rand/v2.ExpFloat64",
+				"math/rand/v2.Float32",
+				"math/rand/v2.Float64",
+				"math/rand/v2.NormFloat64",
+				"(*math/rand/v2.Rand).Int",
+				"(*math/rand/v2.Rand).Int32",
+				"(*math/rand/v2.Rand).Int32N",
+				"(*math/rand/v2.Rand).Int64",
+				"(*math/rand/v2.Rand).Int64N",
+				"(*math/rand/v2.Rand).IntN",
+				"(*math/rand/v2.Rand).N",
+				"(*math/rand/v2.Rand).Uint",
+				"(*math/rand/v2.Rand).Uint32",
+				"(*math/rand/v2.Rand).Uint32N",
+				"(*math/rand/v2.Rand).Uint64",
+				"(*math/rand/v2.Rand).Uint64N",
+				"(*math/rand/v2.Rand).UintN",
+				"(*math/rand/v2.Rand).ExpFloat64",
+				"(*math/rand/v2.Rand).Float32",
+				"(*math/rand/v2.Rand).Float64",
+				"(*math/rand/v2.Rand).NormFloat64":
+				continue
+			}
+		}
+
+		report.Report(pass, op, fmt.Sprintf("identical expressions on the left and right side of the '%s' operator", op.Op))
+	}
+
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4001/sa4001.go b/vendor/honnef.co/go/tools/staticcheck/sa4001/sa4001.go
new file mode 100644
index 0000000..2ca4370
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4001/sa4001.go
@@ -0,0 +1,52 @@
+package sa4001
+
+import (
+	"go/ast"
+	"regexp"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4001",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `\'&*x\' gets simplified to \'x\', it does not copy \'x\'`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	// cgo produces code like fn(&*_Cvar_kSomeCallbacks) which we don't
+	// want to flag.
+	cgoIdent               = regexp.MustCompile(`^_C(func|var)_.+$`)
+	checkIneffectiveCopyQ1 = pattern.MustParse(`(UnaryExpr "&" (StarExpr obj))`)
+	checkIneffectiveCopyQ2 = pattern.MustParse(`(StarExpr (UnaryExpr "&" _))`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		if m, ok := code.Match(pass, checkIneffectiveCopyQ1, node); ok {
+			if ident, ok := m.State["obj"].(*ast.Ident); !ok || !cgoIdent.MatchString(ident.Name) {
+				report.Report(pass, node, "&*x will be simplified to x. It will not copy x.")
+			}
+		} else if _, ok := code.Match(pass, checkIneffectiveCopyQ2, node); ok {
+			report.Report(pass, node, "*&x will be simplified to x. It will not copy x.")
+		}
+	}
+	code.Preorder(pass, fn, (*ast.UnaryExpr)(nil), (*ast.StarExpr)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4003/sa4003.go b/vendor/honnef.co/go/tools/staticcheck/sa4003/sa4003.go
new file mode 100644
index 0000000..eb36c41
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4003/sa4003.go
@@ -0,0 +1,224 @@
+package sa4003
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"math"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4003",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Comparing unsigned values against negative values is pointless`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	isobj := func(expr ast.Expr, name string) bool {
+		if name == "" {
+			return false
+		}
+		sel, ok := expr.(*ast.SelectorExpr)
+		if !ok {
+			return false
+		}
+		return typeutil.IsObject(pass.TypesInfo.ObjectOf(sel.Sel), name)
+	}
+
+	fn := func(node ast.Node) {
+		expr := node.(*ast.BinaryExpr)
+		tx := pass.TypesInfo.TypeOf(expr.X)
+		tset := typeutil.NewTypeSet(tx)
+
+		// We only check for the math constants and integer literals, not for
+		// all constant expressions. This is to avoid
+		// false positives when constant values differ under different build tags.
+		var (
+			maxMathConst string
+			minMathConst string
+			maxLiteral   constant.Value
+			minLiteral   constant.Value
+		)
+
+		allUnsigned := tset.All(func(t *types.Term) bool {
+			if basic, ok := t.Type().Underlying().(*types.Basic); ok {
+				return basic.Info()&types.IsUnsigned != 0
+			}
+			return false
+		})
+
+		if allUnsigned {
+			isZeroLiteral := func(expr ast.Expr) bool {
+				return code.IsIntegerLiteral(pass, expr, constant.MakeInt64(0))
+			}
+			if (expr.Op == token.LSS && isZeroLiteral(expr.Y)) ||
+				(expr.Op == token.GTR && isZeroLiteral(expr.X)) {
+				report.Report(
+					pass,
+					expr,
+					fmt.Sprintf("no value of type %s is less than 0", tx),
+					report.FilterGenerated(),
+				)
+			}
+			if expr.Op == token.GEQ && isZeroLiteral(expr.Y) ||
+				expr.Op == token.LEQ && isZeroLiteral(expr.X) {
+				report.Report(
+					pass,
+					expr,
+					fmt.Sprintf("every value of type %s is >= 0", tx),
+					report.FilterGenerated(),
+				)
+			}
+		}
+
+		core := tset.CoreType()
+		if core == nil {
+			// All remaining checks are only relevant when the type set
+			// contains a single underlying type.
+			//
+			// If we had a 'var x uint8 | uint16',
+			// then the type checker wouldn't permit a check such as
+			// 'if x <= math.MaxUint16', because the constant cannot be converted to all
+			// types in the type set.
+			return
+		}
+
+		basic, ok := core.(*types.Basic)
+		if !ok {
+			return
+		}
+
+		switch basic.Kind() {
+		case types.Uint8:
+			maxMathConst = "math.MaxUint8"
+			minLiteral = constant.MakeUint64(0)
+			maxLiteral = constant.MakeUint64(math.MaxUint8)
+		case types.Uint16:
+			maxMathConst = "math.MaxUint16"
+			minLiteral = constant.MakeUint64(0)
+			maxLiteral = constant.MakeUint64(math.MaxUint16)
+		case types.Uint32:
+			maxMathConst = "math.MaxUint32"
+			minLiteral = constant.MakeUint64(0)
+			maxLiteral = constant.MakeUint64(math.MaxUint32)
+		case types.Uint64:
+			maxMathConst = "math.MaxUint64"
+			minLiteral = constant.MakeUint64(0)
+			maxLiteral = constant.MakeUint64(math.MaxUint64)
+		case types.Uint:
+			// TODO(dh): we could chose 32 bit vs 64 bit depending on the
+			// file's build tags
+			maxMathConst = "math.MaxUint64"
+			minLiteral = constant.MakeUint64(0)
+			maxLiteral = constant.MakeUint64(math.MaxUint64)
+
+		case types.Int8:
+			minMathConst = "math.MinInt8"
+			maxMathConst = "math.MaxInt8"
+			minLiteral = constant.MakeInt64(math.MinInt8)
+			maxLiteral = constant.MakeInt64(math.MaxInt8)
+		case types.Int16:
+			minMathConst = "math.MinInt16"
+			maxMathConst = "math.MaxInt16"
+			minLiteral = constant.MakeInt64(math.MinInt16)
+			maxLiteral = constant.MakeInt64(math.MaxInt16)
+		case types.Int32:
+			minMathConst = "math.MinInt32"
+			maxMathConst = "math.MaxInt32"
+			minLiteral = constant.MakeInt64(math.MinInt32)
+			maxLiteral = constant.MakeInt64(math.MaxInt32)
+		case types.Int64:
+			minMathConst = "math.MinInt64"
+			maxMathConst = "math.MaxInt64"
+			minLiteral = constant.MakeInt64(math.MinInt64)
+			maxLiteral = constant.MakeInt64(math.MaxInt64)
+		case types.Int:
+			// TODO(dh): we could chose 32 bit vs 64 bit depending on the
+			// file's build tags
+			minMathConst = "math.MinInt64"
+			maxMathConst = "math.MaxInt64"
+			minLiteral = constant.MakeInt64(math.MinInt64)
+			maxLiteral = constant.MakeInt64(math.MaxInt64)
+		}
+
+		isLiteral := func(expr ast.Expr, c constant.Value) bool {
+			if c == nil {
+				return false
+			}
+			return code.IsIntegerLiteral(pass, expr, c)
+		}
+
+		x, y, op := expr.X, expr.Y, expr.Op
+		switch op {
+		case token.GEQ, token.GTR:
+		case token.LEQ:
+			x, y = y, x
+			op = token.GEQ
+		case token.LSS:
+			x, y = y, x
+			op = token.GTR
+		default:
+			return
+		}
+
+		if isobj(y, maxMathConst) || isLiteral(y, maxLiteral) {
+			report.Report(
+				pass,
+				expr,
+				fmt.Sprintf("no value of type %s is greater than %s", tx, maxMathConst),
+				report.FilterGenerated(),
+			)
+		}
+		if op == token.GEQ && (isobj(x, maxMathConst) || isLiteral(x, maxLiteral)) {
+			report.Report(
+				pass,
+				expr,
+				fmt.Sprintf("every value of type %s is <= %s", tx, maxMathConst),
+				report.FilterGenerated(),
+			)
+		}
+
+		if !allUnsigned {
+			if isobj(x, minMathConst) || isLiteral(x, minLiteral) {
+				report.Report(
+					pass,
+					expr,
+					fmt.Sprintf("no value of type %s is less than %s", tx, minMathConst),
+					report.FilterGenerated(),
+				)
+			}
+			if op == token.GEQ && (isobj(y, minMathConst) || isLiteral(y, minLiteral)) {
+				report.Report(
+					pass,
+					expr,
+					fmt.Sprintf("every value of type %s is >= %s", tx, minMathConst),
+					report.FilterGenerated(),
+				)
+			}
+		}
+
+	}
+	code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4004/sa4004.go b/vendor/honnef.co/go/tools/staticcheck/sa4004/sa4004.go
new file mode 100644
index 0000000..8f20350
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4004/sa4004.go
@@ -0,0 +1,159 @@
+package sa4004
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4004",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `The loop exits unconditionally after one iteration`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	// This check detects some, but not all unconditional loop exits.
+	// We give up in the following cases:
+	//
+	// - a goto anywhere in the loop. The goto might skip over our
+	// return, and we don't check that it doesn't.
+	//
+	// - any nested, unlabelled continue, even if it is in another
+	// loop or closure.
+	fn := func(node ast.Node) {
+		var body *ast.BlockStmt
+		switch fn := node.(type) {
+		case *ast.FuncDecl:
+			body = fn.Body
+		case *ast.FuncLit:
+			body = fn.Body
+		default:
+			lint.ExhaustiveTypeSwitch(node)
+		}
+		if body == nil {
+			return
+		}
+		labels := map[types.Object]ast.Stmt{}
+		ast.Inspect(body, func(node ast.Node) bool {
+			label, ok := node.(*ast.LabeledStmt)
+			if !ok {
+				return true
+			}
+			labels[pass.TypesInfo.ObjectOf(label.Label)] = label.Stmt
+			return true
+		})
+
+		ast.Inspect(body, func(node ast.Node) bool {
+			var loop ast.Node
+			var body *ast.BlockStmt
+			switch node := node.(type) {
+			case *ast.ForStmt:
+				body = node.Body
+				loop = node
+			case *ast.RangeStmt:
+				ok := typeutil.All(pass.TypesInfo.TypeOf(node.X), func(term *types.Term) bool {
+					switch term.Type().Underlying().(type) {
+					case *types.Slice, *types.Chan, *types.Basic, *types.Pointer, *types.Array:
+						return true
+					case *types.Map:
+						// looping once over a map is a valid pattern for
+						// getting an arbitrary element.
+						return false
+					case *types.Signature:
+						// we have no idea what semantics the function implements
+						return false
+					default:
+						lint.ExhaustiveTypeSwitch(term.Type().Underlying())
+						return false
+					}
+				})
+				if !ok {
+					return true
+				}
+				body = node.Body
+				loop = node
+			default:
+				return true
+			}
+			if len(body.List) < 2 {
+				// TODO(dh): is this check needed? when body.List < 2,
+				// then we can't find both an unconditional exit and a
+				// branching statement (if, ...). and we don't flag
+				// unconditional exits if there has been no branching
+				// in the loop body.
+
+				// avoid flagging the somewhat common pattern of using
+				// a range loop to get the first element in a slice,
+				// or the first rune in a string.
+				return true
+			}
+			var unconditionalExit ast.Node
+			hasBranching := false
+			for _, stmt := range body.List {
+				switch stmt := stmt.(type) {
+				case *ast.BranchStmt:
+					switch stmt.Tok {
+					case token.BREAK:
+						if stmt.Label == nil || labels[pass.TypesInfo.ObjectOf(stmt.Label)] == loop {
+							unconditionalExit = stmt
+						}
+					case token.CONTINUE:
+						if stmt.Label == nil || labels[pass.TypesInfo.ObjectOf(stmt.Label)] == loop {
+							unconditionalExit = nil
+							return false
+						}
+					}
+				case *ast.ReturnStmt:
+					unconditionalExit = stmt
+				case *ast.IfStmt, *ast.ForStmt, *ast.RangeStmt, *ast.SwitchStmt, *ast.SelectStmt:
+					hasBranching = true
+				}
+			}
+			if unconditionalExit == nil || !hasBranching {
+				return false
+			}
+			ast.Inspect(body, func(node ast.Node) bool {
+				if branch, ok := node.(*ast.BranchStmt); ok {
+
+					switch branch.Tok {
+					case token.GOTO:
+						unconditionalExit = nil
+						return false
+					case token.CONTINUE:
+						if branch.Label != nil && labels[pass.TypesInfo.ObjectOf(branch.Label)] != loop {
+							return true
+						}
+						unconditionalExit = nil
+						return false
+					}
+				}
+				return true
+			})
+			if unconditionalExit != nil {
+				report.Report(pass, unconditionalExit, "the surrounding loop is unconditionally terminated")
+			}
+			return true
+		})
+	}
+	code.Preorder(pass, fn, (*ast.FuncDecl)(nil), (*ast.FuncLit)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4005/sa4005.go b/vendor/honnef.co/go/tools/staticcheck/sa4005/sa4005.go
new file mode 100644
index 0000000..c46a038
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4005/sa4005.go
@@ -0,0 +1,134 @@
+package sa4005
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4005",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Field assignment that will never be observed. Did you mean to use a pointer receiver?`,
+		Since:    "2021.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	// The analysis only considers the receiver and its first level
+	// fields. It doesn't look at other parameters, nor at nested
+	// fields.
+	//
+	// The analysis does not detect all kinds of dead stores, only
+	// those of fields that are never read after the write. That is,
+	// we do not flag 'a.x = 1; a.x = 2; _ = a.x'. We might explore
+	// this again if we add support for SROA to go/ir and implement
+	// https://github.com/dominikh/go-tools/issues/191.
+
+	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR)
+fnLoop:
+	for _, fn := range irpkg.SrcFuncs {
+		if recv := fn.Signature.Recv(); recv == nil {
+			continue
+		} else if _, ok := recv.Type().Underlying().(*types.Struct); !ok {
+			continue
+		}
+
+		recv := fn.Params[0]
+		refs := *recv.Referrers()
+		if len(refs) != 1 {
+			continue
+		}
+		store, ok := refs[0].(*ir.Store)
+		if !ok {
+			continue
+		}
+		alloc, ok := store.Addr.(*ir.Alloc)
+		if !ok || alloc.Heap {
+			continue
+		}
+
+		reads := map[int][]ir.Instruction{}
+		writes := map[int][]ir.Instruction{}
+		for _, ref := range *alloc.Referrers() {
+			switch ref := ref.(type) {
+			case *ir.FieldAddr:
+				for _, refref := range *ref.Referrers() {
+					switch refref.(type) {
+					case *ir.Store:
+						writes[ref.Field] = append(writes[ref.Field], refref)
+					case *ir.Load:
+						reads[ref.Field] = append(reads[ref.Field], refref)
+					default:
+						// this should be safe… if the field address
+						// escapes, then alloc.Heap will be true.
+						// there should be no instructions left that,
+						// given this FieldAddr, without escaping, can
+						// effect a load or store.
+						continue
+					}
+				}
+			case *ir.Store:
+				// we could treat this as a store to every field, but
+				// we don't want to decide the semantics of partial
+				// struct initializers. should `v = t{x: 1}` also mark
+				// v.y as being written to?
+				if ref != store {
+					continue fnLoop
+				}
+			case *ir.Load:
+				// a load of the entire struct loads every field
+				for i := 0; i < recv.Type().Underlying().(*types.Struct).NumFields(); i++ {
+					reads[i] = append(reads[i], ref)
+				}
+			default:
+				continue fnLoop
+			}
+		}
+
+		offset := func(instr ir.Instruction) int {
+			for i, other := range instr.Block().Instrs {
+				if instr == other {
+					return i
+				}
+			}
+			panic("couldn't find instruction in its block")
+		}
+
+		for field, ws := range writes {
+			rs := reads[field]
+		wLoop:
+			for _, w := range ws {
+				for _, r := range rs {
+					if w.Block() == r.Block() {
+						if offset(r) > offset(w) {
+							// found a reachable read of our write
+							continue wLoop
+						}
+					} else if irutil.Reachable(w.Block(), r.Block()) {
+						// found a reachable read of our write
+						continue wLoop
+					}
+				}
+				fieldName := recv.Type().Underlying().(*types.Struct).Field(field).Name()
+				report.Report(pass, w, fmt.Sprintf("ineffective assignment to field %s.%s", recv.Type().(interface{ Obj() *types.TypeName }).Obj().Name(), fieldName))
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4006/sa4006.go b/vendor/honnef.co/go/tools/staticcheck/sa4006/sa4006.go
new file mode 100644
index 0000000..0486500
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4006/sa4006.go
@@ -0,0 +1,168 @@
+package sa4006
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4006",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `A value assigned to a variable is never read before being overwritten. Forgotten error check or dead code?`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		if irutil.IsExample(fn) {
+			continue
+		}
+		node := fn.Source()
+		if node == nil {
+			continue
+		}
+		if gen, ok := code.Generator(pass, node.Pos()); ok && gen == generated.Goyacc {
+			// Don't flag unused values in code generated by goyacc.
+			// There may be hundreds of those due to the way the state
+			// machine is constructed.
+			continue
+		}
+
+		switchTags := map[ir.Value]struct{}{}
+		ast.Inspect(node, func(node ast.Node) bool {
+			s, ok := node.(*ast.SwitchStmt)
+			if !ok {
+				return true
+			}
+			v, _ := fn.ValueForExpr(s.Tag)
+			switchTags[v] = struct{}{}
+			return true
+		})
+
+		// OPT(dh): don't use a map, possibly use a bitset
+		var hasUse func(v ir.Value, seen map[ir.Value]struct{}) bool
+		hasUse = func(v ir.Value, seen map[ir.Value]struct{}) bool {
+			if _, ok := seen[v]; ok {
+				return false
+			}
+			if _, ok := switchTags[v]; ok {
+				return true
+			}
+			refs := v.Referrers()
+			if refs == nil {
+				// TODO investigate why refs can be nil
+				return true
+			}
+			for _, ref := range *refs {
+				switch ref := ref.(type) {
+				case *ir.Phi:
+					if seen == nil {
+						seen = map[ir.Value]struct{}{}
+					}
+					seen[v] = struct{}{}
+					if hasUse(ref, seen) {
+						return true
+					}
+				default:
+					return true
+				}
+			}
+			return false
+		}
+
+		ast.Inspect(node, func(node ast.Node) bool {
+			inc, ok := node.(*ast.IncDecStmt)
+			if ok {
+				val, _ := fn.ValueForExpr(inc.X)
+				if val == nil {
+					return true
+				}
+				if _, ok := val.(*ir.Const); ok {
+					// a zero-valued constant, for example in 'foo := []string(nil)'
+					return true
+				}
+				if !hasUse(val, nil) {
+					report.Report(pass, inc, fmt.Sprintf("this value of %s is never used", inc.X))
+				}
+				return true
+			}
+
+			assign, ok := node.(*ast.AssignStmt)
+			if !ok {
+				return true
+			}
+			if len(assign.Lhs) > 1 && len(assign.Rhs) == 1 {
+				// Either a function call with multiple return values,
+				// or a comma-ok assignment
+
+				val, _ := fn.ValueForExpr(assign.Rhs[0])
+				if val == nil {
+					return true
+				}
+				refs := val.Referrers()
+				if refs == nil {
+					return true
+				}
+				for _, ref := range *refs {
+					ex, ok := ref.(*ir.Extract)
+					if !ok {
+						continue
+					}
+					if !hasUse(ex, nil) {
+						lhs := assign.Lhs[ex.Index]
+						if ident, ok := lhs.(*ast.Ident); !ok || ok && ident.Name == "_" {
+							continue
+						}
+						report.Report(pass, assign, fmt.Sprintf("this value of %s is never used", lhs))
+					}
+				}
+				return true
+			}
+			for i, lhs := range assign.Lhs {
+				rhs := assign.Rhs[i]
+				if ident, ok := lhs.(*ast.Ident); !ok || ok && ident.Name == "_" {
+					continue
+				}
+				val, _ := fn.ValueForExpr(rhs)
+				if val == nil {
+					if assign.Tok != token.ASSIGN { // +=, *=, etc.
+						val, _ = fn.ValueForExpr(lhs)
+					}
+					if val == nil {
+						continue
+					}
+				}
+
+				if _, ok := val.(*ir.Const); ok {
+					// a zero-valued constant, for example in 'foo := []string(nil)'
+					continue
+				}
+				if !hasUse(val, nil) {
+					report.Report(pass, assign, fmt.Sprintf("this value of %s is never used", lhs))
+				}
+			}
+			return true
+		})
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4008/sa4008.go b/vendor/honnef.co/go/tools/staticcheck/sa4008/sa4008.go
new file mode 100644
index 0000000..f6c89ee
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4008/sa4008.go
@@ -0,0 +1,100 @@
+package sa4008
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4008",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `The variable in the loop condition never changes, are you incrementing the wrong variable?`,
+		Text: `For example:
+
+	for i := 0; i < 10; j++ { ... }
+
+This may also occur when a loop can only execute once because of unconditional
+control flow that terminates the loop. For example, when a loop body contains an
+unconditional break, return, or panic:
+
+	func f() {
+		panic("oops")
+	}
+	func g() {
+		for i := 0; i < 10; i++ {
+			// f unconditionally calls panic, which means "i" is
+			// never incremented.
+			f()
+		}
+	}`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		cb := func(node ast.Node) bool {
+			loop, ok := node.(*ast.ForStmt)
+			if !ok {
+				return true
+			}
+			if loop.Init == nil || loop.Cond == nil || loop.Post == nil {
+				return true
+			}
+			init, ok := loop.Init.(*ast.AssignStmt)
+			if !ok || len(init.Lhs) != 1 || len(init.Rhs) != 1 {
+				return true
+			}
+			cond, ok := loop.Cond.(*ast.BinaryExpr)
+			if !ok {
+				return true
+			}
+			x, ok := cond.X.(*ast.Ident)
+			if !ok {
+				return true
+			}
+			lhs, ok := init.Lhs[0].(*ast.Ident)
+			if !ok {
+				return true
+			}
+			if pass.TypesInfo.ObjectOf(x) != pass.TypesInfo.ObjectOf(lhs) {
+				return true
+			}
+			if _, ok := loop.Post.(*ast.IncDecStmt); !ok {
+				return true
+			}
+
+			v, isAddr := fn.ValueForExpr(cond.X)
+			if v == nil || isAddr {
+				return true
+			}
+			switch v.(type) {
+			case *ir.Phi:
+				return true
+			case *ir.Load:
+				return true
+			}
+			report.Report(pass, cond, "variable in loop condition never changes")
+
+			return true
+		}
+		if source := fn.Source(); source != nil {
+			ast.Inspect(source, cb)
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4009/sa4009.go b/vendor/honnef.co/go/tools/staticcheck/sa4009/sa4009.go
new file mode 100644
index 0000000..7c94d5e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4009/sa4009.go
@@ -0,0 +1,105 @@
+package sa4009
+
+import (
+	"fmt"
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4009",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `A function argument is overwritten before its first use`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		cb := func(node ast.Node) bool {
+			var typ *ast.FuncType
+			var body *ast.BlockStmt
+			switch fn := node.(type) {
+			case *ast.FuncDecl:
+				typ = fn.Type
+				body = fn.Body
+			case *ast.FuncLit:
+				typ = fn.Type
+				body = fn.Body
+			}
+			if body == nil {
+				return true
+			}
+			if len(typ.Params.List) == 0 {
+				return true
+			}
+			for _, field := range typ.Params.List {
+				for _, arg := range field.Names {
+					obj := pass.TypesInfo.ObjectOf(arg)
+					var irobj *ir.Parameter
+					for _, param := range fn.Params {
+						if param.Object() == obj {
+							irobj = param
+							break
+						}
+					}
+					if irobj == nil {
+						continue
+					}
+					refs := irobj.Referrers()
+					if refs == nil {
+						continue
+					}
+					if len(*refs) != 0 {
+						continue
+					}
+
+					var assignment ast.Node
+					ast.Inspect(body, func(node ast.Node) bool {
+						if assignment != nil {
+							return false
+						}
+						assign, ok := node.(*ast.AssignStmt)
+						if !ok {
+							return true
+						}
+						for _, lhs := range assign.Lhs {
+							ident, ok := lhs.(*ast.Ident)
+							if !ok {
+								continue
+							}
+							if pass.TypesInfo.ObjectOf(ident) == obj {
+								assignment = assign
+								return false
+							}
+						}
+						return true
+					})
+					if assignment != nil {
+						report.Report(pass, arg, fmt.Sprintf("argument %s is overwritten before first use", arg),
+							report.Related(assignment, fmt.Sprintf("assignment to %s", arg)))
+					}
+				}
+			}
+			return true
+		}
+		if source := fn.Source(); source != nil {
+			ast.Inspect(source, cb)
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4010/sa4010.go b/vendor/honnef.co/go/tools/staticcheck/sa4010/sa4010.go
new file mode 100644
index 0000000..f445aa7
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4010/sa4010.go
@@ -0,0 +1,210 @@
+package sa4010
+
+import (
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4010",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `The result of \'append\' will never be observed anywhere`,
+		Text: `Calls to \'append\' produce a new slice value. When the result of
+\'append\' is assigned to a variable that is never subsequently read, the
+append operation may have an unintended effect.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	isAppend := func(ins ir.Value) bool {
+		call, ok := ins.(*ir.Call)
+		if !ok {
+			return false
+		}
+		if call.Call.IsInvoke() {
+			return false
+		}
+		if builtin, ok := call.Call.Value.(*ir.Builtin); !ok || builtin.Name() != "append" {
+			return false
+		}
+		return true
+	}
+
+	// We have to be careful about aliasing.
+	// Multiple slices may refer to the same backing array,
+	// making appends observable even when we don't see the result of append be used anywhere.
+	//
+	// We will have to restrict ourselves to slices that have been allocated within the function,
+	// haven't been sliced,
+	// and haven't been passed anywhere that could retain them (such as function calls or memory stores).
+	//
+	// We check whether an append should be flagged in two steps.
+	//
+	// In the first step, we look at the data flow graph, starting in reverse from the argument to append, till we reach the root.
+	// This graph must only consist of the following instructions:
+	//
+	// - phi
+	// - slice
+	// - const nil
+	// - MakeSlice
+	// - Alloc
+	// - calls to append
+	//
+	// If this step succeeds, we look at all referrers of the values found in the first step, recursively.
+	// These referrers must either be in the set of values found in the first step
+	// or fulfill the same type requirements as step 1, with the exception of appends, which are forbidden.
+	//
+	// If both steps succeed then we know that the backing array hasn't been aliased in an observable manner.
+	//
+	// We could relax these restrictions by making use of additional information:
+	// - if we passed the slice to a function that doesn't retain the slice then we can still flag it
+	// - if a slice has been sliced but is dead afterwards, we can flag appends to the new slice
+
+	// OPT(dh): We could cache the results of both validate functions.
+	// However, we only use these functions on values that we otherwise want to flag, which are very few.
+	// Not caching values hasn't increased the runtimes for the standard library nor k8s.
+	var validateArgument func(v ir.Value, seen map[ir.Value]struct{}) bool
+	validateArgument = func(v ir.Value, seen map[ir.Value]struct{}) bool {
+		if _, ok := seen[v]; ok {
+			// break cycle
+			return true
+		}
+		seen[v] = struct{}{}
+		switch v := v.(type) {
+		case *ir.Phi:
+			for _, edge := range v.Edges {
+				if !validateArgument(edge, seen) {
+					return false
+				}
+			}
+			return true
+		case *ir.Slice:
+			return validateArgument(v.X, seen)
+		case *ir.Const:
+			return true
+		case *ir.MakeSlice:
+			return true
+		case *ir.Alloc:
+			return true
+		case *ir.Call:
+			if isAppend(v) {
+				return validateArgument(v.Call.Args[0], seen)
+			}
+			return false
+		default:
+			return false
+		}
+	}
+
+	var validateReferrers func(v ir.Value, seen map[ir.Instruction]struct{}) bool
+	validateReferrers = func(v ir.Value, seen map[ir.Instruction]struct{}) bool {
+		if refs := v.Referrers(); refs != nil {
+			for _, ref := range *refs {
+				if _, ok := seen[ref]; ok {
+					continue
+				}
+
+				seen[ref] = struct{}{}
+				switch ref.(type) {
+				case *ir.Phi:
+				case *ir.Slice:
+				case *ir.MakeSlice:
+				case *ir.Alloc:
+				default:
+					return false
+				}
+
+				if ref, ok := ref.(ir.Value); ok {
+					if !validateReferrers(ref, seen) {
+						return false
+					}
+				}
+			}
+		}
+		return true
+	}
+
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		for _, block := range fn.Blocks {
+			for _, ins := range block.Instrs {
+				val, ok := ins.(ir.Value)
+				if !ok || !isAppend(val) {
+					continue
+				}
+
+				isUsed := false
+				visited := map[ir.Instruction]bool{}
+				var walkRefs func(refs []ir.Instruction)
+				walkRefs = func(refs []ir.Instruction) {
+				loop:
+					for _, ref := range refs {
+						if visited[ref] {
+							continue
+						}
+						visited[ref] = true
+						switch ref := ref.(type) {
+						case *ir.Phi:
+							walkRefs(*ref.Referrers())
+						case ir.Value:
+							if !isAppend(ref) {
+								isUsed = true
+							} else {
+								walkRefs(*ref.Referrers())
+							}
+						case ir.Instruction:
+							isUsed = true
+							break loop
+						}
+					}
+				}
+
+				refs := val.Referrers()
+				if refs == nil {
+					continue
+				}
+				walkRefs(*refs)
+
+				if isUsed {
+					continue
+				}
+
+				seen := map[ir.Value]struct{}{}
+				if !validateArgument(ins.(*ir.Call).Call.Args[0], seen) {
+					continue
+				}
+
+				seen2 := map[ir.Instruction]struct{}{}
+				for k := range seen {
+					if k, ok := k.(ir.Instruction); ok {
+						seen2[k] = struct{}{}
+					}
+				}
+				seen2[ins] = struct{}{}
+				failed := false
+				for v := range seen {
+					if !validateReferrers(v, seen2) {
+						failed = true
+						break
+					}
+				}
+				if !failed {
+					report.Report(pass, ins, "this result of append is never used, except maybe in other appends")
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4011/sa4011.go b/vendor/honnef.co/go/tools/staticcheck/sa4011/sa4011.go
new file mode 100644
index 0000000..7cfa2ea
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4011/sa4011.go
@@ -0,0 +1,88 @@
+package sa4011
+
+import (
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4011",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Break statement with no effect. Did you mean to break out of an outer loop?`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		var body *ast.BlockStmt
+		switch node := node.(type) {
+		case *ast.ForStmt:
+			body = node.Body
+		case *ast.RangeStmt:
+			body = node.Body
+		default:
+			lint.ExhaustiveTypeSwitch(node)
+		}
+		for _, stmt := range body.List {
+			var blocks [][]ast.Stmt
+			switch stmt := stmt.(type) {
+			case *ast.SwitchStmt:
+				for _, c := range stmt.Body.List {
+					blocks = append(blocks, c.(*ast.CaseClause).Body)
+				}
+			case *ast.SelectStmt:
+				for _, c := range stmt.Body.List {
+					blocks = append(blocks, c.(*ast.CommClause).Body)
+				}
+			default:
+				continue
+			}
+
+			for _, body := range blocks {
+				if len(body) == 0 {
+					continue
+				}
+				lasts := []ast.Stmt{body[len(body)-1]}
+				// TODO(dh): unfold all levels of nested block
+				// statements, not just a single level if statement
+				if ifs, ok := lasts[0].(*ast.IfStmt); ok {
+					if len(ifs.Body.List) == 0 {
+						continue
+					}
+					lasts[0] = ifs.Body.List[len(ifs.Body.List)-1]
+
+					if block, ok := ifs.Else.(*ast.BlockStmt); ok {
+						if len(block.List) != 0 {
+							lasts = append(lasts, block.List[len(block.List)-1])
+						}
+					}
+				}
+				for _, last := range lasts {
+					branch, ok := last.(*ast.BranchStmt)
+					if !ok || branch.Tok != token.BREAK || branch.Label != nil {
+						continue
+					}
+					report.Report(pass, branch, "ineffective break statement. Did you mean to break out of the outer loop?")
+				}
+			}
+		}
+	}
+	code.Preorder(pass, fn, (*ast.ForStmt)(nil), (*ast.RangeStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4012/sa4012.go b/vendor/honnef.co/go/tools/staticcheck/sa4012/sa4012.go
new file mode 100644
index 0000000..4234a28
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4012/sa4012.go
@@ -0,0 +1,51 @@
+package sa4012
+
+import (
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4012",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Comparing a value against NaN even though no value is equal to NaN`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	isNaN := func(v ir.Value) bool {
+		call, ok := v.(*ir.Call)
+		if !ok {
+			return false
+		}
+		return irutil.IsCallTo(call.Common(), "math.NaN")
+	}
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		for _, block := range fn.Blocks {
+			for _, ins := range block.Instrs {
+				ins, ok := ins.(*ir.BinOp)
+				if !ok {
+					continue
+				}
+				if isNaN(irutil.Flatten(ins.X)) || isNaN(irutil.Flatten(ins.Y)) {
+					report.Report(pass, ins, "no value is equal to NaN, not even NaN itself")
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4013/sa4013.go b/vendor/honnef.co/go/tools/staticcheck/sa4013/sa4013.go
new file mode 100644
index 0000000..1bd48f6
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4013/sa4013.go
@@ -0,0 +1,40 @@
+package sa4013
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4013",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Negating a boolean twice (\'!!b\') is the same as writing \'b\'. This is either redundant, or a typo.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkDoubleNegationQ = pattern.MustParse(`(UnaryExpr "!" single@(UnaryExpr "!" x))`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkDoubleNegationQ) {
+		report.Report(pass, node, "negating a boolean twice has no effect; is this a typo?", report.Fixes(
+			edit.Fix("Turn into single negation", edit.ReplaceWithNode(pass.Fset, node, m.State["single"].(ast.Node))),
+			edit.Fix("Remove double negation", edit.ReplaceWithNode(pass.Fset, node, m.State["x"].(ast.Node)))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4014/sa4014.go b/vendor/honnef.co/go/tools/staticcheck/sa4014/sa4014.go
new file mode 100644
index 0000000..de11648
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4014/sa4014.go
@@ -0,0 +1,78 @@
+package sa4014
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4014",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `An if/else if chain has repeated conditions and no side-effects; if the condition didn't match the first time, it won't match the second time, either`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	seen := map[ast.Node]bool{}
+
+	var collectConds func(ifstmt *ast.IfStmt, conds []ast.Expr) ([]ast.Expr, bool)
+	collectConds = func(ifstmt *ast.IfStmt, conds []ast.Expr) ([]ast.Expr, bool) {
+		seen[ifstmt] = true
+		// Bail if any if-statement has an Init statement or side effects in its condition
+		if ifstmt.Init != nil {
+			return nil, false
+		}
+		if code.MayHaveSideEffects(pass, ifstmt.Cond, nil) {
+			return nil, false
+		}
+
+		conds = append(conds, ifstmt.Cond)
+		if elsestmt, ok := ifstmt.Else.(*ast.IfStmt); ok {
+			return collectConds(elsestmt, conds)
+		}
+		return conds, true
+	}
+	fn := func(node ast.Node) {
+		ifstmt := node.(*ast.IfStmt)
+		if seen[ifstmt] {
+			// this if-statement is part of an if/else-if chain that we've already processed
+			return
+		}
+		if ifstmt.Else == nil {
+			// there can be at most one condition
+			return
+		}
+		conds, ok := collectConds(ifstmt, nil)
+		if !ok {
+			return
+		}
+		if len(conds) < 2 {
+			return
+		}
+		counts := map[string]int{}
+		for _, cond := range conds {
+			s := report.Render(pass, cond)
+			counts[s]++
+			if counts[s] == 2 {
+				report.Report(pass, cond, "this condition occurs multiple times in this if/else if chain")
+			}
+		}
+	}
+	code.Preorder(pass, fn, (*ast.IfStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4015/sa4015.go b/vendor/honnef.co/go/tools/staticcheck/sa4015/sa4015.go
new file mode 100644
index 0000000..d94a89d
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4015/sa4015.go
@@ -0,0 +1,56 @@
+package sa4015
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4015",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(checkMathIntRules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Calling functions like \'math.Ceil\' on floats converted from integers doesn't do anything useful`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkMathIntRules = map[string]callcheck.Check{
+	"math.Ceil":  pointlessIntMath,
+	"math.Floor": pointlessIntMath,
+	"math.IsNaN": pointlessIntMath,
+	"math.Trunc": pointlessIntMath,
+	"math.IsInf": pointlessIntMath,
+}
+
+func pointlessIntMath(call *callcheck.Call) {
+	if ConvertedFromInt(call.Args[0].Value) {
+		call.Invalid(fmt.Sprintf("calling %s on a converted integer is pointless", irutil.CallName(call.Instr.Common())))
+	}
+}
+
+func ConvertedFromInt(v callcheck.Value) bool {
+	conv, ok := v.Value.(*ir.Convert)
+	if !ok {
+		return false
+	}
+	return typeutil.NewTypeSet(conv.X.Type()).All(func(t *types.Term) bool {
+		b, ok := t.Type().Underlying().(*types.Basic)
+		return ok && b.Info()&types.IsInteger != 0
+	})
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4016/sa4016.go b/vendor/honnef.co/go/tools/staticcheck/sa4016/sa4016.go
new file mode 100644
index 0000000..993ea65
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4016/sa4016.go
@@ -0,0 +1,116 @@
+package sa4016
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+	"honnef.co/go/tools/go/types/typeutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4016",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Certain bitwise operations, such as \'x ^ 0\', do not do anything useful`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny, // MergeIfAny if we only flag literals, not named constants
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		binop := node.(*ast.BinaryExpr)
+		if !typeutil.All(pass.TypesInfo.TypeOf(binop), func(term *types.Term) bool {
+			b, ok := term.Type().Underlying().(*types.Basic)
+			if !ok {
+				return false
+			}
+			return (b.Info() & types.IsInteger) != 0
+		}) {
+			return
+		}
+		switch binop.Op {
+		case token.AND, token.OR, token.XOR:
+		default:
+			// we do not flag shifts because too often, x<<0 is part
+			// of a pattern, x<<0, x<<8, x<<16, ...
+			return
+		}
+		if y, ok := binop.Y.(*ast.Ident); ok {
+			obj, ok := pass.TypesInfo.ObjectOf(y).(*types.Const)
+			if !ok {
+				return
+			}
+			if obj.Pkg() != pass.Pkg {
+				// identifier was dot-imported
+				return
+			}
+			if v, _ := constant.Int64Val(obj.Val()); v != 0 {
+				return
+			}
+			path, _ := astutil.PathEnclosingInterval(code.File(pass, obj), obj.Pos(), obj.Pos())
+			if len(path) < 2 {
+				return
+			}
+			spec, ok := path[1].(*ast.ValueSpec)
+			if !ok {
+				return
+			}
+			if len(spec.Names) != 1 || len(spec.Values) != 1 {
+				// TODO(dh): we could support this
+				return
+			}
+			ident, ok := spec.Values[0].(*ast.Ident)
+			if !ok {
+				return
+			}
+			if !isIota(pass.TypesInfo.ObjectOf(ident)) {
+				return
+			}
+			switch binop.Op {
+			case token.AND:
+				report.Report(pass, node,
+					fmt.Sprintf("%s always equals 0; %s is defined as iota and has value 0, maybe %s is meant to be 1 << iota?", report.Render(pass, binop), report.Render(pass, binop.Y), report.Render(pass, binop.Y)))
+			case token.OR, token.XOR:
+				report.Report(pass, node,
+					fmt.Sprintf("%s always equals %s; %s is defined as iota and has value 0, maybe %s is meant to be 1 << iota?", report.Render(pass, binop), report.Render(pass, binop.X), report.Render(pass, binop.Y), report.Render(pass, binop.Y)))
+			}
+		} else if code.IsIntegerLiteral(pass, binop.Y, constant.MakeInt64(0)) {
+			switch binop.Op {
+			case token.AND:
+				report.Report(pass, node, fmt.Sprintf("%s always equals 0", report.Render(pass, binop)))
+			case token.OR, token.XOR:
+				report.Report(pass, node, fmt.Sprintf("%s always equals %s", report.Render(pass, binop), report.Render(pass, binop.X)))
+			}
+		}
+	}
+	code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
+	return nil, nil
+}
+
+func isIota(obj types.Object) bool {
+	if obj.Name() != "iota" {
+		return false
+	}
+	c, ok := obj.(*types.Const)
+	if !ok {
+		return false
+	}
+	return c.Pkg() == nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4017/sa4017.go b/vendor/honnef.co/go/tools/staticcheck/sa4017/sa4017.go
new file mode 100644
index 0000000..8302249
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4017/sa4017.go
@@ -0,0 +1,85 @@
+package sa4017
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/purity"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4017",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer, purity.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Discarding the return values of a function without side effects, making the call pointless`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	pure := pass.ResultOf[purity.Analyzer].(purity.Result)
+
+fnLoop:
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		if code.IsInTest(pass, fn) {
+			params := fn.Signature.Params()
+			for param := range params.Variables() {
+				if typeutil.IsPointerToTypeWithName(param.Type(), "testing.B") {
+					// Ignore discarded pure functions in code related
+					// to benchmarks. Instead of matching BenchmarkFoo
+					// functions, we match any function accepting a
+					// *testing.B. Benchmarks sometimes call generic
+					// functions for doing the actual work, and
+					// checking for the parameter is a lot easier and
+					// faster than analyzing call trees.
+					continue fnLoop
+				}
+			}
+		}
+
+		for _, b := range fn.Blocks {
+			for _, ins := range b.Instrs {
+				ins, ok := ins.(*ir.Call)
+				if !ok {
+					continue
+				}
+				refs := ins.Referrers()
+				if refs == nil || len(*refs) > 0 {
+					continue
+				}
+
+				callee := ins.Common().StaticCallee()
+				if callee == nil {
+					continue
+				}
+				if callee.Object() == nil {
+					// TODO(dh): support anonymous functions
+					continue
+				}
+				if _, ok := pure[callee.Object().(*types.Func)]; ok {
+					if pass.Pkg.Path() == "fmt_test" && callee.Object().(*types.Func).FullName() == "fmt.Sprintf" {
+						// special case for benchmarks in the fmt package
+						continue
+					}
+					report.Report(pass, ins, fmt.Sprintf("%s doesn't have side effects and its return value is ignored", callee.Object().Name()))
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4018/sa4018.go b/vendor/honnef.co/go/tools/staticcheck/sa4018/sa4018.go
new file mode 100644
index 0000000..e4c4999
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4018/sa4018.go
@@ -0,0 +1,61 @@
+package sa4018
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"reflect"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/facts/purity"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4018",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer, purity.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Self-assignment of variables`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	pure := pass.ResultOf[purity.Analyzer].(purity.Result)
+
+	fn := func(node ast.Node) {
+		assign := node.(*ast.AssignStmt)
+		if assign.Tok != token.ASSIGN || len(assign.Lhs) != len(assign.Rhs) {
+			return
+		}
+		for i, lhs := range assign.Lhs {
+			rhs := assign.Rhs[i]
+			if reflect.TypeOf(lhs) != reflect.TypeOf(rhs) {
+				continue
+			}
+			if code.MayHaveSideEffects(pass, lhs, pure) || code.MayHaveSideEffects(pass, rhs, pure) {
+				continue
+			}
+
+			rlh := report.Render(pass, lhs)
+			rrh := report.Render(pass, rhs)
+			if rlh == rrh {
+				report.Report(pass, assign, fmt.Sprintf("self-assignment of %s to %s", rrh, rlh), report.FilterGenerated())
+			}
+		}
+	}
+	code.Preorder(pass, fn, (*ast.AssignStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4019/sa4019.go b/vendor/honnef.co/go/tools/staticcheck/sa4019/sa4019.go
new file mode 100644
index 0000000..dd4f0e6
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4019/sa4019.go
@@ -0,0 +1,82 @@
+package sa4019
+
+import (
+	"fmt"
+	"go/ast"
+	"sort"
+	"strings"
+
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4019",
+		Run:      run,
+		Requires: []*analysis.Analyzer{generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Multiple, identical build constraints in the same file`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func buildTagsIdentical(s1, s2 []string) bool {
+	if len(s1) != len(s2) {
+		return false
+	}
+	s1s := make([]string, len(s1))
+	copy(s1s, s1)
+	sort.Strings(s1s)
+	s2s := make([]string, len(s2))
+	copy(s2s, s2)
+	sort.Strings(s2s)
+	for i, s := range s1s {
+		if s != s2s[i] {
+			return false
+		}
+	}
+	return true
+}
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, f := range pass.Files {
+		constraints := buildTags(f)
+		for i, constraint1 := range constraints {
+			for j, constraint2 := range constraints {
+				if i >= j {
+					continue
+				}
+				if buildTagsIdentical(constraint1, constraint2) {
+					msg := fmt.Sprintf("identical build constraints %q and %q",
+						strings.Join(constraint1, " "),
+						strings.Join(constraint2, " "))
+					report.Report(pass, f, msg, report.FilterGenerated(), report.ShortRange())
+				}
+			}
+		}
+	}
+	return nil, nil
+}
+
+func buildTags(f *ast.File) [][]string {
+	var out [][]string
+	for line := range strings.SplitSeq(astutil.Preamble(f), "\n") {
+		if !strings.HasPrefix(line, "+build ") {
+			continue
+		}
+		line = strings.TrimSpace(strings.TrimPrefix(line, "+build "))
+		fields := strings.Fields(line)
+		out = append(out, fields)
+	}
+	return out
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4020/sa4020.go b/vendor/honnef.co/go/tools/staticcheck/sa4020/sa4020.go
new file mode 100644
index 0000000..8ff2fb3
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4020/sa4020.go
@@ -0,0 +1,172 @@
+package sa4020
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/exp/typeparams"
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4020",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Unreachable case clause in a type switch`,
+		Text: `In a type switch like the following
+
+    type T struct{}
+    func (T) Read(b []byte) (int, error) { return 0, nil }
+
+    var v any = T{}
+
+    switch v.(type) {
+    case io.Reader:
+        // ...
+    case T:
+        // unreachable
+    }
+
+the second case clause can never be reached because \'T\' implements
+\'io.Reader\' and case clauses are evaluated in source order.
+
+Another example:
+
+    type T struct{}
+    func (T) Read(b []byte) (int, error) { return 0, nil }
+    func (T) Close() error { return nil }
+
+    var v any = T{}
+
+    switch v.(type) {
+    case io.Reader:
+        // ...
+    case io.ReadCloser:
+        // unreachable
+    }
+
+Even though \'T\' has a \'Close\' method and thus implements \'io.ReadCloser\',
+\'io.Reader\' will always match first. The method set of \'io.Reader\' is a
+subset of \'io.ReadCloser\'. Thus it is impossible to match the second
+case without matching the first case.
+
+
+Structurally equivalent interfaces
+
+A special case of the previous example are structurally identical
+interfaces. Given these declarations
+
+    type T error
+    type V error
+
+    func doSomething() error {
+        err, ok := doAnotherThing()
+        if ok {
+            return T(err)
+        }
+
+        return U(err)
+    }
+
+the following type switch will have an unreachable case clause:
+
+    switch doSomething().(type) {
+    case T:
+        // ...
+    case V:
+        // unreachable
+    }
+
+\'T\' will always match before V because they are structurally equivalent
+and therefore \'doSomething()\''s return value implements both.`,
+		Since:    "2019.2",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	// Check if T subsumes V in a type switch. T subsumes V if T is an interface and T's method set is a subset of V's method set.
+	subsumes := func(T, V types.Type) bool {
+		if typeparams.IsTypeParam(T) {
+			return false
+		}
+		tIface, ok := T.Underlying().(*types.Interface)
+		if !ok {
+			return false
+		}
+
+		return types.Implements(V, tIface)
+	}
+
+	subsumesAny := func(Ts, Vs []types.Type) (types.Type, types.Type, bool) {
+		for _, T := range Ts {
+			for _, V := range Vs {
+				if subsumes(T, V) {
+					return T, V, true
+				}
+			}
+		}
+
+		return nil, nil, false
+	}
+
+	fn := func(node ast.Node) {
+		tsStmt := node.(*ast.TypeSwitchStmt)
+
+		type ccAndTypes struct {
+			cc    *ast.CaseClause
+			types []types.Type
+		}
+
+		// All asserted types in the order of case clauses.
+		ccs := make([]ccAndTypes, 0, len(tsStmt.Body.List))
+		for _, stmt := range tsStmt.Body.List {
+			cc, _ := stmt.(*ast.CaseClause)
+
+			// Exclude the 'default' case.
+			if len(cc.List) == 0 {
+				continue
+			}
+
+			Ts := make([]types.Type, 0, len(cc.List))
+			for _, expr := range cc.List {
+				// Exclude the 'nil' value from any 'case' statement (it is always reachable).
+				if typ := pass.TypesInfo.TypeOf(expr); typ != types.Typ[types.UntypedNil] {
+					Ts = append(Ts, typ)
+				}
+			}
+
+			ccs = append(ccs, ccAndTypes{cc: cc, types: Ts})
+		}
+
+		if len(ccs) <= 1 {
+			// Zero or one case clauses, nothing to check.
+			return
+		}
+
+		// Check if case clauses following cc have types that are subsumed by cc.
+		for i, cc := range ccs[:len(ccs)-1] {
+			for _, next := range ccs[i+1:] {
+				if T, V, yes := subsumesAny(cc.types, next.types); yes {
+					report.Report(pass, next.cc, fmt.Sprintf("unreachable case clause: %s will always match before %s", T.String(), V.String()),
+						report.ShortRange())
+				}
+			}
+		}
+	}
+
+	code.Preorder(pass, fn, (*ast.TypeSwitchStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4021/sa4021.go b/vendor/honnef.co/go/tools/staticcheck/sa4021/sa4021.go
new file mode 100644
index 0000000..6f2133c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4021/sa4021.go
@@ -0,0 +1,36 @@
+package sa4021
+
+import (
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4021",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `\"x = append(y)\" is equivalent to \"x = y\"`,
+		Since:    "2019.2",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var checkSingleArgAppendQ = pattern.MustParse(`(CallExpr (Builtin "append") [_])`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node := range code.Matches(pass, checkSingleArgAppendQ) {
+		report.Report(pass, node, "x = append(y) is equivalent to x = y", report.FilterGenerated())
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4022/sa4022.go b/vendor/honnef.co/go/tools/staticcheck/sa4022/sa4022.go
new file mode 100644
index 0000000..efa32e4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4022/sa4022.go
@@ -0,0 +1,40 @@
+package sa4022
+
+import (
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4022",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Comparing the address of a variable against nil`,
+		Text:     `Code such as \"if &x == nil\" is meaningless, because taking the address of a variable always yields a non-nil pointer.`,
+		Since:    "2020.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var CheckAddressIsNilQ = pattern.MustParse(
+	`(BinaryExpr
+		(UnaryExpr "&" _)
+		(Or "==" "!=")
+		(Builtin "nil"))`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node := range code.Matches(pass, CheckAddressIsNilQ) {
+		report.Report(pass, node, "the address of a variable cannot be nil")
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go b/vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go
new file mode 100644
index 0000000..67ca67c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go
@@ -0,0 +1,219 @@
+package sa4023
+
+import (
+	"fmt"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/nilness"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/exp/typeparams"
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4023",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer, nilness.Analysis},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Impossible comparison of interface value with untyped nil`,
+		Text: `Under the covers, interfaces are implemented as two elements, a
+type T and a value V. V is a concrete value such as an int,
+struct or pointer, never an interface itself, and has type T. For
+instance, if we store the int value 3 in an interface, the
+resulting interface value has, schematically, (T=int, V=3). The
+value V is also known as the interface's dynamic value, since a
+given interface variable might hold different values V (and
+corresponding types T) during the execution of the program.
+
+An interface value is nil only if the V and T are both
+unset, (T=nil, V is not set), In particular, a nil interface will
+always hold a nil type. If we store a nil pointer of type *int
+inside an interface value, the inner type will be *int regardless
+of the value of the pointer: (T=*int, V=nil). Such an interface
+value will therefore be non-nil even when the pointer value V
+inside is nil.
+
+This situation can be confusing, and arises when a nil value is
+stored inside an interface value such as an error return:
+
+    func returnsError() error {
+        var p *MyError = nil
+        if bad() {
+            p = ErrBad
+        }
+        return p // Will always return a non-nil error.
+    }
+
+If all goes well, the function returns a nil p, so the return
+value is an error interface value holding (T=*MyError, V=nil).
+This means that if the caller compares the returned error to nil,
+it will always look as if there was an error even if nothing bad
+happened. To return a proper nil error to the caller, the
+function must return an explicit nil:
+
+    func returnsError() error {
+        if bad() {
+            return ErrBad
+        }
+        return nil
+    }
+
+It's a good idea for functions that return errors always to use
+the error type in their signature (as we did above) rather than a
+concrete type such as \'*MyError\', to help guarantee the error is
+created correctly. As an example, \'os.Open\' returns an error even
+though, if not nil, it's always of concrete type *os.PathError.
+
+Similar situations to those described here can arise whenever
+interfaces are used. Just keep in mind that if any concrete value
+has been stored in the interface, the interface will not be nil.
+For more information, see The Laws of
+Reflection at https://golang.org/doc/articles/laws_of_reflection.html.
+
+This text has been copied from
+https://golang.org/doc/faq#nil_error, licensed under the Creative
+Commons Attribution 3.0 License.`,
+		Since:    "2020.2",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny, // TODO should this be MergeIfAll?
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	// The comparison 'fn() == nil' can never be true if fn() returns
+	// an interface value and only returns typed nils. This is usually
+	// a mistake in the function itself, but all we can say for
+	// certain is that the comparison is pointless.
+	//
+	// Flag results if no untyped nils are being returned, but either
+	// known typed nils, or typed unknown nilness are being returned.
+
+	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR)
+	nilnessRes := pass.ResultOf[nilness.Analysis].(*nilness.Result)
+	for _, fn := range irpkg.SrcFuncs {
+		for _, b := range fn.Blocks {
+			for _, instr := range b.Instrs {
+				binop, ok := instr.(*ir.BinOp)
+				if !ok || !(binop.Op == token.EQL || binop.Op == token.NEQ) {
+					continue
+				}
+				if !types.IsInterface(binop.X.Type()) || typeparams.IsTypeParam(binop.X.Type()) {
+					// TODO support swapped X and Y
+					continue
+				}
+
+				k, ok := binop.Y.(*ir.Const)
+				if !ok || !k.IsNil() {
+					// if binop.X is an interface, then binop.Y can only be a
+					// Const if its untyped. A typed nil constant would first
+					// be passed to MakeInterface.
+					continue
+				}
+
+				var idx int
+				var obj *types.Func
+				switch x := irutil.Flatten(binop.X).(type) {
+				case *ir.Call:
+					callee := x.Call.StaticCallee()
+					if callee == nil {
+						continue
+					}
+					obj, _ = callee.Object().(*types.Func)
+					idx = 0
+				case *ir.Extract:
+					call, ok := irutil.Flatten(x.Tuple).(*ir.Call)
+					if !ok {
+						continue
+					}
+					callee := call.Call.StaticCallee()
+					if callee == nil {
+						continue
+					}
+					obj, _ = callee.Object().(*types.Func)
+					idx = x.Index
+				case *ir.MakeInterface:
+					var qualifier string
+					switch binop.Op {
+					case token.EQL:
+						qualifier = "never"
+					case token.NEQ:
+						qualifier = "always"
+					default:
+						panic("unreachable")
+					}
+
+					terms, err := typeparams.NormalTerms(x.X.Type())
+					if len(terms) == 0 || err != nil {
+						// Type is a type parameter with no type terms (or we
+						// couldn't determine the terms). Such a type _can_ be
+						// nil when put in an interface value.
+						continue
+					}
+
+					if report.HasRange(x.X) {
+						report.Report(pass, binop, fmt.Sprintf("this comparison is %s true", qualifier),
+							report.Related(x.X, "the lhs of the comparison gets its value from here and has a concrete type"))
+					} else {
+						// we can't generate related information for this, so
+						// make the diagnostic itself slightly more useful
+						report.Report(pass, binop,
+							fmt.Sprintf("this comparison is %s true; the lhs of the comparison has been assigned a concretely typed value",
+								qualifier))
+					}
+					continue
+				}
+				if obj == nil {
+					continue
+				}
+
+				nillity := nilnessRes.Nilness(obj, idx)
+				// We aim to detect interface values that are never nil (i.e.,
+				// always typed) but may contain typed nils. This usually
+				// points to a bug in the producer of the value. We
+				// intentionally do not flag comparisons with non-nil interface
+				// values whose stored value is also never nil (such as the
+				// return value of errors.New)--those are more likely to be
+				// defensive code, protecting against a future untyped nil.
+				if nillity.Outer == nilness.NeverNil &&
+					(nillity.Inner == nilness.MaybeNil || nillity.Inner == nilness.AlwaysNil) &&
+					!code.IsInTest(pass, binop) &&
+					!irutil.IsTrivial(irpkg.Pkg.Prog.FuncValue(obj)) {
+					// Don't flag these comparisons in tests. Tests may be
+					// explicitly enforcing the invariant that a value isn't
+					// nil.
+
+					var qualifier string
+					switch binop.Op {
+					case token.EQL:
+						qualifier = "never"
+					case token.NEQ:
+						qualifier = "always"
+					default:
+						panic("unreachable")
+					}
+					report.Report(pass, binop, fmt.Sprintf("this comparison is %s true", qualifier),
+						// TODO support swapped X and Y
+						report.Related(binop.X,
+							fmt.Sprintf("the lhs of the comparison is the %s return value of this function call",
+								report.Ordinal(idx+1))),
+						report.Related(obj,
+							fmt.Sprintf("%s never returns a nil interface value", typeutil.FuncName(obj))))
+				}
+			}
+		}
+	}
+
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4024/sa4024.go b/vendor/honnef.co/go/tools/staticcheck/sa4024/sa4024.go
new file mode 100644
index 0000000..a956050
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4024/sa4024.go
@@ -0,0 +1,58 @@
+package sa4024
+
+import (
+	"fmt"
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4024",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Checking for impossible return value from a builtin function`,
+		Text: `Return values of the \'len\' and \'cap\' builtins cannot be negative.
+
+See https://golang.org/pkg/builtin/#len and https://golang.org/pkg/builtin/#cap.
+
+Example:
+
+    if len(slice) < 0 {
+        fmt.Println("unreachable code")
+    }`,
+		Since:    "2021.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var builtinLessThanZeroQ = pattern.MustParse(`
+	(Or
+		(BinaryExpr
+			(IntegerLiteral "0")
+			">"
+			(CallExpr builtin@(Builtin (Or "len" "cap")) _))
+		(BinaryExpr
+			(CallExpr builtin@(Builtin (Or "len" "cap")) _)
+			"<"
+			(IntegerLiteral "0")))
+`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, matcher := range code.Matches(pass, builtinLessThanZeroQ) {
+		builtin := matcher.State["builtin"].(*ast.Ident)
+		report.Report(pass, node, fmt.Sprintf("builtin function %s does not return negative values", builtin.Name))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4025/sa4025.go b/vendor/honnef.co/go/tools/staticcheck/sa4025/sa4025.go
new file mode 100644
index 0000000..a8bc2e8
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4025/sa4025.go
@@ -0,0 +1,69 @@
+package sa4025
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4025",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "Integer division of literals that results in zero",
+		Text: `When dividing two integer constants, the result will
+also be an integer. Thus, a division such as \'2 / 3\' results in \'0\'.
+This is true for all of the following examples:
+
+	_ = 2 / 3
+	const _ = 2 / 3
+	const _ float64 = 2 / 3
+	_ = float64(2 / 3)
+
+Staticcheck will flag such divisions if both sides of the division are
+integer literals, as it is highly unlikely that the division was
+intended to truncate to zero. Staticcheck will not flag integer
+division involving named constants, to avoid noisy positives.
+`,
+		Since:    "2021.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var integerDivisionQ = pattern.MustParse(`(BinaryExpr (IntegerLiteral _) "/" (IntegerLiteral _))`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node := range code.Matches(pass, integerDivisionQ) {
+		val := constant.ToInt(pass.TypesInfo.Types[node.(ast.Expr)].Value)
+		if v, ok := constant.Uint64Val(val); ok && v == 0 {
+			report.Report(pass, node, fmt.Sprintf("the integer division '%s' results in zero", report.Render(pass, node)))
+		}
+
+		// TODO: we could offer a suggested fix here, but I am not
+		// sure what it should be. There are many options to choose
+		// from.
+
+		// Note: we experimented with flagging divisions that truncate
+		// (e.g. 4 / 3), but it ran into false positives in Go's
+		// 'time' package, which does this, deliberately:
+		//
+		//   unixToInternal int64 = (1969*365 + 1969/4 - 1969/100 + 1969/400) * secondsPerDay
+		//
+		// The check also found a real bug in other code, but I don't
+		// think we can outright ban this kind of division.
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4026/sa4026.go b/vendor/honnef.co/go/tools/staticcheck/sa4026/sa4026.go
new file mode 100644
index 0000000..31681d1
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4026/sa4026.go
@@ -0,0 +1,79 @@
+package sa4026
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4026",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "Go constants cannot express negative zero",
+		Text: `In IEEE 754 floating point math, zero has a sign and can be positive
+or negative. This can be useful in certain numerical code.
+
+Go constants, however, cannot express negative zero. This means that
+the literals \'-0.0\' and \'0.0\' have the same ideal value (zero) and
+will both represent positive zero at runtime.
+
+To explicitly and reliably create a negative zero, you can use the
+\'math.Copysign\' function: \'math.Copysign(0, -1)\'.`,
+		Since:    "2021.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var negativeZeroFloatQ = pattern.MustParse(`
+	(Or
+		(UnaryExpr
+			"-"
+			(BasicLit "FLOAT" "0.0"))
+
+		(UnaryExpr
+			"-"
+			(CallExpr conv@(Object (Or "float32" "float64")) lit@(Or (BasicLit "INT" "0") (BasicLit "FLOAT" "0.0"))))
+
+		(CallExpr
+			conv@(Object (Or "float32" "float64"))
+			(UnaryExpr "-" lit@(BasicLit "INT" "0"))))`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, negativeZeroFloatQ) {
+		if conv, ok := m.State["conv"].(*types.TypeName); ok {
+			var replacement string
+			// TODO(dh): how does this handle type aliases?
+			if conv.Name() == "float32" {
+				replacement = `float32(math.Copysign(0, -1))`
+			} else {
+				replacement = `math.Copysign(0, -1)`
+			}
+			report.Report(pass, node,
+				fmt.Sprintf("in Go, the floating-point expression '%s' is the same as '%s(%s)', it does not produce a negative zero",
+					report.Render(pass, node),
+					conv.Name(),
+					report.Render(pass, m.State["lit"])),
+				report.Fixes(edit.Fix("Use math.Copysign to create negative zero", edit.ReplaceWithString(node, replacement))))
+		} else {
+			const replacement = `math.Copysign(0, -1)`
+			report.Report(pass, node,
+				"in Go, the floating-point literal '-0.0' is the same as '0.0', it does not produce a negative zero",
+				report.Fixes(edit.Fix("Use math.Copysign to create negative zero", edit.ReplaceWithString(node, replacement))))
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4027/sa4027.go b/vendor/honnef.co/go/tools/staticcheck/sa4027/sa4027.go
new file mode 100644
index 0000000..cb8c739
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4027/sa4027.go
@@ -0,0 +1,57 @@
+package sa4027
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4027",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `\'(*net/url.URL).Query\' returns a copy, modifying it doesn't change the URL`,
+		Text: `\'(*net/url.URL).Query\' parses the current value of \'net/url.URL.RawQuery\'
+and returns it as a map of type \'net/url.Values\'. Subsequent changes to
+this map will not affect the URL unless the map gets encoded and
+assigned to the URL's \'RawQuery\'.
+
+As a consequence, the following code pattern is an expensive no-op:
+\'u.Query().Add(key, value)\'.`,
+		Since:    "2021.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var ineffectiveURLQueryAddQ = pattern.MustParse(`(CallExpr (SelectorExpr (CallExpr (SelectorExpr recv (Ident "Query")) []) (Ident meth)) _)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	// TODO(dh): We could make this check more complex and detect
+	// pointless modifications of net/url.Values in general, but that
+	// requires us to get the state machine correct, else we'll cause
+	// false positives.
+
+	for node, m := range code.Matches(pass, ineffectiveURLQueryAddQ) {
+		if !code.IsOfPointerToTypeWithName(pass, m.State["recv"].(ast.Expr), "net/url.URL") {
+			continue
+		}
+		switch m.State["meth"].(string) {
+		case "Add", "Del", "Set":
+		default:
+			continue
+		}
+		report.Report(pass, node, "(*net/url.URL).Query returns a copy, modifying it doesn't change the URL")
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4028/sa4028.go b/vendor/honnef.co/go/tools/staticcheck/sa4028/sa4028.go
new file mode 100644
index 0000000..1873d7b
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4028/sa4028.go
@@ -0,0 +1,35 @@
+package sa4028
+
+import (
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4028",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `\'x % 1\' is always zero`,
+		Since:    "2022.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny, // MergeIfAny if we only flag literals, not named constants
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var moduloOneQ = pattern.MustParse(`(BinaryExpr _ "%" (IntegerLiteral "1"))`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node := range code.Matches(pass, moduloOneQ) {
+		report.Report(pass, node, "x % 1 is always zero")
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4029/sa4029.go b/vendor/honnef.co/go/tools/staticcheck/sa4029/sa4029.go
new file mode 100644
index 0000000..de77e23
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4029/sa4029.go
@@ -0,0 +1,80 @@
+package sa4029
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4029",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "Ineffective attempt at sorting slice",
+		Text: `
+\'sort.Float64Slice\', \'sort.IntSlice\', and \'sort.StringSlice\' are
+types, not functions. Doing \'x = sort.StringSlice(x)\' does nothing,
+especially not sort any values. The correct usage is
+\'sort.Sort(sort.StringSlice(x))\' or \'sort.StringSlice(x).Sort()\',
+but there are more convenient helpers, namely \'sort.Float64s\',
+\'sort.Ints\', and \'sort.Strings\'.
+`,
+		Since:    "2022.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var ineffectiveSortQ = pattern.MustParse(`(AssignStmt target@(Ident _) "=" (CallExpr typ@(Symbol (Or "sort.Float64Slice" "sort.IntSlice" "sort.StringSlice")) [target]))`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, ineffectiveSortQ) {
+		_, ok := types.Unalias(pass.TypesInfo.TypeOf(m.State["target"].(ast.Expr))).(*types.Slice)
+		if !ok {
+			// Avoid flagging 'x = sort.StringSlice(x)' where TypeOf(x) == sort.StringSlice
+			continue
+		}
+
+		var alternative string
+		typeName := types.TypeString(types.Unalias(m.State["typ"].(*types.TypeName).Type()), nil)
+		switch typeName {
+		case "sort.Float64Slice":
+			alternative = "Float64s"
+		case "sort.IntSlice":
+			alternative = "Ints"
+		case "sort.StringSlice":
+			alternative = "Strings"
+		default:
+			panic(fmt.Sprintf("unreachable: %q", typeName))
+		}
+
+		r := &ast.CallExpr{
+			Fun: &ast.SelectorExpr{
+				X:   &ast.Ident{Name: "sort"},
+				Sel: &ast.Ident{Name: alternative},
+			},
+			Args: []ast.Expr{m.State["target"].(ast.Expr)},
+		}
+
+		report.Report(pass, node,
+			fmt.Sprintf("%s is a type, not a function, and %s doesn't sort your values; consider using sort.%s instead",
+				typeName,
+				report.Render(pass, node.(*ast.AssignStmt).Rhs[0]),
+				alternative),
+			report.Fixes(edit.Fix(fmt.Sprintf("Replace with call to sort.%s", alternative), edit.ReplaceWithNode(pass.Fset, node, r))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4030/sa4030.go b/vendor/honnef.co/go/tools/staticcheck/sa4030/sa4030.go
new file mode 100644
index 0000000..fad7c5b
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4030/sa4030.go
@@ -0,0 +1,70 @@
+package sa4030
+
+import (
+	"fmt"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4030",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "Ineffective attempt at generating random number",
+		Text: `
+Functions in the \'math/rand\' package that accept upper limits, such
+as \'Intn\', generate random numbers in the half-open interval [0,n). In
+other words, the generated numbers will be \'>= 0\' and \'< n\' – they
+don't include \'n\'. \'rand.Intn(1)\' therefore doesn't generate \'0\'
+or \'1\', it always generates \'0\'.`,
+		Since:    "2022.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var ineffectiveRandIntQ = pattern.MustParse(`
+	(CallExpr
+		(Symbol
+			name@(Or
+				"math/rand.Int31n"
+				"math/rand.Int63n"
+				"math/rand.Intn"
+				"(*math/rand.Rand).Int31n"
+				"(*math/rand.Rand).Int63n"
+				"(*math/rand.Rand).Intn"
+
+				"math/rand/v2.Int32N"
+				"math/rand/v2.Int64N"
+				"math/rand/v2.IntN"
+				"math/rand/v2.N"
+				"math/rand/v2.Uint32N"
+				"math/rand/v2.Uint64N"
+				"math/rand/v2.UintN"
+
+				"(*math/rand/v2.Rand).Int32N"
+				"(*math/rand/v2.Rand).Int64N"
+				"(*math/rand/v2.Rand).IntN"
+				"(*math/rand/v2.Rand).Uint32N"
+				"(*math/rand/v2.Rand).Uint64N"
+				"(*math/rand/v2.Rand).UintN"))
+		[(IntegerLiteral "1")])`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, ineffectiveRandIntQ) {
+		report.Report(pass, node,
+			fmt.Sprintf("%s(n) generates a random value 0 <= x < n; that is, the generated values don't include n; %s therefore always returns 0",
+				m.State["name"], report.Render(pass, node)))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4031/sa4031.go b/vendor/honnef.co/go/tools/staticcheck/sa4031/sa4031.go
new file mode 100644
index 0000000..3da5ba0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4031/sa4031.go
@@ -0,0 +1,160 @@
+package sa4031
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"sort"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/pattern"
+	"honnef.co/go/tools/staticcheck/sa4022"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4031",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer, inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Checking never-nil value against nil`,
+		Since:    "2022.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var allocationNilCheckQ = pattern.MustParse(`(IfStmt _ cond@(BinaryExpr lhs op@(Or "==" "!=") (Builtin "nil")) _ _)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
+
+	var path []ast.Node
+	fn := func(node ast.Node, stack []ast.Node) {
+		m, ok := code.Match(pass, allocationNilCheckQ, node)
+		if !ok {
+			return
+		}
+		cond := m.State["cond"].(ast.Node)
+		if _, ok := code.Match(pass, sa4022.CheckAddressIsNilQ, cond); ok {
+			// Don't duplicate diagnostics reported by SA4022
+			return
+		}
+		lhs := m.State["lhs"].(ast.Expr)
+		path = path[:0]
+		for i := len(stack) - 1; i >= 0; i-- {
+			path = append(path, stack[i])
+		}
+		irfn := ir.EnclosingFunction(irpkg, path)
+		if irfn == nil {
+			// For example for functions named "_", because we don't generate IR for them.
+			return
+		}
+		v, isAddr := irfn.ValueForExpr(lhs)
+		if isAddr {
+			return
+		}
+
+		seen := map[ir.Value]struct{}{}
+		var values []ir.Value
+		var neverNil func(v ir.Value, track bool) bool
+		neverNil = func(v ir.Value, track bool) bool {
+			if _, ok := seen[v]; ok {
+				return true
+			}
+			seen[v] = struct{}{}
+			switch v := v.(type) {
+			case *ir.MakeClosure, *ir.Function:
+				if track {
+					values = append(values, v)
+				}
+				return true
+			case *ir.MakeChan, *ir.MakeMap, *ir.MakeSlice, *ir.Alloc:
+				if track {
+					values = append(values, v)
+				}
+				return true
+			case *ir.Slice:
+				if track {
+					values = append(values, v)
+				}
+				return neverNil(v.X, false)
+			case *ir.FieldAddr:
+				if track {
+					values = append(values, v)
+				}
+				return neverNil(v.X, false)
+			case *ir.Phi:
+				for _, e := range v.Edges {
+					if !neverNil(e, true) {
+						return false
+					}
+				}
+				return true
+			default:
+				return false
+			}
+		}
+
+		if !neverNil(v, true) {
+			return
+		}
+
+		var qualifier string
+		if op := m.State["op"].(token.Token); op == token.EQL {
+			qualifier = "never"
+		} else {
+			qualifier = "always"
+		}
+		fallback := fmt.Sprintf("this nil check is %s true", qualifier)
+
+		sort.Slice(values, func(i, j int) bool { return values[i].Pos() < values[j].Pos() })
+
+		if ident, ok := m.State["lhs"].(*ast.Ident); ok {
+			if _, ok := pass.TypesInfo.ObjectOf(ident).(*types.Var); ok {
+				var opts []report.Option
+				if v.Parent() == irfn {
+					if len(values) == 1 {
+						opts = append(opts, report.Related(values[0], fmt.Sprintf("this is the value of %s", ident.Name)))
+					} else {
+						for _, vv := range values {
+							opts = append(opts, report.Related(vv, fmt.Sprintf("this is one of the value of %s", ident.Name)))
+						}
+					}
+				}
+
+				switch v.(type) {
+				case *ir.MakeClosure, *ir.Function:
+					report.Report(pass, cond, "the checked variable contains a function and is never nil; did you mean to call it?", opts...)
+				default:
+					report.Report(pass, cond, fallback, opts...)
+				}
+			} else {
+				if _, ok := v.(*ir.Function); ok {
+					report.Report(pass, cond, "functions are never nil; did you mean to call it?")
+				} else {
+					report.Report(pass, cond, fallback)
+				}
+			}
+		} else {
+			if _, ok := v.(*ir.Function); ok {
+				report.Report(pass, cond, "functions are never nil; did you mean to call it?")
+			} else {
+				report.Report(pass, cond, fallback)
+			}
+		}
+	}
+	code.PreorderStack(pass, fn, (*ast.IfStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4032/sa4032.go b/vendor/honnef.co/go/tools/staticcheck/sa4032/sa4032.go
new file mode 100644
index 0000000..99012da
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4032/sa4032.go
@@ -0,0 +1,221 @@
+package sa4032
+
+import (
+	"fmt"
+	"go/ast"
+	"go/build/constraint"
+	"go/constant"
+
+	"golang.org/x/tools/go/analysis"
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/knowledge"
+	"honnef.co/go/tools/pattern"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA4032",
+		Run:      CheckImpossibleGOOSGOARCH,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Comparing \'runtime.GOOS\' or \'runtime.GOARCH\' against impossible value`,
+		Since:    "2024.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	goosComparisonQ   = pattern.MustParse(`(BinaryExpr (Symbol "runtime.GOOS") op@(Or "==" "!=") lit@(BasicLit "STRING" _))`)
+	goarchComparisonQ = pattern.MustParse(`(BinaryExpr (Symbol "runtime.GOARCH") op@(Or "==" "!=") lit@(BasicLit "STRING" _))`)
+)
+
+func CheckImpossibleGOOSGOARCH(pass *analysis.Pass) (any, error) {
+	// TODO(dh): validate GOOS and GOARCH together. that is,
+	// given '(linux && amd64) || (windows && mips)',
+	// flag 'if runtime.GOOS == "linux" && runtime.GOARCH == "mips"'
+	//
+	// We can't use our IR for the control flow graph, because go/types constant folds constant comparisons, so
+	// 'runtime.GOOS == "windows"' will just become 'false'. We can't use the AST-based CFG builder from x/tools,
+	// because it doesn't model branch conditions.
+
+	if !code.CouldMatchAny(pass, goarchComparisonQ, goosComparisonQ) {
+		return nil, nil
+	}
+
+	for _, f := range pass.Files {
+		expr, ok := code.BuildConstraints(pass, f)
+		if !ok {
+			continue
+		}
+
+		ast.Inspect(f, func(node ast.Node) bool {
+			if m, ok := code.Match(pass, goosComparisonQ, node); ok {
+				tv := pass.TypesInfo.Types[m.State["lit"].(ast.Expr)]
+				goos := constant.StringVal(tv.Value)
+
+				if _, ok := knowledge.KnownGOOS[goos]; !ok {
+					// Don't try to reason about GOOS values we don't know about. Maybe the user is using a newer
+					// version of Go that supports a new target, or maybe they run a fork of Go.
+					return true
+				}
+				sat, ok := validateGOOSComparison(expr, goos)
+				if !ok {
+					return true
+				}
+				if !sat {
+					// Note that we do not have to worry about constraints that can never be satisfied, such as 'linux
+					// && windows'. Packages with such files will not be passed to Staticcheck in the first place,
+					// precisely because the constraints aren't satisfiable.
+					report.Report(pass, node,
+						fmt.Sprintf("due to the file's build constraints, runtime.GOOS will never equal %q", goos))
+				}
+			} else if m, ok := code.Match(pass, goarchComparisonQ, node); ok {
+				tv := pass.TypesInfo.Types[m.State["lit"].(ast.Expr)]
+				goarch := constant.StringVal(tv.Value)
+
+				if _, ok := knowledge.KnownGOARCH[goarch]; !ok {
+					// Don't try to reason about GOARCH values we don't know about. Maybe the user is using a newer
+					// version of Go that supports a new target, or maybe they run a fork of Go.
+					return true
+				}
+				sat, ok := validateGOARCHComparison(expr, goarch)
+				if !ok {
+					return true
+				}
+				if !sat {
+					// Note that we do not have to worry about constraints that can never be satisfied, such as 'amd64
+					// && mips'. Packages with such files will not be passed to Staticcheck in the first place,
+					// precisely because the constraints aren't satisfiable.
+					report.Report(pass, node,
+						fmt.Sprintf("due to the file's build constraints, runtime.GOARCH will never equal %q", goarch))
+				}
+			}
+			return true
+		})
+	}
+
+	return nil, nil
+}
+func validateGOOSComparison(expr constraint.Expr, goos string) (sat bool, didCheck bool) {
+	matchGoosTag := func(tag string, goos string) (ok bool, goosTag bool) {
+		switch tag {
+		case "aix",
+			"android",
+			"dragonfly",
+			"freebsd",
+			"hurd",
+			"illumos",
+			"ios",
+			"js",
+			"netbsd",
+			"openbsd",
+			"plan9",
+			"wasip1",
+			"windows":
+			return goos == tag, true
+		case "darwin":
+			return (goos == "darwin" || goos == "ios"), true
+		case "linux":
+			return (goos == "linux" || goos == "android"), true
+		case "solaris":
+			return (goos == "solaris" || goos == "illumos"), true
+		case "unix":
+			return (goos == "aix" ||
+				goos == "android" ||
+				goos == "darwin" ||
+				goos == "dragonfly" ||
+				goos == "freebsd" ||
+				goos == "hurd" ||
+				goos == "illumos" ||
+				goos == "ios" ||
+				goos == "linux" ||
+				goos == "netbsd" ||
+				goos == "openbsd" ||
+				goos == "solaris"), true
+		default:
+			return false, false
+		}
+	}
+
+	return validateTagComparison(expr, func(tag string) (matched bool, special bool) {
+		return matchGoosTag(tag, goos)
+	})
+}
+
+func validateGOARCHComparison(expr constraint.Expr, goarch string) (sat bool, didCheck bool) {
+	matchGoarchTag := func(tag string, goarch string) (ok bool, goosTag bool) {
+		switch tag {
+		case "386",
+			"amd64",
+			"arm",
+			"arm64",
+			"loong64",
+			"mips",
+			"mipsle",
+			"mips64",
+			"mips64le",
+			"ppc64",
+			"ppc64le",
+			"riscv64",
+			"s390x",
+			"sparc64",
+			"wasm":
+			return goarch == tag, true
+		default:
+			return false, false
+		}
+	}
+
+	return validateTagComparison(expr, func(tag string) (matched bool, special bool) {
+		return matchGoarchTag(tag, goarch)
+	})
+}
+
+func validateTagComparison(expr constraint.Expr, matchSpecialTag func(tag string) (matched bool, special bool)) (sat bool, didCheck bool) {
+	otherTags := map[string]int{}
+	// Collect all tags that aren't known architecture-based tags
+	b := expr.Eval(func(tag string) bool {
+		ok, special := matchSpecialTag(tag)
+		if !special {
+			// Assign an ID to this tag, but only if we haven't seen it before. For the expression 'foo && foo', this
+			// callback will be called twice for the 'foo' tag.
+			if _, ok := otherTags[tag]; !ok {
+				otherTags[tag] = len(otherTags)
+			}
+		}
+		return ok
+	})
+
+	if b || len(otherTags) == 0 {
+		// We're done. Either the formula can be satisfied regardless of the values of non-special tags, if any,
+		// or there aren't any non-special tags and the formula cannot be satisfied.
+		return b, true
+	}
+
+	if len(otherTags) > 10 {
+		// We have to try 2**len(otherTags) combinations of tags. 2**10 is about the worst we're willing to try.
+		return false, false
+	}
+
+	// Try all permutations of otherTags. If any evaluates to true, then the expression is satisfiable.
+	for bits := 0; bits < 1< 0 && !strings.HasPrefix(tag, ",") {
+		// For better compatibility with v1, accept almost any unescaped name.
+		n := len(tag) - len(strings.TrimLeftFunc(tag, func(r rune) bool {
+			return !strings.ContainsRune(",\\'\"`", r) // reserve comma, backslash, and quotes
+		}))
+		name := tag[:n]
+
+		// If the next character is not a comma, then the name is either
+		// malformed (if n > 0) or a single-quoted name.
+		// In either case, call consumeTagOption to handle it further.
+		var err error
+		if !strings.HasPrefix(tag[n:], ",") && len(name) != len(tag) {
+			name, n, err = consumeTagOption(tag)
+			if err != nil {
+				report.Report(pass, field.Tag, fmt.Sprintf("malformed `json` tag: %v", err))
+			}
+		}
+		if !utf8.ValidString(name) {
+			report.Report(pass, field.Tag,
+				fmt.Sprintf("invalid UTF-8 in JSON object name %q", name))
+			name = string([]rune(name)) // replace invalid UTF-8 with utf8.RuneError
+		}
+		if name == "-" && tag[0] == '-' {
+			// TODO(dh): offer automatic fix
+			report.Report(pass, field.Tag,
+				fmt.Sprintf("should encoding/json ignore this field or name it \"-\"? Either use `json:\"-\"` to ignore the field or use `json:\"'-'%s` to specify %q as the name",
+					strings.TrimPrefix(strconv.Quote(tagOrig), `"-`), name))
+		}
+		tag = tag[n:]
+	}
+
+	// Handle any additional tag options (if any).
+	var wasFormat bool
+	seenOpts := make(map[string]bool)
+	for len(tag) > 0 {
+		// Consume comma delimiter.
+		if tag[0] != ',' {
+			report.Report(pass, field.Tag,
+				fmt.Sprintf("malformed `json` tag: invalid character %q before next option (expecting ',')",
+					tag[0]))
+		} else {
+			tag = tag[len(","):]
+			if len(tag) == 0 {
+				report.Report(pass, field.Tag, "malformed `json` tag: invalid trailing ',' character")
+				break
+			}
+		}
+
+		// Consume and process the tag option.
+		opt, n, err := consumeTagOption(tag)
+		if err != nil {
+			report.Report(pass, field.Tag, fmt.Sprintf("malformed `json` tag: %v", err))
+		}
+		rawOpt := tag[:n]
+		tag = tag[n:]
+		switch {
+		case wasFormat:
+			report.Report(pass, field.Tag, "`format` tag option was not specified last")
+		case strings.HasPrefix(rawOpt, "'") && strings.TrimFunc(opt, isLetterOrDigit) == "":
+			// TODO(dh): offer automatic fix
+			report.Report(pass, field.Tag,
+				fmt.Sprintf("unnecessarily quoted appearance of `%s` tag option; specify `%s` instead", rawOpt, opt))
+		}
+		switch opt {
+		case "case":
+			if !strings.HasPrefix(tag, ":") {
+				// TODO(dh): offer automatic fix
+				report.Report(pass, field.Tag,
+					"missing value for `case` tag option; specify `case:ignore` or `case:strict` instead")
+				break
+			}
+			tag = tag[len(":"):]
+			opt, n, err := consumeTagOption(tag)
+			if err != nil {
+				report.Report(pass, field.Tag,
+					fmt.Sprintf("malformed value for `case` tag option: %v", err))
+				break
+			}
+			rawOpt := tag[:n]
+			tag = tag[n:]
+			if strings.HasPrefix(rawOpt, "'") {
+				// TODO(dh): offer automatic fix
+				report.Report(pass, field.Tag,
+					fmt.Sprintf("unnecessarily quoted appearance of `case:%s` tag option; specify `case:%s` instead",
+						rawOpt, opt))
+			}
+			switch opt {
+			case "ignore":
+			case "strict":
+			default:
+				report.Report(pass, field.Tag,
+					fmt.Sprintf("invalid appearance of unknown `case:%s` tag value", rawOpt))
+			}
+		case "embed", "inline":
+		case "unknown":
+		case "omitzero":
+		case "omitempty":
+		case "string":
+			const msg = "invalid appearance of `string` tag option; it is only intended for fields of numeric types or pointers to those"
+			tset := typeutil.NewTypeSet(pass.TypesInfo.TypeOf(field.Type))
+			if len(tset.Terms) == 0 {
+				// TODO(dh): improve message, call out the use of type parameters
+				report.Report(pass, field.Tag, msg)
+				continue
+			}
+			for _, term := range tset.Terms {
+				T := typeutil.Dereference(term.Type().Underlying())
+				for _, term2 := range typeutil.NewTypeSet(T).Terms {
+					basic, ok := term2.Type().Underlying().(*types.Basic)
+					// We accept bools and strings because v1 of encoding/json
+					// supports those. We don't mention that in the message,
+					// however, because their support is accidental, and v2
+					// doesn't support it.
+					if !ok || (basic.Info()&(types.IsBoolean|types.IsInteger|types.IsFloat|types.IsString)) == 0 {
+						// TODO(dh): improve message, show how we arrived at the type
+						report.Report(pass, field.Tag, msg)
+					}
+				}
+			}
+		case "format":
+			if !strings.HasPrefix(tag, ":") {
+				report.Report(pass, field.Tag, "missing value for `format` tag option")
+				break
+			}
+			tag = tag[len(":"):]
+			_, n, err := consumeTagOption(tag)
+			if err != nil {
+				report.Report(pass, field.Tag,
+					fmt.Sprintf("malformed value for `format` tag option: %v", err))
+				break
+			}
+			tag = tag[n:]
+			wasFormat = true
+		default:
+			// Reject keys that resemble one of the supported options.
+			// This catches invalid mutants such as "omitEmpty" or "omit_empty".
+			normOpt := strings.ReplaceAll(strings.ToLower(opt), "_", "")
+			switch normOpt {
+			case "case", "inline", "unknown", "omitzero", "omitempty", "string", "format":
+				report.Report(pass, field.Tag,
+					fmt.Sprintf("invalid appearance of `%s` tag option; specify `%s` instead",
+						opt, normOpt))
+			default:
+				report.Report(pass, field.Tag,
+					fmt.Sprintf("invalid appearance of unknown `%s` tag option", opt))
+			}
+		}
+
+		// Reject duplicates.
+		if seenOpts[opt] {
+			report.Report(pass, field.Tag,
+				fmt.Sprintf("duplicate appearance of `%s` tag option", rawOpt))
+		}
+		seenOpts[opt] = true
+	}
+
+	if seenOpts["inline"] && seenOpts["unknown"] {
+		report.Report(pass, field.Tag,
+			"field cannot have both `inline` and `unknown` specified")
+	}
+
+	// TODO(dh): implement more restrictions for types of inlined and unknown
+	// fields, including recursive restrictions:
+	//
+	// - Go struct field %s cannot have any options other than `inline` or `unknown` specified
+	// - inlined Go struct field %s of type %s with `unknown` tag must be a Go map of string key or a jsontext.Value
+	// - inlined Go struct field %s is not exported
+	// - inlined map field %s of type %s must have a string key that does not implement marshal or unmarshal methods
+	// - inlined Go struct field %s of type %s must be a Go struct, Go map of string key, or jsontext.Value
+}
+
+// consumeTagOption consumes the next option,
+// which is either a Go identifier or a single-quoted string.
+// If the next option is invalid, it returns all of in until the next comma,
+// and reports an error.
+func consumeTagOption(in string) (string, int, error) {
+	// For legacy compatibility with v1, assume options are comma-separated.
+	i := strings.IndexByte(in, ',')
+	if i < 0 {
+		i = len(in)
+	}
+
+	switch r, _ := utf8.DecodeRuneInString(in); {
+	// Option as a Go identifier.
+	case r == '_' || unicode.IsLetter(r):
+		n := len(in) - len(strings.TrimLeftFunc(in, isLetterOrDigit))
+		return in[:n], n, nil
+	// Option as a single-quoted string.
+	case r == '\'':
+		// The grammar is nearly identical to a double-quoted Go string literal,
+		// but uses single quotes as the terminators. The reason for a custom
+		// grammar is because both backtick and double quotes cannot be used
+		// verbatim in a struct tag.
+		//
+		// Convert a single-quoted string to a double-quote string and rely on
+		// strconv.Unquote to handle the rest.
+		var inEscape bool
+		b := []byte{'"'}
+		n := len(`'`)
+		for len(in) > n {
+			r, rn := utf8.DecodeRuneInString(in[n:])
+			switch {
+			case inEscape:
+				if r == '\'' {
+					b = b[:len(b)-1] // remove escape character: `\'` => `'`
+				}
+				inEscape = false
+			case r == '\\':
+				inEscape = true
+			case r == '"':
+				b = append(b, '\\') // insert escape character: `"` => `\"`
+			case r == '\'':
+				b = append(b, '"')
+				n += len(`'`)
+				out, err := strconv.Unquote(string(b))
+				if err != nil {
+					return in[:i], i, fmt.Errorf("invalid single-quoted string: %s", in[:n])
+				}
+				return out, n, nil
+			}
+			b = append(b, in[n:][:rn]...)
+			n += rn
+		}
+		if n > 10 {
+			n = 10 // limit the amount of context printed in the error
+		}
+		//lint:ignore ST1005 The ellipsis denotes truncated text
+		return in[:i], i, fmt.Errorf("single-quoted string not terminated: %s...", in[:n])
+	case len(in) == 0:
+		return in[:i], i, io.ErrUnexpectedEOF
+	default:
+		return in[:i], i, fmt.Errorf("invalid character %q at start of option (expecting Unicode letter or single quote)", r)
+	}
+}
+
+func isLetterOrDigit(r rune) bool {
+	return r == '_' || unicode.IsLetter(r) || unicode.IsNumber(r)
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5008/sa5008.go b/vendor/honnef.co/go/tools/staticcheck/sa5008/sa5008.go
new file mode 100644
index 0000000..2b3453f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5008/sa5008.go
@@ -0,0 +1,130 @@
+package sa5008
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/staticcheck/fakereflect"
+	"honnef.co/go/tools/staticcheck/fakexml"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA5008",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Invalid struct tag`,
+		Since:    "2019.2",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	importsGoFlags := false
+
+	// we use the AST instead of (*types.Package).Imports to work
+	// around vendored packages in GOPATH mode. A vendored package's
+	// path will include the vendoring subtree as a prefix.
+	for _, f := range pass.Files {
+		for _, imp := range f.Imports {
+			v := imp.Path.Value
+			if v[1:len(v)-1] == "github.com/jessevdk/go-flags" {
+				importsGoFlags = true
+				break
+			}
+		}
+	}
+
+	fn := func(node ast.Node) {
+		structNode := node.(*ast.StructType)
+		T := pass.TypesInfo.Types[structNode].Type.(*types.Struct)
+		rt := fakereflect.TypeAndCanAddr{
+			Type: T,
+		}
+		for i, field := range structNode.Fields.List {
+			if field.Tag == nil {
+				continue
+			}
+			tags, err := parseStructTag(field.Tag.Value[1 : len(field.Tag.Value)-1])
+			if err != nil {
+				report.Report(pass, field.Tag, fmt.Sprintf("unparseable struct tag: %s", err))
+				continue
+			}
+			for k, v := range tags {
+				if len(v) > 1 {
+					isGoFlagsTag := importsGoFlags &&
+						(k == "choice" || k == "optional-value" || k == "default")
+					if !isGoFlagsTag {
+						report.Report(pass, field.Tag, fmt.Sprintf("duplicate struct tag %q", k))
+					}
+				}
+
+				switch k {
+				case "json":
+					checkJSONTag(pass, field, v[0])
+				case "xml":
+					if _, err := fakexml.StructFieldInfo(rt.Field(i)); err != nil {
+						report.Report(pass, field.Tag, fmt.Sprintf("invalid XML tag: %s", err))
+					}
+					checkXMLTag(pass, field, v[0])
+				}
+			}
+		}
+	}
+	code.Preorder(pass, fn, (*ast.StructType)(nil))
+	return nil, nil
+}
+
+func checkJSONTag(pass *analysis.Pass, field *ast.Field, tag string) {
+	if pass.Pkg.Path() == "encoding/json" ||
+		pass.Pkg.Path() == "encoding/json_test" ||
+		pass.Pkg.Path() == "encoding/json/v2" ||
+		pass.Pkg.Path() == "encoding/json/v2_test" {
+		// don't flag malformed JSON tags in the encoding/json
+		// package; it knows what it is doing, and it is testing
+		// itself.
+		return
+	}
+	//lint:ignore SA9003 TODO(dh): should we flag empty tags?
+	if len(tag) == 0 {
+	}
+
+	validateJSONTag(pass, field, tag)
+}
+
+func checkXMLTag(pass *analysis.Pass, field *ast.Field, tag string) {
+	//lint:ignore SA9003 TODO(dh): should we flag empty tags?
+	if len(tag) == 0 {
+	}
+	fields := strings.Split(tag, ",")
+	counts := map[string]int{}
+	for _, s := range fields[1:] {
+		switch s {
+		case "attr", "chardata", "cdata", "innerxml", "comment":
+			counts[s]++
+		case "omitempty", "any":
+			counts[s]++
+		case "":
+		default:
+			report.Report(pass, field.Tag, fmt.Sprintf("invalid XML tag: unknown option %q", s))
+		}
+	}
+	for k, v := range counts {
+		if v > 1 {
+			report.Report(pass, field.Tag, fmt.Sprintf("invalid XML tag: duplicate option %q", k))
+		}
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5008/structtag.go b/vendor/honnef.co/go/tools/staticcheck/sa5008/structtag.go
new file mode 100644
index 0000000..e8121e5
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5008/structtag.go
@@ -0,0 +1,58 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2019 Dominik Honnef. All rights reserved.
+
+package sa5008
+
+import "strconv"
+
+func parseStructTag(tag string) (map[string][]string, error) {
+	// FIXME(dh): detect missing closing quote
+	out := map[string][]string{}
+
+	for tag != "" {
+		// Skip leading space.
+		i := 0
+		for i < len(tag) && tag[i] == ' ' {
+			i++
+		}
+		tag = tag[i:]
+		if tag == "" {
+			break
+		}
+
+		// Scan to colon. A space, a quote or a control character is a syntax error.
+		// Strictly speaking, control chars include the range [0x7f, 0x9f], not just
+		// [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
+		// as it is simpler to inspect the tag's bytes than the tag's runes.
+		i = 0
+		for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
+			i++
+		}
+		if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
+			break
+		}
+		name := string(tag[:i])
+		tag = tag[i+1:]
+
+		// Scan quoted string to find value.
+		i = 1
+		for i < len(tag) && tag[i] != '"' {
+			if tag[i] == '\\' {
+				i++
+			}
+			i++
+		}
+		if i >= len(tag) {
+			break
+		}
+		qvalue := string(tag[:i+1])
+		tag = tag[i+1:]
+
+		value, err := strconv.Unquote(qvalue)
+		if err != nil {
+			return nil, err
+		}
+		out[name] = append(out[name], value)
+	}
+	return out, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go b/vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go
new file mode 100644
index 0000000..f0ab7ec
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go
@@ -0,0 +1,409 @@
+package sa5009
+
+import (
+	"fmt"
+	"go/constant"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+	"honnef.co/go/tools/printf"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA5009",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Invalid Printf call`,
+		Since:    "2019.2",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+// TODO(dh): detect printf wrappers
+var rules = map[string]callcheck.Check{
+	"fmt.Errorf":                  func(call *callcheck.Call) { check(call, 0, 1) },
+	"fmt.Printf":                  func(call *callcheck.Call) { check(call, 0, 1) },
+	"fmt.Sprintf":                 func(call *callcheck.Call) { check(call, 0, 1) },
+	"fmt.Fprintf":                 func(call *callcheck.Call) { check(call, 1, 2) },
+	"golang.org/x/xerrors.Errorf": func(call *callcheck.Call) { check(call, 0, 1) },
+}
+
+type verbFlag int
+
+const (
+	isInt verbFlag = 1 << iota
+	isBool
+	isFP
+	isString
+	isPointer
+	// Verbs that accept "pseudo pointers" will sometimes dereference
+	// non-nil pointers. For example, %x on a non-nil *struct will print the
+	// individual fields, but on a nil pointer it will print the address.
+	isPseudoPointer
+	isSlice
+	isAny
+	noRecurse
+)
+
+var verbs = [...]verbFlag{
+	'b': isPseudoPointer | isInt | isFP,
+	'c': isInt,
+	'd': isPseudoPointer | isInt,
+	'e': isFP,
+	'E': isFP,
+	'f': isFP,
+	'F': isFP,
+	'g': isFP,
+	'G': isFP,
+	'o': isPseudoPointer | isInt,
+	'O': isPseudoPointer | isInt,
+	'p': isSlice | isPointer | noRecurse,
+	'q': isInt | isString,
+	's': isString,
+	't': isBool,
+	'T': isAny,
+	'U': isInt,
+	'v': isAny,
+	'X': isPseudoPointer | isInt | isFP | isString,
+	'x': isPseudoPointer | isInt | isFP | isString,
+}
+
+func check(call *callcheck.Call, fIdx, vIdx int) {
+	f := call.Args[fIdx]
+	var args []ir.Value
+	switch v := call.Args[vIdx].Value.Value.(type) {
+	case *ir.Slice:
+		var ok bool
+		args, ok = irutil.Vararg(v)
+		if !ok {
+			// We don't know what the actual arguments to the function are
+			return
+		}
+	case *ir.Const:
+		// nil, i.e. no arguments
+	default:
+		// We don't know what the actual arguments to the function are
+		return
+	}
+	checkImpl(f, f.Value.Value, args)
+}
+
+func checkImpl(carg *callcheck.Argument, f ir.Value, args []ir.Value) {
+	var msCache *typeutil.MethodSetCache
+	if f.Parent() != nil {
+		msCache = &f.Parent().Prog.MethodSets
+	}
+
+	elem := func(T types.Type, verb rune) ([]types.Type, bool) {
+		if verbs[verb]&noRecurse != 0 {
+			return []types.Type{T}, false
+		}
+		switch T := T.(type) {
+		case *types.Slice:
+			if verbs[verb]&isSlice != 0 {
+				return []types.Type{T}, false
+			}
+			if verbs[verb]&isString != 0 && types.Identical(T.Elem().Underlying(), types.Typ[types.Byte]) {
+				return []types.Type{T}, false
+			}
+			return []types.Type{T.Elem()}, true
+		case *types.Map:
+			key := T.Key()
+			val := T.Elem()
+			return []types.Type{key, val}, true
+		case *types.Struct:
+			out := make([]types.Type, 0, T.NumFields())
+			for field := range T.Fields() {
+				out = append(out, field.Type())
+			}
+			return out, true
+		case *types.Array:
+			return []types.Type{T.Elem()}, true
+		default:
+			return []types.Type{T}, false
+		}
+	}
+	isInfo := func(T types.Type, info types.BasicInfo) bool {
+		basic, ok := T.Underlying().(*types.Basic)
+		return ok && basic.Info()&info != 0
+	}
+
+	isFormatter := func(T types.Type, ms *types.MethodSet) bool {
+		sel := ms.Lookup(nil, "Format")
+		if sel == nil {
+			return false
+		}
+		fn, ok := sel.Obj().(*types.Func)
+		if !ok {
+			// should be unreachable
+			return false
+		}
+		sig := fn.Type().(*types.Signature)
+		if sig.Params().Len() != 2 {
+			return false
+		}
+		// TODO(dh): check the types of the arguments for more
+		// precision
+		if sig.Results().Len() != 0 {
+			return false
+		}
+		return true
+	}
+
+	var seen typeutil.Map[struct{}]
+	var checkType func(verb rune, T types.Type, top bool) bool
+	checkType = func(verb rune, T types.Type, top bool) bool {
+		if top {
+			seen = typeutil.Map[struct{}]{}
+		}
+		if _, ok := seen.At(T); ok {
+			return true
+		}
+		seen.Set(T, struct{}{})
+		if int(verb) >= len(verbs) {
+			// Unknown verb
+			return true
+		}
+
+		flags := verbs[verb]
+		if flags == 0 {
+			// Unknown verb
+			return true
+		}
+
+		ms := msCache.MethodSet(T)
+		if isFormatter(T, ms) {
+			// the value is responsible for formatting itself
+			return true
+		}
+
+		if flags&isString != 0 && (types.Implements(T, knowledge.Interfaces["fmt.Stringer"]) || types.Implements(T, knowledge.Interfaces["error"])) {
+			// Check for stringer early because we're about to dereference
+			return true
+		}
+
+		T = T.Underlying()
+		if flags&(isPointer|isPseudoPointer) == 0 && top {
+			T = typeutil.Dereference(T)
+		}
+		if flags&isPseudoPointer != 0 && top {
+			t := typeutil.Dereference(T)
+			if _, ok := t.Underlying().(*types.Struct); ok {
+				T = t
+			}
+		}
+
+		if _, ok := T.(*types.Interface); ok {
+			// We don't know what's in the interface
+			return true
+		}
+
+		var info types.BasicInfo
+		if flags&isInt != 0 {
+			info |= types.IsInteger
+		}
+		if flags&isBool != 0 {
+			info |= types.IsBoolean
+		}
+		if flags&isFP != 0 {
+			info |= types.IsFloat | types.IsComplex
+		}
+		if flags&isString != 0 {
+			info |= types.IsString
+		}
+
+		if info != 0 && isInfo(T, info) {
+			return true
+		}
+
+		if flags&isString != 0 {
+			isStringyElem := func(typ types.Type) bool {
+				if typ, ok := typ.Underlying().(*types.Basic); ok {
+					return typ.Kind() == types.Byte
+				}
+				return false
+			}
+			switch T := T.(type) {
+			case *types.Slice:
+				if isStringyElem(T.Elem()) {
+					return true
+				}
+			case *types.Array:
+				if isStringyElem(T.Elem()) {
+					return true
+				}
+			}
+			if types.Implements(T, knowledge.Interfaces["fmt.Stringer"]) || types.Implements(T, knowledge.Interfaces["error"]) {
+				return true
+			}
+		}
+
+		if flags&isPointer != 0 && typeutil.MaybePointerLike(T) {
+			return true
+		}
+		if flags&isPseudoPointer != 0 {
+			switch U := T.Underlying().(type) {
+			case *types.Pointer:
+				if !top {
+					return true
+				}
+
+				if _, ok := U.Elem().Underlying().(*types.Struct); !ok {
+					// TODO(dh): can this condition ever be false? For
+					// *T, if T is a struct, we'll already have
+					// dereferenced it, meaning the *types.Pointer
+					// branch couldn't have been taken. For T that
+					// aren't structs, this condition will always
+					// evaluate to true.
+					return true
+				}
+			case *types.Chan, *types.Signature:
+				// Channels and functions are always treated as
+				// pointers and never recursed into.
+				return true
+			case *types.Basic:
+				if U.Kind() == types.UnsafePointer {
+					return true
+				}
+			case *types.Interface:
+				// we will already have bailed if the type is an
+				// interface.
+				panic("unreachable")
+			default:
+				// other pointer-like types, such as maps or slices,
+				// will be printed element-wise.
+			}
+		}
+
+		if flags&isSlice != 0 {
+			if _, ok := T.(*types.Slice); ok {
+				return true
+			}
+		}
+
+		if flags&isAny != 0 {
+			return true
+		}
+
+		elems, ok := elem(T.Underlying(), verb)
+		if !ok {
+			return false
+		}
+		for _, elem := range elems {
+			if !checkType(verb, elem, false) {
+				return false
+			}
+		}
+
+		return true
+	}
+
+	k, ok := irutil.Flatten(f).(*ir.Const)
+	if !ok {
+		return
+	}
+	actions, err := printf.Parse(constant.StringVal(k.Value))
+	if err != nil {
+		carg.Invalid("couldn't parse format string")
+		return
+	}
+
+	ptr := 1
+	hasExplicit := false
+
+	checkStar := func(verb printf.Verb, star printf.Argument) bool {
+		if star, ok := star.(printf.Star); ok {
+			idx := 0
+			if star.Index == -1 {
+				idx = ptr
+				ptr++
+			} else {
+				hasExplicit = true
+				idx = star.Index
+				ptr = star.Index + 1
+			}
+			if idx == 0 {
+				carg.Invalid(fmt.Sprintf("Printf format %s reads invalid arg 0; indices are 1-based", verb.Raw))
+				return false
+			}
+			if idx > len(args) {
+				carg.Invalid(
+					fmt.Sprintf("Printf format %s reads arg #%d, but call has only %d args",
+						verb.Raw, idx, len(args)))
+				return false
+			}
+			if arg, ok := args[idx-1].(*ir.MakeInterface); ok {
+				if !isInfo(arg.X.Type(), types.IsInteger) {
+					carg.Invalid(fmt.Sprintf("Printf format %s reads non-int arg #%d as argument of *", verb.Raw, idx))
+				}
+			}
+		}
+		return true
+	}
+
+	// We only report one problem per format string. Making a
+	// mistake with an index tends to invalidate all future
+	// implicit indices.
+	for _, action := range actions {
+		verb, ok := action.(printf.Verb)
+		if !ok {
+			continue
+		}
+
+		if !checkStar(verb, verb.Width) || !checkStar(verb, verb.Precision) {
+			return
+		}
+
+		off := ptr
+		if verb.Value != -1 {
+			hasExplicit = true
+			off = verb.Value
+		}
+		if off > len(args) {
+			carg.Invalid(
+				fmt.Sprintf("Printf format %s reads arg #%d, but call has only %d args",
+					verb.Raw, off, len(args)))
+			return
+		} else if verb.Value == 0 && verb.Letter != '%' {
+			carg.Invalid(fmt.Sprintf("Printf format %s reads invalid arg 0; indices are 1-based", verb.Raw))
+			return
+		} else if off != 0 {
+			arg, ok := args[off-1].(*ir.MakeInterface)
+			if ok {
+				if !checkType(verb.Letter, arg.X.Type(), true) {
+					carg.Invalid(fmt.Sprintf("Printf format %s has arg #%d of wrong type %s",
+						verb.Raw, ptr, args[ptr-1].(*ir.MakeInterface).X.Type()))
+					return
+				}
+			}
+		}
+
+		switch verb.Value {
+		case -1:
+			// Consume next argument
+			ptr++
+		case 0:
+			// Don't consume any arguments
+		default:
+			ptr = verb.Value + 1
+		}
+	}
+
+	if !hasExplicit && ptr <= len(args) {
+		carg.Invalid(fmt.Sprintf("Printf call needs %d args but has %d args", ptr-1, len(args)))
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5010/sa5010.go b/vendor/honnef.co/go/tools/staticcheck/sa5010/sa5010.go
new file mode 100644
index 0000000..684d530
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5010/sa5010.go
@@ -0,0 +1,115 @@
+package sa5010
+
+import (
+	"fmt"
+	"go/types"
+	"strings"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA5010",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Impossible type assertion`,
+
+		Text: `Some type assertions can be statically proven to be
+impossible. This is the case when the method sets of both
+arguments of the type assertion conflict with each other, for
+example by containing the same method with different
+signatures.
+
+The Go compiler already applies this check when asserting from an
+interface value to a concrete type. If the concrete type misses
+methods from the interface, or if function signatures don't match,
+then the type assertion can never succeed.
+
+This check applies the same logic when asserting from one interface to
+another. If both interface types contain the same method but with
+different signatures, then the type assertion can never succeed,
+either.`,
+
+		Since:    "2020.1",
+		Severity: lint.SeverityWarning,
+		// Technically this should be MergeIfAll, but the Go compiler
+		// already flags some impossible type assertions, so
+		// MergeIfAny is consistent with the compiler.
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	type entry struct {
+		l, r *types.Func
+	}
+
+	msc := &pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg.Prog.MethodSets
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		for _, b := range fn.Blocks {
+		instrLoop:
+			for _, instr := range b.Instrs {
+				assert, ok := instr.(*ir.TypeAssert)
+				if !ok {
+					continue
+				}
+				var wrong []entry
+				left := assert.X.Type()
+				right := assert.AssertedType
+				righti, ok := right.Underlying().(*types.Interface)
+
+				if !ok {
+					// We only care about interface->interface
+					// assertions. The Go compiler already catches
+					// impossible interface->concrete assertions.
+					continue
+				}
+
+				ms := msc.MethodSet(left)
+				for mr := range righti.Methods() {
+					sel := ms.Lookup(mr.Pkg(), mr.Name())
+					if sel == nil {
+						continue
+					}
+					ml := sel.Obj().(*types.Func)
+					if ml.Origin() != ml || mr.Origin() != mr {
+						// Give up when we see generics.
+						//
+						// TODO(dh): support generics once go/types gets an
+						// exported API for type unification.
+						continue instrLoop
+					}
+					if types.AssignableTo(ml.Type(), mr.Type()) {
+						continue
+					}
+
+					wrong = append(wrong, entry{ml, mr})
+				}
+
+				if len(wrong) != 0 {
+					var s strings.Builder
+					s.WriteString(fmt.Sprintf("impossible type assertion; %s and %s contradict each other:",
+						types.TypeString(left, types.RelativeTo(pass.Pkg)),
+						types.TypeString(right, types.RelativeTo(pass.Pkg))))
+					for _, e := range wrong {
+						s.WriteString(fmt.Sprintf("\n\twrong type for %s method", e.l.Name()))
+						s.WriteString(fmt.Sprintf("\n\t\thave %s", e.l.Type()))
+						s.WriteString(fmt.Sprintf("\n\t\twant %s", e.r.Type()))
+					}
+					report.Report(pass, assert, s.String())
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5012/sa5012.go b/vendor/honnef.co/go/tools/staticcheck/sa5012/sa5012.go
new file mode 100644
index 0000000..51dc39f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5012/sa5012.go
@@ -0,0 +1,287 @@
+package sa5012
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/iterutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:      "SA5012",
+		Run:       run,
+		FactTypes: []analysis.Fact{new(evenElements)},
+		Requires:  []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "Passing odd-sized slice to function expecting even size",
+		Text: `Some functions that take slices as parameters expect the slices to have an even number of elements. 
+Often, these functions treat elements in a slice as pairs. 
+For example, \'strings.NewReplacer\' takes pairs of old and new strings, 
+and calling it with an odd number of elements would be an error.`,
+		Since:    "2020.2",
+		Severity: lint.SeverityError,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+type evenElements struct{}
+
+func (evenElements) AFact() {}
+
+func (evenElements) String() string { return "needs even elements" }
+
+func findSliceLength(v ir.Value) int {
+	// TODO(dh): VRP would help here
+
+	v = irutil.Flatten(v)
+	val := func(v ir.Value) int {
+		if v, ok := v.(*ir.Const); ok {
+			return int(v.Int64())
+		}
+		return -1
+	}
+	switch v := v.(type) {
+	case *ir.Slice:
+		low := 0
+		high := -1
+		if v.Low != nil {
+			low = val(v.Low)
+		}
+		if v.High != nil {
+			high = val(v.High)
+		} else {
+			switch vv := v.X.(type) {
+			case *ir.Alloc:
+				high = int(typeutil.Dereference(vv.Type()).Underlying().(*types.Array).Len())
+			case *ir.Slice:
+				high = findSliceLength(vv)
+			}
+		}
+		if low == -1 || high == -1 {
+			return -1
+		}
+		return high - low
+	default:
+		return -1
+	}
+}
+
+func flagSliceLens(pass *analysis.Pass) {
+	var tag evenElements
+
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		for _, b := range fn.Blocks {
+			for _, instr := range b.Instrs {
+				call, ok := instr.(ir.CallInstruction)
+				if !ok {
+					continue
+				}
+				callee := call.Common().StaticCallee()
+				if callee == nil {
+					continue
+				}
+				for argi, arg := range call.Common().Args {
+					if callee.Signature.Recv() != nil {
+						if argi == 0 {
+							continue
+						}
+						argi--
+					}
+
+					_, ok := arg.Type().Underlying().(*types.Slice)
+					if !ok {
+						continue
+					}
+					param := callee.Signature.Params().At(argi)
+					if !pass.ImportObjectFact(param, &tag) {
+						continue
+					}
+
+					// TODO handle stubs
+
+					// we know the argument has to have even length.
+					// now let's try to find its length
+					if n := findSliceLength(arg); n > -1 && n%2 != 0 {
+						src := call.Source().(*ast.CallExpr).Args[argi]
+						sig := call.Common().Signature()
+						var label string
+						if argi == sig.Params().Len()-1 && sig.Variadic() {
+							label = "variadic argument"
+						} else {
+							label = "argument"
+						}
+						// Note that param.Name() is guaranteed to not
+						// be empty, otherwise the function couldn't
+						// have enforced its length.
+						report.Report(pass, src, fmt.Sprintf("%s %q is expected to have even number of elements, but has %d elements", label, param.Name(), n))
+					}
+				}
+			}
+		}
+	}
+}
+
+func findSliceLenChecks(pass *analysis.Pass) {
+	// mark all function parameters that have to be of even length
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		for _, b := range fn.Blocks {
+			// all paths go through this block
+			if !iterutil.All(fn.Returns(), b.Dominates) {
+				continue
+			}
+
+			// if foo % 2 != 0
+			ifi, ok := b.Control().(*ir.If)
+			if !ok {
+				continue
+			}
+			cmp, ok := ifi.Cond.(*ir.BinOp)
+			if !ok {
+				continue
+			}
+			var needle uint64
+			switch cmp.Op {
+			case token.NEQ:
+				// look for != 0
+				needle = 0
+			case token.EQL:
+				// look for == 1
+				needle = 1
+			default:
+				continue
+			}
+
+			rem, ok1 := cmp.X.(*ir.BinOp)
+			k, ok2 := cmp.Y.(*ir.Const)
+			if ok1 != ok2 {
+				continue
+			}
+			if !ok1 {
+				rem, ok1 = cmp.Y.(*ir.BinOp)
+				k, ok2 = cmp.X.(*ir.Const)
+			}
+			if !ok1 || !ok2 || rem.Op != token.REM || k.Value.Kind() != constant.Int || k.Uint64() != needle {
+				continue
+			}
+			k, ok = rem.Y.(*ir.Const)
+			if !ok || k.Value.Kind() != constant.Int || k.Uint64() != 2 {
+				continue
+			}
+
+			// if len(foo) % 2 != 0
+			call, ok := rem.X.(*ir.Call)
+			if !ok || !irutil.IsCallTo(call.Common(), "len") {
+				continue
+			}
+
+			// we're checking the length of a parameter that is a slice
+			// TODO(dh): support parameters that have flown through sigmas and phis
+			param, ok := call.Call.Args[0].(*ir.Parameter)
+			if !ok {
+				continue
+			}
+			if !typeutil.All(param.Type(), typeutil.IsSlice) {
+				continue
+			}
+
+			// if len(foo) % 2 != 0 then panic
+			if _, ok := b.Succs[0].Control().(*ir.Panic); !ok {
+				continue
+			}
+
+			pass.ExportObjectFact(param.Object(), new(evenElements))
+		}
+	}
+}
+
+func findIndirectSliceLenChecks(pass *analysis.Pass) {
+	seen := map[*ir.Function]struct{}{}
+
+	var doFunction func(fn *ir.Function)
+	doFunction = func(fn *ir.Function) {
+		if _, ok := seen[fn]; ok {
+			return
+		}
+		seen[fn] = struct{}{}
+
+		for _, b := range fn.Blocks {
+			// all paths go through this block
+			if !iterutil.All(fn.Returns(), b.Dominates) {
+				continue
+			}
+
+			for _, instr := range b.Instrs {
+				call, ok := instr.(*ir.Call)
+				if !ok {
+					continue
+				}
+				callee := call.Call.StaticCallee()
+				if callee == nil {
+					continue
+				}
+
+				if callee.Pkg == fn.Pkg || callee.Pkg == nil {
+					doFunction(callee)
+				}
+
+				for argi, arg := range call.Call.Args {
+					if callee.Signature.Recv() != nil {
+						if argi == 0 {
+							continue
+						}
+						argi--
+					}
+
+					// TODO(dh): support parameters that have flown through length-preserving instructions
+					param, ok := arg.(*ir.Parameter)
+					if !ok {
+						continue
+					}
+					if !typeutil.All(param.Type(), typeutil.IsSlice) {
+						continue
+					}
+
+					// We can't use callee.Params to look up the
+					// parameter, because Params is not populated for
+					// external functions. In our modular analysis.
+					// any function in any package that isn't the
+					// current package is considered "external", as it
+					// has been loaded from export data only.
+					sigParams := callee.Signature.Params()
+
+					if !pass.ImportObjectFact(sigParams.At(argi), new(evenElements)) {
+						continue
+					}
+					pass.ExportObjectFact(param.Object(), new(evenElements))
+				}
+			}
+		}
+	}
+
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		doFunction(fn)
+	}
+}
+
+func run(pass *analysis.Pass) (any, error) {
+	findSliceLenChecks(pass)
+	findIndirectSliceLenChecks(pass)
+	flagSliceLens(pass)
+
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa6000/sa6000.go b/vendor/honnef.co/go/tools/staticcheck/sa6000/sa6000.go
new file mode 100644
index 0000000..958cc8f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa6000/sa6000.go
@@ -0,0 +1,57 @@
+package sa6000
+
+import (
+	"fmt"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA6000",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Using \'regexp.Match\' or related in a loop, should use \'regexp.Compile\'`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"regexp.Match":       check("regexp.Match"),
+	"regexp.MatchReader": check("regexp.MatchReader"),
+	"regexp.MatchString": check("regexp.MatchString"),
+}
+
+func check(name string) callcheck.Check {
+	return func(call *callcheck.Call) {
+		if callcheck.ExtractConst(call.Args[0].Value) == nil {
+			return
+		}
+		if !isInLoop(call.Instr.Block()) {
+			return
+		}
+		call.Invalid(fmt.Sprintf("calling %s in a loop has poor performance, consider using regexp.Compile", name))
+	}
+}
+
+func isInLoop(b *ir.BasicBlock) bool {
+	sets := irutil.FindLoops(b.Parent())
+	for _, set := range sets {
+		if set.Has(b) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa6001/sa6001.go b/vendor/honnef.co/go/tools/staticcheck/sa6001/sa6001.go
new file mode 100644
index 0000000..c164967
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa6001/sa6001.go
@@ -0,0 +1,115 @@
+package sa6001
+
+import (
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA6001",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Missing an optimization opportunity when indexing maps by byte slices`,
+
+		Text: `Map keys must be comparable, which precludes the use of byte slices.
+This usually leads to using string keys and converting byte slices to
+strings.
+
+Normally, a conversion of a byte slice to a string needs to copy the data and
+causes allocations. The compiler, however, recognizes \'m[string(b)]\' and
+uses the data of \'b\' directly, without copying it, because it knows that
+the data can't change during the map lookup. This leads to the
+counter-intuitive situation that
+
+    k := string(b)
+    println(m[k])
+    println(m[k])
+
+will be less efficient than
+
+    println(m[string(b)])
+    println(m[string(b)])
+
+because the first version needs to copy and allocate, while the second
+one does not.
+
+For some history on this optimization, check out commit
+f5f5a8b6209f84961687d993b93ea0d397f5d5bf in the Go repository.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		for _, b := range fn.Blocks {
+		insLoop:
+			for _, ins := range b.Instrs {
+				var fromType types.Type
+				var toType types.Type
+
+				// find []byte -> string conversions
+				switch ins := ins.(type) {
+				case *ir.Convert:
+					fromType = ins.X.Type()
+					toType = ins.Type()
+				case *ir.MultiConvert:
+					fromType = ins.X.Type()
+					toType = ins.Type()
+				default:
+					continue
+				}
+				if toType != types.Universe.Lookup("string").Type() {
+					continue
+				}
+				tset := typeutil.NewTypeSet(fromType)
+				// If at least one of the types is []byte, then it's more efficient to inline the conversion
+				if !tset.Any(func(term *types.Term) bool {
+					s, ok := term.Type().Underlying().(*types.Slice)
+					return ok && s.Elem().Underlying() == types.Universe.Lookup("byte").Type()
+				}) {
+					continue
+				}
+				refs := ins.Referrers()
+				anyUses := false
+				for _, ref := range *refs {
+					switch ref := ref.(type) {
+					case *ir.MapLookup:
+						anyUses = true
+						if src, ok := ref.Source().(*ast.IndexExpr); ok {
+							if _, ok := src.Index.(*ast.Ident); !ok {
+								continue insLoop
+							}
+						} else {
+							continue insLoop
+						}
+					default:
+						// the string is used somewhere else than a
+						// map lookup
+						continue insLoop
+					}
+				}
+
+				if !anyUses {
+					continue
+				}
+				report.Report(pass, ins, "m[string(key)] would be more efficient than k := string(key); m[k]")
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa6002/sa6002.go b/vendor/honnef.co/go/tools/staticcheck/sa6002/sa6002.go
new file mode 100644
index 0000000..edfe60a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa6002/sa6002.go
@@ -0,0 +1,52 @@
+package sa6002
+
+import (
+	"go/types"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA6002",
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+		Run:      callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Storing non-pointer values in \'sync.Pool\' allocates memory`,
+		Text: `A \'sync.Pool\' is used to avoid unnecessary allocations and reduce the
+amount of work the garbage collector has to do.
+
+When passing a value that is not a pointer to a function that accepts
+an interface, the value needs to be placed on the heap, which means an
+additional allocation. Slices are a common thing to put in sync.Pools,
+and they're structs with 3 fields (length, capacity, and a pointer to
+an array). In order to avoid the extra allocation, one should store a
+pointer to the slice instead.
+
+See the comments on https://go-review.googlesource.com/c/go/+/24371
+that discuss this problem.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	"(*sync.Pool).Put": func(call *callcheck.Call) {
+		arg := call.Args[knowledge.Arg("(*sync.Pool).Put.x")]
+		typ := arg.Value.Value.Type()
+		_, isSlice := typ.Underlying().(*types.Slice)
+		if !typeutil.MaybePointerLike(typ) || isSlice {
+			arg.Invalid("argument should be pointer-like to avoid allocations")
+		}
+	},
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa6003/sa6003.go b/vendor/honnef.co/go/tools/staticcheck/sa6003/sa6003.go
new file mode 100644
index 0000000..271ee9f
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa6003/sa6003.go
@@ -0,0 +1,42 @@
+package sa6003
+
+import (
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/internal/sharedcheck"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA6003",
+		Run:      sharedcheck.CheckRangeStringRunes,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Converting a string to a slice of runes before ranging over it`,
+		Text: `You may want to loop over the runes in a string. Instead of converting
+the string to a slice of runes and looping over that, you can loop
+over the string itself. That is,
+
+    for _, r := range s {}
+
+and
+
+    for _, r := range []rune(s) {}
+
+will yield the same values. The first version, however, will be faster
+and avoid unnecessary memory allocations.
+
+Do note that if you are interested in the indices, ranging over a
+string and over a slice of runes will yield different indices. The
+first one yields byte offsets, while the second one yields indices in
+the slice of runes.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa6005/sa6005.go b/vendor/honnef.co/go/tools/staticcheck/sa6005/sa6005.go
new file mode 100644
index 0000000..05cfc1c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa6005/sa6005.go
@@ -0,0 +1,78 @@
+package sa6005
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA6005",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Inefficient string comparison with \'strings.ToLower\' or \'strings.ToUpper\'`,
+		Text: `Converting two strings to the same case and comparing them like so
+
+    if strings.ToLower(s1) == strings.ToLower(s2) {
+        ...
+    }
+
+is significantly more expensive than comparing them with
+\'strings.EqualFold(s1, s2)\'. This is due to memory usage as well as
+computational complexity.
+
+\'strings.ToLower\' will have to allocate memory for the new strings, as
+well as convert both strings fully, even if they differ on the very
+first byte. strings.EqualFold, on the other hand, compares the strings
+one character at a time. It doesn't need to create two intermediate
+strings and can return as soon as the first non-matching character has
+been found.
+
+For a more in-depth explanation of this issue, see
+https://blog.digitalocean.com/how-to-efficiently-compare-strings-in-go/`,
+		Since:    "2019.2",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkToLowerToUpperComparisonQ = pattern.MustParse(`
+	(BinaryExpr
+		(CallExpr fun@(Symbol (Or "strings.ToLower" "strings.ToUpper")) [a])
+ 		tok@(Or "==" "!=")
+ 		(CallExpr fun [b]))`)
+	checkToLowerToUpperComparisonR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "strings") (Ident "EqualFold")) [a b])`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkToLowerToUpperComparisonQ) {
+		rn := pattern.NodeToAST(checkToLowerToUpperComparisonR.Root, m.State).(ast.Expr)
+		method := "strings.EqualFold"
+		if m.State["tok"].(token.Token) == token.NEQ {
+			rn = &ast.UnaryExpr{
+				Op: token.NOT,
+				X:  rn,
+			}
+			method = "!" + method
+		}
+
+		report.Report(pass, node,
+			fmt.Sprintf("should use %s instead", method),
+			report.Fixes(edit.Fix("replace with "+method, edit.ReplaceWithNode(pass.Fset, node, rn))))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa6006/sa6006.go b/vendor/honnef.co/go/tools/staticcheck/sa6006/sa6006.go
new file mode 100644
index 0000000..bc56848
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa6006/sa6006.go
@@ -0,0 +1,46 @@
+package sa6006
+
+import (
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA6006",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Using io.WriteString to write \'[]byte\'`,
+		Text: `Using io.WriteString to write a slice of bytes, as in
+
+    io.WriteString(w, string(b))
+
+is both unnecessary and inefficient. Converting from \'[]byte\' to \'string\'
+has to allocate and copy the data, and we could simply use \'w.Write(b)\'
+instead.`,
+
+		Since: "2024.1",
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var ioWriteStringConversion = pattern.MustParse(`(CallExpr (Symbol "io.WriteString") [_ (CallExpr (Builtin "string") [arg])])`)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, ioWriteStringConversion) {
+		if !code.IsOfStringConvertibleByteSlice(pass, m.State["arg"].(ast.Expr)) {
+			continue
+		}
+		report.Report(pass, node, "use io.Writer.Write instead of converting from []byte to string to use io.WriteString")
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9001/sa9001.go b/vendor/honnef.co/go/tools/staticcheck/sa9001/sa9001.go
new file mode 100644
index 0000000..2be35c0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9001/sa9001.go
@@ -0,0 +1,69 @@
+package sa9001
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA9001",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Defers in range loops may not run when you expect them to`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		loop := node.(*ast.RangeStmt)
+		typ := pass.TypesInfo.TypeOf(loop.X)
+		_, ok := typeutil.CoreType(typ).(*types.Chan)
+		if !ok {
+			return
+		}
+
+		stmts := []*ast.DeferStmt{}
+		exits := false
+		fn2 := func(node ast.Node) bool {
+			switch stmt := node.(type) {
+			case *ast.DeferStmt:
+				stmts = append(stmts, stmt)
+			case *ast.FuncLit:
+				// Don't look into function bodies
+				return false
+			case *ast.ReturnStmt:
+				exits = true
+			case *ast.BranchStmt:
+				exits = node.(*ast.BranchStmt).Tok == token.BREAK
+			}
+			return true
+		}
+		ast.Inspect(loop.Body, fn2)
+
+		if exits {
+			return
+		}
+		for _, stmt := range stmts {
+			report.Report(pass, stmt, "defers in this range loop won't run unless the channel gets closed")
+		}
+	}
+	code.Preorder(pass, fn, (*ast.RangeStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9002/sa9002.go b/vendor/honnef.co/go/tools/staticcheck/sa9002/sa9002.go
new file mode 100644
index 0000000..4923bae
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9002/sa9002.go
@@ -0,0 +1,63 @@
+package sa9002
+
+import (
+	"fmt"
+	"go/ast"
+	"strconv"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA9002",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:    `Using a non-octal \'os.FileMode\' that looks like it was meant to be in octal.`,
+		Since:    "2017.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		call := node.(*ast.CallExpr)
+		for _, arg := range call.Args {
+			lit, ok := arg.(*ast.BasicLit)
+			if !ok {
+				continue
+			}
+			if !typeutil.IsTypeWithName(pass.TypesInfo.TypeOf(lit), "os.FileMode") &&
+				!typeutil.IsTypeWithName(pass.TypesInfo.TypeOf(lit), "io/fs.FileMode") {
+				continue
+			}
+			if len(lit.Value) == 3 &&
+				lit.Value[0] != '0' &&
+				lit.Value[0] >= '0' && lit.Value[0] <= '7' &&
+				lit.Value[1] >= '0' && lit.Value[1] <= '7' &&
+				lit.Value[2] >= '0' && lit.Value[2] <= '7' {
+
+				v, err := strconv.ParseInt(lit.Value, 10, 64)
+				if err != nil {
+					continue
+				}
+				report.Report(pass, arg, fmt.Sprintf("file mode '%s' evaluates to %#o; did you mean '0%s'?", lit.Value, v, lit.Value),
+					report.Fixes(edit.Fix("Fix octal literal", edit.ReplaceWithString(arg, "0"+lit.Value))))
+			}
+		}
+	}
+	code.Preorder(pass, fn, (*ast.CallExpr)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9003/sa9003.go b/vendor/honnef.co/go/tools/staticcheck/sa9003/sa9003.go
new file mode 100644
index 0000000..0824eb4
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9003/sa9003.go
@@ -0,0 +1,62 @@
+package sa9003
+
+import (
+	"go/ast"
+
+	"golang.org/x/tools/go/analysis"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA9003",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:      `Empty body in an if or else branch`,
+		Since:      "2017.1",
+		NonDefault: true,
+		Severity:   lint.SeverityWarning,
+		MergeIf:    lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		if fn.Source() == nil {
+			continue
+		}
+		if irutil.IsExample(fn) {
+			continue
+		}
+		cb := func(node ast.Node) bool {
+			ifstmt, ok := node.(*ast.IfStmt)
+			if !ok {
+				return true
+			}
+			if ifstmt.Else != nil {
+				b, ok := ifstmt.Else.(*ast.BlockStmt)
+				if !ok || len(b.List) != 0 {
+					return true
+				}
+				report.Report(pass, ifstmt.Else, "empty branch", report.FilterGenerated(), report.ShortRange())
+			}
+			if len(ifstmt.Body.List) != 0 {
+				return true
+			}
+			report.Report(pass, ifstmt, "empty branch", report.FilterGenerated(), report.ShortRange())
+			return true
+		}
+		if source := fn.Source(); source != nil {
+			ast.Inspect(source, cb)
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9004/sa9004.go b/vendor/honnef.co/go/tools/staticcheck/sa9004/sa9004.go
new file mode 100644
index 0000000..acf242e
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9004/sa9004.go
@@ -0,0 +1,185 @@
+package sa9004
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA9004",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Only the first constant has an explicit type`,
+
+		Text: `In a constant declaration such as the following:
+
+    const (
+        First byte = 1
+        Second     = 2
+    )
+
+the constant Second does not have the same type as the constant First.
+This construct shouldn't be confused with
+
+    const (
+        First byte = iota
+        Second
+    )
+
+where \'First\' and \'Second\' do indeed have the same type. The type is only
+passed on when no explicit value is assigned to the constant.
+
+When declaring enumerations with explicit values it is therefore
+important not to write
+
+    const (
+          EnumFirst EnumType = 1
+          EnumSecond         = 2
+          EnumThird          = 3
+    )
+
+This discrepancy in types can cause various confusing behaviors and
+bugs.
+
+
+Wrong type in variable declarations
+
+The most obvious issue with such incorrect enumerations expresses
+itself as a compile error:
+
+    package pkg
+
+    const (
+        EnumFirst  uint8 = 1
+        EnumSecond       = 2
+    )
+
+    func fn(useFirst bool) {
+        x := EnumSecond
+        if useFirst {
+            x = EnumFirst
+        }
+    }
+
+fails to compile with
+
+    ./const.go:11:5: cannot use EnumFirst (type uint8) as type int in assignment
+
+
+Losing method sets
+
+A more subtle issue occurs with types that have methods and optional
+interfaces. Consider the following:
+
+    package main
+
+    import "fmt"
+
+    type Enum int
+
+    func (e Enum) String() string {
+        return "an enum"
+    }
+
+    const (
+        EnumFirst  Enum = 1
+        EnumSecond      = 2
+    )
+
+    func main() {
+        fmt.Println(EnumFirst)
+        fmt.Println(EnumSecond)
+    }
+
+This code will output
+
+    an enum
+    2
+
+as \'EnumSecond\' has no explicit type, and thus defaults to \'int\'.`,
+		Since:    "2019.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		decl := node.(*ast.GenDecl)
+		if !decl.Lparen.IsValid() {
+			return
+		}
+		if decl.Tok != token.CONST {
+			return
+		}
+
+		groups := astutil.GroupSpecs(pass.Fset, decl.Specs)
+	groupLoop:
+		for _, group := range groups {
+			if len(group) < 2 {
+				continue
+			}
+			if group[0].(*ast.ValueSpec).Type == nil {
+				// first constant doesn't have a type
+				continue groupLoop
+			}
+
+			firstType := pass.TypesInfo.TypeOf(group[0].(*ast.ValueSpec).Values[0])
+			for i, spec := range group {
+				spec := spec.(*ast.ValueSpec)
+				if i > 0 && spec.Type != nil {
+					continue groupLoop
+				}
+				if len(spec.Names) != 1 || len(spec.Values) != 1 {
+					continue groupLoop
+				}
+
+				if !types.ConvertibleTo(pass.TypesInfo.TypeOf(spec.Values[0]), firstType) {
+					continue groupLoop
+				}
+
+				switch v := spec.Values[0].(type) {
+				case *ast.BasicLit:
+				case *ast.UnaryExpr:
+					if _, ok := v.X.(*ast.BasicLit); !ok {
+						continue groupLoop
+					}
+				default:
+					// if it's not a literal it might be typed, such as
+					// time.Microsecond = 1000 * Nanosecond
+					continue groupLoop
+				}
+			}
+			var edits []analysis.TextEdit
+			typ := group[0].(*ast.ValueSpec).Type
+			for _, spec := range group[1:] {
+				nspec := *spec.(*ast.ValueSpec)
+				nspec.Type = typ
+				// The position of `spec` node excludes comments (if any).
+				// However, on generating the source back from the node, the comments are included. Setting `Comment` to nil ensures deduplication of comments.
+				nspec.Comment = nil
+				edits = append(edits, edit.ReplaceWithNode(pass.Fset, spec, &nspec))
+			}
+			report.Report(pass, group[0],
+				"only the first constant in this group has an explicit type",
+				report.Fixes(edit.Fix("Add type to all constants in group", edits...)))
+		}
+	}
+	code.Preorder(pass, fn, (*ast.GenDecl)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9005/sa9005.go b/vendor/honnef.co/go/tools/staticcheck/sa9005/sa9005.go
new file mode 100644
index 0000000..d367ecd
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9005/sa9005.go
@@ -0,0 +1,96 @@
+package sa9005
+
+import (
+	"fmt"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/callcheck"
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/knowledge"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name: "SA9005",
+		Requires: []*analysis.Analyzer{
+			buildir.Analyzer,
+			// Filtering generated code because it may include empty structs generated from data models.
+			generated.Analyzer,
+		},
+		Run: callcheck.Analyzer(rules),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Trying to marshal a struct with no public fields nor custom marshaling`,
+		Text: `
+The \'encoding/json\' and \'encoding/xml\' packages only operate on exported
+fields in structs, not unexported ones. It is usually an error to try
+to (un)marshal structs that only consist of unexported fields.
+
+This check will not flag calls involving types that define custom
+marshaling behavior, e.g. via \'MarshalJSON\' methods. It will also not
+flag empty structs.`,
+		Since:    "2019.2",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var rules = map[string]callcheck.Check{
+	// TODO(dh): should we really flag XML? Even an empty struct
+	// produces a non-zero amount of data, namely its type name.
+	// Let's see if we encounter any false positives.
+	//
+	// Also, should we flag gob?
+	"encoding/json.Marshal":           check(knowledge.Arg("json.Marshal.v"), "MarshalJSON", "MarshalText"),
+	"encoding/json.MarshalIndent":     check(knowledge.Arg("json.MarshalIndent.v"), "MarshalJSON", "MarshalText"),
+	"encoding/xml.Marshal":            check(knowledge.Arg("xml.Marshal.v"), "MarshalXML", "MarshalText"),
+	"encoding/xml.MarshalIndent":      check(knowledge.Arg("xml.MarshalIndent.v"), "MarshalXML", "MarshalText"),
+	"(*encoding/json.Encoder).Encode": check(knowledge.Arg("(*encoding/json.Encoder).Encode.v"), "MarshalJSON", "MarshalText"),
+	"(*encoding/xml.Encoder).Encode":  check(knowledge.Arg("(*encoding/xml.Encoder).Encode.v"), "MarshalXML", "MarshalText"),
+
+	"encoding/json.Unmarshal":         check(knowledge.Arg("json.Unmarshal.v"), "UnmarshalJSON", "UnmarshalText"),
+	"encoding/xml.Unmarshal":          check(knowledge.Arg("xml.Unmarshal.v"), "UnmarshalXML", "UnmarshalText"),
+	"(*encoding/json.Decoder).Decode": check(knowledge.Arg("(*encoding/json.Decoder).Decode.v"), "UnmarshalJSON", "UnmarshalText"),
+	"(*encoding/xml.Decoder).Decode":  check(knowledge.Arg("(*encoding/xml.Decoder).Decode.v"), "UnmarshalXML", "UnmarshalText"),
+}
+
+func check(argN int, meths ...string) callcheck.Check {
+	return func(call *callcheck.Call) {
+		if code.IsGenerated(call.Pass, call.Instr.Pos()) {
+			return
+		}
+		arg := call.Args[argN]
+		T := arg.Value.Value.Type()
+		Ts, ok := typeutil.Dereference(T).Underlying().(*types.Struct)
+		if !ok {
+			return
+		}
+		if Ts.NumFields() == 0 {
+			return
+		}
+		fields := typeutil.FlattenFields(Ts)
+		for _, field := range fields {
+			if field.Var.Exported() {
+				return
+			}
+		}
+		// OPT(dh): we could use a method set cache here
+		ms := call.Instr.Parent().Prog.MethodSets.MethodSet(T)
+		// TODO(dh): we're not checking the signature, which can cause false negatives.
+		// This isn't a huge problem, however, since vet complains about incorrect signatures.
+		for _, meth := range meths {
+			if ms.Lookup(nil, meth) != nil {
+				return
+			}
+		}
+		arg.Invalid(fmt.Sprintf("struct type '%s' doesn't have any exported fields, nor custom marshaling", typeutil.Dereference(T)))
+	}
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9006/sa9006.go b/vendor/honnef.co/go/tools/staticcheck/sa9006/sa9006.go
new file mode 100644
index 0000000..4f92ee1
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9006/sa9006.go
@@ -0,0 +1,100 @@
+package sa9006
+
+import (
+	"fmt"
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA9006",
+		Run:      run,
+		Requires: code.RequiredAnalyzers,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Dubious bit shifting of a fixed size integer value`,
+		Text: `Bit shifting a value past its size will always clear the value.
+
+For instance:
+
+    v := int8(42)
+    v >>= 8
+
+will always result in 0.
+
+This check flags bit shifting operations on fixed size integer values only.
+That is, int, uint and uintptr are never flagged to avoid potential false
+positives in somewhat exotic but valid bit twiddling tricks:
+
+    // Clear any value above 32 bits if integers are more than 32 bits.
+    func f(i int) int {
+        v := i >> 32
+        v = v << 32
+        return i-v
+    }`,
+		Since:    "2020.2",
+		Severity: lint.SeverityWarning,
+		// Technically this should be MergeIfAll, because the type of
+		// v might be different for different build tags. Practically,
+		// don't write code that depends on that.
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+var (
+	checkFixedLengthTypeShiftQ = pattern.MustParse(`
+		(Or
+			(AssignStmt _ (Or ">>=" "<<=") _)
+			(BinaryExpr _ (Or ">>" "<<") _))
+	`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	isDubiousShift := func(x, y ast.Expr) (int64, int64, bool) {
+		typ, ok := pass.TypesInfo.TypeOf(x).Underlying().(*types.Basic)
+		if !ok {
+			return 0, 0, false
+		}
+		switch typ.Kind() {
+		case types.Int8, types.Int16, types.Int32, types.Int64,
+			types.Uint8, types.Uint16, types.Uint32, types.Uint64:
+			// We're only interested in fixed–size types.
+		default:
+			return 0, 0, false
+		}
+
+		const bitsInByte = 8
+		typeBits := pass.TypesSizes.Sizeof(typ) * bitsInByte
+
+		shiftLength, ok := code.ExprToInt(pass, y)
+		if !ok {
+			return 0, 0, false
+		}
+
+		return typeBits, shiftLength, shiftLength >= typeBits
+	}
+
+	for node := range code.Matches(pass, checkFixedLengthTypeShiftQ) {
+		switch e := node.(type) {
+		case *ast.AssignStmt:
+			if size, shift, yes := isDubiousShift(e.Lhs[0], e.Rhs[0]); yes {
+				report.Report(pass, e, fmt.Sprintf("shifting %d-bit value by %d bits will always clear it", size, shift))
+			}
+		case *ast.BinaryExpr:
+			if size, shift, yes := isDubiousShift(e.X, e.Y); yes {
+				report.Report(pass, e, fmt.Sprintf("shifting %d-bit value by %d bits will always clear it", size, shift))
+			}
+		}
+	}
+
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9007/sa9007.go b/vendor/honnef.co/go/tools/staticcheck/sa9007/sa9007.go
new file mode 100644
index 0000000..4522590
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9007/sa9007.go
@@ -0,0 +1,114 @@
+package sa9007
+
+import (
+	"fmt"
+	"os"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA9007",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "Deleting a directory that shouldn't be deleted",
+		Text: `
+It is virtually never correct to delete system directories such as
+/tmp or the user's home directory. However, it can be fairly easy to
+do by mistake, for example by mistakenly using \'os.TempDir\' instead
+of \'ioutil.TempDir\', or by forgetting to add a suffix to the result
+of \'os.UserHomeDir\'.
+
+Writing
+
+    d := os.TempDir()
+    defer os.RemoveAll(d)
+
+in your unit tests will have a devastating effect on the stability of your system.
+
+This check flags attempts at deleting the following directories:
+
+- os.TempDir
+- os.UserCacheDir
+- os.UserConfigDir
+- os.UserHomeDir
+`,
+		Since:    "2022.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		for _, b := range fn.Blocks {
+			for _, instr := range b.Instrs {
+				call, ok := instr.(ir.CallInstruction)
+				if !ok {
+					continue
+				}
+				if !irutil.IsCallTo(call.Common(), "os.RemoveAll") {
+					continue
+				}
+
+				kind := ""
+				ex := ""
+				callName := ""
+				arg := irutil.Flatten(call.Common().Args[0])
+				switch arg := arg.(type) {
+				case *ir.Call:
+					callName = irutil.CallName(&arg.Call)
+					if callName != "os.TempDir" {
+						continue
+					}
+					kind = "temporary"
+					ex = os.TempDir()
+				case *ir.Extract:
+					if arg.Index != 0 {
+						continue
+					}
+					first, ok := arg.Tuple.(*ir.Call)
+					if !ok {
+						continue
+					}
+					callName = irutil.CallName(&first.Call)
+					switch callName {
+					case "os.UserCacheDir":
+						kind = "cache"
+						ex, _ = os.UserCacheDir()
+					case "os.UserConfigDir":
+						kind = "config"
+						ex, _ = os.UserConfigDir()
+					case "os.UserHomeDir":
+						kind = "home"
+						ex, _ = os.UserHomeDir()
+					default:
+						continue
+					}
+				default:
+					continue
+				}
+
+				if ex == "" {
+					report.Report(pass, call, fmt.Sprintf("this call to os.RemoveAll deletes the user's entire %s directory, not a subdirectory therein", kind),
+						report.Related(arg, fmt.Sprintf("this call to %s returns the user's %s directory", callName, kind)))
+				} else {
+					report.Report(pass, call, fmt.Sprintf("this call to os.RemoveAll deletes the user's entire %s directory, not a subdirectory therein", kind),
+						report.Related(arg, fmt.Sprintf("this call to %s returns the user's %s directory, for example %s", callName, kind, ex)))
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9008/sa9008.go b/vendor/honnef.co/go/tools/staticcheck/sa9008/sa9008.go
new file mode 100644
index 0000000..b565ab6
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9008/sa9008.go
@@ -0,0 +1,124 @@
+package sa9008
+
+import (
+	"fmt"
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA9008",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{buildir.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `\'else\' branch of a type assertion is probably not reading the right value`,
+		Text: `
+When declaring variables as part of an \'if\' statement (like in \"if
+foo := ...; foo {\"), the same variables will also be in the scope of
+the \'else\' branch. This means that in the following example
+
+    if x, ok := x.(int); ok {
+        // ...
+    } else {
+        fmt.Printf("unexpected type %T", x)
+    }
+
+\'x\' in the \'else\' branch will refer to the \'x\' from \'x, ok
+:=\'; it will not refer to the \'x\' that is being type-asserted. The
+result of a failed type assertion is the zero value of the type that
+is being asserted to, so \'x\' in the else branch will always have the
+value \'0\' and the type \'int\'.
+`,
+		Since:    "2022.1",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var typeAssertionShadowingElseQ = pattern.MustParse(`(IfStmt (AssignStmt [obj@(Ident _) ok@(Ident _)] ":=" assert@(TypeAssertExpr obj _)) ok _ elseBranch)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	// TODO(dh): without the IR-based verification, this check is able
+	// to find more bugs, but also more prone to false positives. It
+	// would be a good candidate for the 'codereview' category of
+	// checks.
+
+	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
+	for _, m := range code.Matches(pass, typeAssertionShadowingElseQ) {
+		shadow := pass.TypesInfo.ObjectOf(m.State["obj"].(*ast.Ident))
+		shadowed := m.State["assert"].(*ast.TypeAssertExpr).X
+
+		path, exact := astutil.PathEnclosingInterval(code.File(pass, shadow), shadow.Pos(), shadow.Pos())
+		if !exact {
+			// TODO(dh): when can this happen?
+			continue
+		}
+		irfn := ir.EnclosingFunction(irpkg, path)
+		if irfn == nil {
+			// For example for functions named "_", because we don't generate IR for them.
+			continue
+		}
+
+		shadoweeIR, isAddr := irfn.ValueForExpr(m.State["obj"].(*ast.Ident))
+		if shadoweeIR == nil || isAddr {
+			// TODO(dh): is this possible?
+			continue
+		}
+
+		var branch ast.Node
+		switch br := m.State["elseBranch"].(type) {
+		case ast.Node:
+			branch = br
+		case []ast.Stmt:
+			branch = &ast.BlockStmt{List: br}
+		case nil:
+			continue
+		default:
+			panic(fmt.Sprintf("unexpected type %T", br))
+		}
+
+		ast.Inspect(branch, func(node ast.Node) bool {
+			ident, ok := node.(*ast.Ident)
+			if !ok {
+				return true
+			}
+			if pass.TypesInfo.ObjectOf(ident) != shadow {
+				return true
+			}
+
+			v, isAddr := irfn.ValueForExpr(ident)
+			if v == nil || isAddr {
+				return true
+			}
+			if irutil.Flatten(v) != shadoweeIR {
+				// Same types.Object, but different IR value. This
+				// either means that the variable has been
+				// assigned to since the type assertion, or that
+				// the variable has escaped to the heap. Either
+				// way, we shouldn't flag reads of it.
+				return true
+			}
+
+			report.Report(pass, ident,
+				fmt.Sprintf("%s refers to the result of a failed type assertion and is a zero value, not the value that was being type-asserted", report.Render(pass, ident)),
+				report.Related(shadow, "this is the variable being read"),
+				report.Related(shadowed, "this is the variable being shadowed"))
+			return true
+		})
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9009/sa9009.go b/vendor/honnef.co/go/tools/staticcheck/sa9009/sa9009.go
new file mode 100644
index 0000000..f98db5a
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9009/sa9009.go
@@ -0,0 +1,68 @@
+package sa9009
+
+import (
+	"fmt"
+	"strings"
+
+	"golang.org/x/tools/go/analysis"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA9009",
+		Run:      run,
+		Requires: []*analysis.Analyzer{},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "Ineffectual Go compiler directive",
+		Text: `
+A potential Go compiler directive was found, but is ineffectual as it begins
+with whitespace.`,
+		Since:    "2024.1",
+		Severity: lint.SeverityWarning,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, f := range pass.Files {
+		for _, cg := range f.Comments {
+			for _, c := range cg.List {
+				// Compiler directives have to be // comments
+				if !strings.HasPrefix(c.Text, "//") {
+					continue
+				}
+				if pass.Fset.PositionFor(c.Pos(), false).Column != 1 {
+					// Compiler directives have to be top-level. This also
+					// avoids a false positive for
+					// 'import _ "unsafe" // go:linkname'
+					continue
+				}
+				text := strings.TrimLeft(c.Text[2:], " \t")
+				if len(text) == len(c.Text[2:]) {
+					// There was no leading whitespace
+					continue
+				}
+				if !strings.HasPrefix(text, "go:") {
+					// Not an attempted compiler directive
+					continue
+				}
+				text = text[3:]
+				if len(text) == 0 || text[0] < 'a' || text[0] > 'z' {
+					// A letter other than a-z after "go:", so unlikely to be an
+					// attempted compiler directive
+					continue
+				}
+				report.Report(pass, c,
+					fmt.Sprintf(
+						"ineffectual compiler directive due to extraneous space: %q",
+						c.Text))
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9010/sa9010.go b/vendor/honnef.co/go/tools/staticcheck/sa9010/sa9010.go
new file mode 100644
index 0000000..c171ba1
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9010/sa9010.go
@@ -0,0 +1,60 @@
+package sa9010
+
+import (
+	"go/ast"
+	"go/types"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "SA9010",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Returned function should be called in defer`,
+		Text: `
+If you have a function such as:
+
+    func f() func() {
+        // Do something.
+        return func() {
+            // Do something.
+        }
+    }
+
+Then calling that in defer:
+
+    defer f()
+
+Is almost always a mistake, since you typically want to call the returned
+function:
+
+    defer f()()
+`,
+		Since:    "2026.2",
+		Severity: lint.SeverityWarning,
+		MergeIf:  lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(n ast.Node) {
+		def := n.(*ast.DeferStmt)
+		if _, ok := pass.TypesInfo.TypeOf(def.Call).Underlying().(*types.Signature); ok {
+			report.Report(pass, def, "deferred return function not called")
+		}
+	}
+
+	code.Preorder(pass, fn, (*ast.DeferStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/analysis.go b/vendor/honnef.co/go/tools/stylecheck/analysis.go
new file mode 100644
index 0000000..7171bef
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/analysis.go
@@ -0,0 +1,46 @@
+// Code generated by generate.go. DO NOT EDIT.
+
+package stylecheck
+
+import (
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/stylecheck/st1000"
+	"honnef.co/go/tools/stylecheck/st1001"
+	"honnef.co/go/tools/stylecheck/st1003"
+	"honnef.co/go/tools/stylecheck/st1005"
+	"honnef.co/go/tools/stylecheck/st1006"
+	"honnef.co/go/tools/stylecheck/st1008"
+	"honnef.co/go/tools/stylecheck/st1011"
+	"honnef.co/go/tools/stylecheck/st1012"
+	"honnef.co/go/tools/stylecheck/st1013"
+	"honnef.co/go/tools/stylecheck/st1015"
+	"honnef.co/go/tools/stylecheck/st1016"
+	"honnef.co/go/tools/stylecheck/st1017"
+	"honnef.co/go/tools/stylecheck/st1018"
+	"honnef.co/go/tools/stylecheck/st1019"
+	"honnef.co/go/tools/stylecheck/st1020"
+	"honnef.co/go/tools/stylecheck/st1021"
+	"honnef.co/go/tools/stylecheck/st1022"
+	"honnef.co/go/tools/stylecheck/st1023"
+)
+
+var Analyzers = []*lint.Analyzer{
+	st1000.SCAnalyzer,
+	st1001.SCAnalyzer,
+	st1003.SCAnalyzer,
+	st1005.SCAnalyzer,
+	st1006.SCAnalyzer,
+	st1008.SCAnalyzer,
+	st1011.SCAnalyzer,
+	st1012.SCAnalyzer,
+	st1013.SCAnalyzer,
+	st1015.SCAnalyzer,
+	st1016.SCAnalyzer,
+	st1017.SCAnalyzer,
+	st1018.SCAnalyzer,
+	st1019.SCAnalyzer,
+	st1020.SCAnalyzer,
+	st1021.SCAnalyzer,
+	st1022.SCAnalyzer,
+	st1023.SCAnalyzer,
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/doc.go b/vendor/honnef.co/go/tools/stylecheck/doc.go
new file mode 100644
index 0000000..2964990
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/doc.go
@@ -0,0 +1,10 @@
+//go:generate go run ../generate.go
+
+// Package stylecheck contains analyzes that enforce style rules.
+// Most of the recommendations made are universally agreed upon by the wider Go community.
+// Some analyzes, however, implement stricter rules that not everyone will agree with.
+// In the context of Staticcheck, these analyzes are not enabled by default.
+//
+// For the most part it is recommended to follow the advice given by the analyzers that are enabled by default,
+// but you may want to disable additional analyzes on a case by case basis.
+package stylecheck
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1000/st1000.go b/vendor/honnef.co/go/tools/stylecheck/st1000/st1000.go
new file mode 100644
index 0000000..a3cf8c3
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1000/st1000.go
@@ -0,0 +1,83 @@
+package st1000
+
+import (
+	"fmt"
+	"go/ast"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name: "ST1000",
+		Run:  run,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Incorrect or missing package comment`,
+		Text: `Packages must have a package comment that is formatted according to
+the guidelines laid out in
+https://go.dev/wiki/CodeReviewComments#package-comments.`,
+		Since:      "2019.1",
+		NonDefault: true,
+		MergeIf:    lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	// - At least one file in a non-main package should have a package comment
+	//
+	// - The comment should be of the form
+	// "Package x ...". This has a slight potential for false
+	// positives, as multiple files can have package comments, in
+	// which case they get appended. But that doesn't happen a lot in
+	// the real world.
+
+	if pass.Pkg.Name() == "main" {
+		return nil, nil
+	}
+	hasDocs := false
+	for _, f := range pass.Files {
+		if code.IsInTest(pass, f) {
+			continue
+		}
+		text, ok := docText(f.Doc)
+		if ok {
+			hasDocs = true
+			prefix := "Package " + f.Name.Name
+			isNonAlpha := func(b byte) bool {
+				// This check only considers ASCII, which can lead to false negatives for some malformed package
+				// comments.
+				return !((b >= '0' && b <= '9') || (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z'))
+			}
+			if !strings.HasPrefix(text, prefix) || (len(text) > len(prefix) && !isNonAlpha(text[len(prefix)])) {
+				report.Report(pass, f.Doc, fmt.Sprintf(`package comment should be of the form "%s..."`, prefix))
+			}
+		}
+	}
+
+	if !hasDocs {
+		for _, f := range pass.Files {
+			if code.IsInTest(pass, f) {
+				continue
+			}
+			report.Report(pass, f, "at least one file in a package should have a package comment", report.ShortRange())
+		}
+	}
+	return nil, nil
+}
+
+func docText(doc *ast.CommentGroup) (string, bool) {
+	if doc == nil {
+		return "", false
+	}
+	// We trim spaces primarily because of /**/ style comments, which often have leading space.
+	text := strings.TrimSpace(doc.Text())
+	return text, text != ""
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1001/st1001.go b/vendor/honnef.co/go/tools/stylecheck/st1001/st1001.go
new file mode 100644
index 0000000..b4fd06c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1001/st1001.go
@@ -0,0 +1,71 @@
+package st1001
+
+import (
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/config"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1001",
+		Run:      run,
+		Requires: []*analysis.Analyzer{generated.Analyzer, config.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Dot imports are discouraged`,
+		Text: `Dot imports that aren't in external test packages are discouraged.
+
+The \'dot_import_whitelist\' option can be used to whitelist certain
+imports.
+
+Quoting Go Code Review Comments:
+
+> The \'import .\' form can be useful in tests that, due to circular
+> dependencies, cannot be made part of the package being tested:
+> 
+>     package foo_test
+> 
+>     import (
+>         "bar/testutil" // also imports "foo"
+>         . "foo"
+>     )
+> 
+> In this case, the test file cannot be in package foo because it
+> uses \'bar/testutil\', which imports \'foo\'. So we use the \'import .\'
+> form to let the file pretend to be part of package foo even though
+> it is not. Except for this one case, do not use \'import .\' in your
+> programs. It makes the programs much harder to read because it is
+> unclear whether a name like \'Quux\' is a top-level identifier in the
+> current package or in an imported package.`,
+		Since:   "2019.1",
+		Options: []string{"dot_import_whitelist"},
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, f := range pass.Files {
+	imports:
+		for _, imp := range f.Imports {
+			path := imp.Path.Value
+			path = path[1 : len(path)-1]
+			for _, w := range config.For(pass).DotImportWhitelist {
+				if w == path {
+					continue imports
+				}
+			}
+
+			if imp.Name != nil && imp.Name.Name == "." && !code.IsInTest(pass, f) {
+				report.Report(pass, imp, "should not use dot imports", report.FilterGenerated())
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1003/st1003.go b/vendor/honnef.co/go/tools/stylecheck/st1003/st1003.go
new file mode 100644
index 0000000..a8c26e7
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1003/st1003.go
@@ -0,0 +1,310 @@
+package st1003
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strings"
+	"unicode"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/config"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1003",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer, config.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Poorly chosen identifier`,
+		Text: `Identifiers, such as variable and package names, follow certain rules.
+
+See the following links for details:
+
+- https://go.dev/doc/effective_go#package-names
+- https://go.dev/doc/effective_go#mixed-caps
+- https://go.dev/wiki/CodeReviewComments#initialisms
+- https://go.dev/wiki/CodeReviewComments#variable-names`,
+		Since:      "2019.1",
+		NonDefault: true,
+		Options:    []string{"initialisms"},
+		MergeIf:    lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+// knownNameExceptions is a set of names that are known to be exempt from naming checks.
+// This is usually because they are constrained by having to match names in the
+// standard library.
+var knownNameExceptions = map[string]bool{
+	"LastInsertId": true, // must match database/sql
+	"kWh":          true,
+}
+
+func run(pass *analysis.Pass) (any, error) {
+	// A large part of this function is copied from
+	// github.com/golang/lint, Copyright (c) 2013 The Go Authors,
+	// licensed under the BSD 3-clause license.
+
+	allCaps := func(s string) bool {
+		hasUppercaseLetters := false
+		for _, r := range s {
+			if !hasUppercaseLetters && r >= 'A' && r <= 'Z' {
+				hasUppercaseLetters = true
+			}
+			if !((r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '_') {
+				return false
+			}
+		}
+		return hasUppercaseLetters
+	}
+
+	check := func(id *ast.Ident, thing string, initialisms map[string]bool) {
+		if id.Name == "_" {
+			return
+		}
+		if knownNameExceptions[id.Name] {
+			return
+		}
+
+		// Handle two common styles from other languages that don't belong in Go.
+		if len(id.Name) >= 5 && allCaps(id.Name) && strings.Contains(id.Name, "_") {
+			report.Report(pass, id, "should not use ALL_CAPS in Go names; use CamelCase instead", report.FilterGenerated())
+			return
+		}
+
+		should := lintName(id.Name, initialisms)
+		if id.Name == should {
+			return
+		}
+
+		if len(id.Name) > 2 && strings.Contains(id.Name[1:len(id.Name)-1], "_") {
+			report.Report(pass, id, fmt.Sprintf("should not use underscores in Go names; %s %s should be %s", thing, id.Name, should), report.FilterGenerated())
+			return
+		}
+		report.Report(pass, id, fmt.Sprintf("%s %s should be %s", thing, id.Name, should), report.FilterGenerated())
+	}
+	checkList := func(fl *ast.FieldList, thing string, initialisms map[string]bool) {
+		if fl == nil {
+			return
+		}
+		for _, f := range fl.List {
+			for _, id := range f.Names {
+				check(id, thing, initialisms)
+			}
+		}
+	}
+
+	il := config.For(pass).Initialisms
+	initialisms := make(map[string]bool, len(il))
+	for _, word := range il {
+		initialisms[word] = true
+	}
+	for _, f := range pass.Files {
+		// Package names need slightly different handling than other names.
+		if !strings.HasSuffix(f.Name.Name, "_test") && strings.Contains(f.Name.Name, "_") {
+			report.Report(pass, f.Name, "should not use underscores in package names", report.FilterGenerated())
+		}
+		if strings.IndexFunc(f.Name.Name, unicode.IsUpper) != -1 {
+			report.Report(pass, f.Name, fmt.Sprintf("should not use MixedCaps in package name; %s should be %s", f.Name.Name, strings.ToLower(f.Name.Name)), report.FilterGenerated())
+		}
+	}
+
+	fn := func(node ast.Node) {
+		switch v := node.(type) {
+		case *ast.AssignStmt:
+			if v.Tok != token.DEFINE {
+				return
+			}
+			for _, exp := range v.Lhs {
+				if id, ok := exp.(*ast.Ident); ok {
+					check(id, "var", initialisms)
+				}
+			}
+		case *ast.FuncDecl:
+			// Functions with no body are defined elsewhere (in
+			// assembly, or via go:linkname). These are likely to
+			// be something very low level (such as the runtime),
+			// where our rules don't apply.
+			if v.Body == nil {
+				return
+			}
+
+			if code.IsInTest(pass, v) &&
+				(strings.HasPrefix(v.Name.Name, "Example") ||
+					strings.HasPrefix(v.Name.Name, "Test") ||
+					strings.HasPrefix(v.Name.Name, "Benchmark") ||
+					strings.HasPrefix(v.Name.Name, "Fuzz")) {
+				return
+			}
+
+			thing := "func"
+			if v.Recv != nil {
+				thing = "method"
+			}
+
+			if !isTechnicallyExported(v) {
+				check(v.Name, thing, initialisms)
+			}
+
+			checkList(v.Type.Params, thing+" parameter", initialisms)
+			checkList(v.Type.Results, thing+" result", initialisms)
+		case *ast.GenDecl:
+			if v.Tok == token.IMPORT {
+				return
+			}
+			var thing string
+			switch v.Tok {
+			case token.CONST:
+				thing = "const"
+			case token.TYPE:
+				thing = "type"
+			case token.VAR:
+				thing = "var"
+			}
+			for _, spec := range v.Specs {
+				switch s := spec.(type) {
+				case *ast.TypeSpec:
+					check(s.Name, thing, initialisms)
+				case *ast.ValueSpec:
+					for _, id := range s.Names {
+						check(id, thing, initialisms)
+					}
+				}
+			}
+		case *ast.InterfaceType:
+			// Do not check interface method names.
+			// They are often constrained by the method names of concrete types.
+			for _, x := range v.Methods.List {
+				ft, ok := x.Type.(*ast.FuncType)
+				if !ok { // might be an embedded interface name
+					continue
+				}
+				checkList(ft.Params, "interface method parameter", initialisms)
+				checkList(ft.Results, "interface method result", initialisms)
+			}
+		case *ast.RangeStmt:
+			if v.Tok == token.ASSIGN {
+				return
+			}
+			if id, ok := v.Key.(*ast.Ident); ok {
+				check(id, "range var", initialisms)
+			}
+			if id, ok := v.Value.(*ast.Ident); ok {
+				check(id, "range var", initialisms)
+			}
+		case *ast.StructType:
+			for _, f := range v.Fields.List {
+				for _, id := range f.Names {
+					check(id, "struct field", initialisms)
+				}
+			}
+		}
+	}
+
+	needle := []ast.Node{
+		(*ast.AssignStmt)(nil),
+		(*ast.FuncDecl)(nil),
+		(*ast.GenDecl)(nil),
+		(*ast.InterfaceType)(nil),
+		(*ast.RangeStmt)(nil),
+		(*ast.StructType)(nil),
+	}
+
+	code.Preorder(pass, fn, needle...)
+	return nil, nil
+}
+
+// lintName returns a different name if it should be different.
+func lintName(name string, initialisms map[string]bool) (should string) {
+	// A large part of this function is copied from
+	// github.com/golang/lint, Copyright (c) 2013 The Go Authors,
+	// licensed under the BSD 3-clause license.
+
+	// Fast path for simple cases: "_" and all lowercase.
+	if name == "_" {
+		return name
+	}
+	if strings.IndexFunc(name, func(r rune) bool { return !unicode.IsLower(r) }) == -1 {
+		return name
+	}
+
+	// Split camelCase at any lower->upper transition, and split on underscores.
+	// Check each word for common initialisms.
+	runes := []rune(name)
+	w, i := 0, 0 // index of start of word, scan
+	for i+1 <= len(runes) {
+		eow := false // whether we hit the end of a word
+		if i+1 == len(runes) {
+			eow = true
+		} else if runes[i+1] == '_' && i+1 != len(runes)-1 {
+			// underscore; shift the remainder forward over any run of underscores
+			eow = true
+			n := 1
+			for i+n+1 < len(runes) && runes[i+n+1] == '_' {
+				n++
+			}
+
+			// Leave at most one underscore if the underscore is between two digits
+			if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
+				n--
+			}
+
+			copy(runes[i+1:], runes[i+n+1:])
+			runes = runes[:len(runes)-n]
+		} else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
+			// lower->non-lower
+			eow = true
+		}
+		i++
+		if !eow {
+			continue
+		}
+
+		// [w,i) is a word.
+		word := string(runes[w:i])
+		if u := strings.ToUpper(word); initialisms[u] {
+			// Keep consistent case, which is lowercase only at the start.
+			if w == 0 && unicode.IsLower(runes[w]) {
+				u = strings.ToLower(u)
+			}
+			// All the common initialisms are ASCII,
+			// so we can replace the bytes exactly.
+			// TODO(dh): this won't be true once we allow custom initialisms
+			copy(runes[w:], []rune(u))
+		} else if w > 0 && strings.ToLower(word) == word {
+			// already all lowercase, and not the first word, so uppercase the first character.
+			runes[w] = unicode.ToUpper(runes[w])
+		}
+		w = i
+	}
+	return string(runes)
+}
+
+func isTechnicallyExported(f *ast.FuncDecl) bool {
+	if f.Recv != nil || f.Doc == nil {
+		return false
+	}
+
+	const export = "//export "
+	const linkname = "//go:linkname "
+	for _, c := range f.Doc.List {
+		if strings.HasPrefix(c.Text, export) && len(c.Text) == len(export)+len(f.Name.Name) && c.Text[len(export):] == f.Name.Name {
+			return true
+		}
+
+		if strings.HasPrefix(c.Text, linkname) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1005/st1005.go b/vendor/honnef.co/go/tools/stylecheck/st1005/st1005.go
new file mode 100644
index 0000000..477c0a1
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1005/st1005.go
@@ -0,0 +1,130 @@
+package st1005
+
+import (
+	"go/constant"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ir"
+	"honnef.co/go/tools/go/ir/irutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1005",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Incorrectly formatted error string`,
+		Text: `Error strings follow a set of guidelines to ensure uniformity and good
+composability.
+
+Quoting Go Code Review Comments:
+
+> Error strings should not be capitalized (unless beginning with
+> proper nouns or acronyms) or end with punctuation, since they are
+> usually printed following other context. That is, use
+> \'fmt.Errorf("something bad")\' not \'fmt.Errorf("Something bad")\', so
+> that \'log.Printf("Reading %s: %v", filename, err)\' formats without a
+> spurious capital letter mid-message.`,
+		Since:   "2019.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	objNames := map[*ir.Package]map[string]bool{}
+	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
+	objNames[irpkg] = map[string]bool{}
+	for _, m := range irpkg.Members {
+		if typ, ok := m.(*ir.Type); ok {
+			objNames[irpkg][typ.Name()] = true
+		}
+	}
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		objNames[fn.Package()][fn.Name()] = true
+	}
+
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		if code.IsInTest(pass, fn) {
+			// We don't care about malformed error messages in tests;
+			// they're usually for direct human consumption, not part
+			// of an API
+			continue
+		}
+		for _, block := range fn.Blocks {
+		instrLoop:
+			for _, ins := range block.Instrs {
+				call, ok := ins.(*ir.Call)
+				if !ok {
+					continue
+				}
+				if !irutil.IsCallToAny(call.Common(), "errors.New", "fmt.Errorf") {
+					continue
+				}
+
+				k, ok := call.Common().Args[0].(*ir.Const)
+				if !ok {
+					continue
+				}
+
+				s := constant.StringVal(k.Value)
+				if len(s) == 0 {
+					continue
+				}
+				switch s[len(s)-1] {
+				case '.', ':', '!', '\n':
+					report.Report(pass, call, "error strings should not end with punctuation or newlines")
+				}
+				before, _, ok0 := strings.Cut(s, " ")
+				if !ok0 {
+					// single word error message, probably not a real
+					// error but something used in tests or during
+					// debugging
+					continue
+				}
+				word := before
+				first, n := utf8.DecodeRuneInString(word)
+				if !unicode.IsUpper(first) {
+					continue
+				}
+				for _, c := range word[n:] {
+					if unicode.IsUpper(c) || unicode.IsDigit(c) {
+						// Word is probably an initialism or multi-word function name. Digits cover elliptic curves like
+						// P384.
+						continue instrLoop
+					}
+				}
+
+				if strings.ContainsRune(word, '(') {
+					// Might be a function call
+					continue instrLoop
+				}
+				word = strings.TrimRightFunc(word, func(r rune) bool { return unicode.IsPunct(r) })
+				if objNames[fn.Package()][word] {
+					// Word is probably the name of a function or type in this package
+					continue
+				}
+				// First word in error starts with a capital
+				// letter, and the word doesn't contain any other
+				// capitals, making it unlikely to be an
+				// initialism or multi-word function name.
+				//
+				// It could still be a proper noun, though.
+
+				report.Report(pass, call, "error strings should not be capitalized")
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1006/st1006.go b/vendor/honnef.co/go/tools/stylecheck/st1006/st1006.go
new file mode 100644
index 0000000..30b0dc8
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1006/st1006.go
@@ -0,0 +1,65 @@
+package st1006
+
+import (
+	"go/types"
+
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1006",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Poorly chosen receiver name`,
+		Text: `Quoting Go Code Review Comments:
+
+> The name of a method's receiver should be a reflection of its
+> identity; often a one or two letter abbreviation of its type
+> suffices (such as "c" or "cl" for "Client"). Don't use generic
+> names such as "me", "this" or "self", identifiers typical of
+> object-oriented languages that place more emphasis on methods as
+> opposed to functions. The name need not be as descriptive as that
+> of a method argument, as its role is obvious and serves no
+> documentary purpose. It can be very short as it will appear on
+> almost every line of every method of the type; familiarity admits
+> brevity. Be consistent, too: if you call the receiver "c" in one
+> method, don't call it "cl" in another.`,
+		Since:   "2019.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
+	for _, m := range irpkg.Members {
+		if T, ok := m.Object().(*types.TypeName); ok && !T.IsAlias() {
+			ms := typeutil.IntuitiveMethodSet(T.Type(), nil)
+			for _, sel := range ms {
+				fn := sel.Obj().(*types.Func)
+				recv := fn.Type().(*types.Signature).Recv()
+				if typeutil.Dereference(recv.Type()) != T.Type() {
+					// skip embedded methods
+					continue
+				}
+				if recv.Name() == "self" || recv.Name() == "this" {
+					report.Report(pass, recv, `receiver name should be a reflection of its identity; don't use generic names such as "this" or "self"`, report.FilterGenerated())
+				}
+				if recv.Name() == "_" {
+					report.Report(pass, recv, "receiver name should not be an underscore, omit the name if it is unused", report.FilterGenerated())
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1008/st1008.go b/vendor/honnef.co/go/tools/stylecheck/st1008/st1008.go
new file mode 100644
index 0000000..8c9f326
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1008/st1008.go
@@ -0,0 +1,58 @@
+package st1008
+
+import (
+	"go/types"
+
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1008",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:   `A function's error value should be its last return value`,
+		Text:    `A function's error value should be its last return value.`,
+		Since:   `2019.1`,
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+fnLoop:
+	for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
+		sig := fn.Type().(*types.Signature)
+		rets := sig.Results()
+		if rets == nil || rets.Len() < 2 {
+			continue
+		}
+
+		if types.Unalias(rets.At(rets.Len()-1).Type()) == types.Universe.Lookup("error").Type() {
+			// Last return type is error. If the function also returns
+			// errors in other positions, that's fine.
+			continue
+		}
+
+		if rets.Len() >= 2 &&
+			types.Unalias(rets.At(rets.Len()-1).Type()) == types.Universe.Lookup("bool").Type() &&
+			types.Unalias(rets.At(rets.Len()-2).Type()) == types.Universe.Lookup("error").Type() {
+			// Accept (..., error, bool) and assume it's a comma-ok function. It's not clear whether the bool should come last or not for these kinds of functions.
+			continue
+		}
+		for i := rets.Len() - 2; i >= 0; i-- {
+			if types.Unalias(rets.At(i).Type()) == types.Universe.Lookup("error").Type() {
+				report.Report(pass, rets.At(i), "error should be returned as the last argument", report.ShortRange())
+				continue fnLoop
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1011/st1011.go b/vendor/honnef.co/go/tools/stylecheck/st1011/st1011.go
new file mode 100644
index 0000000..cb43bba
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1011/st1011.go
@@ -0,0 +1,88 @@
+package st1011
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1011",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Poorly chosen name for variable of type \'time.Duration\'`,
+		Text: `\'time.Duration\' values represent an amount of time, which is represented
+as a count of nanoseconds. An expression like \'5 * time.Microsecond\'
+yields the value \'5000\'. It is therefore not appropriate to suffix a
+variable of type \'time.Duration\' with any time unit, such as \'Msec\' or
+\'Milli\'.`,
+		Since:   `2019.1`,
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	suffixes := []string{
+		"Sec", "Secs", "Seconds",
+		"Msec", "Msecs",
+		"Milli", "Millis", "Milliseconds",
+		"Usec", "Usecs", "Microseconds",
+		"MS", "Ms",
+	}
+	fn := func(names []*ast.Ident) {
+		for _, name := range names {
+			if _, ok := pass.TypesInfo.Defs[name]; !ok {
+				continue
+			}
+			T := pass.TypesInfo.TypeOf(name)
+			if !typeutil.IsTypeWithName(T, "time.Duration") && !typeutil.IsPointerToTypeWithName(T, "time.Duration") {
+				continue
+			}
+			for _, suffix := range suffixes {
+				if strings.HasSuffix(name.Name, suffix) {
+					report.Report(pass, name, fmt.Sprintf("var %s is of type %v; don't use unit-specific suffix %q", name.Name, T, suffix))
+					break
+				}
+			}
+		}
+	}
+
+	fn2 := func(node ast.Node) {
+		switch node := node.(type) {
+		case *ast.ValueSpec:
+			fn(node.Names)
+		case *ast.FieldList:
+			for _, field := range node.List {
+				fn(field.Names)
+			}
+		case *ast.AssignStmt:
+			if node.Tok != token.DEFINE {
+				break
+			}
+			var names []*ast.Ident
+			for _, lhs := range node.Lhs {
+				if lhs, ok := lhs.(*ast.Ident); ok {
+					names = append(names, lhs)
+				}
+			}
+			fn(names)
+		}
+	}
+
+	code.Preorder(pass, fn2, (*ast.ValueSpec)(nil), (*ast.FieldList)(nil), (*ast.AssignStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1012/st1012.go b/vendor/honnef.co/go/tools/stylecheck/st1012/st1012.go
new file mode 100644
index 0000000..cf921fe
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1012/st1012.go
@@ -0,0 +1,68 @@
+package st1012
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name: "ST1012",
+		Run:  run,
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Poorly chosen name for error variable`,
+		Text: `Error variables that are part of an API should be called \'errFoo\' or
+\'ErrFoo\'.`,
+		Since:   "2019.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, f := range pass.Files {
+		for _, decl := range f.Decls {
+			gen, ok := decl.(*ast.GenDecl)
+			if !ok || gen.Tok != token.VAR {
+				continue
+			}
+			for _, spec := range gen.Specs {
+				spec := spec.(*ast.ValueSpec)
+				if len(spec.Names) != len(spec.Values) {
+					continue
+				}
+
+				for i, name := range spec.Names {
+					val := spec.Values[i]
+					if !code.IsCallToAny(pass, val, "errors.New", "fmt.Errorf") {
+						continue
+					}
+
+					if pass.Pkg.Path() == "net/http" && strings.HasPrefix(name.Name, "http2err") {
+						// special case for internal variable names of
+						// bundled HTTP 2 code in net/http
+						continue
+					}
+					prefix := "err"
+					if name.IsExported() {
+						prefix = "Err"
+					}
+					if !strings.HasPrefix(name.Name, prefix) {
+						report.Report(pass, name, fmt.Sprintf("error var %s should have name of the form %sFoo", name.Name, prefix))
+					}
+				}
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1013/st1013.go b/vendor/honnef.co/go/tools/stylecheck/st1013/st1013.go
new file mode 100644
index 0000000..01fe71c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1013/st1013.go
@@ -0,0 +1,159 @@
+package st1013
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"strconv"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/config"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1013",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer, config.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Should use constants for HTTP error codes, not magic numbers`,
+		Text: `HTTP has a tremendous number of status codes. While some of those are
+well known (200, 400, 404, 500), most of them are not. The \'net/http\'
+package provides constants for all status codes that are part of the
+various specifications. It is recommended to use these constants
+instead of hard-coding magic numbers, to vastly improve the
+readability of your code.`,
+		Since:   "2019.1",
+		Options: []string{"http_status_code_whitelist"},
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var query = pattern.MustParse(`
+	(CallExpr
+		(Symbol
+			name@(Or
+			"net/http.Error"
+			"net/http.Redirect"
+			"net/http.StatusText"
+			"net/http.RedirectHandler"))
+		args)`)
+
+func run(pass *analysis.Pass) (any, error) {
+	whitelist := map[string]bool{}
+	for _, code := range config.For(pass).HTTPStatusCodeWhitelist {
+		whitelist[code] = true
+	}
+	for _, m := range code.Matches(pass, query) {
+		var arg int
+		switch m.State["name"].(string) {
+		case "net/http.Error":
+			arg = 2
+		case "net/http.Redirect":
+			arg = 3
+		case "net/http.StatusText":
+			arg = 0
+		case "net/http.RedirectHandler":
+			arg = 1
+		default:
+			continue
+		}
+		args := m.State["args"].([]ast.Expr)
+		if arg >= len(args) {
+			continue
+		}
+		tv, ok := code.IntegerLiteral(pass, args[arg])
+		if !ok {
+			continue
+		}
+		n, ok := constant.Int64Val(tv.Value)
+		if !ok {
+			continue
+		}
+		if whitelist[strconv.FormatInt(n, 10)] {
+			continue
+		}
+
+		s, ok := httpStatusCodes[n]
+		if !ok {
+			continue
+		}
+		lit := args[arg]
+		report.Report(pass, lit, fmt.Sprintf("should use constant http.%s instead of numeric literal %d", s, n),
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix(fmt.Sprintf("Use http.%s instead of %d", s, n), edit.ReplaceWithString(lit, "http."+s))))
+	}
+	return nil, nil
+}
+
+var httpStatusCodes = map[int64]string{
+	100: "StatusContinue",
+	101: "StatusSwitchingProtocols",
+	102: "StatusProcessing",
+	200: "StatusOK",
+	201: "StatusCreated",
+	202: "StatusAccepted",
+	203: "StatusNonAuthoritativeInfo",
+	204: "StatusNoContent",
+	205: "StatusResetContent",
+	206: "StatusPartialContent",
+	207: "StatusMultiStatus",
+	208: "StatusAlreadyReported",
+	226: "StatusIMUsed",
+	300: "StatusMultipleChoices",
+	301: "StatusMovedPermanently",
+	302: "StatusFound",
+	303: "StatusSeeOther",
+	304: "StatusNotModified",
+	305: "StatusUseProxy",
+	307: "StatusTemporaryRedirect",
+	308: "StatusPermanentRedirect",
+	400: "StatusBadRequest",
+	401: "StatusUnauthorized",
+	402: "StatusPaymentRequired",
+	403: "StatusForbidden",
+	404: "StatusNotFound",
+	405: "StatusMethodNotAllowed",
+	406: "StatusNotAcceptable",
+	407: "StatusProxyAuthRequired",
+	408: "StatusRequestTimeout",
+	409: "StatusConflict",
+	410: "StatusGone",
+	411: "StatusLengthRequired",
+	412: "StatusPreconditionFailed",
+	413: "StatusRequestEntityTooLarge",
+	414: "StatusRequestURITooLong",
+	415: "StatusUnsupportedMediaType",
+	416: "StatusRequestedRangeNotSatisfiable",
+	417: "StatusExpectationFailed",
+	418: "StatusTeapot",
+	422: "StatusUnprocessableEntity",
+	423: "StatusLocked",
+	424: "StatusFailedDependency",
+	426: "StatusUpgradeRequired",
+	428: "StatusPreconditionRequired",
+	429: "StatusTooManyRequests",
+	431: "StatusRequestHeaderFieldsTooLarge",
+	451: "StatusUnavailableForLegalReasons",
+	500: "StatusInternalServerError",
+	501: "StatusNotImplemented",
+	502: "StatusBadGateway",
+	503: "StatusServiceUnavailable",
+	504: "StatusGatewayTimeout",
+	505: "StatusHTTPVersionNotSupported",
+	506: "StatusVariantAlsoNegotiates",
+	507: "StatusInsufficientStorage",
+	508: "StatusLoopDetected",
+	510: "StatusNotExtended",
+	511: "StatusNetworkAuthenticationRequired",
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1015/st1015.go b/vendor/honnef.co/go/tools/stylecheck/st1015/st1015.go
new file mode 100644
index 0000000..18d0e20
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1015/st1015.go
@@ -0,0 +1,77 @@
+package st1015
+
+import (
+	"go/ast"
+	"go/token"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1015",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:   `A switch's default case should be the first or last case`,
+		Since:   "2019.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	hasFallthrough := func(clause ast.Stmt) bool {
+		// A valid fallthrough statement may be used only as the final non-empty statement in a case clause. Thus we can
+		// easily avoid falsely matching fallthroughs in nested switches by not descending into blocks.
+
+		body := clause.(*ast.CaseClause).Body
+		for i := len(body) - 1; i >= 0; i-- {
+			last := body[i]
+			switch stmt := last.(type) {
+			case *ast.EmptyStmt:
+				// Fallthrough may be followed by empty statements
+			case *ast.BranchStmt:
+				return stmt.Tok == token.FALLTHROUGH
+			default:
+				return false
+			}
+		}
+
+		return false
+	}
+
+	fn := func(node ast.Node) {
+		stmt := node.(*ast.SwitchStmt)
+		list := stmt.Body.List
+		defaultIdx := -1
+		for i, c := range list {
+			if c.(*ast.CaseClause).List == nil {
+				defaultIdx = i
+				break
+			}
+		}
+
+		if defaultIdx == -1 || defaultIdx == 0 || defaultIdx == len(list)-1 {
+			// No default case, or it's the first or last case
+			return
+		}
+
+		if hasFallthrough(list[defaultIdx-1]) || hasFallthrough(list[defaultIdx]) {
+			// We either fall into or out of this case; don't mess with the order
+			return
+		}
+
+		report.Report(pass, list[defaultIdx], "default case should be first or last in switch statement", report.FilterGenerated())
+	}
+	code.Preorder(pass, fn, (*ast.SwitchStmt)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1016/st1016.go b/vendor/honnef.co/go/tools/stylecheck/st1016/st1016.go
new file mode 100644
index 0000000..56aa2ea
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1016/st1016.go
@@ -0,0 +1,74 @@
+package st1016
+
+import (
+	"fmt"
+	"go/types"
+	"sort"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/types/typeutil"
+	"honnef.co/go/tools/internal/passes/buildir"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1016",
+		Run:      run,
+		Requires: []*analysis.Analyzer{buildir.Analyzer, generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:      `Use consistent method receiver names`,
+		Since:      "2019.1",
+		NonDefault: true,
+		MergeIf:    lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
+	for _, m := range irpkg.Members {
+		names := map[string]int{}
+
+		var firstFn *types.Func
+		if T, ok := m.Object().(*types.TypeName); ok && !T.IsAlias() {
+			ms := typeutil.IntuitiveMethodSet(T.Type(), nil)
+			for _, sel := range ms {
+				fn := sel.Obj().(*types.Func)
+				recv := fn.Type().(*types.Signature).Recv()
+				if code.IsGenerated(pass, recv.Pos()) {
+					// Don't concern ourselves with methods in generated code
+					continue
+				}
+				if typeutil.Dereference(recv.Type()) != T.Type() {
+					// skip embedded methods
+					continue
+				}
+				if firstFn == nil {
+					firstFn = fn
+				}
+				if recv.Name() != "" && recv.Name() != "_" {
+					names[recv.Name()]++
+				}
+			}
+		}
+
+		if len(names) > 1 {
+			var seen []string
+			for name, count := range names {
+				seen = append(seen, fmt.Sprintf("%dx %q", count, name))
+			}
+			sort.Strings(seen)
+
+			report.Report(pass, firstFn, fmt.Sprintf("methods on the same type should have the same receiver name (seen %s)", strings.Join(seen, ", ")))
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1017/st1017.go b/vendor/honnef.co/go/tools/stylecheck/st1017/st1017.go
new file mode 100644
index 0000000..d279808
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1017/st1017.go
@@ -0,0 +1,47 @@
+package st1017
+
+import (
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/edit"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/pattern"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1017",
+		Run:      run,
+		Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Don't use Yoda conditions`,
+		Text: `Yoda conditions are conditions of the kind \"if 42 == x\", where the
+literal is on the left side of the comparison. These are a common
+idiom in languages in which assignment is an expression, to avoid bugs
+of the kind \"if (x = 42)\". In Go, which doesn't allow for this kind of
+bug, we prefer the more idiomatic \"if x == 42\".`,
+		Since:   "2019.2",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+var (
+	checkYodaConditionsQ = pattern.MustParse(`(BinaryExpr left@(TrulyConstantExpression _) tok@(Or "==" "!=") right@(Not (TrulyConstantExpression _)))`)
+	checkYodaConditionsR = pattern.MustParse(`(BinaryExpr right tok left)`)
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for node, m := range code.Matches(pass, checkYodaConditionsQ) {
+		edits := code.EditMatch(pass, node, m, checkYodaConditionsR)
+		report.Report(pass, node, "don't use Yoda conditions",
+			report.FilterGenerated(),
+			report.Fixes(edit.Fix("Un-Yoda-fy", edits...)))
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1018/st1018.go b/vendor/honnef.co/go/tools/stylecheck/st1018/st1018.go
new file mode 100644
index 0000000..a479c8d
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1018/st1018.go
@@ -0,0 +1,157 @@
+package st1018
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strconv"
+	"unicode"
+	"unicode/utf8"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1018",
+		Run:      run,
+		Requires: []*analysis.Analyzer{inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title:   `Avoid zero-width and control characters in string literals`,
+		Since:   "2019.2",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		lit := node.(*ast.BasicLit)
+		if lit.Kind != token.STRING {
+			return
+		}
+
+		type invalid struct {
+			r   rune
+			off int
+		}
+		var invalids []invalid
+		hasFormat := false
+		hasControl := false
+		prev := rune(-1)
+		const zwj = '\u200d'
+		for off, r := range lit.Value {
+			if unicode.Is(unicode.Cf, r) {
+				if r >= '\U000e0020' && r <= '\U000e007f' {
+					// These are used for spelling out country codes for flag emoji
+				} else if unicode.Is(unicode.Variation_Selector, r) {
+					// Always allow variation selectors
+				} else if r == zwj && (unicode.Is(unicode.S, prev) || unicode.Is(unicode.Variation_Selector, prev)) {
+					// Allow zero-width joiner in emoji, including those that use variation selectors.
+
+					// Technically some foreign scripts make valid use of zero-width joiners, too, but for now we'll err
+					// on the side of flagging all non-emoji uses of ZWJ.
+				} else {
+					switch r {
+					case '\u0600', '\u0601', '\u0602', '\u0603', '\u0604', '\u0605', '\u0890', '\u0891', '\u08e2':
+						// Arabic characters that are not actually invisible. If anyone knows why these are in the
+						// Other, Format category please let me know.
+					case '\u061c', '\u202A', '\u202B', '\u202D', '\u202E', '\u2066', '\u2067', '\u2068', '\u202C', '\u2069':
+						// Bidirectional formatting characters. At best they will render confusingly, at worst they're used
+						// to cause confusion.
+						fallthrough
+					default:
+						invalids = append(invalids, invalid{r, off})
+						hasFormat = true
+					}
+				}
+			} else if unicode.Is(unicode.Cc, r) && r != '\n' && r != '\t' && r != '\r' {
+				invalids = append(invalids, invalid{r, off})
+				hasControl = true
+			}
+			prev = r
+		}
+
+		switch len(invalids) {
+		case 0:
+			return
+		case 1:
+			var kind string
+			if hasFormat {
+				kind = "format"
+			} else if hasControl {
+				kind = "control"
+			} else {
+				panic("unreachable")
+			}
+
+			r := invalids[0]
+			msg := fmt.Sprintf("string literal contains the Unicode %s character %U, consider using the %q escape sequence instead", kind, r.r, r.r)
+
+			replacement := strconv.QuoteRune(r.r)
+			replacement = replacement[1 : len(replacement)-1]
+			edit := analysis.SuggestedFix{
+				Message: fmt.Sprintf("replace %s character %U with %q", kind, r.r, r.r),
+				TextEdits: []analysis.TextEdit{{
+					Pos:     lit.Pos() + token.Pos(r.off),
+					End:     lit.Pos() + token.Pos(r.off) + token.Pos(utf8.RuneLen(r.r)),
+					NewText: []byte(replacement),
+				}},
+			}
+			delete := analysis.SuggestedFix{
+				Message: fmt.Sprintf("delete %s character %U", kind, r.r),
+				TextEdits: []analysis.TextEdit{{
+					Pos: lit.Pos() + token.Pos(r.off),
+					End: lit.Pos() + token.Pos(r.off) + token.Pos(utf8.RuneLen(r.r)),
+				}},
+			}
+			report.Report(pass, lit, msg, report.Fixes(edit, delete))
+		default:
+			var kind string
+			if hasFormat && hasControl {
+				kind = "format and control"
+			} else if hasFormat {
+				kind = "format"
+			} else if hasControl {
+				kind = "control"
+			} else {
+				panic("unreachable")
+			}
+
+			msg := fmt.Sprintf("string literal contains Unicode %s characters, consider using escape sequences instead", kind)
+			var edits []analysis.TextEdit
+			var deletions []analysis.TextEdit
+			for _, r := range invalids {
+				replacement := strconv.QuoteRune(r.r)
+				replacement = replacement[1 : len(replacement)-1]
+				edits = append(edits, analysis.TextEdit{
+					Pos:     lit.Pos() + token.Pos(r.off),
+					End:     lit.Pos() + token.Pos(r.off) + token.Pos(utf8.RuneLen(r.r)),
+					NewText: []byte(replacement),
+				})
+				deletions = append(deletions, analysis.TextEdit{
+					Pos: lit.Pos() + token.Pos(r.off),
+					End: lit.Pos() + token.Pos(r.off) + token.Pos(utf8.RuneLen(r.r)),
+				})
+			}
+			edit := analysis.SuggestedFix{
+				Message:   fmt.Sprintf("replace all %s characters with escape sequences", kind),
+				TextEdits: edits,
+			}
+			delete := analysis.SuggestedFix{
+				Message:   fmt.Sprintf("delete all %s characters", kind),
+				TextEdits: deletions,
+			}
+			report.Report(pass, lit, msg, report.Fixes(edit, delete))
+		}
+	}
+	code.Preorder(pass, fn, (*ast.BasicLit)(nil))
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1019/st1019.go b/vendor/honnef.co/go/tools/stylecheck/st1019/st1019.go
new file mode 100644
index 0000000..d43c818
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1019/st1019.go
@@ -0,0 +1,87 @@
+package st1019
+
+import (
+	"fmt"
+	"go/ast"
+
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1019",
+		Run:      run,
+		Requires: []*analysis.Analyzer{generated.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: `Importing the same package multiple times`,
+		Text: `Go allows importing the same package multiple times, as long as
+different import aliases are being used. That is, the following
+bit of code is valid:
+
+    import (
+        "fmt"
+        fumpt "fmt"
+        format "fmt"
+    )
+
+However, this is very rarely done on purpose. Usually, it is a
+sign of code that got refactored, accidentally adding duplicate
+import statements. It is also a rarely known feature, which may
+contribute to confusion.
+
+Do note that sometimes, this feature may be used
+intentionally (see for example
+https://github.com/golang/go/commit/3409ce39bfd7584523b7a8c150a310cea92d879d)
+– if you want to allow this pattern in your code base, you're
+advised to disable this check.
+
+It is acceptable to import the same package twice if one of the imports
+uses the blank identifier. This is allowed in order to increase
+resilience against erroneous changes when using the same package for its
+side effects as well as its exported API.`,
+		Since:   "2020.1",
+		MergeIf: lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, f := range pass.Files {
+		// Collect all imports by their import path
+		imports := make(map[string][]*ast.ImportSpec, len(f.Imports))
+		for _, imp := range f.Imports {
+			if imp.Name != nil && imp.Name.Name == "_" {
+				// Allow blank imports to coexist with one normal import.
+				//
+				// We don't have to count the number of blank imports,
+				// goimports removes duplicates.
+				continue
+			}
+			imports[imp.Path.Value] = append(imports[imp.Path.Value], imp)
+		}
+
+		for path, value := range imports {
+			if path[1:len(path)-1] == "unsafe" {
+				// Don't flag unsafe. Cgo generated code imports
+				// unsafe as _cgo_unsafe, in addition to the user's import.
+				continue
+			}
+			// If there's more than one import per path, we flag that
+			if len(value) > 1 {
+				s := fmt.Sprintf("package %s is being imported more than once", path)
+				opts := []report.Option{report.FilterGenerated()}
+				for _, imp := range value[1:] {
+					opts = append(opts, report.Related(imp, fmt.Sprintf("other import of %s", path)))
+				}
+				report.Report(pass, value[0], s, opts...)
+			}
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1020/st1020.go b/vendor/honnef.co/go/tools/stylecheck/st1020/st1020.go
new file mode 100644
index 0000000..b395f2c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1020/st1020.go
@@ -0,0 +1,101 @@
+package st1020
+
+import (
+	"fmt"
+	"go/ast"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1020",
+		Run:      run,
+		Requires: []*analysis.Analyzer{generated.Analyzer, inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "The documentation of an exported function should start with the function's name",
+		Text: `Doc comments work best as complete sentences, which
+allow a wide variety of automated presentations. The first sentence
+should be a one-sentence summary that starts with the name being
+declared.
+
+If every doc comment begins with the name of the item it describes,
+you can use the \'doc\' subcommand of the \'go\' tool and run the output
+through grep.
+
+See https://go.dev/doc/effective_go#commentary for more
+information on how to write good documentation.`,
+		Since:      "2020.1",
+		NonDefault: true,
+		MergeIf:    lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	fn := func(node ast.Node) {
+		if code.IsInTest(pass, node) {
+			return
+		}
+
+		decl := node.(*ast.FuncDecl)
+		text, ok := docText(decl.Doc)
+		if !ok {
+			return
+		}
+		if !ast.IsExported(decl.Name.Name) {
+			return
+		}
+		if strings.HasPrefix(text, "Deprecated: ") {
+			return
+		}
+
+		kind := "function"
+		if decl.Recv != nil {
+			kind = "method"
+			var ident *ast.Ident
+			T := decl.Recv.List[0].Type
+			if T_, ok := T.(*ast.StarExpr); ok {
+				T = T_.X
+			}
+			switch T := T.(type) {
+			case *ast.IndexExpr:
+				ident = T.X.(*ast.Ident)
+			case *ast.IndexListExpr:
+				ident = T.X.(*ast.Ident)
+			case *ast.Ident:
+				ident = T
+			default:
+				lint.ExhaustiveTypeSwitch(T)
+			}
+			if !ast.IsExported(ident.Name) {
+				return
+			}
+		}
+		prefix := decl.Name.Name + " "
+		if !strings.HasPrefix(text, prefix) {
+			report.Report(pass, decl.Doc, fmt.Sprintf(`comment on exported %s %s should be of the form "%s..."`, kind, decl.Name.Name, prefix), report.FilterGenerated())
+		}
+	}
+
+	code.Preorder(pass, fn, (*ast.FuncDecl)(nil))
+	return nil, nil
+}
+
+func docText(doc *ast.CommentGroup) (string, bool) {
+	if doc == nil {
+		return "", false
+	}
+	// We trim spaces primarily because of /**/ style comments, which often have leading space.
+	text := strings.TrimSpace(doc.Text())
+	return text, text != ""
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1021/st1021.go b/vendor/honnef.co/go/tools/stylecheck/st1021/st1021.go
new file mode 100644
index 0000000..9a43c81
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1021/st1021.go
@@ -0,0 +1,124 @@
+package st1021
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1021",
+		Run:      run,
+		Requires: []*analysis.Analyzer{generated.Analyzer, inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "The documentation of an exported type should start with type's name",
+		Text: `Doc comments work best as complete sentences, which
+allow a wide variety of automated presentations. The first sentence
+should be a one-sentence summary that starts with the name being
+declared.
+
+If every doc comment begins with the name of the item it describes,
+you can use the \'doc\' subcommand of the \'go\' tool and run the output
+through grep.
+
+See https://go.dev/doc/effective_go#commentary for more
+information on how to write good documentation.`,
+		Since:      "2020.1",
+		NonDefault: true,
+		MergeIf:    lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	var genDecl *ast.GenDecl
+	fn := func(node ast.Node, push bool) bool {
+		if !push {
+			genDecl = nil
+			return false
+		}
+		if code.IsInTest(pass, node) {
+			return false
+		}
+
+		switch node := node.(type) {
+		case *ast.GenDecl:
+			if node.Tok == token.IMPORT {
+				return false
+			}
+			genDecl = node
+			return true
+		case *ast.TypeSpec:
+			if !ast.IsExported(node.Name.Name) {
+				return false
+			}
+
+			doc := node.Doc
+			text, ok := docText(doc)
+			if !ok {
+				if len(genDecl.Specs) != 1 {
+					// more than one spec in the GenDecl, don't validate the
+					// docstring
+					return false
+				}
+				if genDecl.Lparen.IsValid() {
+					// 'type ( T )' is weird, don't guess the user's intention
+					return false
+				}
+				doc = genDecl.Doc
+				text, ok = docText(doc)
+				if !ok {
+					return false
+				}
+			}
+
+			// Check comment before we strip articles in case the type's name is an article.
+			if strings.HasPrefix(text, node.Name.Name+" ") {
+				return false
+			}
+
+			s := text
+			articles := [...]string{"A", "An", "The"}
+			for _, a := range articles {
+				if strings.HasPrefix(s, a+" ") {
+					s = s[len(a)+1:]
+					break
+				}
+			}
+			if !strings.HasPrefix(s, node.Name.Name+" ") {
+				report.Report(pass, doc, fmt.Sprintf(`comment on exported type %s should be of the form "%s ..." (with optional leading article)`, node.Name.Name, node.Name.Name), report.FilterGenerated())
+			}
+			return false
+		case *ast.FuncLit, *ast.FuncDecl:
+			return false
+		default:
+			lint.ExhaustiveTypeSwitch(node)
+			return false
+		}
+	}
+
+	pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes([]ast.Node{(*ast.GenDecl)(nil), (*ast.TypeSpec)(nil), (*ast.FuncLit)(nil), (*ast.FuncDecl)(nil)}, fn)
+	return nil, nil
+}
+
+func docText(doc *ast.CommentGroup) (string, bool) {
+	if doc == nil {
+		return "", false
+	}
+	// We trim spaces primarily because of /**/ style comments, which often have leading space.
+	text := strings.TrimSpace(doc.Text())
+	return text, text != ""
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1022/st1022.go b/vendor/honnef.co/go/tools/stylecheck/st1022/st1022.go
new file mode 100644
index 0000000..2813632
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1022/st1022.go
@@ -0,0 +1,105 @@
+package st1022
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strings"
+
+	"honnef.co/go/tools/analysis/code"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+)
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: &analysis.Analyzer{
+		Name:     "ST1022",
+		Run:      run,
+		Requires: []*analysis.Analyzer{generated.Analyzer, inspect.Analyzer},
+	},
+	Doc: &lint.RawDocumentation{
+		Title: "The documentation of an exported variable or constant should start with variable's name",
+		Text: `Doc comments work best as complete sentences, which
+allow a wide variety of automated presentations. The first sentence
+should be a one-sentence summary that starts with the name being
+declared.
+
+If every doc comment begins with the name of the item it describes,
+you can use the \'doc\' subcommand of the \'go\' tool and run the output
+through grep.
+
+See https://go.dev/doc/effective_go#commentary for more
+information on how to write good documentation.`,
+		Since:      "2020.1",
+		NonDefault: true,
+		MergeIf:    lint.MergeIfAny,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
+
+func run(pass *analysis.Pass) (any, error) {
+	var genDecl *ast.GenDecl
+	fn := func(node ast.Node, push bool) bool {
+		if !push {
+			genDecl = nil
+			return false
+		}
+		if code.IsInTest(pass, node) {
+			return false
+		}
+
+		switch node := node.(type) {
+		case *ast.GenDecl:
+			if node.Tok == token.IMPORT {
+				return false
+			}
+			genDecl = node
+			return true
+		case *ast.ValueSpec:
+			if genDecl.Lparen.IsValid() || len(node.Names) > 1 {
+				// Don't try to guess the user's intention
+				return false
+			}
+			name := node.Names[0].Name
+			if !ast.IsExported(name) {
+				return false
+			}
+			text, ok := docText(genDecl.Doc)
+			if !ok {
+				return false
+			}
+			prefix := name + " "
+			if !strings.HasPrefix(text, prefix) {
+				kind := "var"
+				if genDecl.Tok == token.CONST {
+					kind = "const"
+				}
+				report.Report(pass, genDecl.Doc, fmt.Sprintf(`comment on exported %s %s should be of the form "%s..."`, kind, name, prefix), report.FilterGenerated())
+			}
+			return false
+		case *ast.FuncLit, *ast.FuncDecl:
+			return false
+		default:
+			lint.ExhaustiveTypeSwitch(node)
+			return false
+		}
+	}
+
+	pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes([]ast.Node{(*ast.GenDecl)(nil), (*ast.ValueSpec)(nil), (*ast.FuncLit)(nil), (*ast.FuncDecl)(nil)}, fn)
+	return nil, nil
+}
+
+func docText(doc *ast.CommentGroup) (string, bool) {
+	if doc == nil {
+		return "", false
+	}
+	// We trim spaces primarily because of /**/ style comments, which often have leading space.
+	text := strings.TrimSpace(doc.Text())
+	return text, text != ""
+}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1023/st1023.go b/vendor/honnef.co/go/tools/stylecheck/st1023/st1023.go
new file mode 100644
index 0000000..c1ab2c0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/stylecheck/st1023/st1023.go
@@ -0,0 +1,22 @@
+package st1023
+
+import (
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/internal/sharedcheck"
+)
+
+func init() {
+	SCAnalyzer.Analyzer.Name = "ST1023"
+}
+
+var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
+	Analyzer: sharedcheck.RedundantTypeInDeclarationChecker("should", false),
+	Doc: &lint.RawDocumentation{
+		Title:      "Redundant type in variable declaration",
+		Since:      "2021.1",
+		NonDefault: true,
+		MergeIf:    lint.MergeIfAll,
+	},
+})
+
+var Analyzer = SCAnalyzer.Analyzer
diff --git a/vendor/honnef.co/go/tools/unused/implements.go b/vendor/honnef.co/go/tools/unused/implements.go
new file mode 100644
index 0000000..f7c3796
--- /dev/null
+++ b/vendor/honnef.co/go/tools/unused/implements.go
@@ -0,0 +1,102 @@
+package unused
+
+import (
+	"go/types"
+
+	"honnef.co/go/tools/go/types/typeutil"
+)
+
+// lookupMethod returns the index of and method with matching package and name, or (-1, nil).
+func lookupMethod(T *types.Interface, pkg *types.Package, name string) (int, *types.Func) {
+	if name != "_" {
+		for i := 0; i < T.NumMethods(); i++ {
+			m := T.Method(i)
+			if sameId(m, pkg, name) {
+				return i, m
+			}
+		}
+	}
+	return -1, nil
+}
+
+func sameId(obj types.Object, pkg *types.Package, name string) bool {
+	// spec:
+	// "Two identifiers are different if they are spelled differently,
+	// or if they appear in different packages and are not exported.
+	// Otherwise, they are the same."
+	if name != obj.Name() {
+		return false
+	}
+	// obj.Name == name
+	if obj.Exported() {
+		return true
+	}
+	// not exported, so packages must be the same (pkg == nil for
+	// fields in Universe scope; this can only happen for types
+	// introduced via Eval)
+	if pkg == nil || obj.Pkg() == nil {
+		return pkg == obj.Pkg()
+	}
+	// pkg != nil && obj.pkg != nil
+	return pkg.Path() == obj.Pkg().Path()
+}
+
+func implements(V types.Type, T *types.Interface, msV *types.MethodSet) ([]*types.Selection, bool) {
+	// fast path for common case
+	if T.Empty() {
+		return nil, true
+	}
+
+	if ityp, _ := V.Underlying().(*types.Interface); ityp != nil {
+		// TODO(dh): is this code reachable?
+		for m := range T.Methods() {
+			_, obj := lookupMethod(ityp, m.Pkg(), m.Name())
+			switch {
+			case obj == nil:
+				return nil, false
+			case !types.Identical(obj.Type(), m.Type()):
+				return nil, false
+			}
+		}
+		return nil, true
+	}
+
+	// A concrete type implements T if it implements all methods of T.
+	var sels []*types.Selection
+
+	mapping := map[*types.TypeParam]types.Type{}
+	for m := range T.Methods() {
+		sel := msV.Lookup(m.Pkg(), m.Name())
+		if sel == nil {
+			return nil, false
+		}
+
+		f, _ := sel.Obj().(*types.Func)
+		if f == nil {
+			return nil, false
+		}
+
+		if ok := typeutil.Unify(f.Type(), m.Type(), mapping); !ok {
+			return nil, false
+		}
+
+		sels = append(sels, sel)
+	}
+	for tparam, targ := range mapping {
+		// This checks constraints on a best-effort basis, erring on the side
+		// of accepting too many types.
+		if !satisfiesConstraint(targ, tparam) {
+			return nil, false
+		}
+	}
+	return sels, true
+}
+
+func satisfiesConstraint(t types.Type, tp *types.TypeParam) bool {
+	if t == nil {
+		// t is nil when we unify two type parameters.
+		return true
+	}
+	bound := tp.Constraint().Underlying().(*types.Interface)
+	return types.Satisfies(t, bound)
+}
diff --git a/vendor/honnef.co/go/tools/unused/runtime.go b/vendor/honnef.co/go/tools/unused/runtime.go
new file mode 100644
index 0000000..11be4a3
--- /dev/null
+++ b/vendor/honnef.co/go/tools/unused/runtime.go
@@ -0,0 +1,331 @@
+package unused
+
+// Functions defined in the Go runtime that may be called through
+// compiler magic or via assembly.
+var runtimeFuncs = map[string]bool{
+	// Copied from cmd/compile/internal/typecheck/builtin.go, var runtimeDecls
+	"newobject":               true,
+	"panicindex":              true,
+	"panicslice":              true,
+	"panicdivide":             true,
+	"panicmakeslicelen":       true,
+	"throwinit":               true,
+	"panicwrap":               true,
+	"gopanic":                 true,
+	"gorecover":               true,
+	"goschedguarded":          true,
+	"printbool":               true,
+	"printfloat":              true,
+	"printint":                true,
+	"printhex":                true,
+	"printuint":               true,
+	"printcomplex":            true,
+	"printstring":             true,
+	"printpointer":            true,
+	"printiface":              true,
+	"printeface":              true,
+	"printslice":              true,
+	"printnl":                 true,
+	"printsp":                 true,
+	"printlock":               true,
+	"printunlock":             true,
+	"concatstring2":           true,
+	"concatstring3":           true,
+	"concatstring4":           true,
+	"concatstring5":           true,
+	"concatstrings":           true,
+	"cmpstring":               true,
+	"intstring":               true,
+	"slicebytetostring":       true,
+	"slicebytetostringtmp":    true,
+	"slicerunetostring":       true,
+	"stringtoslicebyte":       true,
+	"stringtoslicerune":       true,
+	"slicecopy":               true,
+	"slicestringcopy":         true,
+	"decoderune":              true,
+	"countrunes":              true,
+	"convI2I":                 true,
+	"convT16":                 true,
+	"convT32":                 true,
+	"convT64":                 true,
+	"convTstring":             true,
+	"convTslice":              true,
+	"convT2E":                 true,
+	"convT2Enoptr":            true,
+	"convT2I":                 true,
+	"convT2Inoptr":            true,
+	"assertE2I":               true,
+	"assertE2I2":              true,
+	"assertI2I":               true,
+	"assertI2I2":              true,
+	"panicdottypeE":           true,
+	"panicdottypeI":           true,
+	"panicnildottype":         true,
+	"ifaceeq":                 true,
+	"efaceeq":                 true,
+	"fastrand":                true,
+	"makemap64":               true,
+	"makemap":                 true,
+	"makemap_small":           true,
+	"mapaccess1":              true,
+	"mapaccess1_fast32":       true,
+	"mapaccess1_fast64":       true,
+	"mapaccess1_faststr":      true,
+	"mapaccess1_fat":          true,
+	"mapaccess2":              true,
+	"mapaccess2_fast32":       true,
+	"mapaccess2_fast64":       true,
+	"mapaccess2_faststr":      true,
+	"mapaccess2_fat":          true,
+	"mapassign":               true,
+	"mapassign_fast32":        true,
+	"mapassign_fast32ptr":     true,
+	"mapassign_fast64":        true,
+	"mapassign_fast64ptr":     true,
+	"mapassign_faststr":       true,
+	"mapiterinit":             true,
+	"mapdelete":               true,
+	"mapdelete_fast32":        true,
+	"mapdelete_fast64":        true,
+	"mapdelete_faststr":       true,
+	"mapiternext":             true,
+	"mapclear":                true,
+	"makechan64":              true,
+	"makechan":                true,
+	"chanrecv1":               true,
+	"chanrecv2":               true,
+	"chansend1":               true,
+	"closechan":               true,
+	"writeBarrier":            true,
+	"typedmemmove":            true,
+	"typedmemclr":             true,
+	"typedslicecopy":          true,
+	"selectnbsend":            true,
+	"selectnbrecv":            true,
+	"selectnbrecv2":           true,
+	"selectsetpc":             true,
+	"selectgo":                true,
+	"block":                   true,
+	"makeslice":               true,
+	"makeslice64":             true,
+	"growslice":               true,
+	"memmove":                 true,
+	"memclrNoHeapPointers":    true,
+	"memclrHasPointers":       true,
+	"memequal":                true,
+	"memequal8":               true,
+	"memequal16":              true,
+	"memequal32":              true,
+	"memequal64":              true,
+	"memequal128":             true,
+	"int64div":                true,
+	"uint64div":               true,
+	"int64mod":                true,
+	"uint64mod":               true,
+	"float64toint64":          true,
+	"float64touint64":         true,
+	"float64touint32":         true,
+	"int64tofloat64":          true,
+	"uint64tofloat64":         true,
+	"uint32tofloat64":         true,
+	"complex128div":           true,
+	"racefuncenter":           true,
+	"racefuncenterfp":         true,
+	"racefuncexit":            true,
+	"raceread":                true,
+	"racewrite":               true,
+	"racereadrange":           true,
+	"racewriterange":          true,
+	"msanread":                true,
+	"msanwrite":               true,
+	"x86HasPOPCNT":            true,
+	"x86HasSSE41":             true,
+	"arm64HasATOMICS":         true,
+	"mallocgc":                true,
+	"panicshift":              true,
+	"panicmakeslicecap":       true,
+	"goPanicIndex":            true,
+	"goPanicIndexU":           true,
+	"goPanicSliceAlen":        true,
+	"goPanicSliceAlenU":       true,
+	"goPanicSliceAcap":        true,
+	"goPanicSliceAcapU":       true,
+	"goPanicSliceB":           true,
+	"goPanicSliceBU":          true,
+	"goPanicSlice3Alen":       true,
+	"goPanicSlice3AlenU":      true,
+	"goPanicSlice3Acap":       true,
+	"goPanicSlice3AcapU":      true,
+	"goPanicSlice3B":          true,
+	"goPanicSlice3BU":         true,
+	"goPanicSlice3C":          true,
+	"goPanicSlice3CU":         true,
+	"goPanicSliceConvert":     true,
+	"printuintptr":            true,
+	"convT":                   true,
+	"convTnoptr":              true,
+	"makeslicecopy":           true,
+	"unsafeslicecheckptr":     true,
+	"panicunsafeslicelen":     true,
+	"panicunsafeslicenilptr":  true,
+	"unsafestringcheckptr":    true,
+	"panicunsafestringlen":    true,
+	"panicunsafestringnilptr": true,
+	"mulUintptr":              true,
+	"memequal0":               true,
+	"f32equal":                true,
+	"f64equal":                true,
+	"c64equal":                true,
+	"c128equal":               true,
+	"strequal":                true,
+	"interequal":              true,
+	"nilinterequal":           true,
+	"memhash":                 true,
+	"memhash0":                true,
+	"memhash8":                true,
+	"memhash16":               true,
+	"memhash32":               true,
+	"memhash64":               true,
+	"memhash128":              true,
+	"f32hash":                 true,
+	"f64hash":                 true,
+	"c64hash":                 true,
+	"c128hash":                true,
+	"strhash":                 true,
+	"interhash":               true,
+	"nilinterhash":            true,
+	"int64tofloat32":          true,
+	"uint64tofloat32":         true,
+	"getcallerpc":             true,
+	"getcallersp":             true,
+	"msanmove":                true,
+	"asanread":                true,
+	"asanwrite":               true,
+	"checkptrAlignment":       true,
+	"checkptrArithmetic":      true,
+	"libfuzzerTraceCmp1":      true,
+	"libfuzzerTraceCmp2":      true,
+	"libfuzzerTraceCmp4":      true,
+	"libfuzzerTraceCmp8":      true,
+	"libfuzzerTraceConstCmp1": true,
+	"libfuzzerTraceConstCmp2": true,
+	"libfuzzerTraceConstCmp4": true,
+	"libfuzzerTraceConstCmp8": true,
+	"libfuzzerHookStrCmp":     true,
+	"libfuzzerHookEqualFold":  true,
+	"addCovMeta":              true,
+	"x86HasFMA":               true,
+	"armHasVFPv4":             true,
+
+	// Extracted from assembly code in the standard library, with the exception of the runtime package itself
+	"abort":                 true,
+	"aeshashbody":           true,
+	"args":                  true,
+	"asminit":               true,
+	"badctxt":               true,
+	"badmcall2":             true,
+	"badmcall":              true,
+	"badmorestackg0":        true,
+	"badmorestackgsignal":   true,
+	"badsignal2":            true,
+	"callbackasm1":          true,
+	"callCfunction":         true,
+	"cgocallback_gofunc":    true,
+	"cgocallbackg":          true,
+	"checkgoarm":            true,
+	"check":                 true,
+	"debugCallCheck":        true,
+	"debugCallWrap":         true,
+	"emptyfunc":             true,
+	"entersyscall":          true,
+	"exit":                  true,
+	"exits":                 true,
+	"exitsyscall":           true,
+	"externalthreadhandler": true,
+	"findnull":              true,
+	"goexit1":               true,
+	"gostring":              true,
+	"i386_set_ldt":          true,
+	"_initcgo":              true,
+	"init_thread_tls":       true,
+	"ldt0setup":             true,
+	"libpreinit":            true,
+	"load_g":                true,
+	"morestack":             true,
+	"mstart":                true,
+	"nacl_sysinfo":          true,
+	"nanotimeQPC":           true,
+	"nanotime":              true,
+	"newosproc0":            true,
+	"newproc":               true,
+	"newstack":              true,
+	"noted":                 true,
+	"nowQPC":                true,
+	"osinit":                true,
+	"printf":                true,
+	"racecallback":          true,
+	"reflectcallmove":       true,
+	"reginit":               true,
+	"rt0_go":                true,
+	"save_g":                true,
+	"schedinit":             true,
+	"setldt":                true,
+	"settls":                true,
+	"sighandler":            true,
+	"sigprofNonGo":          true,
+	"sigtrampgo":            true,
+	"_sigtramp":             true,
+	"sigtramp":              true,
+	"stackcheck":            true,
+	"syscall_chdir":         true,
+	"syscall_chroot":        true,
+	"syscall_close":         true,
+	"syscall_dup2":          true,
+	"syscall_execve":        true,
+	"syscall_exit":          true,
+	"syscall_fcntl":         true,
+	"syscall_forkx":         true,
+	"syscall_gethostname":   true,
+	"syscall_getpid":        true,
+	"syscall_ioctl":         true,
+	"syscall_pipe":          true,
+	"syscall_rawsyscall6":   true,
+	"syscall_rawSyscall6":   true,
+	"syscall_rawsyscall":    true,
+	"syscall_RawSyscall":    true,
+	"syscall_rawsysvicall6": true,
+	"syscall_setgid":        true,
+	"syscall_setgroups":     true,
+	"syscall_setpgid":       true,
+	"syscall_setsid":        true,
+	"syscall_setuid":        true,
+	"syscall_syscall6":      true,
+	"syscall_syscall":       true,
+	"syscall_Syscall":       true,
+	"syscall_sysvicall6":    true,
+	"syscall_wait4":         true,
+	"syscall_write":         true,
+	"traceback":             true,
+	"tstart":                true,
+	"usplitR0":              true,
+	"wbBufFlush":            true,
+	"write":                 true,
+
+	// Other runtime functions that can get called in non-standard ways
+	"bgsweep":             true,
+	"memhash_varlen":      true,
+	"strhashFallback":     true,
+	"asanregisterglobals": true,
+	"cgoUse":              true,
+	"cgoCheckPointer":     true,
+	"cgoCheckResult":      true,
+	"_cgo_panic_internal": true,
+	"addExitHook":         true,
+}
+
+var runtimeCoverageFuncs = map[string]bool{
+	"initHook":            true,
+	"markProfileEmitted":  true,
+	"processCoverTestDir": true,
+}
diff --git a/vendor/honnef.co/go/tools/unused/serialize.go b/vendor/honnef.co/go/tools/unused/serialize.go
new file mode 100644
index 0000000..e971541
--- /dev/null
+++ b/vendor/honnef.co/go/tools/unused/serialize.go
@@ -0,0 +1,99 @@
+package unused
+
+import (
+	"fmt"
+	"go/token"
+	"os"
+
+	"golang.org/x/tools/go/types/objectpath"
+)
+
+type ObjectPath struct {
+	PkgPath string
+	ObjPath objectpath.Path
+}
+
+// XXX make sure that node 0 always exists and is always the root
+
+type SerializedGraph struct {
+	nodes       []Node
+	nodesByPath map[ObjectPath]NodeID
+	// XXX deduplicating on position is dubious for `switch x := foo.(type)`, where x will be declared many times for
+	// the different types, but all at the same position. On the other hand, merging these nodes is probably fine.
+	nodesByPosition map[token.Position]NodeID
+}
+
+func trace(f string, args ...any) {
+	fmt.Fprintf(os.Stderr, f, args...)
+	fmt.Fprintln(os.Stderr)
+}
+
+func (g *SerializedGraph) Merge(nodes []Node) {
+	if g.nodesByPath == nil {
+		g.nodesByPath = map[ObjectPath]NodeID{}
+	}
+	if g.nodesByPosition == nil {
+		g.nodesByPosition = map[token.Position]NodeID{}
+	}
+	if len(g.nodes) == 0 {
+		// Seed nodes with a root node
+		g.nodes = append(g.nodes, Node{})
+	}
+	// OPT(dh): reuse storage between calls to Merge
+	remapping := make([]NodeID, len(nodes))
+
+	// First pass: compute remapping of IDs of to-be-merged nodes
+	for _, n := range nodes {
+		// XXX Column is never 0. it's 1 if there is no column information in the export data. which sucks, because
+		// objects can also genuinely be in column 1.
+		if n.id != 0 && n.obj.Path == (ObjectPath{}) && n.obj.Position.Column == 0 {
+			// If the object has no path, then it couldn't have come from export data, which means it needs to have full
+			// position information including a column.
+			panic(fmt.Sprintf("object %q has no path but also no column information", n.obj.Name))
+		}
+
+		if orig, ok := g.nodesByPath[n.obj.Path]; ok {
+			// We already have a node for this object
+			trace("deduplicating %d -> %d based on path %s", n.id, orig, n.obj.Path)
+			remapping[n.id] = orig
+		} else if orig, ok := g.nodesByPosition[n.obj.Position]; ok && n.obj.Position.Column != 0 {
+			// We already have a node for this object
+			trace("deduplicating %d -> %d based on position %s", n.id, orig, n.obj.Position)
+			remapping[n.id] = orig
+		} else {
+			// This object is new to us; change ID to avoid collision
+			newID := NodeID(len(g.nodes))
+			trace("new node, remapping %d -> %d", n.id, newID)
+			remapping[n.id] = newID
+			g.nodes = append(g.nodes, Node{
+				id:   newID,
+				obj:  n.obj,
+				uses: make([]NodeID, 0, len(n.uses)),
+				owns: make([]NodeID, 0, len(n.owns)),
+			})
+			if n.id == 0 {
+				// Our root uses all the roots of the subgraphs
+				g.nodes[0].uses = append(g.nodes[0].uses, newID)
+			}
+			if n.obj.Path != (ObjectPath{}) {
+				g.nodesByPath[n.obj.Path] = newID
+			}
+			if n.obj.Position.Column != 0 {
+				g.nodesByPosition[n.obj.Position] = newID
+			}
+		}
+	}
+
+	// Second step: apply remapping
+	for _, n := range nodes {
+		n.id = remapping[n.id]
+		for i := range n.uses {
+			n.uses[i] = remapping[n.uses[i]]
+		}
+		for i := range n.owns {
+			n.owns[i] = remapping[n.owns[i]]
+		}
+		g.nodes[n.id].uses = append(g.nodes[n.id].uses, n.uses...)
+		g.nodes[n.id].owns = append(g.nodes[n.id].owns, n.owns...)
+	}
+}
diff --git a/vendor/honnef.co/go/tools/unused/unused.go b/vendor/honnef.co/go/tools/unused/unused.go
new file mode 100644
index 0000000..fd7b5c0
--- /dev/null
+++ b/vendor/honnef.co/go/tools/unused/unused.go
@@ -0,0 +1,1739 @@
+// Package unused contains code for finding unused code.
+package unused
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"io"
+	"reflect"
+	"slices"
+	"strings"
+
+	"honnef.co/go/tools/analysis/facts/directives"
+	"honnef.co/go/tools/analysis/facts/generated"
+	"honnef.co/go/tools/analysis/lint"
+	"honnef.co/go/tools/analysis/report"
+	"honnef.co/go/tools/go/ast/astutil"
+	"honnef.co/go/tools/go/types/typeutil"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/types/objectpath"
+)
+
+// OPT(dh): don't track local variables that can't have any interesting outgoing edges. For example, using a local
+// variable of type int is meaningless; we don't care if `int` is used or not.
+//
+// Note that we do have to track variables with for example array types, because the array type could have involved a
+// named constant.
+//
+// We probably have different culling needs depending on the mode of operation, too. If we analyze multiple packages in
+// one graph (unused's "whole program" mode), we could remove further useless edges (e.g. into nodes that themselves
+// have no outgoing edges and aren't meaningful objects on their own) after having analyzed a package, to keep the
+// in-memory representation small on average. If we only analyze a single package, that step would just waste cycles, as
+// we're about to throw the entire graph away, anyway.
+
+// TODO(dh): currently, types use methods that implement interfaces. However, this makes a method used even if the
+// relevant interface is never used. What if instead interfaces used those methods? Right now we cannot do that, because
+// methods use their receivers, so using a method uses the type. But do we need that edge? Is there a way to refer to a
+// method without explicitly mentioning the type somewhere? If not, the edge from method to receiver is superfluous.
+
+// XXX vet all code for proper use of core types
+
+// TODO(dh): we cannot observe function calls in assembly files.
+
+/*
+
+This overview is true when using the default options. Different options may change individual behaviors.
+
+- packages use:
+  - (1.1) exported named types
+  - (1.2) exported functions (but not methods!)
+  - (1.3) exported variables
+  - (1.4) exported constants
+  - (1.5) init functions
+  - (1.6) functions exported to cgo
+  - (1.7) the main function iff in the main package
+  - (1.8) symbols linked via go:linkname
+  - (1.9) objects in generated files
+
+- named types use:
+  - (2.1) exported methods
+  - (2.2) the type they're based on
+  - (2.5) all their type parameters. Unused type parameters are probably useless, but they're a brand new feature and we
+    don't want to introduce false positives because we couldn't anticipate some novel use-case.
+  - (2.6) all their type arguments
+
+- functions use:
+  - (4.1) all their arguments, return parameters and receivers
+  - (4.2) anonymous functions defined beneath them
+  - (4.3) closures and bound methods.
+    this implements a simplified model where a function is used merely by being referenced, even if it is never called.
+    that way we don't have to keep track of closures escaping functions.
+  - (4.4) functions they return. we assume that someone else will call the returned function
+  - (4.5) functions/interface methods they call
+  - (4.6) types they instantiate or convert to
+  - (4.7) fields they access
+  - (4.9) package-level variables they assign to iff in tests (sinks for benchmarks)
+  - (4.10) all their type parameters. See 2.5 for reasoning.
+  - (4.11) local variables
+  - Note that the majority of this is handled implicitly by seeing idents be used. In particular, unlike the old
+    IR-based implementation, the AST-based one doesn't care about closures, bound methods or anonymous functions.
+    They're all just additional nodes in the AST.
+
+- conversions use:
+  - (5.1) when converting between two equivalent structs, the fields in
+    either struct use each other. the fields are relevant for the
+    conversion, but only if the fields are also accessed outside the
+    conversion.
+  - (5.2) when converting to or from unsafe.Pointer, mark all fields as used.
+
+- structs use:
+  - (6.1) fields of type NoCopy sentinel
+  - (6.2) exported fields
+  - (6.3) embedded fields that help implement interfaces (either fully implements it, or contributes required methods) (recursively)
+  - (6.4) embedded fields that have exported methods (recursively)
+  - (6.5) embedded structs that have exported fields (recursively)
+  - (6.6) all fields if they have a structs.HostLayout field
+
+- (7.1) field accesses use fields
+- (7.2) fields use their types
+
+- (8.0) How we handle interfaces:
+  - (8.1) We do not technically care about interfaces that only consist of
+    exported methods. Exported methods on concrete types are always
+    marked as used.
+  - (8.2) Any concrete type implements all known interfaces. Even if it isn't
+    assigned to any interfaces in our code, the user may receive a value
+    of the type and expect to pass it back to us through an interface.
+
+    Concrete types use their methods that implement interfaces. If the
+    type is used, it uses those methods. Otherwise, it doesn't. This
+    way, types aren't incorrectly marked reachable through the edge
+    from method to type.
+
+  - (8.3) All interface methods are marked as used, even if they never get
+    called. This is to accommodate sum types (unexported interface
+    method that must exist but never gets called.)
+
+  - (8.4) All embedded interfaces are marked as used. This is an
+    extension of 8.3, but we have to explicitly track embedded
+    interfaces because in a chain C->B->A, B wouldn't be marked as
+    used by 8.3 just because it contributes A's methods to C.
+
+- Inherent uses:
+  - (9.2) variables use their types
+  - (9.3) types use their underlying and element types
+  - (9.4) conversions use the type they convert to
+  - (9.7) variable _reads_ use variables, writes do not, except in tests
+  - (9.8) runtime functions that may be called from user code via the compiler
+  - (9.9) objects named the blank identifier are used. They cannot be referred to and are usually used explicitly to
+     use something that would otherwise be unused.
+  - The majority of idents get marked as read by virtue of being in the AST.
+
+- const groups:
+  - (10.1) if one constant out of a block of constants is used, mark all
+    of them used. a lot of the time, unused constants exist for the sake
+    of completeness. See also
+    https://github.com/dominikh/go-tools/issues/365
+
+    Do not, however, include constants named _ in constant groups.
+
+
+- (11.1) anonymous struct types use all their fields. we cannot
+  deduplicate struct types, as that leads to order-dependent
+  reports. we can't not deduplicate struct types while still
+  tracking fields, because then each instance of the unnamed type in
+  the data flow chain will get its own fields, causing false
+  positives. Thus, we only accurately track fields of named struct
+  types, and assume that unnamed struct types use all their fields.
+
+- type parameters use:
+  - (12.1) their constraint type
+
+*/
+
+var Debug io.Writer
+
+func assert(b bool) {
+	if !b {
+		panic("failed assertion")
+	}
+}
+
+// TODO(dh): should we return a map instead of two slices?
+type Result struct {
+	Used   []Object
+	Unused []Object
+	Quiet  []Object
+}
+
+var Analyzer = &lint.Analyzer{
+	Doc: &lint.RawDocumentation{
+		Title: "Unused code",
+	},
+	Analyzer: &analysis.Analyzer{
+		Name:       "U1000",
+		Doc:        "Unused code",
+		Run:        run,
+		Requires:   []*analysis.Analyzer{generated.Analyzer, directives.Analyzer},
+		ResultType: reflect.TypeFor[Result](),
+	},
+}
+
+func newGraph(
+	fset *token.FileSet,
+	files []*ast.File,
+	pkg *types.Package,
+	info *types.Info,
+	directives []lint.Directive,
+	generated map[string]generated.Generator,
+	opts Options,
+) *graph {
+	g := graph{
+		pkg:        pkg,
+		info:       info,
+		files:      files,
+		directives: directives,
+		generated:  generated,
+		fset:       fset,
+		nodes:      []Node{{}},
+		edges:      map[edge]struct{}{},
+		objects:    map[types.Object]NodeID{},
+		opts:       opts,
+	}
+
+	return &g
+}
+
+func run(pass *analysis.Pass) (any, error) {
+	g := newGraph(
+		pass.Fset,
+		pass.Files,
+		pass.Pkg,
+		pass.TypesInfo,
+		pass.ResultOf[directives.Analyzer].([]lint.Directive),
+		pass.ResultOf[generated.Analyzer].(map[string]generated.Generator),
+		DefaultOptions,
+	)
+	g.entry()
+
+	sg := &SerializedGraph{
+		nodes: g.nodes,
+	}
+
+	if Debug != nil {
+		Debug.Write([]byte(sg.Dot()))
+	}
+
+	return sg.Results(), nil
+}
+
+type Options struct {
+	FieldWritesAreUses     bool
+	PostStatementsAreReads bool
+	ExportedIsUsed         bool
+	ExportedFieldsAreUsed  bool
+	ParametersAreUsed      bool
+	LocalVariablesAreUsed  bool
+	GeneratedIsUsed        bool
+}
+
+var DefaultOptions = Options{
+	FieldWritesAreUses:     true,
+	PostStatementsAreReads: false,
+	ExportedIsUsed:         true,
+	ExportedFieldsAreUsed:  true,
+	ParametersAreUsed:      true,
+	LocalVariablesAreUsed:  true,
+	GeneratedIsUsed:        true,
+}
+
+type edgeKind uint8
+
+const (
+	edgeKindUse = iota + 1
+	edgeKindOwn
+)
+
+type edge struct {
+	from, to NodeID
+	kind     edgeKind
+}
+
+type graph struct {
+	pkg        *types.Package
+	info       *types.Info
+	files      []*ast.File
+	fset       *token.FileSet
+	directives []lint.Directive
+	generated  map[string]generated.Generator
+
+	opts Options
+
+	// edges tracks all edges between nodes (uses and owns relationships). This data is also present in the Node struct,
+	// but there it can't be accessed in O(1) time. edges is used to deduplicate edges.
+	edges   map[edge]struct{}
+	nodes   []Node
+	objects map[types.Object]NodeID
+
+	// package-level named types
+	namedTypes     []*types.TypeName
+	interfaceTypes []*types.Interface
+}
+
+type nodeState uint8
+
+//gcassert:inline
+func (ns nodeState) seen() bool { return ns&nodeStateSeen != 0 }
+
+//gcassert:inline
+func (ns nodeState) quiet() bool { return ns&nodeStateQuiet != 0 }
+
+const (
+	nodeStateSeen nodeState = 1 << iota
+	nodeStateQuiet
+)
+
+// OPT(dh): 32 bits would be plenty, but the Node struct would end up with padding, anyway.
+type NodeID uint64
+
+type Node struct {
+	id  NodeID
+	obj Object
+
+	// using slices instead of maps here helps make merging of graphs simpler and more efficient, because we can rewrite
+	// IDs in place instead of having to build new maps.
+	uses []NodeID
+	owns []NodeID
+}
+
+func (g *graph) objectToObject(obj types.Object) Object {
+	// OPT(dh): I think we only need object paths in whole-program mode. In other cases, position-based node merging
+	// should suffice.
+
+	// objectpath.For is an expensive function and we'd like to avoid calling it when we know that there cannot be a
+	// path, or when the path doesn't matter.
+	//
+	// Unexported global objects don't have paths. Local variables may have paths when they're parameters or return
+	// parameters, but we do not care about those, because they're not API that other packages can refer to directly. We
+	// do have to track fields, because they may be part of an anonymous type declared in a parameter or return
+	// parameter. We cannot categorically ignore unexported identifiers, because an exported field might have been
+	// embedded via an unexported field, which will be referred to.
+
+	var relevant bool
+	switch obj := obj.(type) {
+	case *types.Var:
+		// If it's a field or it's an exported top-level variable, we care about it. Otherwise, we don't.
+		// OPT(dh): same question as posed in the default branch
+		relevant = obj.IsField() || token.IsExported(obj.Name())
+	default:
+		// OPT(dh): See if it's worth checking that the object is actually in package scope, and doesn't just have a
+		// capitalized name.
+		relevant = token.IsExported(obj.Name())
+	}
+
+	var path ObjectPath
+	if relevant {
+		objPath, _ := objectpath.For(obj)
+		if objPath != "" {
+			path = ObjectPath{
+				PkgPath: obj.Pkg().Path(),
+				ObjPath: objPath,
+			}
+		}
+	}
+	name := obj.Name()
+	if sig, ok := obj.Type().(*types.Signature); ok && sig.Recv() != nil {
+		switch types.Unalias(sig.Recv().Type()).(type) {
+		case *types.Named, *types.Pointer:
+			typ := types.TypeString(sig.Recv().Type(), func(*types.Package) string { return "" })
+			if len(typ) > 0 && typ[0] == '*' {
+				name = fmt.Sprintf("(%s).%s", typ, obj.Name())
+			} else if len(typ) > 0 {
+				name = fmt.Sprintf("%s.%s", typ, obj.Name())
+			}
+		}
+	}
+	return Object{
+		Name:            name,
+		ShortName:       obj.Name(),
+		Kind:            typString(obj),
+		Path:            path,
+		Position:        g.fset.PositionFor(obj.Pos(), false),
+		DisplayPosition: report.DisplayPosition(g.fset, obj.Pos()),
+	}
+}
+
+func typString(obj types.Object) string {
+	switch obj := obj.(type) {
+	case *types.Func:
+		return "func"
+	case *types.Var:
+		if obj.IsField() {
+			return "field"
+		}
+		return "var"
+	case *types.Const:
+		return "const"
+	case *types.TypeName:
+		if _, ok := obj.Type().(*types.TypeParam); ok {
+			return "type param"
+		} else {
+			return "type"
+		}
+	default:
+		return "identifier"
+	}
+}
+
+func (g *graph) newNode(obj types.Object) NodeID {
+	id := NodeID(len(g.nodes))
+	n := Node{
+		id:  id,
+		obj: g.objectToObject(obj),
+	}
+	g.nodes = append(g.nodes, n)
+	if _, ok := g.objects[obj]; ok {
+		panic(fmt.Sprintf("already had a node for %s", obj))
+	}
+	g.objects[obj] = id
+	return id
+}
+
+func (g *graph) node(obj types.Object) NodeID {
+	if obj == nil {
+		return 0
+	}
+	obj = origin(obj)
+	if n, ok := g.objects[obj]; ok {
+		return n
+	}
+	n := g.newNode(obj)
+	return n
+}
+
+func origin(obj types.Object) types.Object {
+	switch obj := obj.(type) {
+	case *types.Var:
+		return obj.Origin()
+	case *types.Func:
+		return obj.Origin()
+	default:
+		return obj
+	}
+}
+
+func (g *graph) addEdge(e edge) bool {
+	if _, ok := g.edges[e]; ok {
+		return false
+	}
+	g.edges[e] = struct{}{}
+	return true
+}
+
+func (g *graph) addOwned(owner, owned NodeID) {
+	e := edge{owner, owned, edgeKindOwn}
+	if !g.addEdge(e) {
+		return
+	}
+	n := &g.nodes[owner]
+	n.owns = append(n.owns, owned)
+}
+
+func (g *graph) addUse(by, used NodeID) {
+	e := edge{by, used, edgeKindUse}
+	if !g.addEdge(e) {
+		return
+	}
+	nBy := &g.nodes[by]
+	nBy.uses = append(nBy.uses, used)
+}
+
+func (g *graph) see(obj, owner types.Object) {
+	if obj == nil {
+		panic("saw nil object")
+	}
+
+	if g.opts.ExportedIsUsed && obj.Pkg() != g.pkg || obj.Pkg() == nil {
+		return
+	}
+
+	nObj := g.node(obj)
+	if owner != nil {
+		nOwner := g.node(owner)
+		g.addOwned(nOwner, nObj)
+	}
+}
+
+func isIrrelevant(obj types.Object) bool {
+	switch obj.(type) {
+	case *types.PkgName:
+		return true
+	default:
+		return false
+	}
+}
+
+func (g *graph) use(used, by types.Object) {
+	if g.opts.ExportedIsUsed {
+		if used.Pkg() != g.pkg || used.Pkg() == nil {
+			return
+		}
+		if by != nil && by.Pkg() != g.pkg {
+			return
+		}
+	}
+
+	if isIrrelevant(used) {
+		return
+	}
+
+	nUsed := g.node(used)
+	nBy := g.node(by)
+	g.addUse(nBy, nUsed)
+}
+
+func (g *graph) entry() {
+	for _, f := range g.files {
+		for _, cg := range f.Comments {
+			for _, c := range cg.List {
+				if strings.HasPrefix(c.Text, "//go:linkname ") {
+					// FIXME(dh): we're looking at all comments. The
+					// compiler only looks at comments in the
+					// left-most column. The intention probably is to
+					// only look at top-level comments.
+
+					// (1.8) packages use symbols linked via go:linkname
+					fields := strings.Fields(c.Text)
+					if len(fields) == 3 {
+						obj := g.pkg.Scope().Lookup(fields[1])
+						if obj == nil {
+							continue
+						}
+						g.use(obj, nil)
+					}
+				}
+			}
+		}
+	}
+
+	for _, f := range g.files {
+		for _, decl := range f.Decls {
+			g.decl(decl, nil)
+		}
+	}
+
+	if g.opts.GeneratedIsUsed {
+		// OPT(dh): depending on the options used, we do not need to track all objects. For example, if local variables
+		// are always used, then it is enough to use their surrounding function.
+		for obj := range g.objects {
+			path := g.fset.PositionFor(obj.Pos(), false).Filename
+			if _, ok := g.generated[path]; ok {
+				g.use(obj, nil)
+			}
+		}
+	}
+
+	// We use a normal map instead of a typeutil.Map because we deduplicate
+	// these on a best effort basis, as an optimization.
+	allInterfaces := make(map[*types.Interface]struct{})
+	for _, typ := range g.interfaceTypes {
+		allInterfaces[typ] = struct{}{}
+	}
+	for _, ins := range g.info.Instances {
+		if typ, ok := ins.Type.(*types.Named); ok && typ.Obj().Pkg() == g.pkg {
+			if iface, ok := typ.Underlying().(*types.Interface); ok {
+				allInterfaces[iface] = struct{}{}
+			}
+		}
+	}
+	processMethodSet := func(named *types.TypeName, ms *types.MethodSet) {
+		if g.opts.ExportedIsUsed {
+			for m := range ms.Methods() {
+				if token.IsExported(m.Obj().Name()) {
+					// (2.1) named types use exported methods
+					// (6.4) structs use embedded fields that have exported methods
+					//
+					// By reading the selection, we read all embedded fields that are part of the path
+					g.readSelection(m, named)
+				}
+			}
+		}
+
+		if _, ok := named.Type().Underlying().(*types.Interface); !ok {
+			// (8.0) handle interfaces
+			//
+			// We don't care about interfaces implementing interfaces; all their methods are already used, anyway
+			for iface := range allInterfaces {
+				if sels, ok := implements(named.Type(), iface, ms); ok {
+					for _, sel := range sels {
+						// (8.2) any concrete type implements all known interfaces
+						// (6.3) structs use embedded fields that help implement interfaces
+						g.readSelection(sel, named)
+					}
+				}
+			}
+		}
+	}
+
+	for _, named := range g.namedTypes {
+		// OPT(dh): do we already have the method set available?
+		processMethodSet(named, types.NewMethodSet(named.Type()))
+		processMethodSet(named, types.NewMethodSet(types.NewPointer(named.Type())))
+
+	}
+
+	type ignoredKey struct {
+		file string
+		line int
+	}
+	ignores := map[ignoredKey]struct{}{}
+	for _, dir := range g.directives {
+		if dir.Command != "ignore" && dir.Command != "file-ignore" {
+			continue
+		}
+		if len(dir.Arguments) == 0 {
+			continue
+		}
+		if slices.Contains(strings.Split(dir.Arguments[0], ","), "U1000") {
+			pos := g.fset.PositionFor(dir.Node.Pos(), false)
+			var key ignoredKey
+			switch dir.Command {
+			case "ignore":
+				key = ignoredKey{
+					pos.Filename,
+					pos.Line,
+				}
+			case "file-ignore":
+				key = ignoredKey{
+					pos.Filename,
+					-1,
+				}
+			}
+
+			ignores[key] = struct{}{}
+		}
+	}
+
+	if len(ignores) > 0 {
+		// all objects annotated with a //lint:ignore U1000 are considered used
+		for obj := range g.objects {
+			pos := g.fset.PositionFor(obj.Pos(), false)
+			key1 := ignoredKey{
+				pos.Filename,
+				pos.Line,
+			}
+			key2 := ignoredKey{
+				pos.Filename,
+				-1,
+			}
+			_, ok := ignores[key1]
+			if !ok {
+				_, ok = ignores[key2]
+			}
+			if ok {
+				g.use(obj, nil)
+
+				// use methods and fields of ignored types
+				if obj, ok := obj.(*types.TypeName); ok {
+					if obj.IsAlias() {
+						if typ, ok := types.Unalias(obj.Type()).(*types.Named); ok && (g.opts.ExportedIsUsed && typ.Obj().Pkg() != obj.Pkg() || typ.Obj().Pkg() == nil) {
+							// This is an alias of a named type in another package.
+							// Don't walk its fields or methods; we don't have to.
+							//
+							// For aliases to types in the same package, we do want to ignore the fields and methods,
+							// because ignoring the alias should ignore the aliased type.
+							continue
+						}
+					}
+					if typ, ok := types.Unalias(obj.Type()).(*types.Named); ok {
+						for method := range typ.Methods() {
+							g.use(method, nil)
+						}
+					}
+					if typ, ok := obj.Type().Underlying().(*types.Struct); ok {
+						for field := range typ.Fields() {
+							g.use(field, nil)
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+func isOfType[T any](x any) bool {
+	_, ok := x.(T)
+	return ok
+}
+
+func (g *graph) read(node ast.Node, by types.Object) {
+	if node == nil {
+		return
+	}
+
+	switch node := node.(type) {
+	case *ast.Ident:
+		// Among many other things, this handles
+		// (7.1) field accesses use fields
+
+		obj := g.info.ObjectOf(node)
+		g.use(obj, by)
+
+	case *ast.BasicLit:
+		// Nothing to do
+
+	case *ast.SliceExpr:
+		g.read(node.X, by)
+		g.read(node.Low, by)
+		g.read(node.High, by)
+		g.read(node.Max, by)
+
+	case *ast.UnaryExpr:
+		g.read(node.X, by)
+
+	case *ast.ParenExpr:
+		g.read(node.X, by)
+
+	case *ast.ArrayType:
+		g.read(node.Len, by)
+		g.read(node.Elt, by)
+
+	case *ast.SelectorExpr:
+		g.readSelectorExpr(node, by)
+
+	case *ast.IndexExpr:
+		// Among many other things, this handles
+		// (2.6) named types use all their type arguments
+		g.read(node.X, by)
+		g.read(node.Index, by)
+
+	case *ast.IndexListExpr:
+		// Among many other things, this handles
+		// (2.6) named types use all their type arguments
+		g.read(node.X, by)
+		for _, index := range node.Indices {
+			g.read(index, by)
+		}
+
+	case *ast.BinaryExpr:
+		g.read(node.X, by)
+		g.read(node.Y, by)
+
+	case *ast.CompositeLit:
+		g.read(node.Type, by)
+		// We get the type of the node itself, not of node.Type, to handle nested composite literals of the kind
+		// T{{...}}
+		typ, isStruct := typeutil.CoreType(g.info.TypeOf(node)).(*types.Struct)
+
+		if isStruct {
+			unkeyed := len(node.Elts) != 0 && !isOfType[*ast.KeyValueExpr](node.Elts[0])
+			if g.opts.FieldWritesAreUses && unkeyed {
+				// Untagged struct literal that specifies all fields. We have to manually use the fields in the type,
+				// because the unkeyd literal doesn't contain any nodes referring to the fields.
+				for field := range typ.Fields() {
+					g.use(field, by)
+				}
+			}
+			if g.opts.FieldWritesAreUses || unkeyed {
+				for _, elt := range node.Elts {
+					g.read(elt, by)
+				}
+			} else {
+				for _, elt := range node.Elts {
+					kv := elt.(*ast.KeyValueExpr)
+					g.write(kv.Key, by)
+					g.read(kv.Value, by)
+				}
+			}
+			if g.opts.FieldWritesAreUses && !unkeyed {
+				for _, elt := range node.Elts {
+					kv := elt.(*ast.KeyValueExpr)
+					fname := kv.Key.(*ast.Ident).Name
+					_, index, _ := types.LookupFieldOrMethod(typ, true, g.pkg, fname)
+
+					cur := typ
+					for _, step := range index[:len(index)-1] {
+						field := cur.Field(step)
+						g.use(field, by)
+						cur = typeutil.CoreType(field.Type()).(*types.Struct)
+					}
+				}
+			}
+		} else {
+			for _, elt := range node.Elts {
+				g.read(elt, by)
+			}
+		}
+
+	case *ast.KeyValueExpr:
+		g.read(node.Key, by)
+		g.read(node.Value, by)
+
+	case *ast.StarExpr:
+		g.read(node.X, by)
+
+	case *ast.MapType:
+		g.read(node.Key, by)
+		g.read(node.Value, by)
+
+	case *ast.FuncLit:
+		g.read(node.Type, by)
+
+		// See graph.decl's handling of ast.FuncDecl for why this bit of code is necessary.
+		fn := g.info.TypeOf(node).(*types.Signature)
+		for params, i := fn.Params(), 0; i < params.Len(); i++ {
+			g.see(params.At(i), by)
+			if params.At(i).Name() == "" {
+				g.use(params.At(i), by)
+			}
+		}
+
+		g.block(node.Body, by)
+
+	case *ast.FuncType:
+		m := map[*types.Var]struct{}{}
+		if !g.opts.ParametersAreUsed {
+			m = map[*types.Var]struct{}{}
+			// seeScope marks all local variables in the scope as used, but we don't want to unconditionally use
+			// parameters, as this is controlled by Options.ParametersAreUsed. Pass seeScope a list of variables it
+			// should skip.
+			for _, f := range node.Params.List {
+				for _, name := range f.Names {
+					m[g.info.ObjectOf(name).(*types.Var)] = struct{}{}
+				}
+			}
+		}
+		g.seeScope(node, by, m)
+
+		// (4.1) functions use all their arguments, return parameters and receivers
+		// (12.1) type parameters use their constraint type
+		g.read(node.TypeParams, by)
+		if g.opts.ParametersAreUsed {
+			g.read(node.Params, by)
+		}
+		g.read(node.Results, by)
+
+	case *ast.FieldList:
+		if node == nil {
+			return
+		}
+
+		// This branch is only hit for field lists enclosed by parentheses or square brackets, i.e. parameters. Fields
+		// (for structs) and method lists (for interfaces) are handled elsewhere.
+
+		for _, field := range node.List {
+			if len(field.Names) == 0 {
+				g.read(field.Type, by)
+			} else {
+				for _, name := range field.Names {
+					// OPT(dh): instead of by -> name -> type, we could just emit by -> type. We don't care about the
+					// (un)usedness of parameters of any kind.
+					obj := g.info.ObjectOf(name)
+					g.use(obj, by)
+					g.read(field.Type, obj)
+				}
+			}
+		}
+
+	case *ast.ChanType:
+		g.read(node.Value, by)
+
+	case *ast.StructType:
+		// This is only used for anonymous struct types, not named ones.
+
+		for _, field := range node.Fields.List {
+			if len(field.Names) == 0 {
+				// embedded field
+
+				f := g.embeddedField(field.Type, by)
+				g.use(f, by)
+			} else {
+				for _, name := range field.Names {
+					// (11.1) anonymous struct types use all their fields
+					// OPT(dh): instead of by -> name -> type, we could just emit by -> type. If the type is used, then the fields are used.
+					obj := g.info.ObjectOf(name)
+					g.see(obj, by)
+					g.use(obj, by)
+					g.read(field.Type, g.info.ObjectOf(name))
+				}
+			}
+		}
+
+	case *ast.TypeAssertExpr:
+		g.read(node.X, by)
+		g.read(node.Type, by)
+
+	case *ast.InterfaceType:
+		if len(node.Methods.List) != 0 {
+			g.interfaceTypes = append(g.interfaceTypes, g.info.TypeOf(node).(*types.Interface))
+		}
+		for _, meth := range node.Methods.List {
+			switch len(meth.Names) {
+			case 0:
+				// Embedded type or type union
+				// (8.4) all embedded interfaces are marked as used
+				// (this also covers type sets)
+
+				g.read(meth.Type, by)
+			case 1:
+				// Method
+				// (8.3) all interface methods are marked as used
+				obj := g.info.ObjectOf(meth.Names[0])
+				g.see(obj, by)
+				g.use(obj, by)
+				g.read(meth.Type, obj)
+			default:
+				panic(fmt.Sprintf("unexpected number of names: %d", len(meth.Names)))
+			}
+		}
+
+	case *ast.Ellipsis:
+		g.read(node.Elt, by)
+
+	case *ast.CallExpr:
+		g.read(node.Fun, by)
+		for _, arg := range node.Args {
+			g.read(arg, by)
+		}
+
+		// Handle conversions
+		conv := node
+		if len(conv.Args) != 1 || conv.Ellipsis.IsValid() {
+			return
+		}
+
+		dst := g.info.TypeOf(conv.Fun)
+		src := g.info.TypeOf(conv.Args[0])
+
+		// XXX use DereferenceR instead
+		// XXX guard against infinite recursion in DereferenceR
+		tSrc := typeutil.CoreType(typeutil.Dereference(src))
+		tDst := typeutil.CoreType(typeutil.Dereference(dst))
+		stSrc, okSrc := tSrc.(*types.Struct)
+		stDst, okDst := tDst.(*types.Struct)
+		if okDst && okSrc {
+			// Converting between two structs. The fields are
+			// relevant for the conversion, but only if the
+			// fields are also used outside of the conversion.
+			// Mark fields as used by each other.
+
+			assert(stDst.NumFields() == stSrc.NumFields())
+			for i := 0; i < stDst.NumFields(); i++ {
+				// (5.1) when converting between two equivalent structs, the fields in
+				// either struct use each other. the fields are relevant for the
+				// conversion, but only if the fields are also accessed outside the
+				// conversion.
+				g.use(stDst.Field(i), stSrc.Field(i))
+				g.use(stSrc.Field(i), stDst.Field(i))
+			}
+		} else if okSrc && tDst == types.Typ[types.UnsafePointer] {
+			// (5.2) when converting to or from unsafe.Pointer, mark all fields as used.
+			g.useAllFieldsRecursively(stSrc, by)
+		} else if okDst && tSrc == types.Typ[types.UnsafePointer] {
+			// (5.2) when converting to or from unsafe.Pointer, mark all fields as used.
+			g.useAllFieldsRecursively(stDst, by)
+		}
+
+	default:
+		lint.ExhaustiveTypeSwitch(node)
+	}
+}
+
+func (g *graph) useAllFieldsRecursively(typ types.Type, by types.Object) {
+	switch typ := typ.Underlying().(type) {
+	case *types.Struct:
+		for field := range typ.Fields() {
+			g.use(field, by)
+			g.useAllFieldsRecursively(field.Type(), by)
+		}
+	case *types.Array:
+		g.useAllFieldsRecursively(typ.Elem(), by)
+	default:
+		return
+	}
+}
+
+func (g *graph) write(node ast.Node, by types.Object) {
+	if node == nil {
+		return
+	}
+
+	switch node := node.(type) {
+	case *ast.Ident:
+		obj := g.info.ObjectOf(node)
+		if obj == nil {
+			// This can happen for `switch x := v.(type)`, where that x doesn't have an object
+			return
+		}
+
+		// (4.9) functions use package-level variables they assign to iff in tests (sinks for benchmarks)
+		// (9.7) variable _reads_ use variables, writes do not, except in tests
+		path := g.fset.File(obj.Pos()).Name()
+		if strings.HasSuffix(path, "_test.go") {
+			if isGlobal(obj) {
+				g.use(obj, by)
+			}
+		}
+
+	case *ast.IndexExpr:
+		g.read(node.X, by)
+		g.read(node.Index, by)
+
+	case *ast.SelectorExpr:
+		if g.opts.FieldWritesAreUses {
+			// Writing to a field constitutes a use. See https://staticcheck.dev/issues/288 for some discussion on that.
+			//
+			// This code can also get triggered by qualified package variables, in which case it doesn't matter what we do,
+			// because the object is in another package.
+			//
+			// FIXME(dh): ^ isn't true if we track usedness of exported identifiers
+			g.readSelectorExpr(node, by)
+		} else {
+			g.read(node.X, by)
+			g.write(node.Sel, by)
+		}
+
+	case *ast.StarExpr:
+		g.read(node.X, by)
+
+	case *ast.ParenExpr:
+		g.write(node.X, by)
+
+	default:
+		lint.ExhaustiveTypeSwitch(node)
+	}
+}
+
+// readSelectorExpr reads all elements of a selector expression, including implicit fields.
+func (g *graph) readSelectorExpr(sel *ast.SelectorExpr, by types.Object) {
+	// cover AST-based accesses
+	g.read(sel.X, by)
+	g.read(sel.Sel, by)
+
+	tsel, ok := g.info.Selections[sel]
+	if !ok {
+		return
+	}
+	g.readSelection(tsel, by)
+}
+
+func (g *graph) readSelection(sel *types.Selection, by types.Object) {
+	indices := sel.Index()
+	base := sel.Recv()
+	for _, idx := range indices[:len(indices)-1] {
+		// XXX do we need core types here?
+		field := typeutil.Dereference(base.Underlying()).Underlying().(*types.Struct).Field(idx)
+		g.use(field, by)
+		base = field.Type()
+	}
+
+	g.use(sel.Obj(), by)
+}
+
+func (g *graph) block(block *ast.BlockStmt, by types.Object) {
+	if block == nil {
+		return
+	}
+
+	g.seeScope(block, by, nil)
+	for _, stmt := range block.List {
+		g.stmt(stmt, by)
+	}
+}
+
+func isGlobal(obj types.Object) bool {
+	return obj.Parent() == obj.Pkg().Scope()
+}
+
+func (g *graph) decl(decl ast.Decl, by types.Object) {
+	switch decl := decl.(type) {
+	case *ast.GenDecl:
+		switch decl.Tok {
+		case token.IMPORT:
+			// Nothing to do
+
+		case token.CONST:
+			for _, spec := range decl.Specs {
+				vspec := spec.(*ast.ValueSpec)
+				assert(len(vspec.Values) == 0 || len(vspec.Values) == len(vspec.Names))
+				for i, name := range vspec.Names {
+					obj := g.info.ObjectOf(name)
+					g.see(obj, by)
+					g.read(vspec.Type, obj)
+
+					if len(vspec.Values) != 0 {
+						g.read(vspec.Values[i], obj)
+					}
+
+					if name.Name == "_" {
+						// (9.9) objects named the blank identifier are used
+						g.use(obj, by)
+					} else if token.IsExported(name.Name) && isGlobal(obj) && g.opts.ExportedIsUsed {
+						g.use(obj, nil)
+					}
+				}
+			}
+
+			groups := astutil.GroupSpecs(g.fset, decl.Specs)
+			for _, group := range groups {
+				// (10.1) if one constant out of a block of constants is used, mark all of them used
+				//
+				// We encode this as a ring. If we have a constant group 'const ( a; b; c )', then we'll produce the
+				// following graph: a -> b -> c -> a.
+
+				var first, prev, last types.Object
+				for _, spec := range group {
+					for _, name := range spec.(*ast.ValueSpec).Names {
+						if name.Name == "_" {
+							// Having a blank constant in a group doesn't mark the whole group as used
+							continue
+						}
+
+						obj := g.info.ObjectOf(name)
+						if first == nil {
+							first = obj
+						} else {
+							g.use(obj, prev)
+						}
+						prev = obj
+						last = obj
+					}
+				}
+				if first != nil && first != last {
+					g.use(first, last)
+				}
+			}
+
+		case token.TYPE:
+			for _, spec := range decl.Specs {
+				tspec := spec.(*ast.TypeSpec)
+				obj := g.info.ObjectOf(tspec.Name).(*types.TypeName)
+				g.see(obj, by)
+				g.seeScope(tspec, obj, nil)
+				if !tspec.Assign.IsValid() {
+					g.namedTypes = append(g.namedTypes, obj)
+				}
+				if token.IsExported(tspec.Name.Name) && isGlobal(obj) && g.opts.ExportedIsUsed {
+					// (1.1) packages use exported named types
+					g.use(g.info.ObjectOf(tspec.Name), nil)
+				}
+
+				// (2.5) named types use all their type parameters
+				g.read(tspec.TypeParams, obj)
+
+				g.namedType(obj, tspec.Type)
+
+				if tspec.Name.Name == "_" {
+					// (9.9) objects named the blank identifier are used
+					g.use(obj, by)
+				}
+			}
+
+		case token.VAR:
+			// We cannot rely on types.Initializer for package-level variables because
+			// - initializers are only tracked for variables that are actually initialized
+			// - we want to see the AST of the type, if specified, not just the rhs
+
+			for _, spec := range decl.Specs {
+				vspec := spec.(*ast.ValueSpec)
+				for i, name := range vspec.Names {
+					obj := g.info.ObjectOf(name)
+					g.see(obj, by)
+					// variables and constants use their types
+					g.read(vspec.Type, obj)
+
+					if len(vspec.Names) == len(vspec.Values) {
+						// One value per variable
+						g.read(vspec.Values[i], obj)
+					} else if len(vspec.Values) != 0 {
+						// Multiple variables initialized with a single rhs
+						// assert(len(vspec.Values) == 1)
+						if len(vspec.Values) != 1 {
+							panic(g.fset.PositionFor(vspec.Pos(), false))
+						}
+						g.read(vspec.Values[0], obj)
+					}
+
+					if token.IsExported(name.Name) && isGlobal(obj) && g.opts.ExportedIsUsed {
+						// (1.3) packages use exported variables
+						g.use(obj, nil)
+					}
+
+					if name.Name == "_" {
+						// (9.9) objects named the blank identifier are used
+						g.use(obj, by)
+					}
+				}
+			}
+
+		default:
+			panic(fmt.Sprintf("unexpected token %s", decl.Tok))
+		}
+
+	case *ast.FuncDecl:
+		obj := g.info.ObjectOf(decl.Name).(*types.Func).Origin()
+		g.see(obj, nil)
+
+		if token.IsExported(decl.Name.Name) && g.opts.ExportedIsUsed {
+			if decl.Recv == nil {
+				// (1.2) packages use exported functions
+				g.use(obj, nil)
+			}
+		} else if decl.Name.Name == "init" {
+			// (1.5) packages use init functions
+			g.use(obj, nil)
+		} else if decl.Name.Name == "main" && g.pkg.Name() == "main" {
+			// (1.7) packages use the main function iff in the main package
+			g.use(obj, nil)
+		} else if g.pkg.Path() == "runtime" && runtimeFuncs[decl.Name.Name] {
+			// (9.8) runtime functions that may be called from user code via the compiler
+			g.use(obj, nil)
+		} else if g.pkg.Path() == "runtime/coverage" && runtimeCoverageFuncs[decl.Name.Name] {
+			// (9.8) runtime functions that may be called from user code via the compiler
+			g.use(obj, nil)
+		}
+
+		// (4.1) functions use their receivers
+		g.read(decl.Recv, obj)
+		g.read(decl.Type, obj)
+		g.block(decl.Body, obj)
+
+		// g.read(decl.Type) will ultimately call g.seeScopes and see parameters that way. But because it relies
+		// entirely on the AST, it cannot resolve unnamed parameters to types.Object. For that reason we explicitly
+		// handle arguments here, as well as for FuncLits elsewhere.
+		//
+		// g.seeScopes can't get to the types.Signature for this function because there is no mapping from ast.FuncType to
+		// types.Signature, only from ast.Ident to types.Signature.
+		//
+		// This code is only really relevant when Options.ParametersAreUsed is false. Otherwise, all parameters are
+		// considered used, and if we never see a parameter then no harm done (we still see its type separately).
+		fn := g.info.TypeOf(decl.Name).(*types.Signature)
+		for params, i := fn.Params(), 0; i < params.Len(); i++ {
+			g.see(params.At(i), obj)
+			if params.At(i).Name() == "" {
+				g.use(params.At(i), obj)
+			}
+		}
+
+		if decl.Name.Name == "_" {
+			// (9.9) objects named the blank identifier are used
+			g.use(obj, nil)
+		}
+
+		if decl.Doc != nil {
+			for _, cmt := range decl.Doc.List {
+				if strings.HasPrefix(cmt.Text, "//go:cgo_export_") {
+					// (1.6) packages use functions exported to cgo
+					g.use(obj, nil)
+				}
+			}
+		}
+
+	default:
+		// We do not cover BadDecl, but we shouldn't ever see one of those
+		lint.ExhaustiveTypeSwitch(decl)
+	}
+}
+
+// seeScope sees all objects in node's scope. If Options.LocalVariablesAreUsed is true, all objects that aren't fields
+// are marked as used. Variables set in skipLvars will not be marked as used.
+func (g *graph) seeScope(node ast.Node, by types.Object, skipLvars map[*types.Var]struct{}) {
+	// A note on functions and scopes: for a function declaration, the body's BlockStmt can't be found in
+	// types.Info.Scopes. Instead, the FuncType can, and that scope will contain receivers, parameters, return
+	// parameters and immediate local variables.
+
+	scope := g.info.Scopes[node]
+	if scope == nil {
+		return
+	}
+	for _, name := range scope.Names() {
+		obj := scope.Lookup(name)
+		g.see(obj, by)
+
+		if g.opts.LocalVariablesAreUsed {
+			if obj, ok := obj.(*types.Var); ok && !obj.IsField() {
+				if _, ok := skipLvars[obj]; !ok {
+					g.use(obj, by)
+				}
+			}
+		}
+	}
+}
+
+func (g *graph) stmt(stmt ast.Stmt, by types.Object) {
+	if stmt == nil {
+		return
+	}
+
+	for {
+		// We don't care about labels, so unwrap LabeledStmts. Note that a label can itself be labeled.
+		if labeled, ok := stmt.(*ast.LabeledStmt); ok {
+			stmt = labeled.Stmt
+		} else {
+			break
+		}
+	}
+
+	switch stmt := stmt.(type) {
+	case *ast.AssignStmt:
+		for _, lhs := range stmt.Lhs {
+			g.write(lhs, by)
+		}
+		for _, rhs := range stmt.Rhs {
+			// Note: it would be more accurate to have the rhs used by the lhs, but it ultimately doesn't matter,
+			// because local variables always end up used, anyway.
+			//
+			// TODO(dh): we'll have to change that once we allow tracking the usedness of parameters
+			g.read(rhs, by)
+		}
+
+	case *ast.BlockStmt:
+		g.block(stmt, by)
+
+	case *ast.BranchStmt:
+		// Nothing to do
+
+	case *ast.DeclStmt:
+		g.decl(stmt.Decl, by)
+
+	case *ast.DeferStmt:
+		g.read(stmt.Call, by)
+
+	case *ast.ExprStmt:
+		g.read(stmt.X, by)
+
+	case *ast.ForStmt:
+		g.seeScope(stmt, by, nil)
+		g.stmt(stmt.Init, by)
+		g.read(stmt.Cond, by)
+		g.stmt(stmt.Post, by)
+		g.block(stmt.Body, by)
+
+	case *ast.GoStmt:
+		g.read(stmt.Call, by)
+
+	case *ast.IfStmt:
+		g.seeScope(stmt, by, nil)
+		g.stmt(stmt.Init, by)
+		g.read(stmt.Cond, by)
+		g.block(stmt.Body, by)
+		g.stmt(stmt.Else, by)
+
+	case *ast.IncDecStmt:
+		if g.opts.PostStatementsAreReads {
+			g.read(stmt.X, by)
+			g.write(stmt.X, by)
+		} else {
+			// We treat post-increment as a write only. This ends up using fields, and sinks in tests, but not other
+			// variables.
+			g.write(stmt.X, by)
+		}
+
+	case *ast.RangeStmt:
+		g.seeScope(stmt, by, nil)
+
+		g.write(stmt.Key, by)
+		g.write(stmt.Value, by)
+		g.read(stmt.X, by)
+		g.block(stmt.Body, by)
+
+	case *ast.ReturnStmt:
+		for _, ret := range stmt.Results {
+			g.read(ret, by)
+		}
+
+	case *ast.SelectStmt:
+		for _, clause_ := range stmt.Body.List {
+			clause := clause_.(*ast.CommClause)
+			g.seeScope(clause, by, nil)
+			switch comm := clause.Comm.(type) {
+			case *ast.SendStmt:
+				g.read(comm.Chan, by)
+				g.read(comm.Value, by)
+			case *ast.ExprStmt:
+				g.read(ast.Unparen(comm.X).(*ast.UnaryExpr).X, by)
+			case *ast.AssignStmt:
+				for _, lhs := range comm.Lhs {
+					g.write(lhs, by)
+				}
+				for _, rhs := range comm.Rhs {
+					g.read(rhs, by)
+				}
+			case nil:
+			default:
+				lint.ExhaustiveTypeSwitch(comm)
+			}
+			for _, body := range clause.Body {
+				g.stmt(body, by)
+			}
+		}
+
+	case *ast.SendStmt:
+		g.read(stmt.Chan, by)
+		g.read(stmt.Value, by)
+
+	case *ast.SwitchStmt:
+		g.seeScope(stmt, by, nil)
+		g.stmt(stmt.Init, by)
+		g.read(stmt.Tag, by)
+		for _, clause_ := range stmt.Body.List {
+			clause := clause_.(*ast.CaseClause)
+			g.seeScope(clause, by, nil)
+			for _, expr := range clause.List {
+				g.read(expr, by)
+			}
+			for _, body := range clause.Body {
+				g.stmt(body, by)
+			}
+		}
+
+	case *ast.TypeSwitchStmt:
+		g.seeScope(stmt, by, nil)
+		g.stmt(stmt.Init, by)
+		g.stmt(stmt.Assign, by)
+		for _, clause_ := range stmt.Body.List {
+			clause := clause_.(*ast.CaseClause)
+			g.seeScope(clause, by, nil)
+			for _, expr := range clause.List {
+				g.read(expr, by)
+			}
+			for _, body := range clause.Body {
+				g.stmt(body, by)
+			}
+		}
+
+	case *ast.EmptyStmt:
+		// Nothing to do
+
+	default:
+		lint.ExhaustiveTypeSwitch(stmt)
+	}
+}
+
+// embeddedField sees the field declared by the embedded field node, and marks the type as used by the field.
+//
+// Embedded fields are special in two ways: they don't have names, so we don't have immediate access to an ast.Ident to
+// resolve to the field's types.Var and need to instead walk the AST, and we cannot use g.read on the type because
+// eventually we do get to an ast.Ident, and ObjectOf resolves embedded fields to the field they declare, not the type.
+// That's why we have code specially for handling embedded fields.
+func (g *graph) embeddedField(node ast.Node, by types.Object) *types.Var {
+	// We need to traverse the tree to find the ast.Ident, but all the nodes we traverse should be used by the object we
+	// get once we resolve the ident. Collect the nodes and process them once we've found the ident.
+	nodes := make([]ast.Node, 0, 4)
+	for {
+		switch node_ := node.(type) {
+		case *ast.Ident:
+			// obj is the field
+			obj := g.info.ObjectOf(node_).(*types.Var)
+			// the field is declared by the enclosing type
+			g.see(obj, by)
+			for _, n := range nodes {
+				g.read(n, obj)
+			}
+
+			if tname, ok := g.info.Uses[node_].(*types.TypeName); ok && tname.IsAlias() {
+				// When embedding an alias we want to use the alias, not what the alias points to.
+				g.use(tname, obj)
+			} else {
+				switch typ := typeutil.Dereference(g.info.TypeOf(node_)).(type) {
+				case *types.Named:
+					// (7.2) fields use their types
+					g.use(typ.Obj(), obj)
+				case *types.Basic:
+					// Nothing to do
+				default:
+					// Other types are only possible for aliases, which we've already handled
+					lint.ExhaustiveTypeSwitch(typ)
+				}
+			}
+			return obj
+		case *ast.StarExpr:
+			node = node_.X
+		case *ast.SelectorExpr:
+			node = node_.Sel
+			nodes = append(nodes, node_.X)
+		case *ast.IndexExpr:
+			node = node_.X
+			nodes = append(nodes, node_.Index)
+		case *ast.IndexListExpr:
+			node = node_.X
+		default:
+			lint.ExhaustiveTypeSwitch(node_)
+		}
+	}
+}
+
+// isNoCopyType reports whether a type represents the NoCopy sentinel
+// type. The NoCopy type is a named struct with no fields and exactly
+// one method `func Lock()` that is empty.
+//
+// FIXME(dh): currently we're not checking that the function body is
+// empty.
+func isNoCopyType(typ types.Type) bool {
+	st, ok := typ.Underlying().(*types.Struct)
+	if !ok {
+		return false
+	}
+	if st.NumFields() != 0 {
+		return false
+	}
+
+	named, ok := types.Unalias(typ).(*types.Named)
+	if !ok {
+		return false
+	}
+	switch num := named.NumMethods(); num {
+	case 1, 2:
+		for i := range num {
+			meth := named.Method(i)
+			if meth.Name() != "Lock" && meth.Name() != "Unlock" {
+				return false
+			}
+			sig := meth.Type().(*types.Signature)
+			if sig.Params().Len() != 0 || sig.Results().Len() != 0 {
+				return false
+			}
+		}
+	default:
+		return false
+	}
+	return true
+}
+
+func (g *graph) namedType(typ *types.TypeName, spec ast.Expr) {
+	// (2.2) named types use the type they're based on
+
+	if st, ok := spec.(*ast.StructType); ok {
+		var hasHostLayout bool
+
+		// Named structs are special in that their unexported fields are only
+		// used if they're being written to. That is, the fields are not used by
+		// the named type itself, nor are the types of the fields.
+		for _, field := range st.Fields.List {
+			seen := map[*types.Struct]struct{}{}
+			// For `type x struct { *x; F int }`, don't visit the embedded x
+			seen[g.info.TypeOf(st).(*types.Struct)] = struct{}{}
+			var hasExportedField func(t types.Type) bool
+			hasExportedField = func(T types.Type) bool {
+				t, ok := typeutil.Dereference(T).Underlying().(*types.Struct)
+				if !ok {
+					return false
+				}
+				if _, ok := seen[t]; ok {
+					return false
+				}
+				seen[t] = struct{}{}
+				for field := range t.Fields() {
+					if field.Exported() {
+						return true
+					}
+					if field.Embedded() && hasExportedField(field.Type()) {
+						return true
+					}
+				}
+				return false
+			}
+
+			if len(field.Names) == 0 {
+				fieldVar := g.embeddedField(field.Type, typ)
+				if token.IsExported(fieldVar.Name()) && g.opts.ExportedIsUsed {
+					// (6.2) structs use exported fields
+					g.use(fieldVar, typ)
+				}
+				if g.opts.ExportedIsUsed && g.opts.ExportedFieldsAreUsed && hasExportedField(fieldVar.Type()) {
+					// (6.5) structs use embedded structs that have exported fields (recursively)
+					g.use(fieldVar, typ)
+				}
+			} else {
+				for _, name := range field.Names {
+					obj := g.info.ObjectOf(name)
+					g.see(obj, typ)
+					// (7.2) fields use their types
+					//
+					// This handles aliases correctly because ObjectOf(alias) returns the TypeName of the alias, not
+					// what the alias points to.
+					g.read(field.Type, obj)
+					if name.Name == "_" {
+						// (9.9) objects named the blank identifier are used
+						g.use(obj, typ)
+					} else if token.IsExported(name.Name) && g.opts.ExportedIsUsed {
+						// (6.2) structs use exported fields
+						g.use(obj, typ)
+					}
+
+					if isNoCopyType(obj.Type()) {
+						// (6.1) structs use fields of type NoCopy sentinel
+						g.use(obj, typ)
+					}
+				}
+			}
+
+			// (6.6) if the struct has a field of type structs.HostLayout, then
+			// this signals that all fields are relevant to match some
+			// externally specified memory layout.
+			//
+			// This augments the 5.2 heuristic of using all fields when
+			// converting via unsafe.Pointer. For example, 5.2 doesn't currently
+			// handle conversions involving more than one level of pointer
+			// indirection (although it probably should). Another example that
+			// doesn't involve the use of unsafe at all is exporting symbols for
+			// use by C libraries.
+			//
+			// The actual requirements for the use of structs.HostLayout fields
+			// haven't been determined yet. It's an open question whether named
+			// types of underlying type structs.HostLayout, aliases of it,
+			// generic instantiations, or embedding structs that themselves
+			// contain a HostLayout field count as valid uses of the marker (see
+			// https://golang.org/issues/66408#issuecomment-2120644459)
+			//
+			// For now, we require a struct to have a field of type
+			// structs.HostLayout or an alias of it, where the field itself may
+			// be embedded. We don't handle fields whose types are type
+			// parameters.
+			fieldType := types.Unalias(g.info.TypeOf(field.Type))
+			if fieldType, ok := fieldType.(*types.Named); ok {
+				obj := fieldType.Obj()
+				if obj.Name() == "HostLayout" && obj.Pkg().Path() == "structs" {
+					hasHostLayout = true
+				}
+			}
+		}
+
+		// For 6.6.
+		if hasHostLayout {
+			g.useAllFieldsRecursively(typ.Type(), typ)
+		}
+	} else {
+		g.read(spec, typ)
+	}
+}
+
+func (g *SerializedGraph) color(rootID NodeID, states []nodeState) {
+	root := g.nodes[rootID]
+	if states[rootID].seen() {
+		return
+	}
+	states[rootID] |= nodeStateSeen
+	for _, n := range root.uses {
+		g.color(n, states)
+	}
+}
+
+type Object struct {
+	Name      string
+	ShortName string
+	// OPT(dh): use an enum for the kind
+	Kind            string
+	Path            ObjectPath
+	Position        token.Position
+	DisplayPosition token.Position
+}
+
+func (g *SerializedGraph) Results() Result {
+	// XXX objectpath does not return paths for unexported objects, which means that if we analyze the same code twice
+	// (e.g. normal and test variant), then some objects will appear multiple times, but may not be used identically. we
+	// have to deduplicate based on the token.Position. Actually we have to do that, anyway, because we may flag types
+	// local to functions. Those are probably always both used or both unused, but we don't want to flag them twice,
+	// either.
+	//
+	// Note, however, that we still need objectpaths to deduplicate exported identifiers when analyzing independent
+	// packages in whole-program mode, because if package A uses an object from package B, B will have been imported
+	// from export data, and we will not have column information.
+	//
+	// XXX ^ document that design requirement.
+
+	states := g.colorAndQuieten()
+
+	var res Result
+	// OPT(dh): can we find meaningful initial capacities for the used and unused slices?
+	for _, n := range g.nodes[1:] {
+		state := states[n.id]
+		if state.seen() {
+			res.Used = append(res.Used, n.obj)
+		} else if state.quiet() {
+			res.Quiet = append(res.Quiet, n.obj)
+		} else {
+			res.Unused = append(res.Unused, n.obj)
+		}
+	}
+
+	return res
+}
+
+func (g *SerializedGraph) colorAndQuieten() []nodeState {
+	states := make([]nodeState, len(g.nodes)+1)
+	g.color(0, states)
+
+	var quieten func(id NodeID)
+	quieten = func(id NodeID) {
+		states[id] |= nodeStateQuiet
+		for _, owned := range g.nodes[id].owns {
+			quieten(owned)
+		}
+	}
+
+	for _, n := range g.nodes {
+		if states[n.id].seen() {
+			continue
+		}
+		for _, owned := range n.owns {
+			quieten(owned)
+		}
+	}
+
+	return states
+}
+
+// Dot formats a graph in Graphviz dot format.
+func (g *SerializedGraph) Dot() string {
+	b := &strings.Builder{}
+	states := g.colorAndQuieten()
+	// Note: We use addresses in our node names. This only works as long as Go's garbage collector doesn't move
+	// memory around in the middle of our debug printing.
+	debugNode := func(n Node) {
+		if n.id == 0 {
+			fmt.Fprintf(b, "n%d [label=\"Root\"];\n", n.id)
+		} else {
+			color := "red"
+			if states[n.id].seen() {
+				color = "green"
+			} else if states[n.id].quiet() {
+				color = "grey"
+			}
+			label := fmt.Sprintf("%s %s\n%s", n.obj.Kind, n.obj.Name, n.obj.Position)
+			fmt.Fprintf(b, "n%d [label=%q, color=%q];\n", n.id, label, color)
+		}
+		for _, e := range n.uses {
+			fmt.Fprintf(b, "n%d -> n%d;\n", n.id, e)
+		}
+
+		for _, owned := range n.owns {
+			fmt.Fprintf(b, "n%d -> n%d [style=dashed];\n", n.id, owned)
+		}
+	}
+
+	fmt.Fprintf(b, "digraph{\n")
+	for _, v := range g.nodes {
+		debugNode(v)
+	}
+
+	fmt.Fprintf(b, "}\n")
+
+	return b.String()
+}
+
+func Graph(fset *token.FileSet,
+	files []*ast.File,
+	pkg *types.Package,
+	info *types.Info,
+	directives []lint.Directive,
+	generated map[string]generated.Generator,
+	opts Options,
+) []Node {
+	g := newGraph(fset, files, pkg, info, directives, generated, opts)
+	g.entry()
+	return g.nodes
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
new file mode 100644
index 0000000..b9f7d4e
--- /dev/null
+++ b/vendor/modules.txt
@@ -0,0 +1,308 @@
+# github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c
+## explicit; go 1.18
+github.com/BurntSushi/toml
+github.com/BurntSushi/toml/internal
+# github.com/nathan-osman/go-sunrise v1.1.0
+## explicit; go 1.13
+github.com/nathan-osman/go-sunrise
+# golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678
+## explicit; go 1.18
+golang.org/x/exp/typeparams
+# golang.org/x/mod v0.42.0
+## explicit; go 1.26.0
+golang.org/x/mod/internal/lazyregexp
+golang.org/x/mod/module
+golang.org/x/mod/semver
+# golang.org/x/sync v0.24.0
+## explicit; go 1.26.0
+golang.org/x/sync/errgroup
+# golang.org/x/sys v0.49.0
+## explicit; go 1.26.0
+golang.org/x/sys/windows
+# golang.org/x/telemetry v0.0.0-20261010193011-f71dc92da45e
+## explicit; go 1.26.0
+golang.org/x/telemetry
+golang.org/x/telemetry/counter
+golang.org/x/telemetry/internal/config
+golang.org/x/telemetry/internal/configstore
+golang.org/x/telemetry/internal/counter
+golang.org/x/telemetry/internal/crashmonitor
+golang.org/x/telemetry/internal/mmap
+golang.org/x/telemetry/internal/telemetry
+golang.org/x/telemetry/internal/upload
+# golang.org/x/tools v0.52.0
+## explicit; go 1.26.0
+golang.org/x/tools/cmd/deadcode
+golang.org/x/tools/cmd/goimports
+golang.org/x/tools/go/analysis
+golang.org/x/tools/go/analysis/passes/ctrlflow
+golang.org/x/tools/go/analysis/passes/inspect
+golang.org/x/tools/go/ast/astutil
+golang.org/x/tools/go/ast/edge
+golang.org/x/tools/go/ast/inspector
+golang.org/x/tools/go/buildutil
+golang.org/x/tools/go/callgraph
+golang.org/x/tools/go/callgraph/cha
+golang.org/x/tools/go/callgraph/internal/chautil
+golang.org/x/tools/go/callgraph/rta
+golang.org/x/tools/go/callgraph/vta
+golang.org/x/tools/go/callgraph/vta/internal/trie
+golang.org/x/tools/go/cfg
+golang.org/x/tools/go/gcexportdata
+golang.org/x/tools/go/internal/cgo
+golang.org/x/tools/go/loader
+golang.org/x/tools/go/packages
+golang.org/x/tools/go/ssa
+golang.org/x/tools/go/ssa/ssautil
+golang.org/x/tools/go/types/objectpath
+golang.org/x/tools/go/types/typeutil
+golang.org/x/tools/internal/event
+golang.org/x/tools/internal/event/core
+golang.org/x/tools/internal/event/keys
+golang.org/x/tools/internal/event/label
+golang.org/x/tools/internal/gcimporter
+golang.org/x/tools/internal/gocommand
+golang.org/x/tools/internal/gopathwalk
+golang.org/x/tools/internal/imports
+golang.org/x/tools/internal/modindex
+golang.org/x/tools/internal/moremaps
+golang.org/x/tools/internal/packagesinternal
+golang.org/x/tools/internal/pkgbits
+golang.org/x/tools/internal/stdlib
+golang.org/x/tools/internal/typeparams
+golang.org/x/tools/internal/typesinternal
+golang.org/x/tools/internal/versions
+# golang.org/x/vuln v1.9.0
+## explicit; go 1.26.0
+golang.org/x/vuln/cmd/govulncheck
+golang.org/x/vuln/internal
+golang.org/x/vuln/internal/buildinfo
+golang.org/x/vuln/internal/client
+golang.org/x/vuln/internal/derrors
+golang.org/x/vuln/internal/gosym
+golang.org/x/vuln/internal/goversion
+golang.org/x/vuln/internal/govulncheck
+golang.org/x/vuln/internal/openvex
+golang.org/x/vuln/internal/osv
+golang.org/x/vuln/internal/sarif
+golang.org/x/vuln/internal/scan
+golang.org/x/vuln/internal/semver
+golang.org/x/vuln/internal/traces
+golang.org/x/vuln/internal/vulncheck
+golang.org/x/vuln/internal/web
+golang.org/x/vuln/scan
+# honnef.co/go/tools v0.8.2
+## explicit; go 1.26.0
+honnef.co/go/tools/analysis/callcheck
+honnef.co/go/tools/analysis/code
+honnef.co/go/tools/analysis/dfa
+honnef.co/go/tools/analysis/dfa/dense
+honnef.co/go/tools/analysis/edit
+honnef.co/go/tools/analysis/facts/deprecated
+honnef.co/go/tools/analysis/facts/directives
+honnef.co/go/tools/analysis/facts/generated
+honnef.co/go/tools/analysis/facts/nilness
+honnef.co/go/tools/analysis/facts/purity
+honnef.co/go/tools/analysis/facts/tokenfile
+honnef.co/go/tools/analysis/lint
+honnef.co/go/tools/analysis/report
+honnef.co/go/tools/cmd/staticcheck
+honnef.co/go/tools/config
+honnef.co/go/tools/go/ast/astutil
+honnef.co/go/tools/go/buildid
+honnef.co/go/tools/go/ir
+honnef.co/go/tools/go/ir/irutil
+honnef.co/go/tools/go/loader
+honnef.co/go/tools/go/types/typeutil
+honnef.co/go/tools/internal/iterutil
+honnef.co/go/tools/internal/passes/buildir
+honnef.co/go/tools/internal/renameio
+honnef.co/go/tools/internal/robustio
+honnef.co/go/tools/internal/sharedcheck
+honnef.co/go/tools/internal/sync
+honnef.co/go/tools/internal/xtools-internal/aliases
+honnef.co/go/tools/internal/xtools-internal/analysis/typeindex
+honnef.co/go/tools/internal/xtools-internal/astutil
+honnef.co/go/tools/internal/xtools-internal/graph
+honnef.co/go/tools/internal/xtools-internal/moreiters
+honnef.co/go/tools/internal/xtools-internal/typeparams
+honnef.co/go/tools/internal/xtools-internal/typesinternal
+honnef.co/go/tools/internal/xtools-internal/typesinternal/typeindex
+honnef.co/go/tools/internal/xtools-internal/versions
+honnef.co/go/tools/knowledge
+honnef.co/go/tools/lintcmd
+honnef.co/go/tools/lintcmd/cache
+honnef.co/go/tools/lintcmd/cache/cacheprog
+honnef.co/go/tools/lintcmd/runner
+honnef.co/go/tools/lintcmd/version
+honnef.co/go/tools/pattern
+honnef.co/go/tools/printf
+honnef.co/go/tools/quickfix
+honnef.co/go/tools/quickfix/qf1001
+honnef.co/go/tools/quickfix/qf1002
+honnef.co/go/tools/quickfix/qf1003
+honnef.co/go/tools/quickfix/qf1004
+honnef.co/go/tools/quickfix/qf1005
+honnef.co/go/tools/quickfix/qf1006
+honnef.co/go/tools/quickfix/qf1007
+honnef.co/go/tools/quickfix/qf1008
+honnef.co/go/tools/quickfix/qf1009
+honnef.co/go/tools/quickfix/qf1010
+honnef.co/go/tools/quickfix/qf1011
+honnef.co/go/tools/quickfix/qf1012
+honnef.co/go/tools/sarif
+honnef.co/go/tools/simple
+honnef.co/go/tools/simple/s1000
+honnef.co/go/tools/simple/s1001
+honnef.co/go/tools/simple/s1002
+honnef.co/go/tools/simple/s1003
+honnef.co/go/tools/simple/s1004
+honnef.co/go/tools/simple/s1005
+honnef.co/go/tools/simple/s1006
+honnef.co/go/tools/simple/s1007
+honnef.co/go/tools/simple/s1008
+honnef.co/go/tools/simple/s1009
+honnef.co/go/tools/simple/s1010
+honnef.co/go/tools/simple/s1011
+honnef.co/go/tools/simple/s1012
+honnef.co/go/tools/simple/s1016
+honnef.co/go/tools/simple/s1017
+honnef.co/go/tools/simple/s1018
+honnef.co/go/tools/simple/s1019
+honnef.co/go/tools/simple/s1020
+honnef.co/go/tools/simple/s1021
+honnef.co/go/tools/simple/s1023
+honnef.co/go/tools/simple/s1024
+honnef.co/go/tools/simple/s1025
+honnef.co/go/tools/simple/s1028
+honnef.co/go/tools/simple/s1029
+honnef.co/go/tools/simple/s1030
+honnef.co/go/tools/simple/s1031
+honnef.co/go/tools/simple/s1032
+honnef.co/go/tools/simple/s1033
+honnef.co/go/tools/simple/s1034
+honnef.co/go/tools/simple/s1035
+honnef.co/go/tools/simple/s1036
+honnef.co/go/tools/simple/s1037
+honnef.co/go/tools/simple/s1038
+honnef.co/go/tools/simple/s1039
+honnef.co/go/tools/simple/s1040
+honnef.co/go/tools/staticcheck
+honnef.co/go/tools/staticcheck/fakejson
+honnef.co/go/tools/staticcheck/fakereflect
+honnef.co/go/tools/staticcheck/fakexml
+honnef.co/go/tools/staticcheck/sa1000
+honnef.co/go/tools/staticcheck/sa1001
+honnef.co/go/tools/staticcheck/sa1002
+honnef.co/go/tools/staticcheck/sa1003
+honnef.co/go/tools/staticcheck/sa1004
+honnef.co/go/tools/staticcheck/sa1005
+honnef.co/go/tools/staticcheck/sa1006
+honnef.co/go/tools/staticcheck/sa1007
+honnef.co/go/tools/staticcheck/sa1008
+honnef.co/go/tools/staticcheck/sa1010
+honnef.co/go/tools/staticcheck/sa1011
+honnef.co/go/tools/staticcheck/sa1012
+honnef.co/go/tools/staticcheck/sa1013
+honnef.co/go/tools/staticcheck/sa1014
+honnef.co/go/tools/staticcheck/sa1015
+honnef.co/go/tools/staticcheck/sa1016
+honnef.co/go/tools/staticcheck/sa1017
+honnef.co/go/tools/staticcheck/sa1018
+honnef.co/go/tools/staticcheck/sa1019
+honnef.co/go/tools/staticcheck/sa1020
+honnef.co/go/tools/staticcheck/sa1021
+honnef.co/go/tools/staticcheck/sa1023
+honnef.co/go/tools/staticcheck/sa1024
+honnef.co/go/tools/staticcheck/sa1025
+honnef.co/go/tools/staticcheck/sa1026
+honnef.co/go/tools/staticcheck/sa1027
+honnef.co/go/tools/staticcheck/sa1028
+honnef.co/go/tools/staticcheck/sa1029
+honnef.co/go/tools/staticcheck/sa1030
+honnef.co/go/tools/staticcheck/sa1031
+honnef.co/go/tools/staticcheck/sa1032
+honnef.co/go/tools/staticcheck/sa2000
+honnef.co/go/tools/staticcheck/sa2001
+honnef.co/go/tools/staticcheck/sa2002
+honnef.co/go/tools/staticcheck/sa2003
+honnef.co/go/tools/staticcheck/sa3000
+honnef.co/go/tools/staticcheck/sa3001
+honnef.co/go/tools/staticcheck/sa4000
+honnef.co/go/tools/staticcheck/sa4001
+honnef.co/go/tools/staticcheck/sa4003
+honnef.co/go/tools/staticcheck/sa4004
+honnef.co/go/tools/staticcheck/sa4005
+honnef.co/go/tools/staticcheck/sa4006
+honnef.co/go/tools/staticcheck/sa4008
+honnef.co/go/tools/staticcheck/sa4009
+honnef.co/go/tools/staticcheck/sa4010
+honnef.co/go/tools/staticcheck/sa4011
+honnef.co/go/tools/staticcheck/sa4012
+honnef.co/go/tools/staticcheck/sa4013
+honnef.co/go/tools/staticcheck/sa4014
+honnef.co/go/tools/staticcheck/sa4015
+honnef.co/go/tools/staticcheck/sa4016
+honnef.co/go/tools/staticcheck/sa4017
+honnef.co/go/tools/staticcheck/sa4018
+honnef.co/go/tools/staticcheck/sa4019
+honnef.co/go/tools/staticcheck/sa4020
+honnef.co/go/tools/staticcheck/sa4021
+honnef.co/go/tools/staticcheck/sa4022
+honnef.co/go/tools/staticcheck/sa4023
+honnef.co/go/tools/staticcheck/sa4024
+honnef.co/go/tools/staticcheck/sa4025
+honnef.co/go/tools/staticcheck/sa4026
+honnef.co/go/tools/staticcheck/sa4027
+honnef.co/go/tools/staticcheck/sa4028
+honnef.co/go/tools/staticcheck/sa4029
+honnef.co/go/tools/staticcheck/sa4030
+honnef.co/go/tools/staticcheck/sa4031
+honnef.co/go/tools/staticcheck/sa4032
+honnef.co/go/tools/staticcheck/sa5000
+honnef.co/go/tools/staticcheck/sa5001
+honnef.co/go/tools/staticcheck/sa5002
+honnef.co/go/tools/staticcheck/sa5003
+honnef.co/go/tools/staticcheck/sa5004
+honnef.co/go/tools/staticcheck/sa5005
+honnef.co/go/tools/staticcheck/sa5007
+honnef.co/go/tools/staticcheck/sa5008
+honnef.co/go/tools/staticcheck/sa5009
+honnef.co/go/tools/staticcheck/sa5010
+honnef.co/go/tools/staticcheck/sa5012
+honnef.co/go/tools/staticcheck/sa6000
+honnef.co/go/tools/staticcheck/sa6001
+honnef.co/go/tools/staticcheck/sa6002
+honnef.co/go/tools/staticcheck/sa6003
+honnef.co/go/tools/staticcheck/sa6005
+honnef.co/go/tools/staticcheck/sa6006
+honnef.co/go/tools/staticcheck/sa9001
+honnef.co/go/tools/staticcheck/sa9002
+honnef.co/go/tools/staticcheck/sa9003
+honnef.co/go/tools/staticcheck/sa9004
+honnef.co/go/tools/staticcheck/sa9005
+honnef.co/go/tools/staticcheck/sa9006
+honnef.co/go/tools/staticcheck/sa9007
+honnef.co/go/tools/staticcheck/sa9008
+honnef.co/go/tools/staticcheck/sa9009
+honnef.co/go/tools/staticcheck/sa9010
+honnef.co/go/tools/stylecheck
+honnef.co/go/tools/stylecheck/st1000
+honnef.co/go/tools/stylecheck/st1001
+honnef.co/go/tools/stylecheck/st1003
+honnef.co/go/tools/stylecheck/st1005
+honnef.co/go/tools/stylecheck/st1006
+honnef.co/go/tools/stylecheck/st1008
+honnef.co/go/tools/stylecheck/st1011
+honnef.co/go/tools/stylecheck/st1012
+honnef.co/go/tools/stylecheck/st1013
+honnef.co/go/tools/stylecheck/st1015
+honnef.co/go/tools/stylecheck/st1016
+honnef.co/go/tools/stylecheck/st1017
+honnef.co/go/tools/stylecheck/st1018
+honnef.co/go/tools/stylecheck/st1019
+honnef.co/go/tools/stylecheck/st1020
+honnef.co/go/tools/stylecheck/st1021
+honnef.co/go/tools/stylecheck/st1022
+honnef.co/go/tools/stylecheck/st1023
+honnef.co/go/tools/unused