.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.1.1 / go / loader / hash.go
1 package loader
2
3 import (
4         "fmt"
5         "runtime"
6         "sort"
7         "strings"
8
9         "honnef.co/go/tools/internal/cache"
10 )
11
12 // computeHash computes a package's hash. The hash is based on all Go
13 // files that make up the package, as well as the hashes of imported
14 // packages.
15 func computeHash(pkg *PackageSpec) (cache.ActionID, error) {
16         key := cache.NewHash("package " + pkg.PkgPath)
17         fmt.Fprintf(key, "goos %s goarch %s\n", runtime.GOOS, runtime.GOARCH)
18         fmt.Fprintf(key, "import %q\n", pkg.PkgPath)
19
20         // Compute the hashes of all files making up the package. As an
21         // optimization, we use the build ID that Go already computed for
22         // us, because it is virtually identical to hashed all
23         // CompiledGoFiles.
24         success := false
25         if pkg.ExportFile != "" {
26                 id, err := getBuildid(pkg.ExportFile)
27                 if err == nil {
28                         if idx := strings.IndexRune(id, '/'); idx > -1 {
29                                 fmt.Fprintf(key, "files %s\n", id[:idx])
30                                 success = true
31                         }
32                 }
33         }
34         if !success {
35                 for _, f := range pkg.CompiledGoFiles {
36                         h, err := cache.FileHash(f)
37                         if err != nil {
38                                 return cache.ActionID{}, err
39                         }
40                         fmt.Fprintf(key, "file %s %x\n", f, h)
41                 }
42         }
43
44         imps := make([]*PackageSpec, 0, len(pkg.Imports))
45         for _, v := range pkg.Imports {
46                 imps = append(imps, v)
47         }
48         sort.Slice(imps, func(i, j int) bool {
49                 return imps[i].PkgPath < imps[j].PkgPath
50         })
51
52         for _, dep := range imps {
53                 if dep.ExportFile == "" {
54                         fmt.Fprintf(key, "import %s \n", dep.PkgPath)
55                 } else {
56                         id, err := getBuildid(dep.ExportFile)
57                         if err == nil {
58                                 fmt.Fprintf(key, "import %s %s\n", dep.PkgPath, id)
59                         } else {
60                                 fh, err := cache.FileHash(dep.ExportFile)
61                                 if err != nil {
62                                         return cache.ActionID{}, err
63                                 }
64                                 fmt.Fprintf(key, "import %s %x\n", dep.PkgPath, fh)
65                         }
66                 }
67         }
68         return key.Sum(), nil
69 }
70
71 var buildidCache = map[string]string{}
72
73 func getBuildid(f string) (string, error) {
74         if h, ok := buildidCache[f]; ok {
75                 return h, nil
76         }
77         h, err := ReadFile(f)
78         if err != nil {
79                 return "", err
80         }
81         buildidCache[f] = h
82         return h, nil
83 }