98 lines
2.4 KiB
Go
98 lines
2.4 KiB
Go
|
// Copyright 2022 The Go Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
//go:generate go run generate.go
|
||
|
|
||
|
// Package stdlib provides a table of all exported symbols in the
|
||
|
// standard library, along with the version at which they first
|
||
|
// appeared.
|
||
|
package stdlib
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
type Symbol struct {
|
||
|
Name string
|
||
|
Kind Kind
|
||
|
Version Version // Go version that first included the symbol
|
||
|
}
|
||
|
|
||
|
// A Kind indicates the kind of a symbol:
|
||
|
// function, variable, constant, type, and so on.
|
||
|
type Kind int8
|
||
|
|
||
|
const (
|
||
|
Invalid Kind = iota // Example name:
|
||
|
Type // "Buffer"
|
||
|
Func // "Println"
|
||
|
Var // "EOF"
|
||
|
Const // "Pi"
|
||
|
Field // "Point.X"
|
||
|
Method // "(*Buffer).Grow"
|
||
|
)
|
||
|
|
||
|
func (kind Kind) String() string {
|
||
|
return [...]string{
|
||
|
Invalid: "invalid",
|
||
|
Type: "type",
|
||
|
Func: "func",
|
||
|
Var: "var",
|
||
|
Const: "const",
|
||
|
Field: "field",
|
||
|
Method: "method",
|
||
|
}[kind]
|
||
|
}
|
||
|
|
||
|
// A Version represents a version of Go of the form "go1.%d".
|
||
|
type Version int8
|
||
|
|
||
|
// String returns a version string of the form "go1.23", without allocating.
|
||
|
func (v Version) String() string { return versions[v] }
|
||
|
|
||
|
var versions [30]string // (increase constant as needed)
|
||
|
|
||
|
func init() {
|
||
|
for i := range versions {
|
||
|
versions[i] = fmt.Sprintf("go1.%d", i)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// HasPackage reports whether the specified package path is part of
|
||
|
// the standard library's public API.
|
||
|
func HasPackage(path string) bool {
|
||
|
_, ok := PackageSymbols[path]
|
||
|
return ok
|
||
|
}
|
||
|
|
||
|
// SplitField splits the field symbol name into type and field
|
||
|
// components. It must be called only on Field symbols.
|
||
|
//
|
||
|
// Example: "File.Package" -> ("File", "Package")
|
||
|
func (sym *Symbol) SplitField() (typename, name string) {
|
||
|
if sym.Kind != Field {
|
||
|
panic("not a field")
|
||
|
}
|
||
|
typename, name, _ = strings.Cut(sym.Name, ".")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// SplitMethod splits the method symbol name into pointer, receiver,
|
||
|
// and method components. It must be called only on Method symbols.
|
||
|
//
|
||
|
// Example: "(*Buffer).Grow" -> (true, "Buffer", "Grow")
|
||
|
func (sym *Symbol) SplitMethod() (ptr bool, recv, name string) {
|
||
|
if sym.Kind != Method {
|
||
|
panic("not a method")
|
||
|
}
|
||
|
recv, name, _ = strings.Cut(sym.Name, ".")
|
||
|
recv = recv[len("(") : len(recv)-len(")")]
|
||
|
ptr = recv[0] == '*'
|
||
|
if ptr {
|
||
|
recv = recv[len("*"):]
|
||
|
}
|
||
|
return
|
||
|
}
|