stdlib.go 2.8 KB

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