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 / godoc / vfs / os.go
1 // Copyright 2013 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 vfs
6
7 import (
8         "fmt"
9         "go/build"
10         "io/ioutil"
11         "os"
12         pathpkg "path"
13         "path/filepath"
14         "runtime"
15 )
16
17 // We expose a new variable because otherwise we need to copy the findGOROOT logic again
18 // from cmd/godoc which is already copied twice from the standard library.
19
20 // GOROOT is the GOROOT path under which the godoc binary is running.
21 // It is needed to check whether a filesystem root is under GOROOT or not.
22 // This is set from cmd/godoc/main.go.
23 var GOROOT = runtime.GOROOT()
24
25 // OS returns an implementation of FileSystem reading from the
26 // tree rooted at root.  Recording a root is convenient everywhere
27 // but necessary on Windows, because the slash-separated path
28 // passed to Open has no way to specify a drive letter.  Using a root
29 // lets code refer to OS(`c:\`), OS(`d:\`) and so on.
30 func OS(root string) FileSystem {
31         var t RootType
32         switch {
33         case root == GOROOT:
34                 t = RootTypeGoRoot
35         case isGoPath(root):
36                 t = RootTypeGoPath
37         }
38         return osFS{rootPath: root, rootType: t}
39 }
40
41 type osFS struct {
42         rootPath string
43         rootType RootType
44 }
45
46 func isGoPath(path string) bool {
47         for _, bp := range filepath.SplitList(build.Default.GOPATH) {
48                 for _, gp := range filepath.SplitList(path) {
49                         if bp == gp {
50                                 return true
51                         }
52                 }
53         }
54         return false
55 }
56
57 func (root osFS) String() string { return "os(" + root.rootPath + ")" }
58
59 // RootType returns the root type for the filesystem.
60 //
61 // Note that we ignore the path argument because roottype is a property of
62 // this filesystem. But for other filesystems, the roottype might need to be
63 // dynamically deduced at call time.
64 func (root osFS) RootType(path string) RootType {
65         return root.rootType
66 }
67
68 func (root osFS) resolve(path string) string {
69         // Clean the path so that it cannot possibly begin with ../.
70         // If it did, the result of filepath.Join would be outside the
71         // tree rooted at root.  We probably won't ever see a path
72         // with .. in it, but be safe anyway.
73         path = pathpkg.Clean("/" + path)
74
75         return filepath.Join(root.rootPath, path)
76 }
77
78 func (root osFS) Open(path string) (ReadSeekCloser, error) {
79         f, err := os.Open(root.resolve(path))
80         if err != nil {
81                 return nil, err
82         }
83         fi, err := f.Stat()
84         if err != nil {
85                 f.Close()
86                 return nil, err
87         }
88         if fi.IsDir() {
89                 f.Close()
90                 return nil, fmt.Errorf("Open: %s is a directory", path)
91         }
92         return f, nil
93 }
94
95 func (root osFS) Lstat(path string) (os.FileInfo, error) {
96         return os.Lstat(root.resolve(path))
97 }
98
99 func (root osFS) Stat(path string) (os.FileInfo, error) {
100         return os.Stat(root.resolve(path))
101 }
102
103 func (root osFS) ReadDir(path string) ([]os.FileInfo, error) {
104         return ioutil.ReadDir(root.resolve(path)) // is sorted
105 }