GoPLS Viewer

Home|gopls/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).
12package imports
13
14import (
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
30var (
31    pkgIndex = make(map[string][]pkg)
32    exports  = make(map[string]map[string]bool)
33)
34
35func 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        ferr := os.Open(path)
43        if err != nil {
44            log.Print(err)
45            continue
46        }
47        childrenerr := 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(pathchild.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(&bufpkgIndexHead)
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    srcerr = format.Source(src)
86    if err != nil {
87        log.Fatal(err)
88    }
89
90    // Write out source file.
91    err = ioutil.WriteFile("pkgindex.go"src0644)
92    if err != nil {
93        log.Fatal(err)
94    }
95}
96
97const pkgIndexHead = `package imports
98
99func 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
109type 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
114var fset = token.NewFileSet()
115
116func loadPkg(rootimportpath string) {
117    shortName := path.Base(importpath)
118    if shortName == "testdata" {
119        return
120    }
121
122    dir := filepath.Join(rootimportpath)
123    pkgIndex[shortName] = append(pkgIndex[shortName], pkg{
124        importpathimportpath,
125        dir:        dir,
126    })
127
128    pkgDirerr := os.Open(dir)
129    if err != nil {
130        return
131    }
132    childrenerr := 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(rootfilepath.Join(importpathname))
147        }
148    }
149}
150
151func loadExports(dir string) map[string]bool {
152    exports := make(map[string]bool)
153    buildPkgerr := build.ImportDir(dir0)
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"direrr)
159        return nil
160    }
161    for _file := range buildPkg.GoFiles {
162        ferr := parser.ParseFile(fsetfilepath.Join(dirfile), nil0)
163        if err != nil {
164            log.Printf("could not parse %q: %v"fileerr)
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}
175
MembersX
main.RangeStmt_1189.BlockStmt.RangeStmt_1221.p
main.src
pkgIndexHead
main.RangeStmt_846.BlockStmt.children
loadPkg
loadExports.RangeStmt_3451.file
loadPkg.root
loadPkg.importpath
loadPkg.shortName
loadPkg.pkgDir
loadPkg.err
loadExports.RangeStmt_3451.BlockStmt.err
loadExports.err
main.RangeStmt_846.BlockStmt.RangeStmt_1060.child
main.RangeStmt_1189.BlockStmt.RangeStmt_1221.BlockStmt.e
main.buf
pkg.importpath
loadPkg.dir
loadPkg.RangeStmt_2911.child
loadExports.exports
loadExports.RangeStmt_3451.BlockStmt.RangeStmt_3647.name
main.ctx
main.RangeStmt_846.BlockStmt.f
main.RangeStmt_846.BlockStmt.err
loadPkg.children
loadExports
loadExports.dir
loadExports.RangeStmt_3451.BlockStmt.f
main.RangeStmt_1189.ps
main
main.RangeStmt_846.path
main.err
loadPkg.RangeStmt_2911.BlockStmt.name
loadExports.buildPkg
Members
X