Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / buildutil / fakecontext.go
1 package buildutil
2
3 import (
4         "fmt"
5         "go/build"
6         "io"
7         "io/ioutil"
8         "os"
9         "path"
10         "path/filepath"
11         "sort"
12         "strings"
13         "time"
14 )
15
16 // FakeContext returns a build.Context for the fake file tree specified
17 // by pkgs, which maps package import paths to a mapping from file base
18 // names to contents.
19 //
20 // The fake Context has a GOROOT of "/go" and no GOPATH, and overrides
21 // the necessary file access methods to read from memory instead of the
22 // real file system.
23 //
24 // Unlike a real file tree, the fake one has only two levels---packages
25 // and files---so ReadDir("/go/src/") returns all packages under
26 // /go/src/ including, for instance, "math" and "math/big".
27 // ReadDir("/go/src/math/big") would return all the files in the
28 // "math/big" package.
29 //
30 func FakeContext(pkgs map[string]map[string]string) *build.Context {
31         clean := func(filename string) string {
32                 f := path.Clean(filepath.ToSlash(filename))
33                 // Removing "/go/src" while respecting segment
34                 // boundaries has this unfortunate corner case:
35                 if f == "/go/src" {
36                         return ""
37                 }
38                 return strings.TrimPrefix(f, "/go/src/")
39         }
40
41         ctxt := build.Default // copy
42         ctxt.GOROOT = "/go"
43         ctxt.GOPATH = ""
44         ctxt.Compiler = "gc"
45         ctxt.IsDir = func(dir string) bool {
46                 dir = clean(dir)
47                 if dir == "" {
48                         return true // needed by (*build.Context).SrcDirs
49                 }
50                 return pkgs[dir] != nil
51         }
52         ctxt.ReadDir = func(dir string) ([]os.FileInfo, error) {
53                 dir = clean(dir)
54                 var fis []os.FileInfo
55                 if dir == "" {
56                         // enumerate packages
57                         for importPath := range pkgs {
58                                 fis = append(fis, fakeDirInfo(importPath))
59                         }
60                 } else {
61                         // enumerate files of package
62                         for basename := range pkgs[dir] {
63                                 fis = append(fis, fakeFileInfo(basename))
64                         }
65                 }
66                 sort.Sort(byName(fis))
67                 return fis, nil
68         }
69         ctxt.OpenFile = func(filename string) (io.ReadCloser, error) {
70                 filename = clean(filename)
71                 dir, base := path.Split(filename)
72                 content, ok := pkgs[path.Clean(dir)][base]
73                 if !ok {
74                         return nil, fmt.Errorf("file not found: %s", filename)
75                 }
76                 return ioutil.NopCloser(strings.NewReader(content)), nil
77         }
78         ctxt.IsAbsPath = func(path string) bool {
79                 path = filepath.ToSlash(path)
80                 // Don't rely on the default (filepath.Path) since on
81                 // Windows, it reports virtual paths as non-absolute.
82                 return strings.HasPrefix(path, "/")
83         }
84         return &ctxt
85 }
86
87 type byName []os.FileInfo
88
89 func (s byName) Len() int           { return len(s) }
90 func (s byName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
91 func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }
92
93 type fakeFileInfo string
94
95 func (fi fakeFileInfo) Name() string    { return string(fi) }
96 func (fakeFileInfo) Sys() interface{}   { return nil }
97 func (fakeFileInfo) ModTime() time.Time { return time.Time{} }
98 func (fakeFileInfo) IsDir() bool        { return false }
99 func (fakeFileInfo) Size() int64        { return 0 }
100 func (fakeFileInfo) Mode() os.FileMode  { return 0644 }
101
102 type fakeDirInfo string
103
104 func (fd fakeDirInfo) Name() string    { return string(fd) }
105 func (fakeDirInfo) Sys() interface{}   { return nil }
106 func (fakeDirInfo) ModTime() time.Time { return time.Time{} }
107 func (fakeDirInfo) IsDir() bool        { return true }
108 func (fakeDirInfo) Size() int64        { return 0 }
109 func (fakeDirInfo) Mode() os.FileMode  { return 0755 }