github.com/v2fly/tools@v0.100.0/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 73 // The API of the syscall/js package needs to be computed explicitly, 74 // because it's not included in the GOROOT/api/go1.*.txt files at this time. 75 syscallJSAPI(), 76 ) 77 sc := bufio.NewScanner(f) 78 79 pkgs := map[string]map[string]bool{ 80 "unsafe": unsafeSyms, 81 } 82 paths := []string{"unsafe"} 83 84 for sc.Scan() { 85 l := sc.Text() 86 if m := sym.FindStringSubmatch(l); m != nil { 87 path, sym := m[1], m[2] 88 89 if _, ok := pkgs[path]; !ok { 90 pkgs[path] = map[string]bool{} 91 paths = append(paths, path) 92 } 93 pkgs[path][sym] = true 94 } 95 } 96 if err := sc.Err(); err != nil { 97 log.Fatal(err) 98 } 99 sort.Strings(paths) 100 for _, path := range paths { 101 outf("\t%q: []string{\n", path) 102 pkg := pkgs[path] 103 var syms []string 104 for sym := range pkg { 105 syms = append(syms, sym) 106 } 107 sort.Strings(syms) 108 for _, sym := range syms { 109 outf("\t\t%q,\n", sym) 110 } 111 outf("},\n") 112 } 113 outf("}\n") 114 fmtbuf, err := format.Source(buf.Bytes()) 115 if err != nil { 116 log.Fatal(err) 117 } 118 err = ioutil.WriteFile("zstdlib.go", fmtbuf, 0666) 119 if err != nil { 120 log.Fatal(err) 121 } 122 } 123 124 // syscallJSAPI returns the API of the syscall/js package. 125 // It's computed from the contents of $(go env GOROOT)/src/syscall/js. 126 func syscallJSAPI() io.Reader { 127 var exeSuffix string 128 if runtime.GOOS == "windows" { 129 exeSuffix = ".exe" 130 } 131 cmd := exec.Command("go"+exeSuffix, "run", "cmd/api", "-contexts", "js-wasm", "syscall/js") 132 out, err := cmd.Output() 133 if err != nil { 134 log.Fatalln(err) 135 } 136 return bytes.NewReader(out) 137 }