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