aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/tools/go/buildutil/fakecontext.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/tools/go/buildutil/fakecontext.go')
-rw-r--r--vendor/golang.org/x/tools/go/buildutil/fakecontext.go109
1 files changed, 109 insertions, 0 deletions
diff --git a/vendor/golang.org/x/tools/go/buildutil/fakecontext.go b/vendor/golang.org/x/tools/go/buildutil/fakecontext.go
new file mode 100644
index 0000000..8b7f066
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/buildutil/fakecontext.go
@@ -0,0 +1,109 @@
1package buildutil
2
3import (
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//
30func 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
87type byName []os.FileInfo
88
89func (s byName) Len() int { return len(s) }
90func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
91func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }
92
93type fakeFileInfo string
94
95func (fi fakeFileInfo) Name() string { return string(fi) }
96func (fakeFileInfo) Sys() interface{} { return nil }
97func (fakeFileInfo) ModTime() time.Time { return time.Time{} }
98func (fakeFileInfo) IsDir() bool { return false }
99func (fakeFileInfo) Size() int64 { return 0 }
100func (fakeFileInfo) Mode() os.FileMode { return 0644 }
101
102type fakeDirInfo string
103
104func (fd fakeDirInfo) Name() string { return string(fd) }
105func (fakeDirInfo) Sys() interface{} { return nil }
106func (fakeDirInfo) ModTime() time.Time { return time.Time{} }
107func (fakeDirInfo) IsDir() bool { return true }
108func (fakeDirInfo) Size() int64 { return 0 }
109func (fakeDirInfo) Mode() os.FileMode { return 0755 }