summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/tools/internal/modindex/symbols.go
diff options
context:
space:
mode:
authorLibravatar dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>2025-01-14 13:11:20 +0000
committerLibravatar GitHub <noreply@github.com>2025-01-14 13:11:20 +0000
commitb95498b8c206295b55767fa2d4855bee16233734 (patch)
treef8b95d8b5bdbcc062915ae4b59c7a6488fe9da90 /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)
downloadgotosocial-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.go189
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
+}