1 // Copyright 2022 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:generate go run generate.go
6 7 // Package stdlib provides a table of all exported symbols in the
8 // standard library, along with the version at which they first
9 // appeared. It also provides the import graph of std packages.
10 package stdlib
11 12 import (
13 "fmt"
14 "strings"
15 )
16 17 type Symbol struct {
18 Name string
19 Kind Kind
20 Version Version // Go version that first included the symbol
21 // Signature provides the type of a function (defined only for Kind=Func).
22 // Imported types are denoted as pkg.T; pkg is not fully qualified.
23 // TODO(adonovan): use an unambiguous encoding that is parseable.
24 //
25 // Example2:
26 // func[M ~map[K]V, K comparable, V any](m M) M
27 // func(fi fs.FileInfo, link string) (*Header, error)
28 Signature string // if Kind == stdlib.Func
29 }
30 31 // A Kind indicates the kind of a symbol:
32 // function, variable, constant, type, and so on.
33 type Kind int8
34 35 const (
36 Invalid Kind = iota // Example name:
37 Type // "Buffer"
38 Func // "Println"
39 Var // "EOF"
40 Const // "Pi"
41 Field // "Point.X"
42 Method // "(*Buffer).Grow" or "(Reader).Read"
43 )
44 45 func (kind Kind) String() string {
46 return [...]string{
47 Invalid: "invalid",
48 Type: "type",
49 Func: "func",
50 Var: "var",
51 Const: "const",
52 Field: "field",
53 Method: "method",
54 }[kind]
55 }
56 57 // A Version represents a version of Go of the form "go1.%d".
58 type Version int8
59 60 // String returns a version string of the form "go1.23", without allocating.
61 func (v Version) String() string { return versions[v] }
62 63 var versions [30]string // (increase constant as needed)
64 65 func init() {
66 for i := range versions {
67 versions[i] = fmt.Sprintf("go1.%d", i)
68 }
69 }
70 71 // HasPackage reports whether the specified package path is part of
72 // the standard library's public API.
73 func HasPackage(path string) bool {
74 _, ok := PackageSymbols[path]
75 return ok
76 }
77 78 // SplitField splits the field symbol name into type and field
79 // components. It must be called only on Field symbols.
80 //
81 // Example: "File.Package" -> ("File", "Package")
82 func (sym *Symbol) SplitField() (typename, name string) {
83 if sym.Kind != Field {
84 panic("not a field")
85 }
86 typename, name, _ = strings.Cut(sym.Name, ".")
87 return
88 }
89 90 // SplitMethod splits the method symbol name into pointer, receiver,
91 // and method components. It must be called only on Method symbols.
92 //
93 // Example: "(*Buffer).Grow" -> (true, "Buffer", "Grow")
94 func (sym *Symbol) SplitMethod() (ptr bool, recv, name string) {
95 if sym.Kind != Method {
96 panic("not a method")
97 }
98 recv, name, _ = strings.Cut(sym.Name, ".")
99 recv = recv[len("(") : len(recv)-len(")")]
100 ptr = recv[0] == '*'
101 if ptr {
102 recv = recv[len("*"):]
103 }
104 return
105 }
106