diff options
author | 2025-01-14 13:11:20 +0000 | |
---|---|---|
committer | 2025-01-14 13:11:20 +0000 | |
commit | b95498b8c206295b55767fa2d4855bee16233734 (patch) | |
tree | f8b95d8b5bdbcc062915ae4b59c7a6488fe9da90 /vendor/golang.org/x/tools/internal/modindex/symbols.go | |
parent | [chore]: Bump github.com/gin-contrib/gzip from 1.0.1 to 1.1.0 (#3639) (diff) | |
download | gotosocial-b95498b8c206295b55767fa2d4855bee16233734.tar.xz |
[chore]: Bump mvdan.cc/xurls/v2 from 2.5.0 to 2.6.0 (#3643)
Bumps [mvdan.cc/xurls/v2](https://github.com/mvdan/xurls) from 2.5.0 to 2.6.0.
- [Release notes](https://github.com/mvdan/xurls/releases)
- [Commits](https://github.com/mvdan/xurls/compare/v2.5.0...v2.6.0)
---
updated-dependencies:
- dependency-name: mvdan.cc/xurls/v2
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Diffstat (limited to 'vendor/golang.org/x/tools/internal/modindex/symbols.go')
-rw-r--r-- | vendor/golang.org/x/tools/internal/modindex/symbols.go | 189 |
1 files changed, 189 insertions, 0 deletions
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 000000000..2e285ed99 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/modindex/symbols.go @@ -0,0 +1,189 @@ +// 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" + "os" + "path/filepath" + "slices" + "strings" + + "golang.org/x/sync/errgroup" +) + +// The name of a symbol contains information about the symbol: +// <name> T for types +// <name> C for consts +// <name> V for vars +// and for funcs: <name> F <num of return values> (<arg-name> <arg-type>)* +// any spaces in <arg-type> are replaced by $s so that the fields +// of the name are space separated +type symbol struct { + pkg string // name of the symbols's package + name string // declared name + kind string // T, C, V, or F + sig string // signature information, for F +} + +// find the symbols for the best directories +func getSymbols(cd Abspath, dirs map[string][]*directory) { + var g errgroup.Group + g.SetLimit(-1) // maybe throttle this some day + for _, vv := range dirs { + // throttling some day? + d := vv[0] + g.Go(func() error { + thedir := filepath.Join(string(cd), string(d.path)) + mode := parser.SkipObjectResolution + + fi, err := os.ReadDir(thedir) + if err != nil { + return nil // log this someday? + } + for _, fx := range fi { + if !strings.HasSuffix(fx.Name(), ".go") || strings.HasSuffix(fx.Name(), "_test.go") { + continue + } + fname := filepath.Join(thedir, fx.Name()) + tr, err := parser.ParseFile(token.NewFileSet(), fname, nil, mode) + if err != nil { + continue // ignore errors, someday log them? + } + d.syms = append(d.syms, getFileExports(tr)...) + } + return nil + }) + } + g.Wait() +} + +func getFileExports(f *ast.File) []symbol { + pkg := f.Name.Name + if pkg == "main" { + 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" + 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 explict 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 not ignore such pathologies + 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: + switch decl.Tok { + case token.CONST, token.VAR: + tp := "V" + if decl.Tok == token.CONST { + tp = "C" + } + 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: + for _, sp := range decl.Specs { + if s := newsym(pkg, sp.(*ast.TypeSpec).Name.Name, "T", ""); 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 +} + +// 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 { + var nx string + if s.pkg == pkg { + 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) + } else { + continue // PJW: do we want to keep track of these? + } + } + return pkg, names +} |