GoPLS Viewer

Home|gopls/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
5package buildutil
6
7import (
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.
33func FakeContext(pkgs map[string]map[string]string) *build.Context {
34    clean := func(filename stringstring {
35        f := path.Clean(filepath.ToSlash(filename))
36        // Removing "/go/src" while respecting segment
37        // boundaries has this unfortunate corner case:
38        if f == "/go/src" {
39            return ""
40        }
41        return strings.TrimPrefix(f"/go/src/")
42    }
43
44    ctxt := build.Default // copy
45    ctxt.GOROOT = "/go"
46    ctxt.GOPATH = ""
47    ctxt.Compiler = "gc"
48    ctxt.IsDir = func(dir stringbool {
49        dir = clean(dir)
50        if dir == "" {
51            return true // needed by (*build.Context).SrcDirs
52        }
53        return pkgs[dir] != nil
54    }
55    ctxt.ReadDir = func(dir string) ([]os.FileInfoerror) {
56        dir = clean(dir)
57        var fis []os.FileInfo
58        if dir == "" {
59            // enumerate packages
60            for importPath := range pkgs {
61                fis = append(fisfakeDirInfo(importPath))
62            }
63        } else {
64            // enumerate files of package
65            for basename := range pkgs[dir] {
66                fis = append(fisfakeFileInfo(basename))
67            }
68        }
69        sort.Sort(byName(fis))
70        return fisnil
71    }
72    ctxt.OpenFile = func(filename string) (io.ReadClosererror) {
73        filename = clean(filename)
74        dirbase := path.Split(filename)
75        contentok := pkgs[path.Clean(dir)][base]
76        if !ok {
77            return nilfmt.Errorf("file not found: %s"filename)
78        }
79        return ioutil.NopCloser(strings.NewReader(content)), nil
80    }
81    ctxt.IsAbsPath = func(path stringbool {
82        path = filepath.ToSlash(path)
83        // Don't rely on the default (filepath.Path) since on
84        // Windows, it reports virtual paths as non-absolute.
85        return strings.HasPrefix(path"/")
86    }
87    return &ctxt
88}
89
90type byName []os.FileInfo
91
92func (s byNameLen() int           { return len(s) }
93func (s byNameSwap(ij int)      { s[i], s[j] = s[j], s[i] }
94func (s byNameLess(ij intbool { return s[i].Name() < s[j].Name() }
95
96type fakeFileInfo string
97
98func (fi fakeFileInfoName() string    { return string(fi) }
99func (fakeFileInfoSys() interface{}   { return nil }
100func (fakeFileInfoModTime() time.Time { return time.Time{} }
101func (fakeFileInfoIsDir() bool        { return false }
102func (fakeFileInfoSize() int64        { return 0 }
103func (fakeFileInfoMode() os.FileMode  { return 0644 }
104
105type fakeDirInfo string
106
107func (fd fakeDirInfoName() string    { return string(fd) }
108func (fakeDirInfoSys() interface{}   { return nil }
109func (fakeDirInfoModTime() time.Time { return time.Time{} }
110func (fakeDirInfoIsDir() bool        { return true }
111func (fakeDirInfoSize() int64        { return 0 }
112func (fakeDirInfoMode() os.FileMode  { return 0755 }
113
MembersX
FakeContext.BlockStmt.BlockStmt.RangeStmt_1648.importPath
byName.Len.s
byName.Swap.s
fakeFileInfo.Mode
fakeDirInfo.Name.fd
fakeDirInfo.IsDir
FakeContext.BlockStmt.f
fakeFileInfo.Name.fi
fakeDirInfo.Size
path
byName.Less
byName.Less.i
fakeFileInfo
fakeFileInfo.Sys
fakeFileInfo.IsDir
FakeContext.BlockStmt.BlockStmt.RangeStmt_1778.basename
byName
byName.Len
time
byName.Swap
byName.Less.s
fakeDirInfo.Name
fakeDirInfo.ModTime
FakeContext.BlockStmt.base
FakeContext
FakeContext.pkgs
FakeContext.BlockStmt.fis
io
FakeContext.ctxt
byName.Swap.j
byName.Less.j
fakeFileInfo.Name
fakeFileInfo.Size
fakeDirInfo
fakeDirInfo.Sys
fmt
FakeContext.BlockStmt.dir
byName.Swap.i
fakeFileInfo.ModTime
fakeDirInfo.Mode
ioutil
Members
X