.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.1-0.20210319172145-bda8f5cee399 / internal / imports / mkindex.go
1 //go:build ignore
2 // +build ignore
3
4 // Copyright 2013 The Go Authors. All rights reserved.
5 // Use of this source code is governed by a BSD-style
6 // license that can be found in the LICENSE file.
7
8 // Command mkindex creates the file "pkgindex.go" containing an index of the Go
9 // standard library. The file is intended to be built as part of the imports
10 // package, so that the package may be used in environments where a GOROOT is
11 // not available (such as App Engine).
12 package imports
13
14 import (
15         "bytes"
16         "fmt"
17         "go/ast"
18         "go/build"
19         "go/format"
20         "go/parser"
21         "go/token"
22         "io/ioutil"
23         "log"
24         "os"
25         "path"
26         "path/filepath"
27         "strings"
28 )
29
30 var (
31         pkgIndex = make(map[string][]pkg)
32         exports  = make(map[string]map[string]bool)
33 )
34
35 func main() {
36         // Don't use GOPATH.
37         ctx := build.Default
38         ctx.GOPATH = ""
39
40         // Populate pkgIndex global from GOROOT.
41         for _, path := range ctx.SrcDirs() {
42                 f, err := os.Open(path)
43                 if err != nil {
44                         log.Print(err)
45                         continue
46                 }
47                 children, err := f.Readdir(-1)
48                 f.Close()
49                 if err != nil {
50                         log.Print(err)
51                         continue
52                 }
53                 for _, child := range children {
54                         if child.IsDir() {
55                                 loadPkg(path, child.Name())
56                         }
57                 }
58         }
59         // Populate exports global.
60         for _, ps := range pkgIndex {
61                 for _, p := range ps {
62                         e := loadExports(p.dir)
63                         if e != nil {
64                                 exports[p.dir] = e
65                         }
66                 }
67         }
68
69         // Construct source file.
70         var buf bytes.Buffer
71         fmt.Fprint(&buf, pkgIndexHead)
72         fmt.Fprintf(&buf, "var pkgIndexMaster = %#v\n", pkgIndex)
73         fmt.Fprintf(&buf, "var exportsMaster = %#v\n", exports)
74         src := buf.Bytes()
75
76         // Replace main.pkg type name with pkg.
77         src = bytes.Replace(src, []byte("main.pkg"), []byte("pkg"), -1)
78         // Replace actual GOROOT with "/go".
79         src = bytes.Replace(src, []byte(ctx.GOROOT), []byte("/go"), -1)
80         // Add some line wrapping.
81         src = bytes.Replace(src, []byte("}, "), []byte("},\n"), -1)
82         src = bytes.Replace(src, []byte("true, "), []byte("true,\n"), -1)
83
84         var err error
85         src, err = format.Source(src)
86         if err != nil {
87                 log.Fatal(err)
88         }
89
90         // Write out source file.
91         err = ioutil.WriteFile("pkgindex.go", src, 0644)
92         if err != nil {
93                 log.Fatal(err)
94         }
95 }
96
97 const pkgIndexHead = `package imports
98
99 func init() {
100         pkgIndexOnce.Do(func() {
101                 pkgIndex.m = pkgIndexMaster
102         })
103         loadExports = func(dir string) map[string]bool {
104                 return exportsMaster[dir]
105         }
106 }
107 `
108
109 type pkg struct {
110         importpath string // full pkg import path, e.g. "net/http"
111         dir        string // absolute file path to pkg directory e.g. "/usr/lib/go/src/fmt"
112 }
113
114 var fset = token.NewFileSet()
115
116 func loadPkg(root, importpath string) {
117         shortName := path.Base(importpath)
118         if shortName == "testdata" {
119                 return
120         }
121
122         dir := filepath.Join(root, importpath)
123         pkgIndex[shortName] = append(pkgIndex[shortName], pkg{
124                 importpath: importpath,
125                 dir:        dir,
126         })
127
128         pkgDir, err := os.Open(dir)
129         if err != nil {
130                 return
131         }
132         children, err := pkgDir.Readdir(-1)
133         pkgDir.Close()
134         if err != nil {
135                 return
136         }
137         for _, child := range children {
138                 name := child.Name()
139                 if name == "" {
140                         continue
141                 }
142                 if c := name[0]; c == '.' || ('0' <= c && c <= '9') {
143                         continue
144                 }
145                 if child.IsDir() {
146                         loadPkg(root, filepath.Join(importpath, name))
147                 }
148         }
149 }
150
151 func loadExports(dir string) map[string]bool {
152         exports := make(map[string]bool)
153         buildPkg, err := build.ImportDir(dir, 0)
154         if err != nil {
155                 if strings.Contains(err.Error(), "no buildable Go source files in") {
156                         return nil
157                 }
158                 log.Printf("could not import %q: %v", dir, err)
159                 return nil
160         }
161         for _, file := range buildPkg.GoFiles {
162                 f, err := parser.ParseFile(fset, filepath.Join(dir, file), nil, 0)
163                 if err != nil {
164                         log.Printf("could not parse %q: %v", file, err)
165                         continue
166                 }
167                 for name := range f.Scope.Objects {
168                         if ast.IsExported(name) {
169                                 exports[name] = true
170                         }
171                 }
172         }
173         return exports
174 }