github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/internal/imports/mkstdlib.go (about) 1 // Copyright 2019 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 //go:build ignore 6 // +build ignore 7 8 // mkstdlib generates the zstdlib.go file, containing the Go standard 9 // library API symbols. It's baked into the binary to avoid scanning 10 // GOPATH in the common case. 11 package main 12 13 import ( 14 "bufio" 15 "bytes" 16 "fmt" 17 "go/format" 18 "io" 19 "io/ioutil" 20 "log" 21 "os" 22 "path/filepath" 23 "regexp" 24 "runtime" 25 "sort" 26 27 exec "golang.org/x/sys/execabs" 28 ) 29 30 func mustOpen(name string) io.Reader { 31 f, err := os.Open(name) 32 if err != nil { 33 log.Fatal(err) 34 } 35 return f 36 } 37 38 func api(base string) string { 39 return filepath.Join(runtime.GOROOT(), "api", base) 40 } 41 42 var sym = regexp.MustCompile(`^pkg (\S+).*?, (?:var|func|type|const) ([A-Z]\w*)`) 43 44 var unsafeSyms = map[string]bool{"Alignof": true, "ArbitraryType": true, "Offsetof": true, "Pointer": true, "Sizeof": true} 45 46 func main() { 47 var buf bytes.Buffer 48 outf := func(format string, args ...interface{}) { 49 fmt.Fprintf(&buf, format, args...) 50 } 51 outf("// Code generated by mkstdlib.go. DO NOT EDIT.\n\n") 52 outf("package imports\n") 53 outf("var stdlib = map[string][]string{\n") 54 f := io.MultiReader( 55 mustOpen(api("go1.txt")), 56 mustOpen(api("go1.1.txt")), 57 mustOpen(api("go1.2.txt")), 58 mustOpen(api("go1.3.txt")), 59 mustOpen(api("go1.4.txt")), 60 mustOpen(api("go1.5.txt")), 61 mustOpen(api("go1.6.txt")), 62 mustOpen(api("go1.7.txt")), 63 mustOpen(api("go1.8.txt")), 64 mustOpen(api("go1.9.txt")), 65 mustOpen(api("go1.10.txt")), 66 mustOpen(api("go1.11.txt")), 67 mustOpen(api("go1.12.txt")), 68 mustOpen(api("go1.13.txt")), 69 mustOpen(api("go1.14.txt")), 70 mustOpen(api("go1.15.txt")), 71 mustOpen(api("go1.16.txt")), 72 mustOpen(api("go1.17.txt")), 73 mustOpen(api("go1.18.txt")), 74 75 // The API of the syscall/js package needs to be computed explicitly, 76 // because it's not included in the GOROOT/api/go1.*.txt files at this time. 77 syscallJSAPI(), 78 ) 79 sc := bufio.NewScanner(f) 80 81 pkgs := map[string]map[string]bool{ 82 "unsafe": unsafeSyms, 83 } 84 paths := []string{"unsafe"} 85 86 for sc.Scan() { 87 l := sc.Text() 88 if m := sym.FindStringSubmatch(l); m != nil { 89 path, sym := m[1], m[2] 90 91 if _, ok := pkgs[path]; !ok { 92 pkgs[path] = map[string]bool{} 93 paths = append(paths, path) 94 } 95 pkgs[path][sym] = true 96 } 97 } 98 if err := sc.Err(); err != nil { 99 log.Fatal(err) 100 } 101 sort.Strings(paths) 102 for _, path := range paths { 103 outf("\t%q: []string{\n", path) 104 pkg := pkgs[path] 105 var syms []string 106 for sym := range pkg { 107 syms = append(syms, sym) 108 } 109 sort.Strings(syms) 110 for _, sym := range syms { 111 outf("\t\t%q,\n", sym) 112 } 113 outf("},\n") 114 } 115 outf("}\n") 116 fmtbuf, err := format.Source(buf.Bytes()) 117 if err != nil { 118 log.Fatal(err) 119 } 120 err = ioutil.WriteFile("zstdlib.go", fmtbuf, 0666) 121 if err != nil { 122 log.Fatal(err) 123 } 124 } 125 126 // syscallJSAPI returns the API of the syscall/js package. 127 // It's computed from the contents of $(go env GOROOT)/src/syscall/js. 128 func syscallJSAPI() io.Reader { 129 var exeSuffix string 130 if runtime.GOOS == "windows" { 131 exeSuffix = ".exe" 132 } 133 cmd := exec.Command("go"+exeSuffix, "run", "cmd/api", "-contexts", "js-wasm", "syscall/js") 134 out, err := cmd.Output() 135 if err != nil { 136 log.Fatalln(err) 137 } 138 return bytes.NewReader(out) 139 }