1
0
mirror of https://github.com/golang/go synced 2024-11-05 20:06:10 -07:00
go/internal/imports/mkstdlib.go

133 lines
3.0 KiB
Go
Raw Normal View History

// +build ignore
// mkstdlib generates the zstdlib.go file, containing the Go standard
// library API symbols. It's baked into the binary to avoid scanning
// GOPATH in the common case.
package imports
import (
"bufio"
"bytes"
"fmt"
"go/format"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"sort"
"strings"
)
func mustOpen(name string) io.Reader {
f, err := os.Open(name)
if err != nil {
log.Fatal(err)
}
return f
}
func api(base string) string {
return filepath.Join(runtime.GOROOT(), "api", base)
}
var sym = regexp.MustCompile(`^pkg (\S+).*?, (?:var|func|type|const) ([A-Z]\w*)`)
imports: redesign fixImports Redesign fixImports to have a clearer workflow, and hopefully create clear places to plug in go/packages. This change is mostly performance/functionality neutral, but does clean up some corner cases. The new flow centers around the pass type, which encapsulates the process of loading information about the current code, adding possible new imports, and trying to apply them. I'm hoping that it's easy to understand what's happening just by reading fixImports, and that new sources of information (e.g. a network service) fit well into that flow. Where possible, I left the functions near where they were extracted in hopes of making review easier, but it's probably not going to be easy. Sorry. I might move them into a more reasonable order in a followup CL. Notable modifications: - The stdlib cache is restructured to match pass' internal storage. - Sibling imports with conflicting names are considered. - Package name lookups are batched, hopefully making it easier to plug in go/packages. Questions that might be worth answering: - Should findImportGoPath really scan $GOROOT? Unless the user is working on a development copy, it's totally redundant with the cache. - What is the best way to combine candidates from multiple sources? Right now the first one wins, and findStdlibCandidates relies on that to get crypto/rand ahead of math/rand. - In the third pass, should it assume sibling imports or should it actually go load the exports? It didn't load them before, but that seems arbitrary. Change-Id: Ie4ad0b69bfbe9b16883f2b0517b1278575c9f540 Reviewed-on: https://go-review.googlesource.com/c/150339 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-11-19 15:56:05 -07:00
var unsafeSyms = map[string]bool{"Alignof": true, "ArbitraryType": true, "Offsetof": true, "Pointer": true, "Sizeof": true}
func main() {
var buf bytes.Buffer
outf := func(format string, args ...interface{}) {
fmt.Fprintf(&buf, format, args...)
}
outf("// Code generated by mkstdlib.go. DO NOT EDIT.\n\n")
outf("package imports\n")
imports: redesign fixImports Redesign fixImports to have a clearer workflow, and hopefully create clear places to plug in go/packages. This change is mostly performance/functionality neutral, but does clean up some corner cases. The new flow centers around the pass type, which encapsulates the process of loading information about the current code, adding possible new imports, and trying to apply them. I'm hoping that it's easy to understand what's happening just by reading fixImports, and that new sources of information (e.g. a network service) fit well into that flow. Where possible, I left the functions near where they were extracted in hopes of making review easier, but it's probably not going to be easy. Sorry. I might move them into a more reasonable order in a followup CL. Notable modifications: - The stdlib cache is restructured to match pass' internal storage. - Sibling imports with conflicting names are considered. - Package name lookups are batched, hopefully making it easier to plug in go/packages. Questions that might be worth answering: - Should findImportGoPath really scan $GOROOT? Unless the user is working on a development copy, it's totally redundant with the cache. - What is the best way to combine candidates from multiple sources? Right now the first one wins, and findStdlibCandidates relies on that to get crypto/rand ahead of math/rand. - In the third pass, should it assume sibling imports or should it actually go load the exports? It didn't load them before, but that seems arbitrary. Change-Id: Ie4ad0b69bfbe9b16883f2b0517b1278575c9f540 Reviewed-on: https://go-review.googlesource.com/c/150339 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-11-19 15:56:05 -07:00
outf("var stdlib = map[string]map[string]bool{\n")
f := io.MultiReader(
mustOpen(api("go1.txt")),
mustOpen(api("go1.1.txt")),
mustOpen(api("go1.2.txt")),
mustOpen(api("go1.3.txt")),
mustOpen(api("go1.4.txt")),
mustOpen(api("go1.5.txt")),
mustOpen(api("go1.6.txt")),
mustOpen(api("go1.7.txt")),
mustOpen(api("go1.8.txt")),
mustOpen(api("go1.9.txt")),
mustOpen(api("go1.10.txt")),
mustOpen(api("go1.11.txt")),
mustOpen(api("go1.12.txt")),
// The API of the syscall/js package needs to be computed explicitly,
// because it's not included in the GOROOT/api/go1.*.txt files at this time.
syscallJSAPI(),
)
sc := bufio.NewScanner(f)
imports: redesign fixImports Redesign fixImports to have a clearer workflow, and hopefully create clear places to plug in go/packages. This change is mostly performance/functionality neutral, but does clean up some corner cases. The new flow centers around the pass type, which encapsulates the process of loading information about the current code, adding possible new imports, and trying to apply them. I'm hoping that it's easy to understand what's happening just by reading fixImports, and that new sources of information (e.g. a network service) fit well into that flow. Where possible, I left the functions near where they were extracted in hopes of making review easier, but it's probably not going to be easy. Sorry. I might move them into a more reasonable order in a followup CL. Notable modifications: - The stdlib cache is restructured to match pass' internal storage. - Sibling imports with conflicting names are considered. - Package name lookups are batched, hopefully making it easier to plug in go/packages. Questions that might be worth answering: - Should findImportGoPath really scan $GOROOT? Unless the user is working on a development copy, it's totally redundant with the cache. - What is the best way to combine candidates from multiple sources? Right now the first one wins, and findStdlibCandidates relies on that to get crypto/rand ahead of math/rand. - In the third pass, should it assume sibling imports or should it actually go load the exports? It didn't load them before, but that seems arbitrary. Change-Id: Ie4ad0b69bfbe9b16883f2b0517b1278575c9f540 Reviewed-on: https://go-review.googlesource.com/c/150339 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-11-19 15:56:05 -07:00
pkgs := map[string]map[string]bool{
"unsafe": unsafeSyms,
}
paths := []string{"unsafe"}
for sc.Scan() {
l := sc.Text()
has := func(v string) bool { return strings.Contains(l, v) }
if has("struct, ") || has("interface, ") || has(", method (") {
continue
}
if m := sym.FindStringSubmatch(l); m != nil {
imports: redesign fixImports Redesign fixImports to have a clearer workflow, and hopefully create clear places to plug in go/packages. This change is mostly performance/functionality neutral, but does clean up some corner cases. The new flow centers around the pass type, which encapsulates the process of loading information about the current code, adding possible new imports, and trying to apply them. I'm hoping that it's easy to understand what's happening just by reading fixImports, and that new sources of information (e.g. a network service) fit well into that flow. Where possible, I left the functions near where they were extracted in hopes of making review easier, but it's probably not going to be easy. Sorry. I might move them into a more reasonable order in a followup CL. Notable modifications: - The stdlib cache is restructured to match pass' internal storage. - Sibling imports with conflicting names are considered. - Package name lookups are batched, hopefully making it easier to plug in go/packages. Questions that might be worth answering: - Should findImportGoPath really scan $GOROOT? Unless the user is working on a development copy, it's totally redundant with the cache. - What is the best way to combine candidates from multiple sources? Right now the first one wins, and findStdlibCandidates relies on that to get crypto/rand ahead of math/rand. - In the third pass, should it assume sibling imports or should it actually go load the exports? It didn't load them before, but that seems arbitrary. Change-Id: Ie4ad0b69bfbe9b16883f2b0517b1278575c9f540 Reviewed-on: https://go-review.googlesource.com/c/150339 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-11-19 15:56:05 -07:00
path, sym := m[1], m[2]
if _, ok := pkgs[path]; !ok {
pkgs[path] = map[string]bool{}
paths = append(paths, path)
}
imports: redesign fixImports Redesign fixImports to have a clearer workflow, and hopefully create clear places to plug in go/packages. This change is mostly performance/functionality neutral, but does clean up some corner cases. The new flow centers around the pass type, which encapsulates the process of loading information about the current code, adding possible new imports, and trying to apply them. I'm hoping that it's easy to understand what's happening just by reading fixImports, and that new sources of information (e.g. a network service) fit well into that flow. Where possible, I left the functions near where they were extracted in hopes of making review easier, but it's probably not going to be easy. Sorry. I might move them into a more reasonable order in a followup CL. Notable modifications: - The stdlib cache is restructured to match pass' internal storage. - Sibling imports with conflicting names are considered. - Package name lookups are batched, hopefully making it easier to plug in go/packages. Questions that might be worth answering: - Should findImportGoPath really scan $GOROOT? Unless the user is working on a development copy, it's totally redundant with the cache. - What is the best way to combine candidates from multiple sources? Right now the first one wins, and findStdlibCandidates relies on that to get crypto/rand ahead of math/rand. - In the third pass, should it assume sibling imports or should it actually go load the exports? It didn't load them before, but that seems arbitrary. Change-Id: Ie4ad0b69bfbe9b16883f2b0517b1278575c9f540 Reviewed-on: https://go-review.googlesource.com/c/150339 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-11-19 15:56:05 -07:00
pkgs[path][sym] = true
}
}
if err := sc.Err(); err != nil {
log.Fatal(err)
}
imports: redesign fixImports Redesign fixImports to have a clearer workflow, and hopefully create clear places to plug in go/packages. This change is mostly performance/functionality neutral, but does clean up some corner cases. The new flow centers around the pass type, which encapsulates the process of loading information about the current code, adding possible new imports, and trying to apply them. I'm hoping that it's easy to understand what's happening just by reading fixImports, and that new sources of information (e.g. a network service) fit well into that flow. Where possible, I left the functions near where they were extracted in hopes of making review easier, but it's probably not going to be easy. Sorry. I might move them into a more reasonable order in a followup CL. Notable modifications: - The stdlib cache is restructured to match pass' internal storage. - Sibling imports with conflicting names are considered. - Package name lookups are batched, hopefully making it easier to plug in go/packages. Questions that might be worth answering: - Should findImportGoPath really scan $GOROOT? Unless the user is working on a development copy, it's totally redundant with the cache. - What is the best way to combine candidates from multiple sources? Right now the first one wins, and findStdlibCandidates relies on that to get crypto/rand ahead of math/rand. - In the third pass, should it assume sibling imports or should it actually go load the exports? It didn't load them before, but that seems arbitrary. Change-Id: Ie4ad0b69bfbe9b16883f2b0517b1278575c9f540 Reviewed-on: https://go-review.googlesource.com/c/150339 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-11-19 15:56:05 -07:00
sort.Strings(paths)
for _, path := range paths {
outf("\t%q: map[string]bool{\n", path)
pkg := pkgs[path]
var syms []string
for sym := range pkg {
syms = append(syms, sym)
}
imports: redesign fixImports Redesign fixImports to have a clearer workflow, and hopefully create clear places to plug in go/packages. This change is mostly performance/functionality neutral, but does clean up some corner cases. The new flow centers around the pass type, which encapsulates the process of loading information about the current code, adding possible new imports, and trying to apply them. I'm hoping that it's easy to understand what's happening just by reading fixImports, and that new sources of information (e.g. a network service) fit well into that flow. Where possible, I left the functions near where they were extracted in hopes of making review easier, but it's probably not going to be easy. Sorry. I might move them into a more reasonable order in a followup CL. Notable modifications: - The stdlib cache is restructured to match pass' internal storage. - Sibling imports with conflicting names are considered. - Package name lookups are batched, hopefully making it easier to plug in go/packages. Questions that might be worth answering: - Should findImportGoPath really scan $GOROOT? Unless the user is working on a development copy, it's totally redundant with the cache. - What is the best way to combine candidates from multiple sources? Right now the first one wins, and findStdlibCandidates relies on that to get crypto/rand ahead of math/rand. - In the third pass, should it assume sibling imports or should it actually go load the exports? It didn't load them before, but that seems arbitrary. Change-Id: Ie4ad0b69bfbe9b16883f2b0517b1278575c9f540 Reviewed-on: https://go-review.googlesource.com/c/150339 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-11-19 15:56:05 -07:00
sort.Strings(syms)
for _, sym := range syms {
outf("\t\t%q: true,\n", sym)
}
outf("},\n")
}
outf("}\n")
fmtbuf, err := format.Source(buf.Bytes())
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile("zstdlib.go", fmtbuf, 0666)
if err != nil {
log.Fatal(err)
}
}
// syscallJSAPI returns the API of the syscall/js package.
// It's computed from the contents of $(go env GOROOT)/src/syscall/js.
func syscallJSAPI() io.Reader {
var exeSuffix string
if runtime.GOOS == "windows" {
exeSuffix = ".exe"
}
cmd := exec.Command("go"+exeSuffix, "run", "cmd/api", "-contexts", "js-wasm", "syscall/js")
out, err := cmd.Output()
if err != nil {
log.Fatalln(err)
}
return bytes.NewReader(out)
}